summaryrefslogtreecommitdiffstats
path: root/sc/source/core/inc
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 05:54:39 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 05:54:39 +0000
commit267c6f2ac71f92999e969232431ba04678e7437e (patch)
tree358c9467650e1d0a1d7227a21dac2e3d08b622b2 /sc/source/core/inc
parentInitial commit. (diff)
downloadlibreoffice-267c6f2ac71f92999e969232431ba04678e7437e.tar.xz
libreoffice-267c6f2ac71f92999e969232431ba04678e7437e.zip
Adding upstream version 4:24.2.0.upstream/4%24.2.0
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'sc/source/core/inc')
-rw-r--r--sc/source/core/inc/addinhelpid.hxx45
-rw-r--r--sc/source/core/inc/addinlis.hxx84
-rw-r--r--sc/source/core/inc/adiasync.hxx77
-rw-r--r--sc/source/core/inc/bcaslot.hxx398
-rw-r--r--sc/source/core/inc/cellkeytranslator.hxx82
-rw-r--r--sc/source/core/inc/ddelink.hxx84
-rw-r--r--sc/source/core/inc/doubleref.hxx178
-rw-r--r--sc/source/core/inc/formulagroupcl.hxx29
-rw-r--r--sc/source/core/inc/grouptokenconverter.hxx38
-rw-r--r--sc/source/core/inc/interpre.hxx1167
-rw-r--r--sc/source/core/inc/jumpmatrix.hxx122
-rw-r--r--sc/source/core/inc/parclass.hxx144
-rw-r--r--sc/source/core/inc/poolhelp.hxx64
-rw-r--r--sc/source/core/inc/refupdat.hxx71
-rw-r--r--sc/source/core/inc/scrdata.hxx37
-rw-r--r--sc/source/core/inc/sharedstringpoolpurge.hxx47
-rw-r--r--sc/source/core/inc/webservicelink.hxx49
17 files changed, 2716 insertions, 0 deletions
diff --git a/sc/source/core/inc/addinhelpid.hxx b/sc/source/core/inc/addinhelpid.hxx
new file mode 100644
index 0000000000..ccc5406d8f
--- /dev/null
+++ b/sc/source/core/inc/addinhelpid.hxx
@@ -0,0 +1,45 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <rtl/ustring.hxx>
+#include <rtl/string.hxx>
+
+struct ScUnoAddInHelpId;
+
+/** Generates help IDs for standard Calc AddIns. */
+class ScUnoAddInHelpIdGenerator
+{
+private:
+ const ScUnoAddInHelpId* pCurrHelpIds; /// Array of function names and help IDs.
+ sal_uInt32 nArrayCount; /// Count of array entries.
+
+public:
+ ScUnoAddInHelpIdGenerator() = delete;
+ ScUnoAddInHelpIdGenerator( std::u16string_view rServiceName );
+
+ /** Sets service name of the AddIn. Has to be done before requesting help IDs. */
+ void SetServiceName( std::u16string_view rServiceName );
+
+ /** @return The help ID of the function with given built-in name or 0 if not found. */
+ OUString GetHelpId( std::u16string_view rFuncName ) const;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/inc/addinlis.hxx b/sc/source/core/inc/addinlis.hxx
new file mode 100644
index 0000000000..d1cc7f3dd8
--- /dev/null
+++ b/sc/source/core/inc/addinlis.hxx
@@ -0,0 +1,84 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <memory>
+#include "adiasync.hxx"
+#include <com/sun/star/sheet/XResultListener.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <cppuhelper/implbase.hxx>
+
+namespace com::sun::star::sheet { class XVolatileResult; }
+namespace rtl { template <class reference_type> class Reference; }
+
+class ScDocument;
+
+class ScAddInListener final : public cppu::WeakImplHelper<
+ css::sheet::XResultListener,
+ css::lang::XServiceInfo >,
+ public SvtBroadcaster
+{
+private:
+ css::uno::Reference<css::sheet::XVolatileResult> xVolRes;
+ css::uno::Any aResult;
+ std::unique_ptr<ScAddInDocs> pDocs; // documents where this is used
+
+ static ::std::vector<rtl::Reference<ScAddInListener>> aAllListeners;
+
+ // always allocated via CreateListener
+ ScAddInListener( css::uno::Reference<css::sheet::XVolatileResult> xVR,
+ ScDocument* pD );
+
+public:
+ virtual ~ScAddInListener() override;
+
+ // create Listener and put it into global list
+ static ScAddInListener* CreateListener(
+ const css::uno::Reference<css::sheet::XVolatileResult>& xVR,
+ ScDocument* pDoc );
+
+ static ScAddInListener* Get( const css::uno::Reference<css::sheet::XVolatileResult>& xVR );
+
+ static void RemoveDocument( ScDocument* pDocument );
+
+ bool HasDocument( ScDocument* pDoc ) const
+ { return pDocs->find( pDoc ) != pDocs->end(); }
+
+ void AddDocument( ScDocument* pDoc )
+ { pDocs->insert( pDoc ); }
+
+ const css::uno::Any& GetResult() const
+ { return aResult; }
+
+ // XResultListener
+ virtual void SAL_CALL modified( const css::sheet::ResultEvent& aEvent ) override;
+
+ // XEventListener
+ virtual void SAL_CALL disposing( const css::lang::EventObject& Source ) override;
+
+ // XServiceInfo
+ virtual OUString SAL_CALL getImplementationName() override;
+
+ virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override;
+
+ virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/inc/adiasync.hxx b/sc/source/core/inc/adiasync.hxx
new file mode 100644
index 0000000000..b693f12a28
--- /dev/null
+++ b/sc/source/core/inc/adiasync.hxx
@@ -0,0 +1,77 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <svl/broadcast.hxx>
+#include <set>
+#include <tools/solar.h>
+
+#include <callform.hxx>
+
+extern "C" {
+void CALLTYPE ScAddInAsyncCallBack( double& nHandle, void* pData );
+}
+
+class ScDocument;
+using ScAddInDocs = std::set<ScDocument*>;
+
+class ScAddInAsync final : public SvtBroadcaster
+{
+private:
+ union
+ {
+ double nVal; // current value
+ OUString* pStr;
+ };
+ std::unique_ptr<ScAddInDocs> pDocs; // List of using documents
+ LegacyFuncData* mpFuncData; // Pointer to data in collection
+ sal_uLong nHandle; // is casted from double to sal_uLong
+ ParamType meType; // result of type PTR_DOUBLE or PTR_STRING
+ bool bValid; // is value valid?
+
+public:
+ // cTor only if ScAddInAsync::Get fails.
+ // nIndex: Index from FunctionCollection
+ ScAddInAsync(sal_uLong nHandle, LegacyFuncData* pFuncData, ScDocument* pDoc);
+ virtual ~ScAddInAsync() override;
+ static ScAddInAsync* Get( sal_uLong nHandle );
+ static void CallBack( sal_uLong nHandle, void* pData );
+ static void RemoveDocument( ScDocument* pDocument );
+ bool IsValid() const { return bValid; }
+ ParamType GetType() const { return meType; }
+ double GetValue() const { return nVal; }
+ const OUString& GetString() const { return *pStr; }
+ bool HasDocument( ScDocument* pDoc ) const
+ { return pDocs->find( pDoc ) != pDocs->end(); }
+ void AddDocument( ScDocument* pDoc ) { pDocs->insert( pDoc ); }
+
+ // Comparators for PtrArrSort
+ bool operator< ( const ScAddInAsync& r ) const { return nHandle < r.nHandle; }
+};
+
+struct CompareScAddInAsync
+{
+ bool operator()( std::unique_ptr<ScAddInAsync> const& lhs, std::unique_ptr<ScAddInAsync> const& rhs ) const { return (*lhs)<(*rhs); }
+};
+using ScAddInAsyncs = std::set<std::unique_ptr<ScAddInAsync>, CompareScAddInAsync>;
+
+extern ScAddInAsyncs theAddInAsyncTbl; // in adiasync.cxx
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/inc/bcaslot.hxx b/sc/source/core/inc/bcaslot.hxx
new file mode 100644
index 0000000000..6e891e8aab
--- /dev/null
+++ b/sc/source/core/inc/bcaslot.hxx
@@ -0,0 +1,398 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <memory>
+#include <map>
+#include <unordered_set>
+
+#include <svl/broadcast.hxx>
+#include <svl/hint.hxx>
+#include <tools/solar.h>
+
+#include <document.hxx>
+#include <global.hxx>
+
+namespace sc {
+
+struct BroadcasterState;
+class ColumnSpanSet;
+
+}
+class ScHint;
+
+namespace sc {
+
+struct AreaListener
+{
+ ScRange maArea;
+ bool mbGroupListening;
+ SvtListener* mpListener;
+};
+
+}
+
+/**
+ Used in a Unique Associative Container.
+ */
+
+class ScBroadcastArea
+{
+private:
+ ScBroadcastArea* pUpdateChainNext;
+ SvtBroadcaster aBroadcaster;
+ ScRange aRange;
+ sal_uLong nRefCount;
+
+ bool mbInUpdateChain:1;
+ bool mbGroupListening:1;
+
+public:
+ ScBroadcastArea(const ScBroadcastArea&) = delete;
+ const ScBroadcastArea& operator=(const ScBroadcastArea&) = delete;
+
+ ScBroadcastArea( const ScRange& rRange );
+
+ SvtBroadcaster& GetBroadcaster() { return aBroadcaster; }
+ const SvtBroadcaster& GetBroadcaster() const { return aBroadcaster; }
+ void UpdateRange( const ScRange& rNewRange )
+ { aRange = rNewRange; }
+ const ScRange& GetRange() const { return aRange; }
+ void IncRef() { ++nRefCount; }
+ sal_uLong DecRef() { return nRefCount ? --nRefCount : 0; }
+ sal_uLong GetRef() const { return nRefCount; }
+ ScBroadcastArea* GetUpdateChainNext() const { return pUpdateChainNext; }
+ void SetUpdateChainNext( ScBroadcastArea* p ) { pUpdateChainNext = p; }
+ bool IsInUpdateChain() const { return mbInUpdateChain; }
+ void SetInUpdateChain( bool b ) { mbInUpdateChain = b; }
+
+ bool IsGroupListening() const { return mbGroupListening; }
+ void SetGroupListening( bool b ) { mbGroupListening = b; }
+
+ /** Equalness of this or range. */
+ inline bool operator==( const ScBroadcastArea & rArea ) const;
+};
+
+inline bool ScBroadcastArea::operator==( const ScBroadcastArea & rArea ) const
+{
+ return aRange == rArea.aRange && mbGroupListening == rArea.mbGroupListening;
+}
+
+struct ScBroadcastAreaEntry
+{
+ ScBroadcastArea* mpArea;
+ mutable bool mbErasure; ///< TRUE if marked for erasure in this set
+
+ ScBroadcastAreaEntry( ScBroadcastArea* p ) : mpArea( p), mbErasure( false) {}
+};
+
+struct ScBroadcastAreaHash
+{
+ size_t operator()( const ScBroadcastAreaEntry& rEntry ) const
+ {
+ return rEntry.mpArea->GetRange().hashArea() + static_cast<size_t>(rEntry.mpArea->IsGroupListening());
+ }
+};
+
+struct ScBroadcastAreaEqual
+{
+ bool operator()( const ScBroadcastAreaEntry& rEntry1, const ScBroadcastAreaEntry& rEntry2) const
+ {
+ return *rEntry1.mpArea == *rEntry2.mpArea;
+ }
+};
+
+typedef std::unordered_set< ScBroadcastAreaEntry, ScBroadcastAreaHash, ScBroadcastAreaEqual > ScBroadcastAreas;
+
+struct ScBroadcastAreaBulkHash
+{
+ size_t operator()( const ScBroadcastArea* p ) const
+ {
+ return reinterpret_cast<size_t>(p);
+ }
+};
+
+struct ScBroadcastAreaBulkEqual
+{
+ bool operator()( const ScBroadcastArea* p1, const ScBroadcastArea* p2) const
+ {
+ return p1 == p2;
+ }
+};
+
+typedef std::unordered_set< const ScBroadcastArea*, ScBroadcastAreaBulkHash,
+ ScBroadcastAreaBulkEqual > ScBroadcastAreasBulk;
+
+class ScBroadcastAreaSlotMachine;
+
+/// Collection of BroadcastAreas
+class ScBroadcastAreaSlot
+{
+private:
+ ScBroadcastAreas aBroadcastAreaTbl;
+ mutable ScBroadcastArea aTmpSeekBroadcastArea; // for FindBroadcastArea()
+ ScDocument* pDoc;
+ ScBroadcastAreaSlotMachine* pBASM;
+ bool mbInBroadcastIteration;
+
+ /**
+ * If true, the slot has at least one area broadcaster marked for removal.
+ * This flag is used only during broadcast iteration, to speed up
+ * iteration. Using this flag is cheaper than dereferencing each iterator
+ * and checking its own flag inside especially when no areas are marked
+ * for removal.
+ */
+ bool mbHasErasedArea;
+
+ ScBroadcastAreas::iterator FindBroadcastArea( const ScRange& rRange, bool bGroupListening );
+
+ /**
+ More hypothetical (memory would probably be doomed anyway) check
+ whether there would be an overflow when adding an area, setting the
+ proper state if so.
+
+ @return HardRecalcState::ETERNAL if a HardRecalcState is effective and
+ area is not to be added.
+ */
+ ScDocument::HardRecalcState CheckHardRecalcStateCondition() const;
+
+ /** Finally erase all areas pushed as to-be-erased. */
+ void FinallyEraseAreas();
+
+ static bool isMarkedErased( const ScBroadcastAreas::const_iterator& rIter )
+ {
+ return rIter->mbErasure;
+ }
+
+public:
+ ScBroadcastAreaSlot( ScDocument* pDoc,
+ ScBroadcastAreaSlotMachine* pBASM );
+ ~ScBroadcastAreaSlot();
+
+ /**
+ Only here new ScBroadcastArea objects are created, prevention of dupes.
+
+ @param rpArea
+ If NULL, a new ScBroadcastArea is created and assigned ton the
+ reference if a matching area wasn't found. If a matching area was
+ found, that is assigned. In any case, the SvtListener is added to
+ the broadcaster.
+
+ If not NULL then no listeners are started, only the area is
+ inserted and the reference count incremented. Effectively the same
+ as InsertListeningArea(), so use that instead.
+
+ @return
+ true if rpArea passed was NULL and ScBroadcastArea is newly
+ created.
+ */
+ bool StartListeningArea(
+ const ScRange& rRange, bool bGroupListening, SvtListener* pListener, ScBroadcastArea*& rpArea );
+
+ /**
+ Insert a ScBroadcastArea obtained via StartListeningArea() to
+ subsequent slots.
+ */
+ void InsertListeningArea( ScBroadcastArea* pArea );
+
+ void EndListeningArea(
+ const ScRange& rRange, bool bGroupListening, SvtListener* pListener, ScBroadcastArea*& rpArea );
+
+ bool AreaBroadcast( const ScRange& rRange, SfxHintId nHint );
+ bool AreaBroadcast( const ScHint& rHint );
+ void DelBroadcastAreasInRange( const ScRange& rRange );
+ void UpdateRemove( UpdateRefMode eUpdateRefMode,
+ const ScRange& rRange,
+ SCCOL nDx, SCROW nDy, SCTAB nDz );
+ void UpdateRemoveArea( ScBroadcastArea* pArea );
+ void UpdateInsert( ScBroadcastArea* pArea );
+
+ bool IsInBroadcastIteration() const { return mbInBroadcastIteration; }
+
+ /** Erase an area from set and delete it if last reference, or if
+ mbInBroadcastIteration is set push it to the vector of to-be-erased
+ areas instead.
+
+ Meant to be used internally and from ScBroadcastAreaSlotMachine only.
+ */
+ void EraseArea( ScBroadcastAreas::iterator& rIter );
+
+ void GetAllListeners(
+ const ScRange& rRange, std::vector<sc::AreaListener>& rListeners,
+ sc::AreaOverlapType eType, sc::ListenerGroupType eGroup );
+
+ void CollectBroadcasterState(sc::BroadcasterState& rState) const;
+};
+
+/**
+ BroadcastAreaSlots and their management, once per document.
+ */
+
+class ScBroadcastAreaSlotMachine
+{
+private:
+ typedef std::map<ScBroadcastArea*, sc::ColumnSpanSet> BulkGroupAreasType;
+
+ /**
+ Slot offset arrangement of columns and rows, once per sheet.
+
+ +---+---+
+ | 0 | 3 |
+ +---+---+
+ | 1 | 4 |
+ +---+---+
+ | 2 | 5 |
+ +---+---+
+ */
+
+ class TableSlots
+ {
+ public:
+ TableSlots(SCSIZE nBcaSlots);
+ TableSlots(TableSlots&&) noexcept;
+ ~TableSlots();
+ ScBroadcastAreaSlot** getSlots() const { return ppSlots.get(); }
+
+ private:
+ SCSIZE mnBcaSlots;
+ std::unique_ptr<ScBroadcastAreaSlot*[]> ppSlots;
+
+ TableSlots( const TableSlots& ) = delete;
+ TableSlots& operator=( const TableSlots& ) = delete;
+ };
+
+ typedef ::std::map< SCTAB, TableSlots > TableSlotsMap;
+
+ typedef ::std::vector< ::std::pair< ScBroadcastAreaSlot*, ScBroadcastAreas::iterator > > AreasToBeErased;
+
+private:
+ struct ScSlotData
+ {
+ SCROW nStartRow; // first row of this segment
+ SCROW nStopRow; // first row of next segment
+ SCSIZE nSliceRow; // row slice size in this segment
+ SCSIZE nCumulatedRow; // cumulated slots of previous segments (previous rows)
+ SCROW nStartCol; // first column of this segment
+ SCROW nStopCol; // first column of next segment
+ SCSIZE nSliceCol; // column slice size in this segment
+ SCSIZE nCumulatedCol; // cumulated slots of previous segments (previous columns)
+
+ ScSlotData( SCROW r1, SCROW r2, SCSIZE sr, SCSIZE cr, SCCOL c1, SCCOL c2, SCSIZE sc, SCSIZE cc )
+ : nStartRow(r1)
+ , nStopRow(r2)
+ , nSliceRow(sr)
+ , nCumulatedRow(cr)
+ , nStartCol(c1)
+ , nStopCol(c2)
+ , nSliceCol(sc)
+ , nCumulatedCol(cc) {}
+ };
+ typedef ::std::vector< ScSlotData > ScSlotDistribution;
+ ScSlotDistribution maSlotDistribution;
+ SCSIZE mnBcaSlotsCol;
+ SCSIZE mnBcaSlots;
+ ScBroadcastAreasBulk aBulkBroadcastAreas;
+ BulkGroupAreasType m_BulkGroupAreas;
+ TableSlotsMap aTableSlotsMap;
+ AreasToBeErased maAreasToBeErased;
+ std::unique_ptr<SvtBroadcaster> pBCAlways; // for the RC_ALWAYS special range
+ ScDocument *pDoc;
+ ScBroadcastArea *pUpdateChain;
+ ScBroadcastArea *pEOUpdateChain;
+ sal_uInt32 nInBulkBroadcast;
+
+ inline SCSIZE ComputeSlotOffset( const ScAddress& rAddress ) const;
+ void ComputeAreaPoints( const ScRange& rRange,
+ SCSIZE& nStart, SCSIZE& nEnd,
+ SCSIZE& nRowBreak ) const;
+#ifdef DBG_UTIL
+ void DoChecks();
+#endif
+
+public:
+ ScBroadcastAreaSlotMachine( ScDocument* pDoc );
+ ~ScBroadcastAreaSlotMachine();
+ void StartListeningArea(
+ const ScRange& rRange, bool bGroupListening, SvtListener* pListener );
+
+ void EndListeningArea(
+ const ScRange& rRange, bool bGroupListening, SvtListener* pListener );
+
+ bool AreaBroadcast( const ScRange& rRange, SfxHintId nHint );
+ bool AreaBroadcast( const ScHint& rHint ) const;
+ // return: at least one broadcast occurred
+ void DelBroadcastAreasInRange( const ScRange& rRange );
+ void UpdateBroadcastAreas( UpdateRefMode eUpdateRefMode,
+ const ScRange& rRange,
+ SCCOL nDx, SCROW nDy, SCTAB nDz );
+ void EnterBulkBroadcast();
+ void LeaveBulkBroadcast( SfxHintId nHintId );
+ bool InsertBulkArea( const ScBroadcastArea* p );
+
+ void InsertBulkGroupArea( ScBroadcastArea* pArea, const ScRange& rRange );
+ void RemoveBulkGroupArea( ScBroadcastArea* pArea );
+ bool BulkBroadcastGroupAreas( SfxHintId nHintId );
+
+ /// @return: how many removed
+ size_t RemoveBulkArea( const ScBroadcastArea* p );
+ void SetUpdateChain( ScBroadcastArea* p ) { pUpdateChain = p; }
+ ScBroadcastArea* GetEOUpdateChain() const { return pEOUpdateChain; }
+ void SetEOUpdateChain( ScBroadcastArea* p ) { pEOUpdateChain = p; }
+ bool IsInBulkBroadcast() const { return nInBulkBroadcast > 0; }
+
+ // only for ScBroadcastAreaSlot
+ void PushAreaToBeErased( ScBroadcastAreaSlot* pSlot,
+ ScBroadcastAreas::iterator& rIter );
+ // only for ScBroadcastAreaSlot
+ void FinallyEraseAreas( ScBroadcastAreaSlot* pSlot );
+
+ std::vector<sc::AreaListener> GetAllListeners(
+ const ScRange& rRange, sc::AreaOverlapType eType,
+ sc::ListenerGroupType eGroup = sc::ListenerGroupType::Both );
+
+ void CollectBroadcasterState(sc::BroadcasterState& rState) const;
+};
+
+class ScBulkBroadcast
+{
+ ScBroadcastAreaSlotMachine* pBASM;
+ SfxHintId mnHintId;
+
+ ScBulkBroadcast(ScBulkBroadcast const &) = delete;
+ ScBulkBroadcast(ScBulkBroadcast &&) = delete;
+ ScBulkBroadcast & operator =(ScBulkBroadcast const &) = delete;
+ ScBulkBroadcast & operator =(ScBulkBroadcast &&) = delete;
+
+public:
+ explicit ScBulkBroadcast( ScBroadcastAreaSlotMachine* p, SfxHintId nHintId ) :
+ pBASM(p),
+ mnHintId(nHintId)
+ {
+ if (pBASM)
+ pBASM->EnterBulkBroadcast();
+ }
+ ~ScBulkBroadcast() COVERITY_NOEXCEPT_FALSE
+ {
+ if (pBASM)
+ pBASM->LeaveBulkBroadcast( mnHintId );
+ }
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/inc/cellkeytranslator.hxx b/sc/source/core/inc/cellkeytranslator.hxx
new file mode 100644
index 0000000000..953e0c99ed
--- /dev/null
+++ b/sc/source/core/inc/cellkeytranslator.hxx
@@ -0,0 +1,82 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <formula/opcode.hxx>
+#include <unotools/transliterationwrapper.hxx>
+#include <vector>
+#include <memory>
+#include <unordered_map>
+
+namespace com::sun::star::lang
+{
+struct Locale;
+}
+
+struct TransItem;
+
+struct ScCellKeyword
+{
+ const char* mpName;
+ OpCode meOpCode;
+ const css::lang::Locale& mrLocale;
+
+ ScCellKeyword(const char* pName, OpCode eOpCode, const css::lang::Locale& rLocale);
+};
+
+typedef std::unordered_map<OUString, ::std::vector<ScCellKeyword>> ScCellKeywordHashMap;
+
+/** Translate cell function keywords.
+
+ This class provides a convenient way to translate a string keyword used as
+ a cell function argument. Since Calc's built-in cell functions don't
+ localize string keywords, this class is used mainly to deal with an Excel
+ document where string names may be localized.
+
+ To use, simply call the
+
+ ScCellKeywordTranslator::transKeyword(...)
+
+ function.
+
+ Note that when the locale and/or the opcode is specified, the function
+ tries to find a string with matching locale and/or opcode. But when it
+ fails to find one that satisfies the specified locale and/or opcode, it
+ returns a translated string with non-matching locale and/or opcode if
+ available. */
+class ScCellKeywordTranslator
+{
+public:
+ static void transKeyword(OUString& rName, const css::lang::Locale* pLocale, OpCode eOpCode);
+ ~ScCellKeywordTranslator();
+
+private:
+ ScCellKeywordTranslator();
+
+ void addToMap(const OUString& rKey, const char* pName, const css::lang::Locale& rLocale,
+ OpCode eOpCode);
+ void addToMap(const TransItem* pItems, const css::lang::Locale& rLocale);
+
+ static ::std::unique_ptr<ScCellKeywordTranslator> spInstance;
+ ScCellKeywordHashMap maStringNameMap;
+ ::utl::TransliterationWrapper maTransWrapper;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/inc/ddelink.hxx b/sc/source/core/inc/ddelink.hxx
new file mode 100644
index 0000000000..d872a102cc
--- /dev/null
+++ b/sc/source/core/inc/ddelink.hxx
@@ -0,0 +1,84 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <sfx2/lnkbase.hxx>
+#include <svl/broadcast.hxx>
+#include <types.hxx>
+
+namespace com::sun::star::uno { class Any; }
+
+class ScDocument;
+class ScMultipleReadHeader;
+class ScMultipleWriteHeader;
+class SvStream;
+
+class ScDdeLink final : public ::sfx2::SvBaseLink, public SvtBroadcaster
+{
+private:
+static bool bIsInUpdate;
+
+ ScDocument& rDoc;
+
+ OUString aAppl; // connection/ link data
+ OUString aTopic;
+ OUString aItem;
+ sal_uInt8 nMode; // number format mode
+
+ bool bNeedUpdate; // is set, if update was not possible
+
+ ScMatrixRef pResult;
+
+public:
+
+ ScDdeLink( ScDocument& rD,
+ OUString aA, OUString aT, OUString aI,
+ sal_uInt8 nM );
+ ScDdeLink( ScDocument& rD, SvStream& rStream, ScMultipleReadHeader& rHdr );
+ ScDdeLink( ScDocument& rD, const ScDdeLink& rOther );
+ virtual ~ScDdeLink() override;
+
+ void Store( SvStream& rStream, ScMultipleWriteHeader& rHdr ) const;
+
+ // SvBaseLink override:
+ virtual ::sfx2::SvBaseLink::UpdateResult DataChanged(
+ const OUString& rMimeType, const css::uno::Any & rValue ) override;
+
+ // SvtBroadcaster override:
+ virtual void ListenersGone() override;
+
+ // for interpreter:
+
+ const ScMatrix* GetResult() const;
+ void SetResult( const ScMatrixRef& pRes );
+
+ const OUString& GetAppl() const { return aAppl; }
+ const OUString& GetTopic() const { return aTopic; }
+ const OUString& GetItem() const { return aItem; }
+ sal_uInt8 GetMode() const { return nMode; }
+
+ void TryUpdate();
+
+ bool NeedsUpdate() const { return bNeedUpdate; }
+
+ static bool IsInUpdate() { return bIsInUpdate; }
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/inc/doubleref.hxx b/sc/source/core/inc/doubleref.hxx
new file mode 100644
index 0000000000..cda9241590
--- /dev/null
+++ b/sc/source/core/inc/doubleref.hxx
@@ -0,0 +1,178 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <sal/config.h>
+
+#include <memory>
+
+#include <address.hxx>
+#include <types.hxx>
+
+class ScDocument;
+struct ScDBQueryParamBase;
+struct ScQueryParamBase;
+enum class FormulaError : sal_uInt16;
+
+/**
+ * Base class for abstracting range data backends for database functions.
+ */
+class ScDBRangeBase
+{
+public:
+ ScDBRangeBase() = delete;
+
+ virtual ~ScDBRangeBase() = 0;
+
+ bool fillQueryEntries(ScQueryParamBase* pParam, const ScDBRangeBase* pDBRef) const;
+
+ virtual SCCOL getColSize() const = 0;
+ virtual SCROW getRowSize() const = 0;
+ virtual SCSIZE getVisibleDataCellCount() const = 0;
+
+ /**
+ * Get a string value of a specified cell position. Note that the
+ * position of the upper left cell of the range is always (0, 0) even if
+ * the reference type is of internal range.
+ *
+ * @param nCol column position (0 to column size-1)
+ * @param nRow row position (0 to row size-1)
+ */
+ virtual OUString getString(SCCOL nCol, SCROW nRow) const = 0;
+
+ virtual SCCOL getFirstFieldColumn() const = 0;
+
+ /**
+ * Get a <i>0-based</i> column index that corresponds with the passed field
+ * index. Note that the field index passed as the 1st parameter is
+ * <i>1-based.</i>
+ *
+ * @param nIndex 1-based field index.
+ *
+ * @return 0-based column index
+ */
+ virtual SCCOL findFieldColumn(SCCOL nIndex) const = 0;
+ virtual SCCOL findFieldColumn(const OUString& rStr, FormulaError* pErr = nullptr) const = 0;
+ virtual std::unique_ptr<ScDBQueryParamBase>
+ createQueryParam(const ScDBRangeBase* pQueryRef) const = 0;
+ virtual bool isRangeEqual(const ScRange& rRange) const = 0;
+
+protected:
+ ScDBRangeBase(ScDocument* pDoc);
+ ScDocument* getDoc() const { return mpDoc; }
+
+ /**
+ * Populate query options that are always the same for all database
+ * queries.
+ */
+ static void fillQueryOptions(ScQueryParamBase* pParam);
+
+private:
+ ScDocument* mpDoc;
+};
+
+class ScDBInternalRange final : public ScDBRangeBase
+{
+public:
+ explicit ScDBInternalRange(ScDocument* pDoc, const ScRange& rRange);
+ virtual ~ScDBInternalRange() override;
+
+ const ScRange& getRange() const { return maRange; }
+
+ virtual SCCOL getColSize() const override;
+ virtual SCROW getRowSize() const override;
+ virtual SCSIZE getVisibleDataCellCount() const override;
+
+ /**
+ * Get a string value of a specified cell position. Note that the
+ * position of the upper left cell of the range is always (0, 0) even if
+ * the reference type is of internal range.
+ *
+ * @param nCol column position (0 to column size-1)
+ * @param nRow row position (0 to row size-1)
+ */
+ virtual OUString getString(SCCOL nCol, SCROW nRow) const override;
+
+ virtual SCCOL getFirstFieldColumn() const override;
+ /**
+ * Get a <i>0-based</i> column index that corresponds with the passed field
+ * index. Note that the field index passed as the 1st parameter is
+ * <i>1-based.</i>
+ *
+ * @param nIndex 1-based field index.
+ *
+ * @return 0-based column index
+ */
+ virtual SCCOL findFieldColumn(SCCOL nIndex) const override;
+ virtual SCCOL findFieldColumn(const OUString& rStr,
+ FormulaError* pErr = nullptr) const override;
+ virtual std::unique_ptr<ScDBQueryParamBase>
+ createQueryParam(const ScDBRangeBase* pQueryRef) const override;
+ virtual bool isRangeEqual(const ScRange& rRange) const override;
+
+private:
+ ScRange maRange;
+};
+
+class ScDBExternalRange final : public ScDBRangeBase
+{
+public:
+ explicit ScDBExternalRange(ScDocument* pDoc, ScMatrixRef pMat);
+ virtual ~ScDBExternalRange() override;
+
+ virtual SCCOL getColSize() const override;
+ virtual SCROW getRowSize() const override;
+ virtual SCSIZE getVisibleDataCellCount() const override;
+
+ /**
+ * Get a string value of a specified cell position. Note that the
+ * position of the upper left cell of the range is always (0, 0) even if
+ * the reference type is of internal range.
+ *
+ * @param nCol column position (0 to column size-1)
+ * @param nRow row position (0 to row size-1)
+ */
+ virtual OUString getString(SCCOL nCol, SCROW nRow) const override;
+
+ virtual SCCOL getFirstFieldColumn() const override;
+
+ /**
+ * Get a <i>0-based</i> column index that corresponds with the passed field
+ * index. Note that the field index passed as the 1st parameter is
+ * <i>1-based.</i>
+ *
+ * @param nIndex 1-based field index.
+ *
+ * @return 0-based column index
+ */
+ virtual SCCOL findFieldColumn(SCCOL nIndex) const override;
+ virtual SCCOL findFieldColumn(const OUString& rStr,
+ FormulaError* pErr = nullptr) const override;
+ virtual std::unique_ptr<ScDBQueryParamBase>
+ createQueryParam(const ScDBRangeBase* pQueryRef) const override;
+ virtual bool isRangeEqual(const ScRange& rRange) const override;
+
+private:
+ const ScMatrixRef mpMatrix;
+ SCCOL mnCols;
+ SCROW mnRows;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/inc/formulagroupcl.hxx b/sc/source/core/inc/formulagroupcl.hxx
new file mode 100644
index 0000000000..586b21f4c5
--- /dev/null
+++ b/sc/source/core/inc/formulagroupcl.hxx
@@ -0,0 +1,29 @@
+/* -*- 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/.
+ */
+
+#pragma once
+
+#include <formulagroup.hxx>
+
+namespace sc::opencl {
+
+class FormulaGroupInterpreterOpenCL final : public FormulaGroupInterpreter
+{
+public:
+ FormulaGroupInterpreterOpenCL();
+ virtual ~FormulaGroupInterpreterOpenCL() override;
+
+ virtual ScMatrixRef inverseMatrix( const ScMatrix& rMat ) override;
+ virtual bool interpret( ScDocument& rDoc, const ScAddress& rTopPos,
+ ScFormulaCellGroupRef& xGroup, ScTokenArray& rCode ) override;
+};
+
+} // namespace sc::opencl
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/inc/grouptokenconverter.hxx b/sc/source/core/inc/grouptokenconverter.hxx
new file mode 100644
index 0000000000..0d2f02227b
--- /dev/null
+++ b/sc/source/core/inc/grouptokenconverter.hxx
@@ -0,0 +1,38 @@
+/* -*- 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/.
+ */
+
+#pragma once
+
+#include <types.hxx>
+#include <formulalogger.hxx>
+
+class ScDocument;
+class ScFormulaCell;
+class ScTokenArray;
+namespace sc { struct FormulaGroupContext; }
+
+class ScGroupTokenConverter
+{
+ ScTokenArray& mrGroupTokens;
+ ScDocument& mrDoc;
+ std::shared_ptr<sc::FormulaGroupContext> mxFormulaGroupContext;
+ const ScFormulaCell& mrCell;
+ const ScAddress& mrPos;
+
+ bool isSelfReferenceRelative(const ScAddress& rRefPos, SCROW nRelRow);
+ bool isSelfReferenceAbsolute(const ScAddress& rRefPos);
+ SCROW trimLength(SCTAB nTab, SCCOL nCol1, SCCOL nCol2, SCROW nRow, SCROW nRowLen);
+
+public:
+ ScGroupTokenConverter(ScTokenArray& rGroupTokens, ScDocument& rDoc, const ScFormulaCell& rCell, const ScAddress& rPos);
+
+ bool convert( const ScTokenArray& rCode, sc::FormulaLogger::GroupScope& rScope );
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/inc/interpre.hxx b/sc/source/core/inc/interpre.hxx
new file mode 100644
index 0000000000..64b9a8ae5b
--- /dev/null
+++ b/sc/source/core/inc/interpre.hxx
@@ -0,0 +1,1167 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <rtl/math.hxx>
+#include <rtl/ustring.hxx>
+#include <unotools/textsearch.hxx>
+#include <formula/errorcodes.hxx>
+#include <formula/tokenarray.hxx>
+#include <types.hxx>
+#include <externalrefmgr.hxx>
+#include <calcconfig.hxx>
+#include <token.hxx>
+#include <math.hxx>
+#include <kahan.hxx>
+#include "parclass.hxx"
+
+#include <map>
+#include <memory>
+#include <vector>
+#include <limits>
+#include <ostream>
+
+namespace sfx2 { class LinkManager; }
+
+class ScDocument;
+class SbxVariable;
+class ScFormulaCell;
+class ScDBRangeBase;
+struct ScQueryParam;
+struct ScDBQueryParamBase;
+struct ScQueryEntry;
+
+struct ScSingleRefData;
+struct ScComplexRefData;
+struct ScInterpreterContext;
+
+class ScJumpMatrix;
+struct ScRefCellValue;
+
+namespace sc {
+
+struct CompareOptions;
+
+struct ParamIfsResult
+{
+ KahanSum mfSum = 0.0;
+ double mfCount = 0.0;
+ double mfMin = std::numeric_limits<double>::max();
+ double mfMax = std::numeric_limits<double>::lowest();
+};
+
+template<typename charT, typename traits>
+inline std::basic_ostream<charT, traits> & operator <<(std::basic_ostream<charT, traits> & stream, const ParamIfsResult& rRes)
+{
+ stream << "{" <<
+ "sum=" << rRes.mfSum.get() << "," <<
+ "count=" << rRes.mfCount << "," <<
+ "min=" << rRes.mfMin << "," <<
+ "max=" << rRes.mfMax << "," <<
+ "}";
+
+ return stream;
+}
+
+}
+
+namespace svl {
+
+class SharedStringPool;
+
+}
+
+/// Arbitrary 256MB result string length limit.
+constexpr sal_Int32 kScInterpreterMaxStrLen = SAL_MAX_INT32 / 8;
+
+constexpr size_t MAXSTACK = 512;
+
+class ScTokenStack
+{
+public:
+ const formula::FormulaToken* pPointer[ MAXSTACK ];
+};
+
+enum ScIterFunc {
+ ifSUM, // Add up
+ ifSUMSQ, // Sums of squares
+ ifPRODUCT, // Product
+ ifAVERAGE, // Average
+ ifCOUNT, // Count Values
+ ifCOUNT2, // Count Values (not empty)
+ ifMIN, // Minimum
+ ifMAX // Maximum
+};
+
+enum ScIterFuncIf
+{
+ ifSUMIF, // Conditional sum
+ ifAVERAGEIF // Conditional average
+};
+
+enum ScETSType
+{
+ etsAdd,
+ etsMult,
+ etsSeason,
+ etsPIAdd,
+ etsPIMult,
+ etsStatAdd,
+ etsStatMult
+};
+
+struct FormulaTokenRef_less
+{
+ bool operator () ( const formula::FormulaConstTokenRef& r1, const formula::FormulaConstTokenRef& r2 ) const
+ { return r1.get() < r2.get(); }
+};
+typedef ::std::map< const formula::FormulaConstTokenRef, formula::FormulaConstTokenRef, FormulaTokenRef_less> ScTokenMatrixMap;
+
+class ScInterpreter
+{
+ // distribution function objects need the GetxxxDist methods
+ friend class ScGammaDistFunction;
+ friend class ScBetaDistFunction;
+ friend class ScTDistFunction;
+ friend class ScFDistFunction;
+ friend class ScChiDistFunction;
+ friend class ScChiSqDistFunction;
+
+public:
+ static void SetGlobalConfig(const ScCalcConfig& rConfig);
+ static const ScCalcConfig& GetGlobalConfig();
+
+ static void GlobalExit(); // called by ScGlobal::Clear()
+
+ /** Detect if string should be used as regular expression or wildcard
+ expression or literal string.
+ */
+ static utl::SearchParam::SearchType DetectSearchType(std::u16string_view rStr, const ScDocument& rDoc );
+
+ /// Fail safe division, returning a FormulaError::DivisionByZero coded into a double
+ /// if denominator is 0.0
+ static inline double div( const double& fNumerator, const double& fDenominator );
+
+ ScMatrixRef GetNewMat(SCSIZE nC, SCSIZE nR, bool bEmpty = false);
+
+ ScMatrixRef GetNewMat(SCSIZE nC, SCSIZE nR, const std::vector<double>& rValues);
+
+ enum VolatileType {
+ VOLATILE,
+ VOLATILE_MACRO,
+ NOT_VOLATILE
+ };
+
+ VolatileType GetVolatileType() const { return meVolatileType;}
+
+private:
+ static ScCalcConfig& GetOrCreateGlobalConfig();
+ static ScCalcConfig *mpGlobalConfig;
+
+ static thread_local std::unique_ptr<ScTokenStack> pGlobalStack;
+ static thread_local bool bGlobalStackInUse;
+
+ ScCalcConfig maCalcConfig;
+ formula::FormulaTokenIterator aCode;
+ ScAddress aPos;
+ ScTokenArray* pArr;
+ ScInterpreterContext& mrContext;
+ ScDocument& mrDoc;
+ sfx2::LinkManager* mpLinkManager;
+ svl::SharedStringPool& mrStrPool;
+ formula::FormulaConstTokenRef xResult;
+ ScJumpMatrix* pJumpMatrix; // currently active array condition, if any
+ ScTokenMatrixMap maTokenMatrixMap; // map FormulaToken* to formula::FormulaTokenRef if in array condition
+ ScFormulaCell* pMyFormulaCell; // the cell of this formula expression
+ SvNumberFormatter* pFormatter;
+
+ const formula::FormulaToken* pCur; // current token
+ ScTokenStack* pStackObj; // contains the stacks
+ const formula::FormulaToken ** pStack; // the current stack
+ FormulaError nGlobalError; // global (local to this formula expression) error
+ sal_uInt16 sp; // stack pointer
+ sal_uInt16 maxsp; // the maximal used stack pointer
+ sal_uInt32 nFuncFmtIndex; // NumberFormatIndex of a function
+ sal_uInt32 nCurFmtIndex; // current NumberFormatIndex
+ sal_uInt32 nRetFmtIndex; // NumberFormatIndex of an expression, if any
+ SvNumFormatType nFuncFmtType; // NumberFormatType of a function
+ SvNumFormatType nCurFmtType; // current NumberFormatType
+ SvNumFormatType nRetFmtType; // NumberFormatType of an expression
+ FormulaError mnStringNoValueError; // the error set in ConvertStringToValue() if no value
+ SubtotalFlags mnSubTotalFlags; // flags for subtotal and aggregate functions
+ sal_uInt8 cPar; // current count of parameters
+ bool bCalcAsShown; // precision as shown
+ bool bMatrixFormula; // formula cell is a matrix formula
+
+ VolatileType meVolatileType;
+
+ void MakeMatNew(ScMatrixRef& rMat, SCSIZE nC, SCSIZE nR);
+
+ /// Merge global and document specific settings.
+ void MergeCalcConfig();
+
+ // nMust <= nAct <= nMax ? ok : PushError
+ inline bool MustHaveParamCount( short nAct, short nMust );
+ inline bool MustHaveParamCount( short nAct, short nMust, short nMax );
+ inline bool MustHaveParamCountMin( short nAct, short nMin );
+ inline bool MustHaveParamCountMinWithStackCheck( short nAct, short nMin );
+ void PushParameterExpected();
+ void PushIllegalParameter();
+ void PushIllegalArgument();
+ void PushNoValue();
+ void PushNA();
+
+ // Functions for accessing a document
+
+ void ReplaceCell( ScAddress& ); // for TableOp
+ bool IsTableOpInRange( const ScRange& );
+ sal_uInt32 GetCellNumberFormat( const ScAddress& rPos, ScRefCellValue& rCell );
+ double ConvertStringToValue( const OUString& );
+public:
+ static double ScGetGCD(double fx, double fy);
+ /** For matrix back calls into the current interpreter.
+ Uses rError instead of nGlobalError and rCurFmtType instead of nCurFmtType. */
+ double ConvertStringToValue( const OUString&, FormulaError& rError, SvNumFormatType& rCurFmtType );
+private:
+ double GetCellValue( const ScAddress&, ScRefCellValue& rCell );
+ double GetCellValueOrZero( const ScAddress&, ScRefCellValue& rCell );
+ double GetValueCellValue( const ScAddress&, double fOrig );
+ void GetCellString( svl::SharedString& rStr, ScRefCellValue& rCell );
+ static FormulaError GetCellErrCode( const ScRefCellValue& rCell );
+
+ bool CreateDoubleArr(SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
+ SCCOL nCol2, SCROW nRow2, SCTAB nTab2, sal_uInt8* pCellArr);
+ bool CreateStringArr(SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
+ SCCOL nCol2, SCROW nRow2, SCTAB nTab2, sal_uInt8* pCellArr);
+ bool CreateCellArr(SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
+ SCCOL nCol2, SCROW nRow2, SCTAB nTab2, sal_uInt8* pCellArr);
+
+ // Stack operations
+
+ /** Does substitute with formula::FormulaErrorToken in case nGlobalError is set and the token
+ passed is not formula::FormulaErrorToken.
+ Increments RefCount of the original token if not substituted. */
+ void Push( const formula::FormulaToken& r );
+
+ /** Does not substitute with formula::FormulaErrorToken in case nGlobalError is set.
+ Used to push RPN tokens or from within Push() or tokens that are already
+ explicit formula::FormulaErrorToken. Increments RefCount. */
+ void PushWithoutError( const formula::FormulaToken& r );
+
+ /** Does substitute with formula::FormulaErrorToken in case nGlobalError is set and the token
+ passed is not formula::FormulaErrorToken.
+ Increments RefCount of the original token if not substituted.
+ ATTENTION! The token had to be allocated with `new' and must not be used
+ after this call if no RefCount was set because possibly it gets immediately
+ deleted in case of a FormulaError::StackOverflow or if substituted with formula::FormulaErrorToken! */
+ void PushTempToken( formula::FormulaToken* );
+
+ /** Pushes the token or substitutes with formula::FormulaErrorToken in case
+ nGlobalError is set and the token passed is not formula::FormulaErrorToken.
+ Increments RefCount of the original token if not substituted. */
+ void PushTokenRef( const formula::FormulaConstTokenRef& );
+
+ /** Does not substitute with formula::FormulaErrorToken in case nGlobalError is set.
+ Used to push tokens from within PushTempToken() or tokens that are already
+ explicit formula::FormulaErrorToken. Increments RefCount.
+ ATTENTION! The token had to be allocated with `new' and must not be used
+ after this call if no RefCount was set because possibly it gets immediately
+ decremented again and thus deleted in case of a FormulaError::StackOverflow! */
+ void PushTempTokenWithoutError( const formula::FormulaToken* );
+
+ /** If nGlobalError is set push formula::FormulaErrorToken.
+ If nGlobalError is not set do nothing.
+ Used in PushTempToken() and alike to simplify handling.
+ @return: <TRUE/> if nGlobalError. */
+ bool IfErrorPushError()
+ {
+ if (nGlobalError != FormulaError::NONE)
+ {
+ PushTempTokenWithoutError( new formula::FormulaErrorToken( nGlobalError));
+ return true;
+ }
+ return false;
+ }
+
+ /** Obtain cell result / content from address and push as temp token.
+
+ @param bDisplayEmptyAsString
+ is passed to ScEmptyCell in case of an empty cell result.
+
+ @param pRetTypeExpr
+ @param pRetIndexExpr
+ Obtain number format and type if _both_, type and index pointer,
+ are not NULL.
+
+ @param bFinalResult
+ If TRUE, only a standard FormulaDoubleToken is pushed.
+ If FALSE, PushDouble() is used that may push either a
+ FormulaDoubleToken or a FormulaTypedDoubleToken.
+ */
+ void PushCellResultToken( bool bDisplayEmptyAsString, const ScAddress & rAddress,
+ SvNumFormatType * pRetTypeExpr, sal_uInt32 * pRetIndexExpr, bool bFinalResult = false );
+
+ formula::FormulaConstTokenRef PopToken();
+ void Pop();
+ void PopError();
+ double PopDouble();
+ const svl::SharedString & PopString();
+ void ValidateRef( const ScSingleRefData & rRef );
+ void ValidateRef( const ScComplexRefData & rRef );
+ void ValidateRef( const ScRefList & rRefList );
+ void SingleRefToVars( const ScSingleRefData & rRef, SCCOL & rCol, SCROW & rRow, SCTAB & rTab );
+ void PopSingleRef( ScAddress& );
+ void PopSingleRef(SCCOL& rCol, SCROW &rRow, SCTAB& rTab);
+ void DoubleRefToRange( const ScComplexRefData&, ScRange&, bool bDontCheckForTableOp = false );
+ /** If formula::StackVar formula::svDoubleRef pop ScDoubleRefToken and return values of
+ ScComplexRefData.
+ Else if StackVar svRefList return values of the ScComplexRefData where
+ rRefInList is pointing to. rRefInList is incremented. If rRefInList was the
+ last element in list pop ScRefListToken and set rRefInList to 0, else
+ rParam is incremented (!) to allow usage as in
+ while(nParamCount--) PopDoubleRef(aRange,nParamCount,nRefInList);
+ */
+ void PopDoubleRef( ScRange & rRange, short & rParam, size_t & rRefInList );
+ void PopDoubleRef( ScRange&, bool bDontCheckForTableOp = false );
+ void DoubleRefToVars( const formula::FormulaToken* p,
+ SCCOL& rCol1, SCROW &rRow1, SCTAB& rTab1,
+ SCCOL& rCol2, SCROW &rRow2, SCTAB& rTab2 );
+ ScDBRangeBase* PopDBDoubleRef();
+ void PopDoubleRef(SCCOL& rCol1, SCROW &rRow1, SCTAB& rTab1,
+ SCCOL& rCol2, SCROW &rRow2, SCTAB& rTab2 );
+ // peek double ref data
+ const ScComplexRefData* GetStackDoubleRef(size_t rRefInList = 0);
+
+ void PopExternalSingleRef(sal_uInt16& rFileId, OUString& rTabName, ScSingleRefData& rRef);
+
+ /** Guarantees that nGlobalError is set if rToken could not be obtained. */
+ void PopExternalSingleRef(ScExternalRefCache::TokenRef& rToken, ScExternalRefCache::CellFormat* pFmt = nullptr);
+
+ /** Guarantees that nGlobalError is set if rToken could not be obtained. */
+ void PopExternalSingleRef(sal_uInt16& rFileId, OUString& rTabName, ScSingleRefData& rRef,
+ ScExternalRefCache::TokenRef& rToken, ScExternalRefCache::CellFormat* pFmt = nullptr);
+
+ void PopExternalDoubleRef(sal_uInt16& rFileId, OUString& rTabName, ScComplexRefData& rRef);
+ void PopExternalDoubleRef(ScExternalRefCache::TokenArrayRef& rArray);
+ void PopExternalDoubleRef(ScMatrixRef& rMat);
+ void GetExternalDoubleRef(sal_uInt16 nFileId, const OUString& rTabName, const ScComplexRefData& aData, ScExternalRefCache::TokenArrayRef& rArray);
+ bool PopDoubleRefOrSingleRef( ScAddress& rAdr );
+ void PopDoubleRefPushMatrix();
+ void PopRefListPushMatrixOrRef();
+ // If MatrixFormula: convert svDoubleRef to svMatrix, create JumpMatrix.
+ // Else convert area reference parameters marked as ForceArray to array.
+ // Returns true if JumpMatrix created.
+ bool ConvertMatrixParameters();
+ // If MatrixFormula: ConvertMatrixJumpConditionToMatrix()
+ inline void MatrixJumpConditionToMatrix();
+ // For MatrixFormula (preconditions already checked by
+ // MatrixJumpConditionToMatrix()): convert svDoubleRef to svMatrix, or if
+ // JumpMatrix currently in effect convert also other types to svMatrix so
+ // another JumpMatrix will be created by jump commands.
+ void ConvertMatrixJumpConditionToMatrix();
+ // If MatrixFormula or ForceArray: ConvertMatrixParameters()
+ inline bool MatrixParameterConversion();
+ // If MatrixFormula or ForceArray. Can be used within spreadsheet functions
+ // that do not depend on the formula cell's matrix size, for which only
+ // bMatrixFormula can be used.
+ inline bool IsInArrayContext() const;
+ ScMatrixRef PopMatrix();
+ sc::RangeMatrix PopRangeMatrix();
+ void QueryMatrixType(const ScMatrixRef& xMat, SvNumFormatType& rRetTypeExpr, sal_uInt32& rRetIndexExpr);
+
+ formula::FormulaToken* CreateFormulaDoubleToken( double fVal, SvNumFormatType nFmt = SvNumFormatType::NUMBER );
+ formula::FormulaToken* CreateDoubleOrTypedToken( double fVal );
+
+ void PushDouble(double nVal);
+ void PushInt( int nVal );
+ void PushStringBuffer( const sal_Unicode* pString );
+ void PushString( const OUString& rStr );
+ void PushString( const svl::SharedString& rString );
+ void PushSingleRef(SCCOL nCol, SCROW nRow, SCTAB nTab);
+ void PushDoubleRef(SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
+ SCCOL nCol2, SCROW nRow2, SCTAB nTab2);
+ void PushExternalSingleRef(sal_uInt16 nFileId, const OUString& rTabName,
+ SCCOL nCol, SCROW nRow, SCTAB nTab);
+ void PushExternalDoubleRef(sal_uInt16 nFileId, const OUString& rTabName,
+ SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
+ SCCOL nCol2, SCROW nRow2, SCTAB nTab2);
+ void PushSingleRef( const ScRefAddress& rRef );
+ void PushDoubleRef( const ScRefAddress& rRef1, const ScRefAddress& rRef2 );
+ void PushMatrix( const sc::RangeMatrix& rMat );
+ void PushMatrix(const ScMatrixRef& pMat);
+ void PushError( FormulaError nError );
+ /// Raw stack type without default replacements.
+ formula::StackVar GetRawStackType();
+ /// Stack type with replacement of defaults, e.g. svMissing and formula::svEmptyCell will result in formula::svDouble.
+ formula::StackVar GetStackType();
+ // peek StackType of Parameter, Parameter 1 == TOS, 2 == TOS-1, ...
+ formula::StackVar GetStackType( sal_uInt8 nParam );
+ sal_uInt8 GetByte() const { return cPar; }
+ // reverse order of stack
+ void ReverseStack( sal_uInt8 nParamCount );
+ // generates a position-dependent SingleRef out of a DoubleRef
+ bool DoubleRefToPosSingleRef( const ScRange& rRange, ScAddress& rAdr );
+ double GetDoubleFromMatrix(const ScMatrixRef& pMat);
+ double GetDouble();
+ double GetDoubleWithDefault(double nDefault);
+ bool IsMissing() const;
+ sal_Int32 double_to_int32(double fVal);
+ /** if GetDouble() not within int32 limits sets nGlobalError and returns SAL_MAX_INT32 */
+ sal_Int32 GetInt32();
+ /** if GetDoubleWithDefault() not within int32 limits sets nGlobalError and returns SAL_MAX_INT32 */
+ sal_Int32 GetInt32WithDefault( sal_Int32 nDefault );
+ /** if GetDouble() not within int32 limits sets nGlobalError and returns SAL_MAX_INT32 */
+ sal_Int32 GetFloor32();
+ /** if GetDouble() not within int16 limits sets nGlobalError and returns SAL_MAX_INT16 */
+ sal_Int16 GetInt16();
+ /** if GetDouble() not within uint32 limits sets nGlobalError and returns SAL_MAX_UINT32 */
+ sal_uInt32 GetUInt32();
+ bool GetBool() { return GetDouble() != 0.0; }
+ /// returns TRUE if double (or error, check nGlobalError), else FALSE
+ bool GetDoubleOrString( double& rValue, svl::SharedString& rString );
+ svl::SharedString GetString();
+ svl::SharedString GetStringFromMatrix(const ScMatrixRef& pMat);
+ svl::SharedString GetStringFromDouble( const double fVal);
+ // pop matrix and obtain one element, upper left or according to jump matrix
+ ScMatValType GetDoubleOrStringFromMatrix( double& rDouble, svl::SharedString& rString );
+ ScMatrixRef CreateMatrixFromDoubleRef( const formula::FormulaToken* pToken,
+ SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
+ SCCOL nCol2, SCROW nRow2, SCTAB nTab2 );
+ inline ScTokenMatrixMap& GetTokenMatrixMap();
+ ScMatrixRef GetMatrix();
+ ScMatrixRef GetMatrix( short & rParam, size_t & rInRefList );
+ sc::RangeMatrix GetRangeMatrix();
+
+ void ScTableOp(); // repeated operations
+
+ // common helper functions
+
+ void CurFmtToFuncFmt()
+ { nFuncFmtType = nCurFmtType; nFuncFmtIndex = nCurFmtIndex; }
+
+ /** Check if a double is suitable as string position or length argument.
+
+ If fVal is Inf or NaN it is changed to -1, if it is less than 0 it is
+ sanitized to 0, if it is greater than some implementation defined max
+ string length it is sanitized to that max.
+
+ @return TRUE if double value fVal is suitable as string argument and was
+ not sanitized.
+ FALSE if not and fVal was adapted.
+ */
+ static inline bool CheckStringPositionArgument( double & fVal );
+
+ /** Obtain a sal_Int32 suitable as string position or length argument.
+ Returns -1 if the number is Inf or NaN or less than 0 or greater than some
+ implementation defined max string length. In these cases also sets
+ nGlobalError to FormulaError::IllegalArgument, if not already set. */
+ inline sal_Int32 GetStringPositionArgument();
+
+ // Check for String overflow of rResult+rAdd and set error and erase rResult
+ // if so. Return true if ok, false if overflow
+ inline bool CheckStringResultLen( OUString& rResult, sal_Int32 nIncrease );
+
+ // Check for String overflow of rResult+rAdd and set error and erase rResult
+ // if so. Return true if ok, false if overflow
+ inline bool CheckStringResultLen( OUStringBuffer& rResult, sal_Int32 nIncrease );
+
+ // Set error according to rVal, and set rVal to 0.0 if there was an error.
+ inline void TreatDoubleError( double& rVal );
+ // Lookup using ScLookupCache, @returns true if found and result address
+ bool LookupQueryWithCache( ScAddress & o_rResultPos,
+ const ScQueryParam & rParam, const ScComplexRefData* refData ) const;
+
+ void ScIfJump();
+ void ScIfError( bool bNAonly );
+ void ScChooseJump();
+
+ // Be sure to only call this if pStack[sp-nStackLevel] really contains a
+ // ScJumpMatrixToken, no further checks are applied!
+ // Returns true if last jump was executed and result matrix pushed.
+ bool JumpMatrix( short nStackLevel );
+
+ double Compare( ScQueryOp eOp );
+ /** @param pOptions
+ NULL means case sensitivity document option is to be used!
+ */
+ sc::RangeMatrix CompareMat( ScQueryOp eOp, sc::CompareOptions* pOptions = nullptr );
+ ScMatrixRef QueryMat( const ScMatrixRef& pMat, sc::CompareOptions& rOptions );
+ void ScEqual();
+ void ScNotEqual();
+ void ScLess();
+ void ScGreater();
+ void ScLessEqual();
+ void ScGreaterEqual();
+ void ScAnd();
+ void ScOr();
+ void ScXor();
+ void ScNot();
+ void ScNeg();
+ void ScPercentSign();
+ void ScIntersect();
+ void ScRangeFunc();
+ void ScUnionFunc();
+ void ScPi();
+ void ScRandom();
+ void ScRandbetween();
+ void ScRandomImpl( const std::function<double( double fFirst, double fLast )>& RandomFunc,
+ double fFirst, double fLast );
+ void ScTrue();
+ void ScFalse();
+ void ScDeg();
+ void ScRad();
+ void ScSin();
+ void ScCos();
+ void ScTan();
+ void ScCot();
+ void ScArcSin();
+ void ScArcCos();
+ void ScArcTan();
+ void ScArcCot();
+ void ScSinHyp();
+ void ScCosHyp();
+ void ScTanHyp();
+ void ScCotHyp();
+ void ScArcSinHyp();
+ void ScArcCosHyp();
+ void ScArcTanHyp();
+ void ScArcCotHyp();
+ void ScCosecant();
+ void ScSecant();
+ void ScCosecantHyp();
+ void ScSecantHyp();
+ void ScExp();
+ void ScLn();
+ void ScLog10();
+ void ScSqrt();
+ void ScIsEmpty();
+ bool IsString();
+ void ScIsString();
+ void ScIsNonString();
+ void ScIsLogical();
+ void ScType();
+ void ScCell();
+ void ScCellExternal();
+ void ScIsRef();
+ void ScIsValue();
+ void ScIsFormula();
+ void ScFormula();
+ void ScRoman();
+ void ScArabic();
+ void ScIsNV();
+ void ScIsErr();
+ void ScIsError();
+ bool IsEven();
+ void ScIsEven();
+ void ScIsOdd();
+ void ScN();
+ void ScCode();
+ void ScTrim();
+ void ScUpper();
+ void ScProper();
+ void ScLower();
+ void ScLen();
+ void ScT();
+ void ScValue();
+ void ScNumberValue();
+ void ScClean();
+ void ScChar();
+ void ScJis();
+ void ScAsc();
+ void ScUnicode();
+ void ScUnichar();
+ void ScMin( bool bTextAsZero = false );
+ void ScMax( bool bTextAsZero = false );
+ /** Check for array of references to determine the maximum size of a return
+ column vector if in array context. */
+ size_t GetRefListArrayMaxSize( short nParamCount );
+ /** Switch to array reference list if current TOS is one and create/init or
+ update matrix and return true. Else return false. */
+ bool SwitchToArrayRefList( ScMatrixRef& xResMat, SCSIZE nMatRows, double fCurrent,
+ const std::function<void( SCSIZE i, double fCurrent )>& MatOpFunc, bool bDoMatOp );
+ void IterateParameters( ScIterFunc, bool bTextAsZero = false );
+ void ScSumSQ();
+ void ScSum();
+ void ScProduct();
+ void ScAverage( bool bTextAsZero = false );
+ void ScCount();
+ void ScCount2();
+ void GetStVarParams( bool bTextAsZero, double(*VarResult)( double fVal, size_t nValCount ) );
+ void ScVar( bool bTextAsZero = false );
+ void ScVarP( bool bTextAsZero = false );
+ void ScStDev( bool bTextAsZero = false );
+ void ScStDevP( bool bTextAsZero = false );
+ void ScRawSubtract();
+ void ScColumns();
+ void ScRows();
+ void ScSheets();
+ void ScColumn();
+ void ScRow();
+ void ScSheet();
+ void ScMatch();
+ void IterateParametersIf( ScIterFuncIf );
+ void ScCountIf();
+ void ScSumIf();
+ void ScAverageIf();
+ void IterateParametersIfs( double(*ResultFunc)( const sc::ParamIfsResult& rRes ) );
+ void ScSumIfs();
+ void ScAverageIfs();
+ void ScCountIfs();
+ void ScCountEmptyCells();
+ void ScLookup();
+ void ScHLookup();
+ void ScVLookup();
+ void ScSubTotal();
+
+ // If upon call rMissingField==true then the database field parameter may be
+ // missing (Xcl DCOUNT() syntax), or may be faked as missing by having the
+ // value 0.0 or being exactly the entire database range reference (old SO
+ // compatibility). If this was the case then rMissingField is set to true upon
+ // return. If rMissingField==false upon call all "missing cases" are considered
+ // to be an error.
+ std::unique_ptr<ScDBQueryParamBase> GetDBParams( bool& rMissingField );
+
+ void DBIterator( ScIterFunc );
+ void ScDBSum();
+ void ScDBCount();
+ void ScDBCount2();
+ void ScDBAverage();
+ void ScDBGet();
+ void ScDBMax();
+ void ScDBMin();
+ void ScDBProduct();
+ void GetDBStVarParams( double& rVal, double& rValCount );
+ void ScDBStdDev();
+ void ScDBStdDevP();
+ void ScDBVar();
+ void ScDBVarP();
+ void ScIndirect();
+ void ScAddressFunc();
+ void ScOffset();
+ void ScIndex();
+ void ScMultiArea();
+ void ScAreas();
+ void ScCurrency();
+ void ScReplace();
+ void ScFixed();
+ void ScFind();
+ void ScExact();
+ void ScLeft();
+ void ScRight();
+ void ScSearch();
+ void ScMid();
+ void ScText();
+ void ScSubstitute();
+ void ScRept();
+ void ScRegex();
+ void ScConcat();
+ void ScConcat_MS();
+ void ScTextJoin_MS();
+ void ScIfs_MS();
+ void ScSwitch_MS();
+ void ScMinIfs_MS();
+ void ScMaxIfs_MS();
+ void ScExternal();
+ void ScMissing();
+ void ScMacro();
+ bool SetSbxVariable( SbxVariable* pVar, const ScAddress& );
+ FormulaError GetErrorType();
+ void ScErrorType();
+ void ScErrorType_ODF();
+ void ScDBArea();
+ void ScColRowNameAuto();
+ void ScGetPivotData();
+ void ScHyperLink();
+ void ScBahtText();
+ void ScBitAnd();
+ void ScBitOr();
+ void ScBitXor();
+ void ScBitRshift();
+ void ScBitLshift();
+ void ScTTT();
+ void ScDebugVar();
+
+ /** Obtain the date serial number for a given date.
+ @param bStrict
+ If false, nYear < 100 takes the two-digit year setting into account,
+ and rollover of invalid calendar dates takes place, e.g. 1999-02-31 =>
+ 1999-03-03.
+ If true, the date passed must be a valid Gregorian calendar date. No
+ two-digit expanding or rollover is done.
+
+ Date must be Gregorian, i.e. >= 1582-10-15.
+ */
+ double GetDateSerial( sal_Int16 nYear, sal_Int16 nMonth, sal_Int16 nDay, bool bStrict );
+
+ void ScGetActDate();
+ void ScGetActTime();
+ void ScGetYear();
+ void ScGetMonth();
+ void ScGetDay();
+ void ScGetDayOfWeek();
+ void ScGetWeekOfYear();
+ void ScGetIsoWeekOfYear();
+ void ScWeeknumOOo();
+ void ScEasterSunday();
+ FormulaError GetWeekendAndHolidayMasks( const sal_uInt8 nParamCount, const sal_uInt32 nNullDate,
+ ::std::vector<double>& rSortArray, bool bWeekendMask[ 7 ] );
+ FormulaError GetWeekendAndHolidayMasks_MS( const sal_uInt8 nParamCount, const sal_uInt32 nNullDate,
+ ::std::vector<double>& rSortArray, bool bWeekendMask[ 7 ], bool bWorkdayFunction );
+ static inline sal_Int16 GetDayOfWeek( sal_Int32 n );
+ void ScNetWorkdays( bool bOOXML_Version );
+ void ScWorkday_MS();
+ void ScGetHour();
+ void ScGetMin();
+ void ScGetSec();
+ void ScPlusMinus();
+ void ScAbs();
+ void ScInt();
+ void ScEven();
+ void ScOdd();
+ void ScCeil( bool bODFF );
+ void ScCeil_MS();
+ void ScCeil_Precise();
+ void ScFloor( bool bODFF );
+ void ScFloor_MS();
+ void ScFloor_Precise();
+ void RoundNumber( rtl_math_RoundingMode eMode );
+ void ScRound();
+ void ScRoundUp();
+ void ScRoundDown();
+ void ScGetDateValue();
+ void ScGetTimeValue();
+ void ScArcTan2();
+ void ScLog();
+ void ScGetDate();
+ void ScGetTime();
+ void ScGetDiffDate();
+ void ScGetDiffDate360();
+ void ScGetDateDif();
+ void ScPower();
+ void ScAmpersand();
+ void ScAdd();
+ void ScSub();
+ void ScMul();
+ void ScDiv();
+ void ScPow();
+ void ScCurrent();
+ void ScStyle();
+ void ScDde();
+ void ScBase();
+ void ScDecimal();
+ void ScConvertOOo();
+ void ScEuroConvert();
+ void ScRoundSignificant();
+ static void RoundSignificant( double fX, double fDigits, double &fRes );
+
+ // financial functions
+ void ScNPV();
+ void ScIRR();
+ void ScMIRR();
+ void ScISPMT();
+
+ static double ScGetPV(double fRate, double fNper, double fPmt,
+ double fFv, bool bPayInAdvance);
+ void ScPV();
+ void ScSYD();
+ static double ScGetDDB(double fCost, double fSalvage, double fLife,
+ double fPeriod, double fFactor);
+ void ScDDB();
+ void ScDB();
+ static double ScInterVDB(double fCost, double fSalvage, double fLife, double fLife1,
+ double fPeriod, double fFactor);
+ void ScVDB();
+ void ScPDuration();
+ void ScSLN();
+ static double ScGetPMT(double fRate, double fNper, double fPv,
+ double fFv, bool bPayInAdvance);
+ void ScPMT();
+ void ScRRI();
+ static double ScGetFV(double fRate, double fNper, double fPmt,
+ double fPv, bool bPayInAdvance);
+ void ScFV();
+ void ScNper();
+ static bool RateIteration(double fNper, double fPayment, double fPv,
+ double fFv, bool bPayType, double& fGuess);
+ void ScRate();
+ double ScGetIpmt(double fRate, double fPer, double fNper, double fPv,
+ double fFv, bool bPayInAdvance, double& fPmt);
+ void ScIpmt();
+ void ScPpmt();
+ void ScCumIpmt();
+ void ScCumPrinc();
+ void ScEffect();
+ void ScNominal();
+ void ScMod();
+ void ScIntercept();
+ void ScGCD();
+ void ScLCM();
+
+ // matrix functions
+ void ScMatValue();
+ static void MEMat(const ScMatrixRef& mM, SCSIZE n);
+ void ScMatDet();
+ void ScMatInv();
+ void ScMatMult();
+ void ScMatTrans();
+ void ScEMat();
+ void ScMatRef();
+ ScMatrixRef MatConcat(const ScMatrixRef& pMat1, const ScMatrixRef& pMat2);
+ void ScSumProduct();
+ void ScSumX2MY2();
+ void ScSumX2DY2();
+ void ScSumXMY2();
+ void ScGrowth();
+ bool CalculateSkew(KahanSum& fSum, double& fCount, std::vector<double>& values);
+ void CalculateSkewOrSkewp( bool bSkewp );
+ void CalculateSlopeIntercept(bool bSlope);
+ void CalculateSmallLarge(bool bSmall);
+ void CalculatePearsonCovar( bool _bPearson, bool _bStexy, bool _bSample ); //fdo#70000 argument _bSample is ignored if _bPearson == true
+ bool CalculateTest( bool _bTemplin
+ ,const SCSIZE nC1, const SCSIZE nC2,const SCSIZE nR1,const SCSIZE nR2
+ ,const ScMatrixRef& pMat1,const ScMatrixRef& pMat2
+ ,double& fT,double& fF);
+ void CalculateLookup(bool bHLookup);
+ bool FillEntry(ScQueryEntry& rEntry);
+ void CalculateAddSub(bool _bSub);
+ void CalculateTrendGrowth(bool _bGrowth);
+ void CalculateRGPRKP(bool _bRKP);
+ void CalculateSumX2MY2SumX2DY2(bool _bSumX2DY2);
+ void CalculateMatrixValue(const ScMatrix* pMat,SCSIZE nC,SCSIZE nR);
+ bool CheckMatrix(bool _bLOG,sal_uInt8& nCase,SCSIZE& nCX,SCSIZE& nCY,SCSIZE& nRX,SCSIZE& nRY,SCSIZE& M,SCSIZE& N,ScMatrixRef& pMatX,ScMatrixRef& pMatY);
+ void ScLinest();
+ void ScLogest();
+ void ScForecast();
+ void ScForecast_Ets( ScETSType eETSType );
+ void ScFourier();
+ void ScNoName();
+ void ScBadName();
+ // Statistics:
+ static double taylor(const double* pPolynom, sal_uInt16 nMax, double x);
+ static double gauss(double x);
+
+public:
+ static double phi(double x);
+ static double integralPhi(double x);
+ static double gaussinv(double x);
+ static double GetPercentile( ::std::vector<double> & rArray, double fPercentile );
+
+
+private:
+ double GetBetaDist(double x, double alpha, double beta); //cumulative distribution function
+ double GetBetaDistPDF(double fX, double fA, double fB); //probability density function)
+ double GetChiDist(double fChi, double fDF); // for LEGACY.CHIDIST, returns right tail
+ double GetChiSqDistCDF(double fX, double fDF); // for CHISQDIST, returns left tail
+ static double GetChiSqDistPDF(double fX, double fDF); // probability density function
+ double GetFDist(double x, double fF1, double fF2);
+ double GetTDist( double T, double fDF, int nType );
+ double Fakultaet(double x);
+ static double BinomKoeff(double n, double k);
+ double GetGamma(double x);
+ static double GetLogGamma(double x);
+ double GetBeta(double fAlpha, double fBeta);
+ static double GetLogBeta(double fAlpha, double fBeta);
+ double GetBinomDistPMF(double x, double n, double p); //probability mass function
+ double GetHypGeomDist( double x, double n, double M, double N );
+ void ScLogGamma();
+ void ScGamma();
+ void ScPhi();
+ void ScGauss();
+ void ScStdNormDist();
+ void ScStdNormDist_MS();
+ void ScFisher();
+ void ScFisherInv();
+ void ScFact();
+ void ScNormDist( int nMinParamCount );
+ void ScGammaDist( bool bODFF );
+ void ScGammaInv();
+ void ScExpDist();
+ void ScBinomDist();
+ void ScPoissonDist( bool bODFF );
+ void ScCombin();
+ void ScCombinA();
+ void ScPermut();
+ void ScPermutationA();
+ void ScB();
+ void ScHypGeomDist( int nMinParamCount );
+ void ScLogNormDist( int nMinParamCount );
+ void ScLogNormInv();
+ void ScTDist();
+ void ScTDist_MS();
+ void ScTDist_T( int nTails );
+ void ScFDist();
+ void ScFDist_LT();
+ void ScChiDist( bool bODFF); // for LEGACY.CHIDIST, returns right tail
+ void ScChiSqDist(); // returns left tail or density
+ void ScChiSqDist_MS();
+ void ScChiSqInv(); // inverse to CHISQDIST
+ void ScWeibull();
+ void ScBetaDist();
+ void ScBetaDist_MS();
+ void ScFInv();
+ void ScFInv_LT();
+ void ScTInv( int nType );
+ void ScChiInv();
+ void ScBetaInv();
+ void ScCritBinom();
+ void ScNegBinomDist();
+ void ScNegBinomDist_MS();
+ void ScKurt();
+ void ScHarMean();
+ void ScGeoMean();
+ void ScStandard();
+ void ScSkew();
+ void ScSkewp();
+ void ScMedian();
+ double GetMedian( ::std::vector<double> & rArray );
+ double GetPercentileExclusive( ::std::vector<double> & rArray, double fPercentile );
+ std::vector<double> GetRankNumberArray( SCSIZE& rCol, SCSIZE& rRow );
+ void GetNumberSequenceArray( sal_uInt8 nParamCount, ::std::vector<double>& rArray, bool bConvertTextInArray );
+ void GetSortArray( sal_uInt8 nParamCount, ::std::vector<double>& rSortArray, ::std::vector<tools::Long>* pIndexOrder, bool bConvertTextInArray, bool bAllowEmptyArray );
+ static void QuickSort(::std::vector<double>& rSortArray, ::std::vector<tools::Long>* pIndexOrder);
+ void ScModalValue();
+ void ScModalValue_MS( bool bSingle );
+ void ScAveDev();
+ void ScAggregate();
+ void ScDevSq();
+ void ScZTest();
+ void ScTTest();
+ void ScFTest();
+ void ScChiTest();
+ void ScRank( bool bAverage );
+ void ScPercentile( bool bInclusive );
+ void ScPercentrank( bool bInclusive );
+ static double GetPercentrank( ::std::vector<double> & rArray, double fVal, bool bInclusive );
+ void ScLarge();
+ void ScSmall();
+ void ScFrequency();
+ void ScQuartile( bool bInclusive );
+ void ScNormInv();
+ void ScSNormInv();
+ void ScConfidence();
+ void ScConfidenceT();
+ void ScTrimMean();
+ void ScProbability();
+ void ScCorrel();
+ void ScCovarianceP();
+ void ScCovarianceS();
+ void ScPearson();
+ void ScRSQ();
+ void ScSTEYX();
+ void ScSlope();
+ void ScTrend();
+ void ScInfo();
+ void ScLenB();
+ void ScRightB();
+ void ScLeftB();
+ void ScMidB();
+ void ScReplaceB();
+ void ScFindB();
+ void ScSearchB();
+
+ void ScFilterXML();
+ void ScWebservice();
+ void ScEncodeURL();
+ void ScColor();
+ void ScErf();
+ void ScErfc();
+
+ static const double fMaxGammaArgument;
+
+ double GetGammaContFraction(double fA,double fX);
+ double GetGammaSeries(double fA,double fX);
+ double GetLowRegIGamma(double fA,double fX); // lower regularized incomplete gamma function, GAMMAQ
+ double GetUpRegIGamma(double fA,double fX); // upper regularized incomplete gamma function, GAMMAP
+ // probability density function; fLambda is "scale" parameter
+ double GetGammaDistPDF(double fX, double fAlpha, double fLambda);
+ // cumulative distribution function; fLambda is "scale" parameter
+ double GetGammaDist(double fX, double fAlpha, double fLambda);
+ double GetTInv( double fAlpha, double fSize, int nType );
+
+public:
+ ScInterpreter( ScFormulaCell* pCell, ScDocument& rDoc, ScInterpreterContext& rContext,
+ const ScAddress&, ScTokenArray&, bool bForGroupThreading = false );
+ ~ScInterpreter();
+
+ // Used only for threaded formula-groups.
+ // Resets the interpreter object, allowing reuse of interpreter object for each cell
+ // in the group.
+ void Init( ScFormulaCell* pCell, const ScAddress& rPos, ScTokenArray& rTokArray );
+
+ formula::StackVar Interpret();
+
+ void SetError(FormulaError nError)
+ { if (nError != FormulaError::NONE && nGlobalError == FormulaError::NONE) nGlobalError = nError; }
+ void AssertFormulaMatrix();
+
+ void SetLinkManager(sfx2::LinkManager* pLinkMgr)
+ { mpLinkManager = pLinkMgr; }
+
+ FormulaError GetError() const { return nGlobalError; }
+ formula::StackVar GetResultType() const { return xResult->GetType(); }
+ const svl::SharedString & GetStringResult() const;
+ double GetNumResult() const { return xResult->GetDouble(); }
+ const formula::FormulaConstTokenRef& GetResultToken() const { return xResult; }
+ SvNumFormatType GetRetFormatType() const { return nRetFmtType; }
+ sal_uLong GetRetFormatIndex() const { return nRetFmtIndex; }
+};
+
+inline bool ScInterpreter::IsInArrayContext() const
+{
+ return bMatrixFormula || pCur->IsInForceArray();
+}
+
+inline void ScInterpreter::MatrixJumpConditionToMatrix()
+{
+ if (IsInArrayContext())
+ ConvertMatrixJumpConditionToMatrix();
+}
+
+inline bool ScInterpreter::MatrixParameterConversion()
+{
+ if ( (IsInArrayContext() || ScParameterClassification::HasForceArray( pCur->GetOpCode())) &&
+ !pJumpMatrix && sp > 0 )
+ return ConvertMatrixParameters();
+ return false;
+}
+
+inline ScTokenMatrixMap& ScInterpreter::GetTokenMatrixMap()
+{
+ return maTokenMatrixMap;
+}
+
+inline bool ScInterpreter::MustHaveParamCount( short nAct, short nMust )
+{
+ if ( nAct == nMust )
+ return true;
+ if ( nAct < nMust )
+ PushParameterExpected();
+ else
+ PushIllegalParameter();
+ return false;
+}
+
+inline bool ScInterpreter::MustHaveParamCount( short nAct, short nMust, short nMax )
+{
+ if ( nMust <= nAct && nAct <= nMax )
+ return true;
+ if ( nAct < nMust )
+ PushParameterExpected();
+ else
+ PushIllegalParameter();
+ return false;
+}
+
+inline bool ScInterpreter::MustHaveParamCountMin( short nAct, short nMin )
+{
+ if ( nAct >= nMin )
+ return true;
+ PushParameterExpected();
+ return false;
+}
+
+inline bool ScInterpreter::MustHaveParamCountMinWithStackCheck( short nAct, short nMin )
+{
+ assert(sp >= nAct);
+ if (sp < nAct)
+ {
+ PushError(FormulaError::UnknownStackVariable);
+ return false;
+ }
+ return MustHaveParamCountMin( nAct, nMin);
+}
+
+inline bool ScInterpreter::CheckStringPositionArgument( double & fVal )
+{
+ if (!std::isfinite( fVal))
+ {
+ fVal = -1.0;
+ return false;
+ }
+ else if (fVal < 0.0)
+ {
+ fVal = 0.0;
+ return false;
+ }
+ else if (fVal > SAL_MAX_INT32)
+ {
+ fVal = static_cast<double>(SAL_MAX_INT32);
+ return false;
+ }
+ return true;
+}
+
+inline sal_Int32 ScInterpreter::GetStringPositionArgument()
+{
+ double fVal = rtl::math::approxFloor( GetDouble());
+ if (!CheckStringPositionArgument( fVal))
+ {
+ fVal = -1.0;
+ SetError( FormulaError::IllegalArgument);
+ }
+ return static_cast<sal_Int32>(fVal);
+}
+
+inline bool ScInterpreter::CheckStringResultLen( OUString& rResult, sal_Int32 nIncrease )
+{
+ if (nIncrease > kScInterpreterMaxStrLen - rResult.getLength())
+ {
+ SetError( FormulaError::StringOverflow );
+ rResult.clear();
+ return false;
+ }
+ return true;
+}
+
+inline bool ScInterpreter::CheckStringResultLen( OUStringBuffer& rResult, sal_Int32 nIncrease )
+{
+ if (nIncrease > kScInterpreterMaxStrLen - rResult.getLength())
+ {
+ SetError( FormulaError::StringOverflow );
+ rResult.setLength(0);
+ return false;
+ }
+ return true;
+}
+
+inline void ScInterpreter::TreatDoubleError( double& rVal )
+{
+ if ( !std::isfinite( rVal ) )
+ {
+ FormulaError nErr = GetDoubleErrorValue( rVal );
+ if ( nErr != FormulaError::NONE )
+ SetError( nErr );
+ else
+ SetError( FormulaError::NoValue );
+ rVal = 0.0;
+ }
+}
+
+inline double ScInterpreter::div( const double& fNumerator, const double& fDenominator )
+{
+ return sc::div(fNumerator, fDenominator);
+}
+
+inline sal_Int16 ScInterpreter::GetDayOfWeek( sal_Int32 n )
+{ // monday = 0, ..., sunday = 6
+ return static_cast< sal_Int16 >( ( n - 1 ) % 7 );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/inc/jumpmatrix.hxx b/sc/source/core/inc/jumpmatrix.hxx
new file mode 100644
index 0000000000..f0fb9c1abb
--- /dev/null
+++ b/sc/source/core/inc/jumpmatrix.hxx
@@ -0,0 +1,122 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <limits.h>
+#include <vector>
+#include <types.hxx>
+#include <address.hxx>
+#include <token.hxx>
+
+namespace formula { class FormulaToken; }
+
+typedef ::std::vector< const formula::FormulaToken*> ScTokenVec;
+
+struct ScJumpMatrixEntry
+{
+ double fBool; // 0:= false 1:= true also if no-path
+ // other values may contain error conditions like NAN and INF
+ short nStart; // start of path (actually start-1, see formula::FormulaTokenIterator)
+ short nNext; // next after path
+ // jump path exists if nStart != nNext, else no path
+ short nStop; // optional stop of path (nPC < nStop)
+
+ void SetJump( double fBoolP, short nStartP, short nNextP, short nStopP )
+ {
+ fBool = fBoolP;
+ nStart = nStartP;
+ nNext = nNextP;
+ nStop = nStopP;
+ }
+ void GetJump( double& rBool, short& rStart, short& rNext, short& rStop ) const
+ {
+ rBool = fBool;
+ rStart = nStart;
+ rNext = nNext;
+ rStop = nStop;
+ }
+};
+
+class ScJumpMatrix
+{
+ std::vector<ScJumpMatrixEntry> mvJump; // the jumps
+ ScMatrixRef pMat; // the results
+ ScRefList mvRefList; // array of references result, if any
+ ScTokenVec mvParams; // parameter stack
+ SCSIZE nCols;
+ SCSIZE nRows;
+ SCSIZE nCurCol;
+ SCSIZE nCurRow;
+ SCSIZE nResMatCols;
+ SCSIZE nResMatRows;
+ OpCode meOp;
+ bool bStarted;
+
+ // Buffer result ranges to be able to set a range of identically typed
+ // values at the result matrix in order to avoid multiple shrinks and
+ // growths of multi_type_vector segments, which is a major performance
+ // bottleneck, see fdo#72929
+ ::std::vector< svl::SharedString > mvBufferStrings;
+ ::std::vector< double > mvBufferDoubles;
+ SCSIZE mnBufferCol;
+ SCSIZE mnBufferRowStart;
+ SCSIZE mnBufferEmptyCount;
+ SCSIZE mnBufferEmptyPathCount;
+
+ enum BufferType
+ {
+ BUFFER_NONE,
+ BUFFER_DOUBLE,
+ BUFFER_STRING,
+ BUFFER_EMPTY,
+ BUFFER_EMPTYPATH
+ };
+
+ /** Flush different types or non-consecutive buffers. */
+ void FlushBufferOtherThan( BufferType eType, SCSIZE nC, SCSIZE nR );
+
+ ScJumpMatrix( const ScJumpMatrix& ) = delete;
+ ScJumpMatrix& operator=( const ScJumpMatrix& ) = delete;
+
+public:
+ ScJumpMatrix( OpCode eOp, SCSIZE nColsP, SCSIZE nRowsP );
+ ~ScJumpMatrix();
+ void GetDimensions( SCSIZE& rCols, SCSIZE& rRows ) const;
+ void SetJump( SCSIZE nCol, SCSIZE nRow, double fBool, short nStart, short nNext );
+ void GetJump( SCSIZE nCol, SCSIZE nRow, double& rBool, short& rStart, short& rNext, short& rStop ) const;
+ void SetAllJumps( double fBool, short nStart, short nNext, short nStop = SHRT_MAX );
+ void SetJumpParameters( ScTokenVec&& p );
+ const ScTokenVec & GetJumpParameters() const { return mvParams;}
+ bool HasResultMatrix() const;
+ ScMatrix* GetResultMatrix(); ///< also applies pending buffered values
+ void GetPos( SCSIZE& rCol, SCSIZE& rRow ) const;
+ bool Next( SCSIZE& rCol, SCSIZE& rRow );
+ void GetResMatDimensions( SCSIZE& rCols, SCSIZE& rRows );
+ void SetNewResMat( SCSIZE nNewCols, SCSIZE nNewRows );
+ ScRefList& GetRefList();
+ OpCode GetOpCode() const { return meOp; }
+
+ void PutResultDouble( double fVal, SCSIZE nC, SCSIZE nR );
+ void PutResultString( const svl::SharedString& rStr, SCSIZE nC, SCSIZE nR );
+ void PutResultEmpty( SCSIZE nC, SCSIZE nR );
+ void PutResultEmptyPath( SCSIZE nC, SCSIZE nR );
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/inc/parclass.hxx b/sc/source/core/inc/parclass.hxx
new file mode 100644
index 0000000000..4b043fd7fe
--- /dev/null
+++ b/sc/source/core/inc/parclass.hxx
@@ -0,0 +1,144 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <formula/opcode.hxx>
+#include <formula/paramclass.hxx>
+
+/** Activate parameter classification documentation.
+
+ Building with DEBUG_SC_PARCLASSDOC 1 enables generation of parameter
+ classification documentation when instantiating the first Calc document if
+ the environment variable OOO_CALC_GENPARCLASSDOC is set and SAL_LOG
+ contains +INFO.sc.core
+
+ Generated output contains CALC_GENPARCLASSDOC that can be easily grep'ed for.
+
+ Activation adds overhead to Calc initialization time to gather information
+ that otherwise is not needed for anything else.
+ */
+#define DEBUG_SC_PARCLASSDOC 0
+
+namespace formula
+{
+ class FormulaToken;
+}
+
+class ScParameterClassification
+{
+public:
+
+ /// MUST be called once before any other method.
+ static void Init();
+
+ static void Exit();
+
+ /** Get one parameter type for function eOp.
+ @param nParameter
+ Which parameter, 0-based.
+ SAL_MAX_UINT16 for return type of eOp.
+ */
+ static formula::ParamClass GetParameterType( const formula::FormulaToken* pToken,
+ sal_uInt16 nParameter);
+
+ /** Whether OpCode has a parameter of type
+ ForceArray or ReferenceOrForceArray. */
+ static bool HasForceArray( OpCode eOp)
+ {
+ return 0 <= static_cast<short>(eOp) &&
+ eOp <= SC_OPCODE_LAST_OPCODE_ID &&
+ pData[eOp].bHasForceArray;
+ }
+
+private:
+
+ struct CommonData
+ {
+ const static sal_Int32 nMaxParams = 7;
+
+ formula::ParamClass nParam[nMaxParams];
+ sal_uInt8 nRepeatLast;
+ formula::ParamClass eReturn;
+ };
+
+ struct RawData
+ {
+ OpCode eOp;
+ CommonData aData;
+ };
+
+ struct RunData;
+ friend struct ScParameterClassification::RunData;
+ struct RunData
+ {
+ CommonData aData;
+ sal_uInt8 nMinParams; // fix or minimum, or repeat start
+ bool bHasForceArray;
+ };
+
+ static const RawData pRawData[];
+ static RunData* pData;
+
+ // ocExternal AddIns
+ static formula::ParamClass GetExternalParameterType(
+ const formula::FormulaToken* pToken, sal_uInt16 nParameter);
+
+#if DEBUG_SC_PARCLASSDOC
+ // Generate documentation to stdout if environment variable
+ // OOO_CALC_GENPARCLASSDOC is set.
+ static void GenerateDocumentation();
+
+ /* OpCodes not specified in the implementation are taken from the global
+ * function list and all parameters, if any, are assumed to be of type
+ * Value. This could also be done in the product version if needed, but we
+ * don't want to spoil startup time. However, doing so could propagate the
+ * minimum parameter count to the formula compiler, which, together with
+ * additional information about optional parameters, could react on missing
+ * parameters then. */
+ static void MergeArgumentsFromFunctionResource();
+
+ /** Minimum number of parameters, or fix number
+ of parameters if HasRepeatParameters()
+ returns sal_False. For opcodes not specified in
+ the implementation a parameter count of 1
+ is assumed, for opcodes out of range 0 is
+ assumed. If HasRepeatParameters() returns
+ sal_True, information is NOT related to whether
+ any parameters are optional, only the type
+ of parameters is significant. */
+ static inline sal_uInt8 GetMinimumParameters( OpCode eOp)
+ {
+ if ( eOp <= SC_OPCODE_LAST_OPCODE_ID )
+ return pData[eOp].aData.nParam[0]
+ == formula::ParamClass::Unknown ? 1 :
+ pData[eOp].nMinParams;
+ return 0;
+ }
+
+ /** Whether last parameter types are repeated. */
+ static inline bool HasRepeatParameters( OpCode eOp)
+ {
+ return eOp <= SC_OPCODE_LAST_OPCODE_ID
+ && pData[eOp].aData.nRepeatLast > 0;
+ }
+#endif // DEBUG_SC_PARCLASSDOC
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/inc/poolhelp.hxx b/sc/source/core/inc/poolhelp.hxx
new file mode 100644
index 0000000000..860e1b3a8b
--- /dev/null
+++ b/sc/source/core/inc/poolhelp.hxx
@@ -0,0 +1,64 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <rtl/ref.hxx>
+#include <salhelper/simplereferenceobject.hxx>
+#include <docoptio.hxx>
+#include <svl/itempool.hxx>
+#include <mutex>
+
+class ScDocument;
+class ScDocumentPool;
+class ScStyleSheetPool;
+class SvNumberFormatter;
+class SfxItemPool;
+
+class ScPoolHelper final : public salhelper::SimpleReferenceObject
+{
+private:
+ mutable std::mutex maMtxCreateNumFormatter;
+ ScDocOptions aOpt;
+ rtl::Reference<ScDocumentPool> pDocPool;
+ rtl::Reference< ScStyleSheetPool > mxStylePool;
+ mutable std::unique_ptr<SvNumberFormatter> pFormTable;
+ mutable rtl::Reference<SfxItemPool> pEditPool; // EditTextObjectPool
+ mutable rtl::Reference<SfxItemPool> pEnginePool; // EditEnginePool
+
+public:
+ ScPoolHelper( ScDocument& rSourceDoc );
+ virtual ~ScPoolHelper() override;
+
+ // called in dtor of main document
+ void SourceDocumentGone();
+
+ // access to pointers (are never 0):
+ ScDocumentPool* GetDocPool() const { return pDocPool.get(); }
+ ScStyleSheetPool* GetStylePool() const { return mxStylePool.get(); }
+ SvNumberFormatter* GetFormTable() const;
+ SfxItemPool* GetEditPool() const;
+ SfxItemPool* GetEnginePool() const;
+
+ void SetFormTableOpt(const ScDocOptions& rOpt);
+
+ std::unique_ptr<SvNumberFormatter> CreateNumberFormatter() const;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/inc/refupdat.hxx b/sc/source/core/inc/refupdat.hxx
new file mode 100644
index 0000000000..cd3ab69dfa
--- /dev/null
+++ b/sc/source/core/inc/refupdat.hxx
@@ -0,0 +1,71 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <global.hxx>
+
+class ScDocument;
+class ScBigRange;
+struct ScComplexRefData;
+class ScAddress;
+class ScRange;
+
+enum ScRefUpdateRes {
+ UR_NOTHING = 0, ///< Reference not affected, no change at all.
+ UR_UPDATED = 1, ///< Reference was adjusted/updated.
+ UR_INVALID = 2, ///< Some part of the reference became invalid.
+ UR_STICKY = 3 /**< Not updated because the reference is sticky,
+ but would had been updated if it wasn't. For
+ entire columns/rows. Essentially the same as
+ not UR_NOTHING for the caller but allows
+ differentiation. */
+};
+
+class ScRefUpdate
+{
+public:
+
+ static ScRefUpdateRes Update
+ ( const ScDocument* pDoc, UpdateRefMode eUpdateRefMode,
+ SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
+ SCCOL nCol2, SCROW nRow2, SCTAB nTab2,
+ SCCOL nDx, SCROW nDy, SCTAB nDz,
+ SCCOL& theCol1, SCROW& theRow1, SCTAB& theTab1,
+ SCCOL& theCol2, SCROW& theRow2, SCTAB& theTab2 );
+
+ static ScRefUpdateRes Update( UpdateRefMode eUpdateRefMode,
+ const ScBigRange& rWhere,
+ sal_Int32 nDx, sal_Int32 nDy, sal_Int32 nDz,
+ ScBigRange& rWhat );
+
+ static void MoveRelWrap( const ScDocument& rDoc, const ScAddress& rPos,
+ SCCOL nMaxCol, SCROW nMaxRow, ScComplexRefData& rRef );
+
+ static ScRefUpdateRes UpdateTranspose(
+ const ScDocument& rDoc, const ScRange& rSource, const ScAddress& rDest, ScRange& rRef );
+
+ static void DoTranspose( SCCOL& rCol, SCROW& rRow, SCTAB& rTab, const ScDocument& rDoc,
+ const ScRange& rSource, const ScAddress& rDest );
+
+ static ScRefUpdateRes UpdateGrow(
+ const ScRange& rArea, SCCOL nGrowX, SCROW nGrowY, ScRange& rRef );
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/inc/scrdata.hxx b/sc/source/core/inc/scrdata.hxx
new file mode 100644
index 0000000000..0698e12573
--- /dev/null
+++ b/sc/source/core/inc/scrdata.hxx
@@ -0,0 +1,37 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <com/sun/star/uno/Reference.hxx>
+
+namespace com::sun::star::i18n
+{
+class XBreakIterator;
+}
+
+class ScScriptTypeData
+{
+public:
+ css::uno::Reference<css::i18n::XBreakIterator> xBreakIter;
+
+ ScScriptTypeData() {}
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/inc/sharedstringpoolpurge.hxx b/sc/source/core/inc/sharedstringpoolpurge.hxx
new file mode 100644
index 0000000000..87b11f3a05
--- /dev/null
+++ b/sc/source/core/inc/sharedstringpoolpurge.hxx
@@ -0,0 +1,47 @@
+/* -*- 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/.
+ *
+ */
+
+#pragma once
+
+#include <memory>
+#include <vector>
+
+#include <svl/sharedstringpool.hxx>
+#include <vcl/timer.hxx>
+
+namespace svl
+{
+class SharedStringPool;
+}
+
+namespace sc
+{
+/*
+Calls svl::SharedStringPool::purge() after a delay when idle. Can be
+used to compress repeated calls, as purge() may be somewhat expensive
+with large documents. And since vcl links to svl, it's not possible
+to use VCL timers in svl, so a separate class is needed.
+*/
+class SharedStringPoolPurge
+{
+public:
+ SharedStringPoolPurge();
+ ~SharedStringPoolPurge();
+ void delayedPurge(const std::shared_ptr<svl::SharedStringPool>& pool);
+
+private:
+ void cleanup();
+ std::vector<std::shared_ptr<svl::SharedStringPool>> mPoolsToPurge;
+ Timer mTimer;
+ DECL_LINK(timerHandler, Timer*, void);
+};
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/inc/webservicelink.hxx b/sc/source/core/inc/webservicelink.hxx
new file mode 100644
index 0000000000..8504a8c1b6
--- /dev/null
+++ b/sc/source/core/inc/webservicelink.hxx
@@ -0,0 +1,49 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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/.
+ */
+
+#pragma once
+
+#include <sfx2/lnkbase.hxx>
+#include <svl/broadcast.hxx>
+
+namespace com::sun::star::uno
+{
+class Any;
+}
+
+class ScDocument;
+
+class ScWebServiceLink final : public ::sfx2::SvBaseLink, public SvtBroadcaster
+{
+private:
+ ScDocument* pDoc;
+ OUString aURL; // connection/ link data
+ bool bHasResult; // is set aResult is useful
+ OUString aResult;
+
+public:
+ ScWebServiceLink(ScDocument* pD, OUString aURL);
+ virtual ~ScWebServiceLink() override;
+
+ // SvBaseLink override:
+ virtual ::sfx2::SvBaseLink::UpdateResult DataChanged(const OUString& rMimeType,
+ const css::uno::Any& rValue) override;
+
+ // SvtBroadcaster override:
+ virtual void ListenersGone() override;
+
+ // for interpreter:
+
+ const OUString& GetResult() const { return aResult; }
+ bool HasResult() const { return bHasResult; }
+
+ const OUString& GetURL() const { return aURL; }
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */