/* -*- 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 using namespace com::sun::star; // Special value for zoom //! somewhere central #define SC_ZOOMVAL_OPTIMAL (-1) #define SC_ZOOMVAL_WHOLEPAGE (-2) #define SC_ZOOMVAL_PAGEWIDTH (-3) // Number of PropertyValues in a function description #define SC_FUNCDESC_PROPCOUNT 5 // everything without Which-ID, map only for PropertySetInfo static std::span lcl_GetSettingsPropertyMap() { static const SfxItemPropertyMapEntry aSettingsPropertyMap_Impl[] = { { SC_UNONAME_DOAUTOCP, 0, cppu::UnoType::get(), 0, 0}, { SC_UNONAME_ENTERED, 0, cppu::UnoType::get(), 0, 0}, { SC_UNONAME_EXPREF, 0, cppu::UnoType::get(), 0, 0}, { SC_UNONAME_EXTFMT, 0, cppu::UnoType::get(), 0, 0}, { SC_UNONAME_LINKUPD, 0, cppu::UnoType::get(), 0, 0}, { SC_UNONAME_MARKHDR, 0, cppu::UnoType::get(), 0, 0}, { SC_UNONAME_METRIC, 0, cppu::UnoType::get(), 0, 0}, { SC_UNONAME_MOVEDIR, 0, cppu::UnoType::get(), 0, 0}, { SC_UNONAME_MOVESEL, 0, cppu::UnoType::get(), 0, 0}, { SC_UNONAME_PRALLSH, 0, cppu::UnoType::get(), 0, 0}, { SC_UNONAME_PREMPTY, 0, cppu::UnoType::get(), 0, 0}, { SC_UNONAME_RANGEFIN, 0, cppu::UnoType::get(), 0, 0}, { SC_UNONAME_SCALE, 0, cppu::UnoType::get(), 0, 0}, { SC_UNONAME_STBFUNC, 0, cppu::UnoType::get(), 0, 0}, { SC_UNONAME_ULISTS, 0, cppu::UnoType>::get(), 0, 0}, { SC_UNONAME_PRMETRICS,0, cppu::UnoType::get(), 0, 0}, { SC_UNONAME_USETABCOL,0, cppu::UnoType::get(), 0, 0}, { SC_UNONAME_REPLWARN, 0, cppu::UnoType::get(), 0, 0}, }; return aSettingsPropertyMap_Impl; } constexpr OUString SCFUNCTIONLISTOBJ_SERVICE = u"com.sun.star.sheet.FunctionDescriptions"_ustr; constexpr OUString SCRECENTFUNCTIONSOBJ_SERVICE = u"com.sun.star.sheet.RecentFunctions"_ustr; constexpr OUString SCSPREADSHEETSETTINGS_SERVICE = u"com.sun.star.sheet.GlobalSheetSettings"_ustr; SC_SIMPLE_SERVICE_INFO( ScFunctionListObj, "stardiv.StarCalc.ScFunctionListObj", SCFUNCTIONLISTOBJ_SERVICE ) SC_SIMPLE_SERVICE_INFO( ScRecentFunctionsObj, "stardiv.StarCalc.ScRecentFunctionsObj", SCRECENTFUNCTIONSOBJ_SERVICE ) SC_SIMPLE_SERVICE_INFO( ScSpreadsheetSettings, "stardiv.StarCalc.ScSpreadsheetSettings", SCSPREADSHEETSETTINGS_SERVICE ) ScSpreadsheetSettings::ScSpreadsheetSettings() : aPropSet( lcl_GetSettingsPropertyMap() ) { } ScSpreadsheetSettings::~ScSpreadsheetSettings() { } extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* Calc_ScSpreadsheetSettings_get_implementation( css::uno::XComponentContext* , css::uno::Sequence const&) { SolarMutexGuard aGuard; ScDLL::Init(); return cppu::acquire(new ScSpreadsheetSettings()); } bool ScSpreadsheetSettings::getPropertyBool(const OUString& aPropertyName) { uno::Any any = getPropertyValue(aPropertyName); bool b = false; any >>= b; return b; } sal_Int16 ScSpreadsheetSettings::getPropertyInt16(const OUString& aPropertyName) { uno::Any any = getPropertyValue(aPropertyName); sal_Int16 b = 0; any >>= b; return b; } // XPropertySet uno::Reference SAL_CALL ScSpreadsheetSettings::getPropertySetInfo() { SolarMutexGuard aGuard; static uno::Reference aRef( new SfxItemPropertySetInfo( aPropSet.getPropertyMap() )); return aRef; } void SAL_CALL ScSpreadsheetSettings::setPropertyValue( const OUString& aPropertyName, const uno::Any& aValue ) { SolarMutexGuard aGuard; ScModule* pScMod = SC_MOD(); ScAppOptions aAppOpt(pScMod->GetAppOptions()); ScInputOptions aInpOpt(pScMod->GetInputOptions()); bool bSaveApp = false; bool bSaveInp = false; // print options aren't loaded until needed if (aPropertyName == SC_UNONAME_DOAUTOCP) { aAppOpt.SetAutoComplete( ScUnoHelpFunctions::GetBoolFromAny( aValue ) ); bSaveApp = true; } else if (aPropertyName == SC_UNONAME_ENTERED) { aInpOpt.SetEnterEdit( ScUnoHelpFunctions::GetBoolFromAny( aValue ) ); bSaveInp = true; } else if (aPropertyName == SC_UNONAME_EXPREF) { aInpOpt.SetExpandRefs( ScUnoHelpFunctions::GetBoolFromAny( aValue ) ); bSaveInp = true; } else if (aPropertyName == SC_UNONAME_EXTFMT) { aInpOpt.SetExtendFormat( ScUnoHelpFunctions::GetBoolFromAny( aValue ) ); bSaveInp = true; } else if (aPropertyName == SC_UNONAME_LINKUPD) { // XXX NOTE: this is not css::document::Settings property // LinkUpdateMode but css::sheet::XGlobalSheetSettings attribute // LinkUpdateMode. sal_Int16 n; if (!(aValue >>= n) || n < 0 || n >= ScLkUpdMode::LM_UNKNOWN) { throw css::lang::IllegalArgumentException( ("LinkUpdateMode property value must be a SHORT with a value in the range of 0--2" " as documented for css::sheet::XGlobalSheetSettings attribute LinkUpdateMode"), css::uno::Reference(), -1); } aAppOpt.SetLinkMode( static_cast(n) ); bSaveApp = true; } else if (aPropertyName == SC_UNONAME_MARKHDR) { aInpOpt.SetMarkHeader( ScUnoHelpFunctions::GetBoolFromAny( aValue ) ); bSaveInp = true; } else if (aPropertyName == SC_UNONAME_MOVESEL) { aInpOpt.SetMoveSelection( ScUnoHelpFunctions::GetBoolFromAny( aValue ) ); bSaveInp = true; } else if (aPropertyName == SC_UNONAME_RANGEFIN) { aInpOpt.SetRangeFinder( ScUnoHelpFunctions::GetBoolFromAny( aValue ) ); bSaveInp = true; } else if (aPropertyName == SC_UNONAME_USETABCOL) { aInpOpt.SetUseTabCol( ScUnoHelpFunctions::GetBoolFromAny( aValue ) ); bSaveInp = true; } else if (aPropertyName == SC_UNONAME_PRMETRICS) { aInpOpt.SetTextWysiwyg( ScUnoHelpFunctions::GetBoolFromAny( aValue ) ); bSaveInp = true; } else if (aPropertyName == SC_UNONAME_REPLWARN) { aInpOpt.SetReplaceCellsWarn( ScUnoHelpFunctions::GetBoolFromAny( aValue ) ); bSaveInp = true; } else if (aPropertyName == SC_UNONAME_METRIC) { aAppOpt.SetAppMetric( static_cast(ScUnoHelpFunctions::GetInt16FromAny( aValue )) ); bSaveApp = true; } else if (aPropertyName == SC_UNONAME_MOVEDIR) { aInpOpt.SetMoveDir( ScUnoHelpFunctions::GetInt16FromAny( aValue ) ); bSaveInp = true; } else if (aPropertyName == SC_UNONAME_SCALE) { short nVal = ScUnoHelpFunctions::GetInt16FromAny( aValue ); if ( nVal < 0 ) { SvxZoomType eType = SvxZoomType::PERCENT; switch (nVal) { case SC_ZOOMVAL_OPTIMAL: eType = SvxZoomType::OPTIMAL; break; case SC_ZOOMVAL_WHOLEPAGE: eType = SvxZoomType::WHOLEPAGE; break; case SC_ZOOMVAL_PAGEWIDTH: eType = SvxZoomType::PAGEWIDTH; break; } aAppOpt.SetZoomType( eType ); } else if ( nVal >= MINZOOM && nVal <= MAXZOOM ) { aAppOpt.SetZoom( nVal ); aAppOpt.SetZoomType( SvxZoomType::PERCENT ); } bSaveApp = true; } else if (aPropertyName == SC_UNONAME_STBFUNC) { aAppOpt.SetStatusFunc( ScUnoHelpFunctions::GetInt16FromAny( aValue ) ); bSaveApp = true; } else if (aPropertyName == SC_UNONAME_ULISTS) { ScUserList* pUserList = ScGlobal::GetUserList(); uno::Sequence aSeq; if ( pUserList && ( aValue >>= aSeq ) ) { // directly change the active list // ScGlobal::SetUseTabCol does not do much else pUserList->clear(); for (const OUString& aEntry : aSeq) { pUserList->emplace_back(aEntry); } bSaveApp = true; // List with App-Options are saved } } else if (aPropertyName == SC_UNONAME_PRALLSH) { ScPrintOptions aPrintOpt(pScMod->GetPrintOptions()); aPrintOpt.SetAllSheets( ScUnoHelpFunctions::GetBoolFromAny( aValue ) ); pScMod->SetPrintOptions( aPrintOpt ); } else if (aPropertyName == SC_UNONAME_PREMPTY) { ScPrintOptions aPrintOpt(pScMod->GetPrintOptions()); aPrintOpt.SetSkipEmpty( !ScUnoHelpFunctions::GetBoolFromAny( aValue ) ); // reversed pScMod->SetPrintOptions( aPrintOpt ); SfxGetpApp()->Broadcast( SfxHint( SfxHintId::ScPrintOptions ) ); // update previews } if ( bSaveApp ) pScMod->SetAppOptions( aAppOpt ); if ( bSaveInp ) pScMod->SetInputOptions( aInpOpt ); } uno::Any SAL_CALL ScSpreadsheetSettings::getPropertyValue( const OUString& aPropertyName ) { SolarMutexGuard aGuard; uno::Any aRet; ScModule* pScMod = SC_MOD(); ScAppOptions aAppOpt = pScMod->GetAppOptions(); const ScInputOptions& aInpOpt = pScMod->GetInputOptions(); // print options aren't loaded until needed if (aPropertyName == SC_UNONAME_DOAUTOCP) aRet <<= aAppOpt.GetAutoComplete(); else if (aPropertyName == SC_UNONAME_ENTERED ) aRet <<= aInpOpt.GetEnterEdit(); else if (aPropertyName == SC_UNONAME_EXPREF ) aRet <<= aInpOpt.GetExpandRefs(); else if (aPropertyName == SC_UNONAME_EXTFMT ) aRet <<= aInpOpt.GetExtendFormat(); else if (aPropertyName == SC_UNONAME_LINKUPD ) aRet <<= static_cast(aAppOpt.GetLinkMode()); else if (aPropertyName == SC_UNONAME_MARKHDR ) aRet <<= aInpOpt.GetMarkHeader(); else if (aPropertyName == SC_UNONAME_MOVESEL ) aRet <<= aInpOpt.GetMoveSelection(); else if (aPropertyName == SC_UNONAME_RANGEFIN ) aRet <<= aInpOpt.GetRangeFinder(); else if (aPropertyName == SC_UNONAME_USETABCOL ) aRet <<= aInpOpt.GetUseTabCol(); else if (aPropertyName == SC_UNONAME_PRMETRICS ) aRet <<= aInpOpt.GetTextWysiwyg(); else if (aPropertyName == SC_UNONAME_REPLWARN ) aRet <<= aInpOpt.GetReplaceCellsWarn(); else if (aPropertyName == SC_UNONAME_METRIC ) aRet <<= static_cast(aAppOpt.GetAppMetric()); else if (aPropertyName == SC_UNONAME_MOVEDIR ) aRet <<= static_cast(aInpOpt.GetMoveDir()); else if (aPropertyName == SC_UNONAME_STBFUNC ) aRet <<= static_cast(aAppOpt.GetStatusFunc()); else if (aPropertyName == SC_UNONAME_SCALE ) { sal_Int16 nZoomVal = 0; switch ( aAppOpt.GetZoomType() ) { case SvxZoomType::PERCENT: nZoomVal = aAppOpt.GetZoom(); break; case SvxZoomType::OPTIMAL: nZoomVal = SC_ZOOMVAL_OPTIMAL; break; case SvxZoomType::WHOLEPAGE: nZoomVal = SC_ZOOMVAL_WHOLEPAGE; break; case SvxZoomType::PAGEWIDTH: nZoomVal = SC_ZOOMVAL_PAGEWIDTH; break; default: { // added to avoid warnings } } aRet <<= nZoomVal; } else if (aPropertyName == SC_UNONAME_ULISTS ) { ScUserList* pUserList = ScGlobal::GetUserList(); if (pUserList) { size_t nCount = pUserList->size(); uno::Sequence aSeq(nCount); OUString* pAry = aSeq.getArray(); for (size_t i=0; iGetPrintOptions().GetAllSheets(); else if (aPropertyName == SC_UNONAME_PREMPTY ) aRet <<= !pScMod->GetPrintOptions().GetSkipEmpty(); // reversed return aRet; } SC_IMPL_DUMMY_PROPERTY_LISTENER( ScSpreadsheetSettings ) ScRecentFunctionsObj::ScRecentFunctionsObj() { } ScRecentFunctionsObj::~ScRecentFunctionsObj() { } extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* ScRecentFunctionsObj_get_implementation(css::uno::XComponentContext*, css::uno::Sequence const &) { SolarMutexGuard aGuard; ScDLL::Init(); return cppu::acquire(new ScRecentFunctionsObj()); } // XRecentFunctions uno::Sequence SAL_CALL ScRecentFunctionsObj::getRecentFunctionIds() { SolarMutexGuard aGuard; const ScAppOptions& rOpt = SC_MOD()->GetAppOptions(); sal_uInt16 nCount = rOpt.GetLRUFuncListCount(); const sal_uInt16* pFuncs = rOpt.GetLRUFuncList(); if (pFuncs) { uno::Sequence aSeq(nCount); sal_Int32* pAry = aSeq.getArray(); for (sal_uInt16 i=0; i& aRecentFunctionIds ) { SolarMutexGuard aGuard; sal_uInt16 nCount = static_cast(std::min( aRecentFunctionIds.getLength(), sal_Int32(LRU_MAX) )); const sal_Int32* pAry = aRecentFunctionIds.getConstArray(); std::unique_ptr pFuncs(nCount ? new sal_uInt16[nCount] : nullptr); for (sal_uInt16 i=0; i(pAry[i]); //! check for valid values? ScModule* pScMod = SC_MOD(); ScAppOptions aNewOpts(pScMod->GetAppOptions()); aNewOpts.SetLRUFuncList(pFuncs.get(), nCount); pScMod->SetAppOptions(aNewOpts); } sal_Int32 SAL_CALL ScRecentFunctionsObj::getMaxRecentFunctions() { return LRU_MAX; } ScFunctionListObj::ScFunctionListObj() { } ScFunctionListObj::~ScFunctionListObj() { } extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* ScFunctionListObj_get_implementation(css::uno::XComponentContext*, css::uno::Sequence const &) { SolarMutexGuard aGuard; ScDLL::Init(); return cppu::acquire(new ScFunctionListObj()); } static void lcl_FillSequence( uno::Sequence& rSequence, const ScFuncDesc& rDesc ) { rDesc.initArgumentInfo(); // full argument info is needed OSL_ENSURE( rSequence.getLength() == SC_FUNCDESC_PROPCOUNT, "Wrong count" ); beans::PropertyValue* pArray = rSequence.getArray(); pArray[0].Name = SC_UNONAME_ID; pArray[0].Value <<= static_cast(rDesc.nFIndex); pArray[1].Name = SC_UNONAME_CATEGORY; pArray[1].Value <<= static_cast(rDesc.nCategory); pArray[2].Name = SC_UNONAME_NAME; if (rDesc.mxFuncName) pArray[2].Value <<= *rDesc.mxFuncName; pArray[3].Name = SC_UNONAME_DESCRIPTION; if (rDesc.mxFuncDesc) pArray[3].Value <<= *rDesc.mxFuncDesc; pArray[4].Name = SC_UNONAME_ARGUMENTS; if (rDesc.maDefArgNames.empty() || rDesc.maDefArgDescs.empty() || !rDesc.pDefArgFlags) return; sal_uInt16 nCount = rDesc.nArgCount; if (nCount >= PAIRED_VAR_ARGS) nCount -= PAIRED_VAR_ARGS - 2; else if (nCount >= VAR_ARGS) nCount -= VAR_ARGS - 1; sal_uInt16 nSeqCount = rDesc.GetSuppressedArgCount(); if (nSeqCount >= PAIRED_VAR_ARGS) nSeqCount -= PAIRED_VAR_ARGS - 2; else if (nSeqCount >= VAR_ARGS) nSeqCount -= VAR_ARGS - 1; if (!nSeqCount) return; uno::Sequence aArgSeq(nSeqCount); sheet::FunctionArgument* pArgAry = aArgSeq.getArray(); for (sal_uInt16 i=0, j=0; i SAL_CALL ScFunctionListObj::getById( sal_Int32 nId ) { SolarMutexGuard aGuard; const ScFunctionList* pFuncList = ScGlobal::GetStarCalcFunctionList(); if ( !pFuncList ) throw uno::RuntimeException(); // should not happen sal_uInt16 nCount = static_cast(pFuncList->GetCount()); for (sal_uInt16 nIndex=0; nIndexGetFunction(nIndex); if ( pDesc && pDesc->nFIndex == nId ) { uno::Sequence aSeq( SC_FUNCDESC_PROPCOUNT ); lcl_FillSequence( aSeq, *pDesc ); return aSeq; } } throw lang::IllegalArgumentException(); // not found } // XNameAccess uno::Any SAL_CALL ScFunctionListObj::getByName( const OUString& aName ) { SolarMutexGuard aGuard; const ScFunctionList* pFuncList = ScGlobal::GetStarCalcFunctionList(); if ( !pFuncList ) throw uno::RuntimeException(); // should not happen sal_uInt16 nCount = static_cast(pFuncList->GetCount()); for (sal_uInt16 nIndex=0; nIndexGetFunction(nIndex); //! Case-insensitive??? if ( pDesc && pDesc->mxFuncName && aName == *pDesc->mxFuncName ) { uno::Sequence aSeq( SC_FUNCDESC_PROPCOUNT ); lcl_FillSequence( aSeq, *pDesc ); return uno::Any(aSeq); } } throw container::NoSuchElementException(); // not found } // XIndexAccess sal_Int32 SAL_CALL ScFunctionListObj::getCount() { SolarMutexGuard aGuard; sal_Int32 nCount = 0; const ScFunctionList* pFuncList = ScGlobal::GetStarCalcFunctionList(); if ( pFuncList ) nCount = static_cast(pFuncList->GetCount()); return nCount; } uno::Any SAL_CALL ScFunctionListObj::getByIndex( sal_Int32 nIndex ) { SolarMutexGuard aGuard; const ScFunctionList* pFuncList = ScGlobal::GetStarCalcFunctionList(); if ( !pFuncList ) throw uno::RuntimeException(); // should not happen if ( nIndex >= 0 && o3tl::make_unsigned(nIndex) < pFuncList->GetCount() ) { const ScFuncDesc* pDesc = pFuncList->GetFunction(nIndex); if ( pDesc ) { uno::Sequence aSeq( SC_FUNCDESC_PROPCOUNT ); lcl_FillSequence( aSeq, *pDesc ); return uno::Any(aSeq); } } throw lang::IndexOutOfBoundsException(); // illegal index } // XEnumerationAccess uno::Reference SAL_CALL ScFunctionListObj::createEnumeration() { SolarMutexGuard aGuard; return new ScIndexEnumeration(this, "com.sun.star.sheet.FunctionDescriptionEnumeration"); } // XElementAccess uno::Type SAL_CALL ScFunctionListObj::getElementType() { return cppu::UnoType>::get(); } sal_Bool SAL_CALL ScFunctionListObj::hasElements() { SolarMutexGuard aGuard; return ( getCount() > 0 ); } uno::Sequence SAL_CALL ScFunctionListObj::getElementNames() { SolarMutexGuard aGuard; const ScFunctionList* pFuncList = ScGlobal::GetStarCalcFunctionList(); if ( pFuncList ) { sal_uInt32 nCount = pFuncList->GetCount(); uno::Sequence aSeq(nCount); OUString* pAry = aSeq.getArray(); for (sal_uInt32 nIndex=0; nIndexGetFunction(nIndex); if ( pDesc && pDesc->mxFuncName ) pAry[nIndex] = *pDesc->mxFuncName; } return aSeq; } return {}; } sal_Bool SAL_CALL ScFunctionListObj::hasByName( const OUString& aName ) { SolarMutexGuard aGuard; const ScFunctionList* pFuncList = ScGlobal::GetStarCalcFunctionList(); if ( pFuncList ) { sal_uInt32 nCount = pFuncList->GetCount(); for (sal_uInt32 nIndex=0; nIndexGetFunction(nIndex); //! Case-insensitive??? if ( pDesc && pDesc->mxFuncName && aName == *pDesc->mxFuncName ) return true; } } return false; } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */