summaryrefslogtreecommitdiffstats
path: root/sc/inc/column.hxx
diff options
context:
space:
mode:
Diffstat (limited to 'sc/inc/column.hxx')
-rw-r--r--sc/inc/column.hxx1089
1 files changed, 1089 insertions, 0 deletions
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
new file mode 100644
index 0000000000..733923b0f5
--- /dev/null
+++ b/sc/inc/column.hxx
@@ -0,0 +1,1089 @@
+/* -*- 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"
+#include "address.hxx"
+#include "cellvalue.hxx"
+#include "columnspanset.hxx"
+#include "rangelst.hxx"
+#include "types.hxx"
+#include "mtvelements.hxx"
+#include <formula/types.hxx>
+#include <svl/zforlist.hxx>
+#include <svx/svdobj.hxx>
+#include "attarray.hxx"
+
+#include <optional>
+#include <set>
+#include <vector>
+
+#include <mdds/flat_segment_tree.hpp>
+
+namespace editeng { class SvxBorderLine; }
+namespace formula { struct VectorRefArray; }
+
+namespace sc {
+
+struct BroadcasterState;
+struct FormulaGroupEntry;
+class StartListeningContext;
+class EndListeningContext;
+class CopyFromClipContext;
+class CopyToClipContext;
+class CopyToDocContext;
+class MixDocContext;
+struct RefUpdateContext;
+struct RefUpdateInsertTabContext;
+struct RefUpdateDeleteTabContext;
+struct RefUpdateMoveTabContext;
+class EditTextIterator;
+struct NoteEntry;
+class DocumentStreamAccess;
+class CellValues;
+class TableValues;
+struct RowSpan;
+class RowHeightContext;
+class CompileFormulaContext;
+struct SetFormulaDirtyContext;
+enum class MatrixEdge;
+class ColumnIterator;
+class Sparkline;
+
+}
+
+class Fraction;
+class OutputDevice;
+class ScItemPoolCache;
+class SvtListener;
+class SfxPoolItem;
+class SfxStyleSheetBase;
+class SvxBoxInfoItem;
+class SvxBoxItem;
+
+class ScDocument;
+class ScEditDataArray;
+class ScFormulaCell;
+class ScMarkData;
+class ScPatternAttr;
+class ScStyleSheet;
+class SvtBroadcaster;
+class ScTypedStrData;
+class ScProgress;
+class ScFunctionData;
+class ScFlatBoolRowSegments;
+struct ScSetStringParam;
+struct ScColWidthParam;
+struct ScRefCellValue;
+struct ScCellValue;
+class ScHint;
+enum class ScMF;
+struct ScFilterEntries;
+struct ScInterpreterContext;
+
+struct ScNeededSizeOptions
+{
+ const ScPatternAttr* pPattern;
+ bool bFormula;
+ bool bSkipMerged;
+ bool bGetFont;
+ bool bTotalSize;
+
+ ScNeededSizeOptions();
+};
+
+// A shared implementation of some column code and data.
+// This is used by ScColumn, but also by ScTable for the unallocated
+// columns (one instance that is the default for all not-yet allocated columns).
+class ScColumnData
+{
+protected:
+ std::unique_ptr<ScAttrArray> pAttrArray;
+
+ ScColumnData(const ScColumnData&) = delete;
+ ScColumnData& operator= (const ScColumnData&) = delete;
+
+public:
+ ScColumnData() = default;
+ void InitAttrArray(ScAttrArray* attrArray) { pAttrArray.reset(attrArray); }
+
+ ScDocument& GetDoc() const { return pAttrArray->GetDoc(); }
+
+ ScAttrArray& AttrArray() { return *pAttrArray; }
+ const ScAttrArray& AttrArray() const { return *pAttrArray; }
+
+ const SfxPoolItem& GetAttr( SCROW nRow, sal_uInt16 nWhich ) const;
+ template<class T> const T& GetAttr( SCROW nRow, TypedWhichId<T> nWhich ) const
+ {
+ return static_cast<const T&>(GetAttr(nRow, sal_uInt16(nWhich)));
+ }
+ const SfxPoolItem& GetAttr( SCROW nRow, sal_uInt16 nWhich, SCROW& nStartRow, SCROW& nEndRow ) const;
+ template<class T> const T& GetAttr( SCROW nRow, TypedWhichId<T> nWhich, SCROW& nStartRow, SCROW& nEndRow ) const
+ {
+ return static_cast<const T&>(GetAttr(nRow, sal_uInt16(nWhich), nStartRow, nEndRow));
+ }
+
+ void SetAttrEntries(std::vector<ScAttrEntry> && vNewData);
+
+ const ScPatternAttr* GetPattern( SCROW nRow ) const;
+ const ScPatternAttr* GetMostUsedPattern( SCROW nStartRow, SCROW nEndRow ) const;
+ void ApplySelectionStyle(const ScStyleSheet& rStyle, SCROW nTop, SCROW nBottom);
+ void ApplySelectionCache(ScItemPoolCache* pCache, SCROW nStartRow, SCROW nEndRow,
+ ScEditDataArray* pDataArray, bool* pIsChanged);
+ void ApplyPatternArea( SCROW nStartRow, SCROW nEndRow, const ScPatternAttr& rPatAttr,
+ ScEditDataArray* pDataArray = nullptr,
+ bool* const pIsChanged = nullptr);
+ void MergePatternArea( ScMergePatternState& rState, SCROW nRow1, SCROW nRow2, bool bDeep ) const;
+
+ sal_uInt32 GetNumberFormat( const ScInterpreterContext& rContext, SCROW nRow ) const;
+ sal_uInt32 GetNumberFormat( SCROW nStartRow, SCROW nEndRow ) const;
+
+ /// Including current, may return -1
+ SCROW GetNextUnprotected( SCROW nRow, bool bUp ) const;
+
+ const ScStyleSheet* GetStyle( SCROW nRow ) const;
+ void ApplyStyleArea( SCROW nStartRow, SCROW nEndRow, const ScStyleSheet& rStyle );
+
+ bool HasAttrib( SCROW nRow1, SCROW nRow2, HasAttrFlags nMask ) const;
+ bool HasAttrib( SCROW nRow, HasAttrFlags nMask, SCROW* nStartRow = nullptr, SCROW* nEndRow = nullptr ) const;
+
+ std::unique_ptr<ScAttrIterator> CreateAttrIterator( SCROW nStartRow, SCROW nEndRow ) const;
+
+ bool IsAllAttrEqual( const ScColumnData& rCol, SCROW nStartRow, SCROW nEndRow ) const;
+
+ void ClearSelectionItems(const sal_uInt16* pWhich, SCROW nStartRow, SCROW nEndRow);
+ void ChangeSelectionIndent(bool bIncrement, SCROW nStartRow, SCROW nEndRow);
+
+ bool TestInsertRow( SCSIZE nSize ) const;
+ void InsertRow( SCROW nStartRow, SCSIZE nSize );
+ void DeleteRow( SCROW nStartRow, SCSIZE nSize );
+
+ // Applies a function to the selected ranges.
+ // The function looks like
+ // ApplyDataFunc(ScColumnData& applyTo, SCROW nTop, SCROW nBottom)
+ template <typename ApplyDataFunc> void Apply(const ScMarkData&, SCCOL, ApplyDataFunc);
+};
+
+// Use protected inheritance to prevent publishing some internal ScColumnData
+// functions as part of ScColumn. If they should be public in ScColumn,
+// use 'using' to make them public.
+class ScColumn : protected ScColumnData
+{
+ // Empty values correspond with empty cells. All non-empty cell positions
+ // must have non-empty elements. For text width, the value should be
+ // either the real text width, or TEXTWIDTH_DIRTY in case it hasn't been
+ // calculated yet. For script type, it should be either the real script
+ // type value or SvtScriptType::UNKNOWN.
+ sc::CellTextAttrStoreType maCellTextAttrs;
+
+ // Cell notes
+ sc::CellNoteStoreType maCellNotes;
+
+ // Broadcasters for formula cells.
+ sc::BroadcasterStoreType maBroadcasters;
+
+ // Cell values.
+ sc::CellStoreType maCells;
+
+ // Sparklines
+ sc::SparklineStoreType maSparklines;
+
+ size_t mnBlkCountFormula;
+
+ SCCOL nCol;
+ SCTAB nTab;
+
+ bool mbEmptyBroadcastersPending : 1; // a broadcaster not removed during EnableDelayDeletingBroadcasters()
+
+friend class ScDocument; // for FillInfo
+friend class ScTable;
+friend class ScValueIterator;
+friend class ScHorizontalValueIterator;
+friend class ScDBQueryDataIterator;
+template< ScQueryCellIteratorAccess accessType, ScQueryCellIteratorType queryType >
+friend class ScQueryCellIteratorBase;
+template< ScQueryCellIteratorAccess accessType >
+friend class ScQueryCellIteratorAccessSpecific;
+friend class ScFormulaGroupIterator;
+friend class ScCellIterator;
+friend class ScHorizontalCellIterator;
+friend class ScColumnTextWidthIterator;
+friend class ScDocumentImport;
+friend class sc::DocumentStreamAccess;
+friend class sc::SingleColumnSpanSet;
+friend class sc::ColumnSpanSet;
+friend class sc::EditTextIterator;
+friend class sc::CellValues;
+friend class sc::TableValues;
+friend class sc::CellStoreEvent;
+
+ bool ParseString(
+ ScCellValue& rCell,
+ SCROW nRow, SCTAB nTab, const OUString& rString, formula::FormulaGrammar::AddressConvention eConv,
+ const ScSetStringParam* pParam );
+
+ void duplicateSparkline(sc::CopyFromClipContext& rContext, sc::ColumnBlockPosition* pBlockPos,
+ size_t nColOffset, size_t nDestSize, ScAddress aDestPosition);
+
+public:
+
+ /** Broadcast mode for SetDirty(SCROW,SCROW,BroadcastMode). */
+ enum BroadcastMode
+ {
+ BROADCAST_NONE, ///< no broadcasting
+ BROADCAST_DATA_POSITIONS, ///< broadcast existing cells with position => does AreaBroadcast
+ BROADCAST_BROADCASTERS ///< broadcast only existing cell broadcasters => no AreaBroadcast of range!
+ };
+
+ ScColumn(ScSheetLimits const &);
+ ~ScColumn() COVERITY_NOEXCEPT_FALSE;
+
+ void Init(SCCOL nNewCol, SCTAB nNewTab, ScDocument& rDoc, bool bEmptyAttrArray);
+
+ using ScColumnData::GetDoc;
+ SCTAB GetTab() const { return nTab; }
+ SCCOL GetCol() const { return nCol; }
+ sc::CellStoreType& GetCellStore() { return maCells; }
+ const sc::CellStoreType& GetCellStore() const { return maCells; }
+ sc::CellTextAttrStoreType& GetCellAttrStore() { return maCellTextAttrs; }
+ const sc::CellTextAttrStoreType& GetCellAttrStore() const { return maCellTextAttrs; }
+ sc::CellNoteStoreType& GetCellNoteStore() { return maCellNotes; }
+ const sc::CellNoteStoreType& GetCellNoteStore() const { return maCellNotes; }
+ sc::SparklineStoreType& GetSparklineStore() { return maSparklines; }
+ const sc::SparklineStoreType& GetSparklineStore() const { return maSparklines; }
+
+ ScRefCellValue GetCellValue( SCROW nRow ) const;
+ ScRefCellValue GetCellValue( sc::ColumnBlockPosition& rBlockPos, SCROW nRow );
+ ScRefCellValue GetCellValue( sc::ColumnBlockConstPosition& rBlockPos, SCROW nRow ) const;
+ static ScRefCellValue GetCellValue( const sc::CellStoreType::const_iterator& itPos, size_t nOffset );
+
+ const sc::CellTextAttr* GetCellTextAttr( SCROW nRow ) const;
+ const sc::CellTextAttr* GetCellTextAttr( sc::ColumnBlockConstPosition& rBlockPos, SCROW nRow ) const;
+
+ void Delete( SCROW nRow );
+ void DeleteContent( SCROW nRow, bool bBroadcast = true );
+ void FreeAll();
+ void FreeNotes();
+ void Swap( ScColumn& rOther, SCROW nRow1, SCROW nRow2, bool bPattern );
+
+ bool HasAttribSelection( const ScMarkData& rMark, HasAttrFlags nMask ) const;
+ bool IsMerged( SCROW nRow ) const;
+ bool ExtendMerge( SCCOL nThisCol, SCROW nStartRow, SCROW nEndRow,
+ SCCOL& rPaintCol, SCROW& rPaintRow,
+ bool bRefresh );
+
+ bool IsEmptyData() const;
+ bool IsEmptyAttr() const;
+
+ // data only:
+ bool IsEmptyData(SCROW nStartRow, SCROW nEndRow) const;
+ SCSIZE GetEmptyLinesInBlock( SCROW nStartRow, SCROW nEndRow, ScDirection eDir ) const;
+ bool HasDataAt( SCROW nRow, ScDataAreaExtras* pDataAreaExtras = nullptr ) const;
+ bool HasDataAt( sc::ColumnBlockConstPosition& rBlockPos, SCROW nRow,
+ ScDataAreaExtras* pDataAreaExtras = nullptr ) const;
+ bool HasDataAt( sc::ColumnBlockPosition& rBlockPos, SCROW nRow,
+ ScDataAreaExtras* pDataAreaExtras = nullptr );
+ void GetDataExtrasAt( SCROW nRow, ScDataAreaExtras& rDataAreaExtras ) const;
+ bool HasVisibleDataAt(SCROW nRow) const;
+ SCROW GetFirstDataPos() const;
+ SCROW GetLastDataPos() const;
+ SCROW GetLastDataPos( SCROW nLastRow, ScDataAreaExtras* pDataAreaExtras = nullptr ) const;
+ bool GetPrevDataPos(SCROW& rRow) const;
+ bool GetNextDataPos(SCROW& rRow) const;
+ bool TrimEmptyBlocks(SCROW& rRowStart, SCROW& rRowEnd) const;
+ void FindDataAreaPos(SCROW& rRow, bool bDown) const; // (without Broadcaster)
+ void FindUsed( SCROW nStartRow, SCROW nEndRow, mdds::flat_segment_tree<SCROW, bool>& rUsed ) const;
+
+ SCSIZE VisibleCount( SCROW nStartRow, SCROW nEndRow ) const;
+ sc::MatrixEdge GetBlockMatrixEdges(SCROW nRow1, SCROW nRow2, sc::MatrixEdge nMask, bool bNoMatrixAtAll ) const;
+ // Repeated calls to HasSelectionMatrixFragment() repeatedly call rMark.GetMarkedRanges(),
+ // which may be quite slow. For that reason first save the result of rMark.GetMarkedRanges()
+ // pass that to HasSelectionMatrixFragment() calls.
+ bool HasSelectionMatrixFragment(const ScMarkData& rMark, const ScRangeList& rRangeList) const;
+
+ bool GetFirstVisibleAttr( SCROW& rFirstRow ) const;
+ bool GetLastVisibleAttr( SCROW& rLastRow, bool bSkipEmpty ) const;
+ bool HasVisibleAttrIn( SCROW nStartRow, SCROW nEndRow ) const;
+ bool IsVisibleAttrEqual( const ScColumn& rCol, SCROW nStartRow, SCROW nEndRow ) const;
+
+ bool TestInsertCol( SCROW nStartRow, SCROW nEndRow) const;
+ bool TestInsertRow( SCROW nStartRow, SCSIZE nSize ) const;
+ void InsertRow( SCROW nStartRow, SCSIZE nSize );
+ void GetUnprotectedCells(SCROW nStartRow, SCROW nEndRow, ScRangeList& rRangeList ) const;
+
+ /**
+ * @param nStartRow top row position
+ * @param nSize size of the segment to delete.
+ * @param pGroupPos when non-NULL, stores the top position of formula
+ * group that's been merged as a result of row deletion.
+ */
+ void DeleteRow( SCROW nStartRow, SCSIZE nSize, std::vector<ScAddress>* pGroupPos );
+
+ void DeleteArea(
+ SCROW nStartRow, SCROW nEndRow, InsertDeleteFlags nDelFlag,
+ bool bBroadcast = true, sc::ColumnSpanSet* pBroadcastSpans = nullptr );
+
+ void DeleteRanges( const std::vector<sc::RowSpan>& rRanges, InsertDeleteFlags nDelFlag );
+
+ void CopyToClip(
+ sc::CopyToClipContext& rCxt, SCROW nRow1, SCROW nRow2, ScColumn& rColumn ) const;
+
+ void CopyStaticToDocument(
+ SCROW nRow1, SCROW nRow2, const SvNumberFormatterMergeMap& rMap, ScColumn& rDestCol );
+
+ void CopyCellToDocument( SCROW nSrcRow, SCROW nDestRow, ScColumn& rDestCol );
+ void InitBlockPosition( sc::ColumnBlockPosition& rBlockPos );
+ void InitBlockPosition( sc::ColumnBlockConstPosition& rBlockPos ) const;
+
+ void DeleteBeforeCopyFromClip(
+ sc::CopyFromClipContext& rCxt, const ScColumn& rClipCol, sc::ColumnSpanSet& rBroadcastSpans );
+
+ void CopyOneCellFromClip( sc::CopyFromClipContext& rCxt, SCROW nRow1, SCROW nRow2, size_t nColOffset );
+
+ void CopyFromClip(
+ sc::CopyFromClipContext& rCxt, SCROW nRow1, SCROW nRow2, tools::Long nDy, ScColumn& rColumn );
+
+ void RemoveEditAttribs( sc::ColumnBlockPosition& rBlockPos, SCROW nStartRow, SCROW nEndRow );
+
+ // Selection (?) of this document
+ void MixMarked(
+ sc::MixDocContext& rCxt, const ScMarkData& rMark, ScPasteFunc nFunction,
+ bool bSkipEmpty, const ScColumn& rSrcCol );
+ void MixData(
+ sc::MixDocContext& rCxt, SCROW nRow1, SCROW nRow2, ScPasteFunc nFunction, bool bSkipEmpty,
+ const ScColumn& rSrcCol );
+
+ void UpdateSelectionFunction(
+ const ScRangeList& rRanges, ScFunctionData& rData, const ScFlatBoolRowSegments& rHiddenRows );
+
+ void CopyToColumn(
+ sc::CopyToDocContext& rCxt, SCROW nRow1, SCROW nRow2, InsertDeleteFlags nFlags, bool bMarked,
+ ScColumn& rColumn, const ScMarkData* pMarkData = nullptr, bool bAsLink = false,
+ bool bGlobalNamesToLocal = false ) const;
+
+ void UndoToColumn(
+ sc::CopyToDocContext& rCxt, SCROW nRow1, SCROW nRow2, InsertDeleteFlags nFlags, bool bMarked,
+ ScColumn& rColumn) const;
+
+ void CopyScenarioFrom( const ScColumn& rSrcCol );
+ void CopyScenarioTo( ScColumn& rDestCol ) const;
+ bool TestCopyScenarioTo( const ScColumn& rDestCol ) const;
+ void MarkScenarioIn( ScMarkData& rDestMark ) const;
+
+ void CopyUpdated( const ScColumn* pPosCol, ScColumn& rDestCol ) const;
+
+ void SwapCol(ScColumn& rCol);
+ void MoveTo(SCROW nStartRow, SCROW nEndRow, ScColumn& rCol);
+
+ bool HasEditCells(SCROW nStartRow, SCROW nEndRow, SCROW& rFirst);
+
+ bool SetString(
+ SCROW nRow, SCTAB nTab, const OUString& rString, formula::FormulaGrammar::AddressConvention eConv,
+ const ScSetStringParam* pParam = nullptr );
+
+ void SetEditText( SCROW nRow, std::unique_ptr<EditTextObject> pEditText );
+ void SetEditText( sc::ColumnBlockPosition& rBlockPos, SCROW nRow, std::unique_ptr<EditTextObject> pEditText );
+ void SetEditText( sc::ColumnBlockPosition& rBlockPos, SCROW nRow, const EditTextObject& rEditText );
+ void SetEditText( SCROW nRow, const EditTextObject& rEditText, const SfxItemPool* pEditPool );
+ void SetFormula( SCROW nRow, const ScTokenArray& rArray, formula::FormulaGrammar::Grammar eGram );
+ void SetFormula( SCROW nRow, const OUString& rFormula, formula::FormulaGrammar::Grammar eGram );
+
+ /**
+ * Takes ownership of pCell
+ *
+ * @return pCell if it was successfully inserted, NULL otherwise. pCell
+ * is deleted automatically on failure to insert.
+ */
+ ScFormulaCell* SetFormulaCell(
+ SCROW nRow, ScFormulaCell* pCell,
+ sc::StartListeningType eListenType = sc::SingleCellListening,
+ bool bInheritNumFormatIfNeeded = true);
+ void SetFormulaCell(
+ sc::ColumnBlockPosition& rBlockPos, SCROW nRow, ScFormulaCell* pCell,
+ sc::StartListeningType eListenType = sc::SingleCellListening,
+ bool bInheritNumFormatIfNeeded = true);
+
+ bool SetFormulaCells( SCROW nRow, std::vector<ScFormulaCell*>& rCells );
+
+ bool HasFormulaCell() const;
+ bool HasFormulaCell( SCROW nRow1, SCROW nRow2 ) const;
+
+ void CloneFormulaCell(
+ sc::ColumnBlockPosition& rBlockPos,
+ const ScFormulaCell& rSrc, const sc::CellTextAttr& rAttr,
+ const std::vector<sc::RowSpan>& rRanges );
+
+ void CloneFormulaCell(
+ const ScFormulaCell& rSrc, const sc::CellTextAttr& rAttr,
+ const std::vector<sc::RowSpan>& rRanges );
+
+ svl::SharedString GetSharedString( SCROW nRow ) const;
+
+ void SetRawString( SCROW nRow, const OUString& rStr );
+ void SetRawString( SCROW nRow, const svl::SharedString& rStr );
+ void SetRawString( sc::ColumnBlockPosition& rBlockPos, SCROW nRow, const svl::SharedString& rStr, bool bBroadcast = true );
+ void SetValue( SCROW nRow, double fVal );
+ void SetValues( const SCROW nRow, const std::vector<double>& rVals );
+ void SetValue( sc::ColumnBlockPosition& rBlockPos, SCROW nRow, double fVal, bool bBroadcast = true );
+ void SetError( SCROW nRow, const FormulaError nError);
+
+ OUString GetString( SCROW nRow, const ScInterpreterContext* pContext = nullptr ) const
+ { return GetString( GetCellValue( nRow ), nRow, pContext ); }
+ OUString GetString( sc::ColumnBlockConstPosition& rBlockPos, SCROW nRow,
+ const ScInterpreterContext* pContext = nullptr ) const
+ { return GetString( GetCellValue( rBlockPos, nRow ), nRow, pContext ); }
+ double* GetValueCell( SCROW nRow );
+ // Note that if pShared is set and a value is returned that way, the returned OUString is empty.
+ OUString GetInputString( SCROW nRow, bool bForceSystemLocale = false ) const
+ { return GetInputString( GetCellValue( nRow ), nRow, bForceSystemLocale ); }
+ OUString GetInputString( sc::ColumnBlockConstPosition& rBlockPos, SCROW nRow,
+ bool bForceSystemLocale = false ) const
+ { return GetInputString( GetCellValue( rBlockPos, nRow ), nRow, bForceSystemLocale ); }
+ double GetValue( SCROW nRow ) const;
+ const EditTextObject* GetEditText( SCROW nRow ) const;
+ void RemoveEditTextCharAttribs( SCROW nRow, const ScPatternAttr& rAttr );
+ OUString GetFormula( SCROW nRow ) const;
+ const ScFormulaCell* GetFormulaCell( SCROW nRow ) const;
+ ScFormulaCell* GetFormulaCell( SCROW nRow );
+ ScFormulaCell * const * GetFormulaCellBlockAddress( SCROW nRow, size_t& rBlockSize ) const;
+ CellType GetCellType( SCROW nRow ) const;
+ SCSIZE GetCellCount() const;
+ sal_uInt64 GetWeightedCount() const;
+ sal_uInt64 GetWeightedCount(SCROW nStartRow, SCROW nEndRow) const;
+ sal_uInt64 GetCodeCount() const; // RPN-Code in formulas
+ FormulaError GetErrCode( SCROW nRow ) const;
+
+ bool HasStringData( SCROW nRow ) const;
+ bool HasValueData( SCROW nRow ) const;
+ bool HasStringCells( SCROW nStartRow, SCROW nEndRow ) const;
+
+ sc::MultiDataCellState::StateType HasDataCellsInRange(
+ SCROW nRow1, SCROW nRow2, SCROW* pRow1 ) const;
+
+ bool IsFormulaDirty( SCROW nRow ) const;
+
+ void CheckVectorizationState();
+ void SetAllFormulasDirty( const sc::SetFormulaDirtyContext& rCxt );
+ void SetDirtyFromClip( SCROW nRow1, SCROW nRow2, sc::ColumnSpanSet& rBroadcastSpans );
+ void SetDirty( SCROW nRow1, SCROW nRow2, BroadcastMode );
+ void SetDirtyVar();
+ void SetDirtyAfterLoad();
+ void SetTableOpDirty( const ScRange& );
+ void CalcAll();
+ void CalcAfterLoad( sc::CompileFormulaContext& rCxt, bool bStartListening );
+ void CompileAll( sc::CompileFormulaContext& rCxt );
+ void CompileXML( sc::CompileFormulaContext& rCxt, ScProgress& rProgress );
+
+ /** Broadcast single broadcasters in range, without explicitly setting
+ anything dirty, not doing area broadcasts.
+ @param rHint address is modified to adapt to the actual broadcasted
+ position on each iteration and upon return points to the last
+ position broadcasted. */
+ bool BroadcastBroadcasters( SCROW nRow1, SCROW nRow2, SfxHintId nHint );
+
+ bool CompileErrorCells( sc::CompileFormulaContext& rCxt, FormulaError nErrCode );
+
+ void ResetChanged( SCROW nStartRow, SCROW nEndRow );
+
+ bool UpdateReferenceOnCopy( sc::RefUpdateContext& rCxt, ScDocument* pUndoDoc = nullptr );
+
+ /**
+ * Update reference addresses in formula cell in response to mass cell
+ * movement.
+ *
+ * @return true if reference of at least one formula cell has been
+ * updated, false otherwise.
+ */
+ bool UpdateReference( sc::RefUpdateContext& rCxt, ScDocument* pUndoDoc );
+
+ void UpdateInsertTab( sc::RefUpdateInsertTabContext& rCxt );
+ void UpdateInsertTabOnlyCells( sc::RefUpdateInsertTabContext& rCxt );
+ void UpdateDeleteTab( sc::RefUpdateDeleteTabContext& rCxt );
+ void UpdateMoveTab( sc::RefUpdateMoveTabContext& rCxt, SCTAB nTabNo );
+ void UpdateCompile( bool bForceIfNameInUse = false );
+ void UpdateTranspose( const ScRange& rSource, const ScAddress& rDest,
+ ScDocument* pUndoDoc );
+ void UpdateGrow( const ScRange& rArea, SCCOL nGrowX, SCROW nGrowY );
+
+ void SetTabNo(SCTAB nNewTab);
+ void FindRangeNamesInUse(SCROW nRow1, SCROW nRow2, sc::UpdatedRangeNames& rIndexes) const;
+
+ void PreprocessRangeNameUpdate(
+ sc::EndListeningContext& rEndListenCxt, sc::CompileFormulaContext& rCompileCxt );
+
+ void CompileHybridFormula(
+ sc::StartListeningContext& rStartListenCxt, sc::CompileFormulaContext& rCompileCxt );
+
+ void PreprocessDBDataUpdate(
+ sc::EndListeningContext& rEndListenCxt, sc::CompileFormulaContext& rCompileCxt );
+
+ using ScColumnData::GetAttr;
+ using ScColumnData::GetPattern;
+ using ScColumnData::GetNumberFormat;
+
+ void MergeSelectionPattern( ScMergePatternState& rState, const ScMarkData& rMark, bool bDeep ) const;
+ void MergeBlockFrame( SvxBoxItem* pLineOuter, SvxBoxInfoItem* pLineInner,
+ ScLineFlags& rFlags,
+ SCROW nStartRow, SCROW nEndRow, bool bLeft, SCCOL nDistRight ) const;
+ void ApplyBlockFrame(const SvxBoxItem& rLineOuter, const SvxBoxInfoItem* pLineInner,
+ SCROW nStartRow, SCROW nEndRow, bool bLeft, SCCOL nDistRight);
+
+ void ApplyAttr( SCROW nRow, const SfxPoolItem& rAttr );
+ void ApplyPattern( SCROW nRow, const ScPatternAttr& rPatAttr );
+ const ScPatternAttr* SetPattern( SCROW nRow, std::unique_ptr<ScPatternAttr> );
+ void SetPattern( SCROW nRow, const ScPatternAttr& );
+ void SetPatternArea( SCROW nStartRow, SCROW nEndRow, const ScPatternAttr& );
+ void ApplyPatternIfNumberformatIncompatible( const ScRange& rRange,
+ const ScPatternAttr& rPattern, SvNumFormatType nNewType );
+
+ void ApplyStyle( SCROW nRow, const ScStyleSheet* rStyle );
+ void ApplySelectionLineStyle( const ScMarkData& rMark,
+ const ::editeng::SvxBorderLine* pLine, bool bColorOnly );
+ void AddCondFormat(SCROW nStartRow, SCROW nEndRow, sal_uInt32 nIndex );
+ void RemoveCondFormat(SCROW nStartRow, SCROW nEndRow, sal_uInt32 nIndex );
+
+ const ScStyleSheet* GetSelectionStyle( const ScMarkData& rMark, bool& rFound ) const;
+ const ScStyleSheet* GetAreaStyle( bool& rFound, SCROW nRow1, SCROW nRow2 ) const;
+
+ void FindStyleSheet( const SfxStyleSheetBase* pStyleSheet, ScFlatBoolRowSegments& rUsedRows, bool bReset );
+ bool IsStyleSheetUsed( const ScStyleSheet& rStyle ) const;
+
+ /// May return -1 if not found
+ SCROW SearchStyle(
+ SCROW nRow, const ScStyleSheet* pSearchStyle, bool bUp, bool bInSelection,
+ const ScMarkData& rMark) const;
+
+ bool SearchStyleRange(
+ SCROW& rRow, SCROW& rEndRow, const ScStyleSheet* pSearchStyle, bool bUp,
+ bool bInSelection, const ScMarkData& rMark) const;
+
+ bool ApplyFlags( SCROW nStartRow, SCROW nEndRow, ScMF nFlags );
+ bool RemoveFlags( SCROW nStartRow, SCROW nEndRow, ScMF nFlags );
+ void ClearItems( SCROW nStartRow, SCROW nEndRow, const sal_uInt16* pWhich );
+
+ void RemoveProtected( SCROW nStartRow, SCROW nEndRow );
+
+ void DeleteSelection( InsertDeleteFlags nDelFlag, const ScMarkData& rMark, bool bBroadcast );
+
+ tools::Long GetNeededSize(
+ SCROW nRow, OutputDevice* pDev, double nPPTX, double nPPTY,
+ const Fraction& rZoomX, const Fraction& rZoomY,
+ bool bWidth, const ScNeededSizeOptions& rOptions, const ScPatternAttr** pPatternChange,
+ bool bInPrintTwips = false ) const;
+
+ sal_uInt16 GetOptimalColWidth(
+ OutputDevice* pDev, double nPPTX, double nPPTY,
+ const Fraction& rZoomX, const Fraction& rZoomY,
+ bool bFormula, sal_uInt16 nOldWidth, const ScMarkData* pMarkData, const ScColWidthParam* pParam) const;
+
+ void GetOptimalHeight(
+ sc::RowHeightContext& rCxt, SCROW nStartRow, SCROW nEndRow, sal_uInt16 nMinHeight, SCROW nMinStart );
+
+ void GetFilterEntries(
+ sc::ColumnBlockConstPosition& rBlockPos, SCROW nStartRow, SCROW nEndRow,
+ ScFilterEntries& rFilterEntries, bool bFiltering, bool bFilteredRow );
+
+ void GetBackColorFilterEntries(SCROW nRow1, SCROW nRow2, ScFilterEntries& rFilterEntries );
+
+ bool GetDataEntries( SCROW nRow, std::set<ScTypedStrData>& rStrings) const;
+
+ void UpdateInsertTabAbs(SCTAB nNewPos);
+ bool TestTabRefAbs(SCTAB nTable) const;
+ bool GetNextSpellingCell(SCROW& nRow, bool bInSel, const ScMarkData& rData) const;
+
+ void StartListeningFormulaCells(
+ sc::StartListeningContext& rStartCxt, sc::EndListeningContext& rEndCxt, SCROW nRow1, SCROW nRow2 );
+
+ void EndListeningFormulaCells(
+ sc::EndListeningContext& rCxt, SCROW nRow1, SCROW nRow2,
+ SCROW* pStartRow, SCROW* pEndRow );
+
+ void StartListening( SvtListener& rLst, SCROW nRow );
+ void EndListening( SvtListener& rLst, SCROW nRow );
+ void StartListening( sc::StartListeningContext& rCxt, const ScAddress& rAddress, SvtListener& rListener );
+ void EndListening( sc::EndListeningContext& rCxt, const ScAddress& rAddress, SvtListener& rListener );
+ void StartListeners( sc::StartListeningContext& rCxt, bool bAll );
+ void SetDirtyIfPostponed();
+ void BroadcastRecalcOnRefMove();
+ void CollectListeners( std::vector<SvtListener*>& rListeners, SCROW nRow1, SCROW nRow2 );
+ void CollectFormulaCells( std::vector<ScFormulaCell*>& rCells, SCROW nRow1, SCROW nRow2 );
+
+ void CompileDBFormula( sc::CompileFormulaContext& rCxt );
+ void CompileColRowNameFormula( sc::CompileFormulaContext& rCxt );
+
+ sal_Int32 GetMaxStringLen( SCROW nRowStart, SCROW nRowEnd, rtl_TextEncoding eCharSet ) const;
+ sal_Int32 GetMaxNumberStringLen( sal_uInt16& nPrecision,
+ SCROW nRowStart, SCROW nRowEnd ) const;
+
+ sal_uInt16 GetTextWidth(SCROW nRow) const;
+ void SetTextWidth(SCROW nRow, sal_uInt16 nWidth);
+
+ SvtScriptType GetScriptType( SCROW nRow ) const;
+
+ /**
+ * Get combined script types of the specified range. This method may
+ * update script types on demand if they have not been determined.
+ */
+ SvtScriptType GetRangeScriptType( sc::CellTextAttrStoreType::iterator& itPos, SCROW nRow1, SCROW nRow2,
+ const sc::CellStoreType::iterator& itr);
+
+ void SetScriptType( SCROW nRow, SvtScriptType nType );
+ void UpdateScriptTypes( SCROW nRow1, SCROW nRow2 );
+
+ formula::FormulaTokenRef ResolveStaticReference( SCROW nRow );
+ bool ResolveStaticReference( ScMatrix& rMat, SCCOL nMatCol, SCROW nRow1, SCROW nRow2 );
+ void FillMatrix( ScMatrix& rMat, size_t nMatCol, SCROW nRow1, SCROW nRow2, svl::SharedStringPool* pPool ) const;
+ formula::VectorRefArray FetchVectorRefArray( SCROW nRow1, SCROW nRow2 );
+ bool HandleRefArrayForParallelism( SCROW nRow1, SCROW nRow2,
+ const ScFormulaCellGroupRef& mxGroup, ScAddress* pDirtiedAddress );
+#ifdef DBG_UTIL
+ void AssertNoInterpretNeeded( SCROW nRow1, SCROW nRow2 );
+#endif
+ void SetFormulaResults( SCROW nRow, const double* pResults, size_t nLen );
+
+ void CalculateInThread( ScInterpreterContext& rContext, SCROW nRow, size_t nLen, size_t nOffset,
+ unsigned nThisThread, unsigned nThreadsTotal );
+ void HandleStuffAfterParallelCalculation( SCROW nRow, size_t nLen, ScInterpreter* pInterpreter );
+
+ void SetNumberFormat( SCROW nRow, sal_uInt32 nNumberFormat );
+
+ SvtBroadcaster* GetBroadcaster( SCROW nRow );
+ const SvtBroadcaster* GetBroadcaster( SCROW nRow ) const;
+
+ void DeleteBroadcasters( sc::ColumnBlockPosition& rBlockPos, SCROW nRow1, SCROW nRow2 );
+ void PrepareBroadcastersForDestruction();
+ void DeleteEmptyBroadcasters();
+
+ void Broadcast( SCROW nRow );
+ void BroadcastCells( const std::vector<SCROW>& rRows, SfxHintId nHint );
+ void BroadcastRows( SCROW nStartRow, SCROW nEndRow, SfxHintId nHint );
+
+ // Spaklines
+ sc::SparklineCell* GetSparklineCell(SCROW nRow);
+ void CreateSparklineCell(SCROW nRow, std::shared_ptr<sc::Sparkline> const& pSparkline);
+ void DeleteSparklineCells(sc::ColumnBlockPosition& rBlockPos, SCROW nRow1, SCROW nRow2);
+ bool DeleteSparkline(SCROW nRow);
+ bool IsSparklinesEmptyBlock(SCROW nStartRow, SCROW nEndRow) const;
+ void CopyCellSparklinesToDocument(SCROW nRow1, SCROW nRow2, ScColumn& rDestCol, SCROW nRowOffsetDest = 0) const;
+ void DuplicateSparklines(SCROW nStartRow, size_t nDataSize, ScColumn& rDestCol,
+ sc::ColumnBlockPosition& rDestBlockPos, SCROW nRowOffsetDest = 0) const;
+ bool HasSparklines() const;
+ SCROW GetSparklinesMaxRow() const;
+ SCROW GetSparklinesMinRow() const;
+
+ // cell notes
+ ScPostIt* GetCellNote( SCROW nRow );
+ const ScPostIt* GetCellNote( SCROW nRow ) const;
+ ScPostIt* GetCellNote( sc::ColumnBlockConstPosition& rBlockPos, SCROW nRow );
+ const ScPostIt* GetCellNote( sc::ColumnBlockConstPosition& rBlockPos, SCROW nRow ) const;
+ void DeleteCellNotes( sc::ColumnBlockPosition& rBlockPos, SCROW nRow1, SCROW nRow2, bool bForgetCaptionOwnership );
+ bool HasCellNote(SCROW nStartRow, SCROW nEndRow) const;
+ bool HasCellNotes() const;
+ void SetCellNote( SCROW nRow, std::unique_ptr<ScPostIt> pNote);
+ bool IsNotesEmptyBlock(SCROW nStartRow, SCROW nEndRow) const;
+
+ std::unique_ptr<ScPostIt> ReleaseNote( SCROW nRow );
+ size_t GetNoteCount() const;
+ void CreateAllNoteCaptions();
+ void ForgetNoteCaptions( SCROW nRow1, SCROW nRow2, bool bPreserveData );
+ SCROW GetNotePosition( size_t nIndex ) const;
+ void GetAllNoteEntries( std::vector<sc::NoteEntry>& rNotes ) const;
+ void GetNotesInRange( SCROW nStartRow, SCROW nEndRow, std::vector<sc::NoteEntry>& rNotes ) const;
+
+ SCROW GetCellNotesMaxRow() const;
+ SCROW GetCellNotesMinRow() const;
+
+ void CopyCellNotesToDocument(
+ SCROW nRow1, SCROW nRow2, ScColumn& rDestCol, bool bCloneCaption = true,
+ SCROW nRowOffsetDest = 0) const;
+
+ void DuplicateNotes(SCROW nStartRow, size_t nDataSize, ScColumn& rDestCol,
+ sc::ColumnBlockPosition& rDestBlockPos, bool bCloneCaption, SCROW nRowOffsetDest = 0) const;
+
+ void UpdateNoteCaptions( SCROW nRow1, SCROW nRow2, bool bAddressChanged = true );
+ void CommentNotifyAddressChange( SCROW nRow1, SCROW nRow2 );
+
+ void UpdateDrawObjects( std::vector<std::vector<SdrObject*>>& pObjects, SCROW nRowStart, SCROW nRowEnd );
+ void UpdateDrawObjectsForRow( std::vector<SdrObject*>& pObjects, SCCOL nTargetCol, SCROW nTargetRow );
+ bool IsDrawObjectsEmptyBlock(SCROW nStartRow, SCROW nEndRow) const;
+
+ void InterpretDirtyCells( SCROW nRow1, SCROW nRow2 );
+ bool InterpretCellsIfNeeded( SCROW nRow1, SCROW nRow2 );
+
+ static void JoinNewFormulaCell( const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell );
+
+ /**
+ * Detach a formula cell that's about to be deleted, or removed from
+ * document storage (if that ever happens).
+ *
+ * @param rNewSharedRows collects possible new shared row ranges (top and
+ * bottom of shared or remaining single twice) resulting from
+ * unsharing to reestablish listeners on.
+ */
+ void DetachFormulaCell( const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell,
+ std::vector<SCROW>& rNewSharedRows );
+
+ /** Re-establish listeners on unshared formula groups */
+ void StartListeningUnshared( const std::vector<SCROW>& rNewSharedRows );
+
+ void DetachFormulaCells( const sc::CellStoreType::position_type& aPos, size_t nLength,
+ std::vector<SCROW>* pNewSharedRows );
+
+ void AttachFormulaCells( sc::StartListeningContext& rCxt, SCROW nRow1, SCROW nRow2 );
+ void DetachFormulaCells( sc::EndListeningContext& rCxt, SCROW nRow1, SCROW nRow2 );
+
+ /**
+ * Regroup formula cells for the entire column.
+ */
+ void RegroupFormulaCells( std::vector<ScAddress>* pGroupPos = nullptr );
+
+ /**
+ * Reset column position of formula cells within specified row range.
+ * If bUpdateRefs==true then reference positions are also adjusted to
+ * reflect the new position so that the formula cells still reference the
+ * same cells or ranges after the position change.
+ * The position of a formula cell before the call is interpreted as the old
+ * position of that cell.
+ *
+ * Caller needs to ensure that no formula groups cross the top and bottom
+ * row boundaries.
+ *
+ * @param nRow1 top row boundary
+ * @param nRow2 bottom row boundary
+ * @param bUpdateRefs whether to adjust references
+ */
+ void ResetFormulaCellPositions( SCROW nRow1, SCROW nRow2, bool bUpdateRefs );
+
+ void SplitFormulaGroupByRelativeRef( const ScRange& rBoundRange );
+
+ void TransferCellValuesTo( SCROW nRow, size_t nLen, sc::CellValues& rDest );
+ void CopyCellValuesFrom( SCROW nRow, const sc::CellValues& rSrc );
+ void ConvertFormulaToValue(
+ sc::EndListeningContext& rCxt, SCROW nRow1, SCROW nRow2, sc::TableValues* pUndo );
+
+ void SwapNonEmpty(
+ sc::TableValues& rValues, sc::StartListeningContext& rStartCxt, sc::EndListeningContext& rEndCxt );
+
+ std::optional<sc::ColumnIterator> GetColumnIterator( SCROW nRow1, SCROW nRow2 ) const;
+
+ bool EnsureFormulaCellResults( SCROW nRow1, SCROW nRow2, bool bSkipRunning = false );
+
+ void StoreToCache(SvStream& rStrm) const;
+ void RestoreFromCache(SvStream& rStrm);
+
+#if DUMP_COLUMN_STORAGE
+ void DumpColumnStorage() const;
+#endif
+
+ SCSIZE GetPatternCount() const;
+ SCSIZE GetPatternCount( SCROW nRow1, SCROW nRow2 ) const;
+ bool ReservePatternCount( SCSIZE nReserve );
+
+ void CheckIntegrity() const;
+
+private:
+
+ sc::CellStoreType::iterator GetPositionToInsert( SCROW nRow, std::vector<SCROW>& rNewSharedRows,
+ bool bInsertFormula );
+ sc::CellStoreType::iterator GetPositionToInsert( const sc::CellStoreType::iterator& it, SCROW nRow,
+ std::vector<SCROW>& rNewSharedRows, bool bInsertFormula );
+
+ void AttachNewFormulaCell(
+ const sc::CellStoreType::iterator& itPos, SCROW nRow, ScFormulaCell& rCell,
+ const std::vector<SCROW>& rNewSharedRows,
+ bool bJoin = true, sc::StartListeningType eListenType = sc::SingleCellListening );
+
+ void AttachNewFormulaCell(
+ const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell,
+ const std::vector<SCROW>& rNewSharedRows,
+ bool bJoin = true, sc::StartListeningType eListenType = sc::SingleCellListening );
+
+public:
+ void AttachNewFormulaCells(const sc::CellStoreType::position_type& aPos, size_t nLength,
+ std::vector<SCROW>& rNewSharedRows);
+
+private:
+ void BroadcastNewCell( SCROW nRow );
+ bool UpdateScriptType( sc::CellTextAttr& rAttr, SCROW nRow, sc::CellStoreType::iterator& itr );
+
+ const ScFormulaCell* FetchFormulaCell( SCROW nRow ) const;
+
+ SCROW FindNextVisibleRowWithContent(
+ sc::CellStoreType::const_iterator& itPos, SCROW nRow, bool bForward) const;
+ SCROW FindNextVisibleRow(SCROW nRow, bool bForward) const;
+
+ OUString GetString( const ScRefCellValue& cell, SCROW nRow, const ScInterpreterContext* pContext = nullptr ) const;
+ OUString GetInputString( const ScRefCellValue& cell, SCROW nRow, bool bForceSystemLocale = false ) const;
+
+ /**
+ * Called whenever the state of cell array gets modified i.e. new cell
+ * insertion, cell removal or relocation, cell value update and so on.
+ *
+ * Call this only from those methods where maCells is modified directly.
+ */
+ void CellStorageModified();
+ void CellNotesDeleting(SCROW nRow1, SCROW nRow2, bool bForgetCaptionOwnership );
+
+ void CopyCellTextAttrsToDocument(SCROW nRow1, SCROW nRow2, ScColumn& rDestCol) const;
+
+ struct DeleteCellsResult
+ {
+ /** cell ranges that have been deleted. */
+ sc::SingleColumnSpanSet aDeletedRows;
+ /** formula cell range that has stopped listening. */
+ std::vector<std::pair<SCROW, SCROW>> aFormulaRanges;
+
+ DeleteCellsResult( const ScDocument& rDoc );
+ DeleteCellsResult( const DeleteCellsResult& ) = delete;
+ };
+
+ std::unique_ptr<DeleteCellsResult> DeleteCells(
+ sc::ColumnBlockPosition& rBlockPos, SCROW nRow1, SCROW nRow2, InsertDeleteFlags nDelFlag );
+
+ /**
+ * Get all non-grouped formula cells and formula cell groups in the whole
+ * column.
+ */
+ std::vector<sc::FormulaGroupEntry> GetFormulaGroupEntries();
+
+ void EndListeningIntersectedGroup(
+ sc::EndListeningContext& rCxt, SCROW nRow, std::vector<ScAddress>* pGroupPos );
+
+ void EndListeningIntersectedGroups(
+ sc::EndListeningContext& rCxt, SCROW nRow1, SCROW nRow2, std::vector<ScAddress>* pGroupPos );
+
+ void EndListeningGroup( sc::EndListeningContext& rCxt, SCROW nRow );
+ void SetNeedsListeningGroup( SCROW nRow );
+
+ void CollectBroadcasterState(sc::BroadcasterState& rState) const;
+};
+
+inline bool ScColumn::IsEmptyAttr() const
+{
+ return pAttrArray->IsEmpty();
+}
+
+inline bool ScColumnData::IsAllAttrEqual( const ScColumnData& rCol, SCROW nStartRow, SCROW nEndRow ) const
+{
+ return pAttrArray->IsAllEqual( *rCol.pAttrArray, nStartRow, nEndRow );
+}
+
+inline bool ScColumn::IsVisibleAttrEqual( const ScColumn& rCol, SCROW nStartRow, SCROW nEndRow ) const
+{
+ return pAttrArray->IsVisibleEqual( *rCol.pAttrArray, nStartRow, nEndRow );
+}
+
+inline bool ScColumn::GetFirstVisibleAttr( SCROW& rFirstRow ) const
+{
+ return pAttrArray->GetFirstVisibleAttr( rFirstRow );
+}
+
+inline bool ScColumn::GetLastVisibleAttr( SCROW& rLastRow, bool bSkipEmpty ) const
+{
+ // row of last cell is needed
+ SCROW nLastData = GetLastDataPos(); // always including notes, 0 if none
+ return pAttrArray->GetLastVisibleAttr( rLastRow, nLastData, bSkipEmpty );
+}
+
+inline bool ScColumn::HasVisibleAttrIn( SCROW nStartRow, SCROW nEndRow ) const
+{
+ return pAttrArray->HasVisibleAttrIn( nStartRow, nEndRow );
+}
+
+inline SCSIZE ScColumn::GetPatternCount() const
+{
+ return pAttrArray->Count();
+}
+
+inline SCSIZE ScColumn::GetPatternCount( SCROW nRow1, SCROW nRow2 ) const
+{
+ return pAttrArray->Count( nRow1, nRow2 );
+}
+
+inline bool ScColumn::ReservePatternCount( SCSIZE nReserve )
+{
+ return pAttrArray && pAttrArray->Reserve( nReserve );
+}
+
+inline bool ScColumn::IsMerged( SCROW nRow ) const
+{
+ return pAttrArray->IsMerged(nRow);
+}
+
+inline SCROW ScColumnData::GetNextUnprotected( SCROW nRow, bool bUp ) const
+{
+ return pAttrArray->GetNextUnprotected(nRow, bUp);
+}
+
+inline bool ScColumnData::HasAttrib( SCROW nRow1, SCROW nRow2, HasAttrFlags nMask ) const
+{
+ return pAttrArray->HasAttrib( nRow1, nRow2, nMask );
+}
+
+inline bool ScColumnData::HasAttrib( SCROW nRow, HasAttrFlags nMask, SCROW* nStartRow, SCROW* nEndRow ) const
+{
+ return pAttrArray->HasAttrib( nRow, nMask, nStartRow, nEndRow );
+}
+
+inline bool ScColumn::ExtendMerge( SCCOL nThisCol, SCROW nStartRow, SCROW nEndRow,
+ SCCOL& rPaintCol, SCROW& rPaintRow,
+ bool bRefresh )
+{
+ return pAttrArray->ExtendMerge( nThisCol, nStartRow, nEndRow, rPaintCol, rPaintRow, bRefresh );
+}
+
+inline void ScColumnData::MergePatternArea( ScMergePatternState& rState, SCROW nRow1, SCROW nRow2, bool bDeep ) const
+{
+ pAttrArray->MergePatternArea( nRow1, nRow2, rState, bDeep );
+}
+
+inline void ScColumn::MergeBlockFrame( SvxBoxItem* pLineOuter, SvxBoxInfoItem* pLineInner,
+ ScLineFlags& rFlags,
+ SCROW nStartRow, SCROW nEndRow, bool bLeft, SCCOL nDistRight ) const
+{
+ pAttrArray->MergeBlockFrame( pLineOuter, pLineInner, rFlags, nStartRow, nEndRow, bLeft, nDistRight );
+}
+
+inline void ScColumn::ApplyBlockFrame(const SvxBoxItem& rLineOuter, const SvxBoxInfoItem* pLineInner,
+ SCROW nStartRow, SCROW nEndRow, bool bLeft, SCCOL nDistRight)
+{
+ pAttrArray->ApplyBlockFrame(rLineOuter, pLineInner, nStartRow, nEndRow, bLeft, nDistRight);
+}
+
+inline const ScPatternAttr* ScColumnData::GetPattern( SCROW nRow ) const
+{
+ return pAttrArray->GetPattern( nRow );
+}
+
+inline const SfxPoolItem& ScColumnData::GetAttr( SCROW nRow, sal_uInt16 nWhich ) const
+{
+ return pAttrArray->GetPattern( nRow )->GetItemSet().Get(nWhich);
+}
+
+inline const SfxPoolItem& ScColumnData::GetAttr( SCROW nRow, sal_uInt16 nWhich, SCROW& nStartRow, SCROW& nEndRow ) const
+{
+ return pAttrArray->GetPatternRange( nStartRow, nEndRow, nRow )->GetItemSet().Get(nWhich);
+}
+
+inline sal_uInt32 ScColumnData::GetNumberFormat( const ScInterpreterContext& rContext, SCROW nRow ) const
+{
+ return pAttrArray->GetPattern( nRow )->GetNumberFormat( rContext.GetFormatTable() );
+}
+
+inline void ScColumn::AddCondFormat( SCROW nStartRow, SCROW nEndRow, sal_uInt32 nIndex )
+{
+ pAttrArray->AddCondFormat( nStartRow, nEndRow, nIndex );
+}
+
+inline void ScColumn::RemoveCondFormat( SCROW nStartRow, SCROW nEndRow, sal_uInt32 nIndex )
+{
+ pAttrArray->RemoveCondFormat( nStartRow, nEndRow, nIndex );
+}
+
+inline void ScColumnData::ApplyStyleArea( SCROW nStartRow, SCROW nEndRow, const ScStyleSheet& rStyle )
+{
+ pAttrArray->ApplyStyleArea(nStartRow, nEndRow, rStyle);
+}
+
+inline const ScStyleSheet* ScColumnData::GetStyle( SCROW nRow ) const
+{
+ return pAttrArray->GetPattern( nRow )->GetStyleSheet();
+}
+
+inline void ScColumn::FindStyleSheet( const SfxStyleSheetBase* pStyleSheet, ScFlatBoolRowSegments& rUsedRows, bool bReset )
+{
+ pAttrArray->FindStyleSheet( pStyleSheet, rUsedRows, bReset );
+}
+
+inline bool ScColumn::IsStyleSheetUsed( const ScStyleSheet& rStyle ) const
+{
+ return pAttrArray->IsStyleSheetUsed( rStyle );
+}
+
+inline bool ScColumn::ApplyFlags( SCROW nStartRow, SCROW nEndRow, ScMF nFlags )
+{
+ return pAttrArray->ApplyFlags( nStartRow, nEndRow, nFlags );
+}
+
+inline bool ScColumn::RemoveFlags( SCROW nStartRow, SCROW nEndRow, ScMF nFlags )
+{
+ return pAttrArray->RemoveFlags( nStartRow, nEndRow, nFlags );
+}
+
+inline void ScColumn::ClearItems( SCROW nStartRow, SCROW nEndRow, const sal_uInt16* pWhich )
+{
+ pAttrArray->ClearItems( nStartRow, nEndRow, pWhich );
+}
+
+inline const ScPatternAttr* ScColumn::SetPattern( SCROW nRow, std::unique_ptr<ScPatternAttr> pPatAttr )
+{
+ return pAttrArray->SetPattern( nRow, std::move(pPatAttr), true/*bPutToPool*/ );
+}
+
+inline void ScColumn::SetPattern( SCROW nRow, const ScPatternAttr& rPatAttr )
+{
+ pAttrArray->SetPattern( nRow, &rPatAttr, true/*bPutToPool*/ );
+}
+
+inline void ScColumn::SetPatternArea( SCROW nStartRow, SCROW nEndRow,
+ const ScPatternAttr& rPatAttr )
+{
+ pAttrArray->SetPatternArea( nStartRow, nEndRow, &rPatAttr, true/*bPutToPool*/ );
+}
+
+inline void ScColumnData::SetAttrEntries(std::vector<ScAttrEntry> && vNewData)
+{
+ pAttrArray->SetAttrEntries( std::move( vNewData ));
+}
+
+inline bool ScColumnData::TestInsertRow( SCSIZE nSize ) const
+{
+ return pAttrArray->TestInsertRow( nSize );
+}
+
+inline void ScColumnData::InsertRow( SCROW nStartRow, SCSIZE nSize )
+{
+ pAttrArray->InsertRow( nStartRow, nSize );
+}
+
+inline void ScColumnData::DeleteRow(SCROW nStartRow, SCSIZE nSize)
+{
+ pAttrArray->DeleteRow( nStartRow, nSize );
+}
+
+template <typename ApplyDataFunc>
+void ScColumnData::Apply(const ScMarkData& rMark, SCCOL nCol, ApplyDataFunc apply)
+{
+ if (rMark.IsMultiMarked())
+ {
+ ScMultiSelIter aMultiIter(rMark.GetMultiSelData(), nCol);
+ SCROW nTop, nBottom;
+ while (aMultiIter.Next(nTop, nBottom))
+ apply(*this, nTop, nBottom);
+ }
+ else if (rMark.IsMarked())
+ {
+ const ScRange& aRange = rMark.GetMarkArea();
+ if (aRange.aStart.Col() <= nCol && nCol <= aRange.aEnd.Col())
+ apply(*this, aRange.aStart.Row(), aRange.aEnd.Row());
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */