[Libreoffice-commits] core.git: Branch 'feature/formula-core-rework' - editeng/source include/editeng sc/inc sc/Library_sc.mk sc/qa sc/source
Kohei Yoshida
kohei.yoshida at gmail.com
Tue Jun 18 11:49:10 PDT 2013
editeng/source/editeng/editobj.cxx | 5
include/editeng/editobj.hxx | 1
sc/Library_sc.mk | 2
sc/inc/cellclonehandler.hxx | 61
sc/inc/cellvalue.hxx | 27
sc/inc/column.hxx | 156 -
sc/inc/columnspanset.hxx | 54
sc/inc/dociter.hxx | 175 -
sc/inc/document.hxx | 12
sc/inc/documentimport.hxx | 4
sc/inc/editutil.hxx | 2
sc/inc/formulacell.hxx | 2
sc/inc/markdata.hxx | 2
sc/inc/mtvcellfunc.hxx | 154 +
sc/inc/mtvelements.hxx | 27
sc/inc/mtvfunctions.hxx | 786 +++++++
sc/inc/scopetools.hxx | 33
sc/inc/table.hxx | 44
sc/inc/types.hxx | 16
sc/qa/unit/ucalc.cxx | 68
sc/source/core/data/cell2.cxx | 43
sc/source/core/data/cellclonehandler.cxx | 89
sc/source/core/data/cellvalue.cxx | 151 +
sc/source/core/data/column.cxx | 2871 +++++++++++++++-----------
sc/source/core/data/column2.cxx | 2461 ++++++++++++----------
sc/source/core/data/column3.cxx | 3108 +++++++++++++++++------------
sc/source/core/data/columnspanset.cxx | 117 +
sc/source/core/data/dociter.cxx | 1289 +++++-------
sc/source/core/data/documen2.cxx | 13
sc/source/core/data/documen4.cxx | 33
sc/source/core/data/documen8.cxx | 9
sc/source/core/data/document.cxx | 22
sc/source/core/data/documentimport.cxx | 47
sc/source/core/data/fillinfo.cxx | 92
sc/source/core/data/formulacell.cxx | 266 +-
sc/source/core/data/markdata.cxx | 7
sc/source/core/data/mtvelements.cxx | 16
sc/source/core/data/table1.cxx | 100
sc/source/core/data/table2.cxx | 382 ++-
sc/source/core/data/table3.cxx | 297 +-
sc/source/core/data/table4.cxx | 182 -
sc/source/core/data/table5.cxx | 18
sc/source/core/data/table6.cxx | 305 +-
sc/source/core/inc/interpre.hxx | 1
sc/source/core/tool/chgtrack.cxx | 19
sc/source/core/tool/editutil.cxx | 26
sc/source/core/tool/scmatrix.cxx | 178 -
sc/source/core/tool/scopetools.cxx | 28
sc/source/filter/xml/XMLExportIterator.cxx | 2
sc/source/ui/docshell/dbdocimp.cxx | 3
sc/source/ui/docshell/docsh8.cxx | 3
sc/source/ui/docshell/impex.cxx | 2
sc/source/ui/undo/undodat.cxx | 1
53 files changed, 8098 insertions(+), 5714 deletions(-)
New commits:
commit 813dddf5b403b6b5ee1369b589f3e9ee80bb4a1a
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date: Fri May 24 11:52:18 2013 -0400
Switch to using multi_type_vector for cell storage.
The old style cell storage is no more. Currently the code is buildable,
but crashes during unit test.
Change-Id: Ie688e22e95c7fb02b9e97b23df0fc1883a97945f
diff --git a/editeng/source/editeng/editobj.cxx b/editeng/source/editeng/editobj.cxx
index 2dd86b9..efb5eb1 100644
--- a/editeng/source/editeng/editobj.cxx
+++ b/editeng/source/editeng/editobj.cxx
@@ -303,6 +303,11 @@ editeng::FieldUpdater EditTextObject::GetFieldUpdater()
return mpImpl->GetFieldUpdater();
}
+const SfxItemPool* EditTextObject::GetPool() const
+{
+ return mpImpl->GetPool();
+}
+
sal_uInt16 EditTextObject::GetUserType() const
{
return mpImpl->GetUserType();
diff --git a/include/editeng/editobj.hxx b/include/editeng/editobj.hxx
index 6713e50..83f6475 100644
--- a/include/editeng/editobj.hxx
+++ b/include/editeng/editobj.hxx
@@ -71,6 +71,7 @@ public:
EditTextObject( const EditTextObject& r );
virtual ~EditTextObject();
+ const SfxItemPool* GetPool() const;
sal_uInt16 GetUserType() const; // For OutlinerMode, it can however not save in compatible format
void SetUserType( sal_uInt16 n );
diff --git a/sc/Library_sc.mk b/sc/Library_sc.mk
index 373ba8a..d7de9aa 100644
--- a/sc/Library_sc.mk
+++ b/sc/Library_sc.mk
@@ -89,6 +89,7 @@ $(eval $(call gb_Library_add_exception_objects,sc,\
sc/source/core/data/bigrange \
sc/source/core/data/cell \
sc/source/core/data/cell2 \
+ sc/source/core/data/cellclonehandler \
sc/source/core/data/cellvalue \
sc/source/core/data/clipcontext \
sc/source/core/data/clipparam \
@@ -235,6 +236,7 @@ $(eval $(call gb_Library_add_exception_objects,sc,\
sc/source/core/tool/reftokenhelper \
sc/source/core/tool/refupdat \
sc/source/core/tool/scmatrix \
+ sc/source/core/tool/scopetools \
sc/source/core/tool/simplerangelist \
sc/source/core/tool/stringutil \
sc/source/core/tool/subtotal \
diff --git a/sc/inc/cellclonehandler.hxx b/sc/inc/cellclonehandler.hxx
new file mode 100644
index 0000000..a08383c
--- /dev/null
+++ b/sc/inc/cellclonehandler.hxx
@@ -0,0 +1,61 @@
+/* -*- 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/.
+ */
+
+#ifndef SC_CELLCLONEHANDLER_HXX
+#define SC_CELLCLONEHANDLER_HXX
+
+#include "rtl/ustring.hxx"
+#include "address.hxx"
+#include "mtvelements.hxx"
+
+class ScDocument;
+class EditTextObject;
+class ScFormulaCell;
+
+namespace sc {
+
+class CellBlockCloneHandler
+{
+ ScDocument& mrSrcDoc;
+ ScDocument& mrDestDoc;
+ CellStoreType& mrDestCellStore;
+
+protected:
+ ScDocument& getSrcDoc();
+ ScDocument& getDestDoc();
+ const ScDocument& getDestDoc() const;
+ CellStoreType& getDestCellStore();
+
+public:
+ CellBlockCloneHandler(
+ ScDocument& rSrcDoc, ScDocument& rDestDoc, CellStoreType& rDestCellStore);
+ virtual ~CellBlockCloneHandler();
+
+ virtual void cloneDoubleBlock(
+ CellStoreType::iterator& itPos, const ScAddress& rSrcPos, const ScAddress& rDestPos,
+ const numeric_block::const_iterator& itBegin, const numeric_block::const_iterator& itEnd);
+
+ virtual void cloneStringBlock(
+ CellStoreType::iterator& itPos, const ScAddress& rSrcPos, const ScAddress& rDestPos,
+ const string_block::const_iterator& itBegin, const string_block::const_iterator& itEnd);
+
+ virtual void cloneEditTextBlock(
+ CellStoreType::iterator& itPos, const ScAddress& rSrcPos, const ScAddress& rDestPos,
+ const edittext_block::const_iterator& itBegin, const edittext_block::const_iterator& itEnd);
+
+ virtual void cloneFormulaBlock(
+ CellStoreType::iterator& itPos, const ScAddress& rSrcPos, const ScAddress& rDestPos,
+ const formula_block::const_iterator& itBegin, const formula_block::const_iterator& itEnd);
+};
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/inc/cellvalue.hxx b/sc/inc/cellvalue.hxx
index fb7c175..b1be68d 100644
--- a/sc/inc/cellvalue.hxx
+++ b/sc/inc/cellvalue.hxx
@@ -7,15 +7,16 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
-#ifndef __SC_CELLVALUE_HXX__
-#define __SC_CELLVALUE_HXX__
+#ifndef SC_CELLVALUE_HXX
+#define SC_CELLVALUE_HXX
#include "global.hxx"
+#include "mtvelements.hxx"
class ScDocument;
class ScFormulaCell;
class EditTextObject;
-class ScBaseCell;
+class ScColumn;
/**
* Store arbitrary cell value of any kind. It only stores cell value and
@@ -42,6 +43,12 @@ struct SC_DLLPUBLIC ScCellValue
void clear();
+ void set( double fValue );
+ void set( const OUString& rStr );
+ void set( const EditTextObject& rEditText );
+ void set( const ScFormulaCell& rFormula );
+ void set( ScFormulaCell* pFormula );
+
/**
* Take cell value from specified position in specified document.
*/
@@ -50,11 +57,6 @@ struct SC_DLLPUBLIC ScCellValue
void assign( const ScCellValue& rOther, ScDocument& rDestDoc, int nCloneFlags = SC_CLONECELL_DEFAULT );
/**
- * TODO: Remove this later.
- */
- void assign( const ScBaseCell& rCell );
-
- /**
* Set cell value at specified position in specified document.
*/
void commit( ScDocument& rDoc, const ScAddress& rPos ) const;
@@ -66,6 +68,8 @@ struct SC_DLLPUBLIC ScCellValue
*/
void release( ScDocument& rDoc, const ScAddress& rPos );
+ void release( ScColumn& rColumn, SCROW nRow );
+
bool hasString() const;
bool hasNumeric() const;
@@ -110,16 +114,15 @@ struct SC_DLLPUBLIC ScRefCellValue
*/
void assign( ScDocument& rDoc, const ScAddress& rPos );
- /**
- * TODO: Remove this later.
- */
- void assign( ScBaseCell& rCell );
+ void assign( const sc::CellStoreType::const_iterator& itPos, size_t nOffset );
/**
* Set cell value at specified position in specified document.
*/
void commit( ScDocument& rDoc, const ScAddress& rPos ) const;
+ void commit( ScColumn& rColumn, SCROW nRow ) const;
+
bool hasString() const;
bool hasNumeric() const;
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index e2c6b45..c0b9c35 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -32,6 +32,7 @@
#include <vector>
#include <boost/intrusive_ptr.hpp>
+#include <mdds/flat_segment_tree.hpp>
namespace editeng { class SvxBorderLine; }
@@ -44,6 +45,8 @@ namespace sc {
class CopyToDocContext;
class MixDocContext;
struct ColumnBlockPosition;
+ class CellBlockCloneHandler;
+ class SingleColumnSpanSet;
}
class Fraction;
@@ -58,7 +61,6 @@ class SvxBoxItem;
class ScAttrIterator;
class ScAttrArray;
struct ScAttrEntry;
-class ScBaseCell;
class ScDocument;
class ScEditDataArray;
class ScFormulaCell;
@@ -77,6 +79,7 @@ struct ScColWidthParam;
class ScColumnTextWidthIterator;
struct ScFormulaCellGroup;
struct ScRefCellValue;
+struct ScCellValue;
class ScDocumentImport;
struct ScNeededSizeOptions
@@ -90,28 +93,6 @@ struct ScNeededSizeOptions
ScNeededSizeOptions();
};
-struct ColEntry
-{
- SCROW nRow;
- ScBaseCell* pCell;
-
- struct Less : std::binary_function<ColEntry, ColEntry, bool>
- {
- bool operator() (const ColEntry& r1, const ColEntry& r2) const;
- };
-};
-
-struct ColDoubleEntry
-{
- SCROW mnStart;
- std::vector<double> maData;
-
- struct LessByPtr : std::binary_function<ColDoubleEntry*, ColDoubleEntry*, bool>
- {
- bool operator() (const ColDoubleEntry* p1, const ColDoubleEntry* p2) const;
- };
-};
-
class ScColumn
{
// Empty values correspond with empty cells. All non-empty cell positions
@@ -130,10 +111,6 @@ class ScColumn
SCCOL nCol;
SCTAB nTab;
- std::vector<ColEntry> maItems;
-
- // temporary until we switch to mdds container
- std::vector<ColDoubleEntry *> maDoubles;
std::vector<ScFormulaCellGroupRef> maFnGroups;
ScAttrArray* pAttrArray;
@@ -141,43 +118,39 @@ class ScColumn
bool mbDirtyGroups; /// formula groups are dirty.
friend class ScDocument; // for FillInfo
+friend class ScTable;
friend class ScDocumentIterator;
friend class ScValueIterator;
friend class ScHorizontalValueIterator;
friend class ScDBQueryDataIterator;
-friend class ScColumnIterator;
friend class ScQueryCellIterator;
-friend class ScMarkedDataIter;
friend class ScCellIterator;
friend class ScHorizontalCellIterator;
friend class ScHorizontalAttrIterator;
friend class ScColumnTextWidthIterator;
friend class ScDocumentImport;
+friend class sc::SingleColumnSpanSet;
ScColumn(const ScColumn&); // disabled
ScColumn& operator= (const ScColumn&); // disabled
- std::vector<ColEntry>::iterator Search( SCROW nRow );
- std::vector<ColEntry>::const_iterator Search( SCROW nRow ) const;
-
public:
ScColumn();
~ScColumn();
void Init(SCCOL nNewCol, SCTAB nNewTab, ScDocument* pDoc);
- bool Search( SCROW nRow, SCSIZE& nIndex ) const;
- ScBaseCell* GetCell( SCROW nRow ) const;
+ ScDocument& GetDoc();
+ const ScDocument& GetDoc() const;
+ SCTAB GetTab() const { return nTab; }
+ SCCOL GetCol() const { return nCol; }
+
ScRefCellValue GetCellValue( SCROW nRow ) const;
- void Insert( sc::ColumnBlockPosition& rBlockPos, SCROW nRow, ScBaseCell* pCell );
- void Insert( SCROW nRow, ScBaseCell* pCell );
- void Insert( SCROW nRow, sal_uInt32 nFormatIndex, ScBaseCell* pCell );
- void Append( sc::ColumnBlockPosition& rBlockPos, SCROW nRow, ScBaseCell* pCell );
- void Append( SCROW nRow, ScBaseCell* pCell );
+ ScRefCellValue GetCellValue( sc::CellStoreType::const_iterator& itPos, SCROW nRow ) const;
+ ScRefCellValue GetCellValue( sc::CellStoreType::const_iterator& itPos, size_t nOffset ) const;
+
void Delete( SCROW nRow );
- void DeleteAtIndex( SCSIZE nIndex );
void FreeAll();
- void ReserveSize( SCSIZE nSize );
void SwapRow( SCROW nRow1, SCROW nRow2 );
void SwapCell( SCROW nRow, ScColumn& rCol);
void RebuildFormulaGroups();
@@ -188,7 +161,6 @@ public:
SCCOL& rPaintCol, SCROW& rPaintRow,
bool bRefresh );
- bool IsEmptyVisData() const; // without Broadcaster
bool IsEmptyData() const;
bool IsEmptyAttr() const;
bool IsEmpty() const;
@@ -200,12 +172,10 @@ public:
bool HasVisibleDataAt(SCROW nRow) const;
SCROW GetFirstDataPos() const;
SCROW GetLastDataPos() const;
- SCROW GetLastVisDataPos() const; // without Broadcaster
- SCROW GetFirstVisDataPos() const;
bool GetPrevDataPos(SCROW& rRow) const;
bool GetNextDataPos(SCROW& rRow) const;
void FindDataAreaPos(SCROW& rRow, bool bDown) const; // (without Broadcaster)
- void FindUsed( SCROW nStartRow, SCROW nEndRow, bool* pUsed ) const;
+ void FindUsed( SCROW nStartRow, SCROW nEndRow, mdds::flat_segment_tree<SCROW, bool>& rUsed ) const;
SCSIZE VisibleCount( SCROW nStartRow, SCROW nEndRow ) const;
sal_uInt16 GetBlockMatrixEdges( SCROW nRow1, SCROW nRow2, sal_uInt16 nMask ) const;
@@ -219,7 +189,7 @@ public:
bool IsAllAttrEqual( const ScColumn& rCol, SCROW nStartRow, SCROW nEndRow ) const;
bool TestInsertCol( SCROW nStartRow, SCROW nEndRow) const;
- bool TestInsertRow( SCSIZE nSize ) const;
+ bool TestInsertRow( SCROW nStartRow, SCSIZE nSize ) const;
void InsertRow( SCROW nStartRow, SCSIZE nSize );
void DeleteRow( SCROW nStartRow, SCSIZE nSize );
void DeleteArea(SCROW nStartRow, SCROW nEndRow, sal_uInt16 nDelFlag );
@@ -228,11 +198,11 @@ public:
void CopyStaticToDocument(SCROW nRow1, SCROW nRow2, ScColumn& rDestCol);
void CopyCellToDocument( SCROW nSrcRow, SCROW nDestRow, ScColumn& rDestCol );
bool InitBlockPosition( sc::ColumnBlockPosition& rBlockPos );
+ bool InitBlockPosition( sc::ColumnBlockConstPosition& rBlockPos ) const;
void CopyFromClip(
sc::CopyFromClipContext& rCxt, SCROW nRow1, SCROW nRow2, long nDy, ScColumn& rColumn );
void StartListeningInArea( sc::StartListeningContext& rCxt, SCROW nRow1, SCROW nRow2 );
- void BroadcastInArea( SCROW nRow1, SCROW nRow2 );
void RemoveEditAttribs( SCROW nStartRow, SCROW nEndRow );
@@ -244,21 +214,15 @@ public:
sc::MixDocContext& rCxt, SCROW nRow1, SCROW nRow2, sal_uInt16 nFunction, bool bSkipEmpty,
const ScColumn& rSrcCol );
- ScFormulaCell* CreateRefCell( ScDocument* pDestDoc, const ScAddress& rDestPos,
- SCSIZE nIndex, sal_uInt16 nFlags ) const;
-
ScAttrIterator* CreateAttrIterator( SCROW nStartRow, SCROW nEndRow ) const;
-
- SCCOL GetCol() const { return nCol; }
-
// UpdateSelectionFunction: multi-select
void UpdateSelectionFunction(
const ScMarkData& rMark, ScFunctionData& rData, ScFlatBoolRowSegments& rHiddenRows,
- bool bDoExclude, SCROW nExStartRow, SCROW nExEndRow ) const;
+ bool bDoExclude, SCROW nExStartRow, SCROW nExEndRow );
void UpdateAreaFunction(
- ScFunctionData& rData, ScFlatBoolRowSegments& rHiddenRows, SCROW nStartRow, SCROW nEndRow) const;
+ ScFunctionData& rData, ScFlatBoolRowSegments& rHiddenRows, SCROW nStartRow, SCROW nEndRow);
void CopyToColumn(
sc::CopyToDocContext& rCxt, SCROW nRow1, SCROW nRow2, sal_uInt16 nFlags, bool bMarked,
@@ -286,12 +250,18 @@ public:
ScSetStringParam* pParam = NULL );
void SetEditText( SCROW nRow, EditTextObject* pEditText );
+ void SetEditText( sc::ColumnBlockPosition& rBlockPos, SCROW nRow, 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 );
void SetFormulaCell( SCROW nRow, ScFormulaCell* pCell );
+ void SetFormulaCell( sc::ColumnBlockPosition& rBlockPos, SCROW nRow, ScFormulaCell* pCell );
- void SetValue( SCROW nRow, const double& rVal);
+ void SetRawString( SCROW nRow, const OUString& rStr, bool bBroadcast = true );
+ void SetRawString( sc::ColumnBlockPosition& rBlockPos, SCROW nRow, const OUString& rStr, bool bBroadcast = true );
+ void SetValue( SCROW nRow, double fVal );
+ void SetValue( sc::ColumnBlockPosition& rBlockPos, SCROW nRow, double fVal, bool bBroadcast = true );
void SetError( SCROW nRow, const sal_uInt16 nError);
void GetString( SCROW nRow, OUString& rString ) const;
@@ -318,7 +288,7 @@ public:
bool IsFormulaDirty( SCROW nRow ) const;
void SetDirty();
- void SetDirty( const ScRange& );
+ void SetDirty( SCROW nRow1, SCROW nRow2 );
void SetDirtyVar();
void SetDirtyAfterLoad();
void SetTableOpDirty( const ScRange& );
@@ -428,7 +398,7 @@ public:
SCsROW GetNextUnprotected( SCROW nRow, bool bUp ) const;
void GetFilterEntries(SCROW nStartRow, SCROW nEndRow, std::vector<ScTypedStrData>& rStrings, bool& rHasDates);
- bool GetDataEntries(SCROW nRow, std::set<ScTypedStrData>& rStrings, bool bLimit);
+ bool GetDataEntries( SCROW nRow, std::set<ScTypedStrData>& rStrings, bool bLimit ) const;
void UpdateInsertTabAbs(SCTAB nNewPos);
bool TestTabRefAbs(SCTAB nTable) const;
@@ -458,6 +428,11 @@ public:
void SetTextWidth(SCROW nRow, sal_uInt16 nWidth);
sal_uInt8 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.
+ */
sal_uInt8 GetRangeScriptType( sc::CellTextAttrStoreType::iterator& itPos, SCROW nRow1, SCROW nRow2 );
void SetScriptType( SCROW nRow, sal_uInt8 nType );
@@ -469,8 +444,6 @@ public:
bool ResolveStaticReference( ScMatrix& rMat, SCCOL nMatCol, SCROW nRow1, SCROW nRow2 );
const double* FetchDoubleArray( sc::FormulaGroupContext& rCxt, SCROW nRow1, SCROW nRow2 ) const;
- ScRefCellValue GetRefCellValue( SCROW );
-
void SetNumberFormat( SCROW nRow, sal_uInt32 nNumberFormat );
SvtBroadcaster* GetBroadcaster( SCROW nRow );
@@ -478,17 +451,25 @@ public:
void DeleteBroadcasters( sc::ColumnBlockPosition& rBlockPos, SCROW nRow1, SCROW nRow2 );
bool HasBroadcaster() const;
+ void BroadcastCells( const std::vector<SCROW>& rRows );
+ void EndFormulaListening( sc::ColumnBlockPosition& rBlockPos, SCROW nRow1, SCROW nRow2 );
+
private:
- void UpdateScriptType( sc::CellTextAttr& rAttr, SCROW nRow );
- void DeleteRange(
- SCSIZE nStartIndex, SCSIZE nEndIndex, sal_uInt16 nDelFlag, std::vector<SCROW>& rDeletedRows );
+ void CopyCellsInRangeToColumn(
+ sc::ColumnBlockConstPosition* rSrcColPos, sc::ColumnBlockPosition* pDestColPos,
+ sc::CellBlockCloneHandler& Hdl, SCROW nRow1, SCROW nRow2, ScColumn& rColumn ) const;
- const ScFormulaCell* FetchFormulaCell( SCROW nRow ) const;
+ sc::CellStoreType::iterator GetPositionToInsert( SCROW nRow );
+ sc::CellStoreType::iterator GetPositionToInsert( const sc::CellStoreType::iterator& it, SCROW nRow );
+ void ActivateNewFormulaCell( ScFormulaCell* pCell );
+ void BroadcastNewCell( SCROW nRow );
+ void UpdateScriptType( sc::CellTextAttr& rAttr, SCROW nRow );
- ScBaseCell* CloneCell(SCSIZE nIndex, sal_uInt16 nFlags, ScDocument& rDestDoc, const ScAddress& rDestPos) const;
+ const ScFormulaCell* FetchFormulaCell( SCROW nRow ) const;
- SCROW FindNextVisibleRowWithContent(SCROW nRow, bool bForward) const;
+ SCROW FindNextVisibleRowWithContent(
+ sc::CellStoreType::const_iterator& itPos, SCROW nRow, bool bForward) const;
SCROW FindNextVisibleRow(SCROW nRow, bool bForward) const;
/**
@@ -501,52 +482,21 @@ private:
void CopyCellTextAttrsToDocument(SCROW nRow1, SCROW nRow2, ScColumn& rDestCol) const;
- void SetCell( sc::ColumnBlockPosition& rBlockPos, SCROW nRow, ScBaseCell* pNewCell );
- void SetCell( SCROW nRow, ScBaseCell* pNewCell );
- void PostSetCell( SCROW nRow, ScBaseCell* pNewCell );
-
/**
* Clear and re-populate the cell text attribute array from the non-empty
* cells stored in the cell array.
*/
void ResetCellTextAttrs();
-};
+ void SwapCellTextAttrs( SCROW nRow1, SCROW nRow2 );
-class ScColumnIterator // walk through all data of a area/range
-{
- const ScColumn* pColumn;
- SCSIZE nPos;
- SCROW nTop;
- SCROW nBottom;
-public:
- ScColumnIterator( const ScColumn* pCol, SCROW nStart=0, SCROW nEnd=MAXROW );
- ~ScColumnIterator();
-
- bool Next( SCROW& rRow, ScBaseCell*& rpCell );
- SCSIZE GetIndex() const;
-};
-
-
-class ScMarkedDataIter // walk through data in a selected area/range
-{
- const ScColumn* pColumn;
- SCSIZE nPos;
- ScMarkArrayIter* pMarkIter;
- SCROW nTop;
- SCROW nBottom;
- bool bNext;
- bool bAll;
-
-public:
- ScMarkedDataIter( const ScColumn* pCol, const ScMarkData* pMarkData,
- bool bAllIfNone = false );
- ~ScMarkedDataIter();
-
- bool Next( SCSIZE& rIndex );
+ /**
+ * Retrieve the cell value and set that slot empty. The ownership of that
+ * cell value moves to the returned cell value object.
+ */
+ void ReleaseCellValue( sc::CellStoreType::iterator& itPos, SCROW nRow, ScCellValue& rVal );
};
-
#endif
diff --git a/sc/inc/columnspanset.hxx b/sc/inc/columnspanset.hxx
index ab24828..55c3f57 100644
--- a/sc/inc/columnspanset.hxx
+++ b/sc/inc/columnspanset.hxx
@@ -16,8 +16,13 @@
#include <mdds/flat_segment_tree.hpp>
#include <boost/noncopyable.hpp>
+class ScColumn;
+class ScMarkData;
+
namespace sc {
+struct ColumnBlockConstPosition;
+
/**
* Structure that stores segments of boolean flags per column, and perform
* custom action on those segments.
@@ -49,6 +54,55 @@ public:
void executeFromTop(Action& ac) const;
};
+/**
+ * Keep track of spans in a single column only.
+ */
+class SingleColumnSpanSet
+{
+public:
+ typedef mdds::flat_segment_tree<SCROW, bool> ColumnSpansType;
+
+ struct Span
+ {
+ SCROW mnRow1;
+ SCROW mnRow2;
+
+ Span(SCROW nRow1, SCROW nRow2) : mnRow1(nRow1), mnRow2(nRow2) {}
+ };
+
+ typedef std::vector<Span> SpansType;
+
+ SingleColumnSpanSet();
+
+ /**
+ * Scan an entire column and tag all non-empty cell positions.
+ */
+ void scan(const ScColumn& rColumn);
+
+ /**
+ * Scan a column between specified range, and tag all non-empty cell
+ * positions.
+ */
+ void scan(const ScColumn& rColumn, SCROW nStart, SCROW nEnd);
+
+ void scan(
+ ColumnBlockConstPosition& rBlockPos, const ScColumn& rColumn, SCROW nStart, SCROW nEnd);
+
+ /**
+ * Scan all marked data and tag all marked segments in specified column.
+ */
+ void scan(const ScMarkData& rMark, SCTAB nTab, SCCOL nCol);
+
+ void set(SCROW nRow1, SCROW nRow2, bool bVal);
+
+ void getRows(std::vector<SCROW> &rRows) const;
+
+ void getSpans(SpansType& rSpans) const;
+
+private:
+ ColumnSpansType maSpans;
+};
+
}
#endif
diff --git a/sc/inc/dociter.hxx b/sc/inc/dociter.hxx
index cfffb7e..87d17b2 100644
--- a/sc/inc/dociter.hxx
+++ b/sc/inc/dociter.hxx
@@ -25,6 +25,7 @@
#include "global.hxx"
#include "scdllapi.h"
#include "cellvalue.hxx"
+#include "mtvelements.hxx"
#include <memory>
@@ -34,7 +35,6 @@
#include <boost/scoped_ptr.hpp>
class ScDocument;
-class ScBaseCell;
class ScPatternAttr;
class ScAttrArray;
class ScAttrIterator;
@@ -47,84 +47,52 @@ struct ScDBQueryParamInternal;
struct ScDBQueryParamMatrix;
class ScFormulaCell;
-class ScDocumentIterator // walk through all non-empty cells
-{
-private:
- ScDocument* pDoc;
- SCTAB nStartTab;
- SCTAB nEndTab;
-
- const ScPatternAttr* pDefPattern;
-
- SCCOL nCol;
- SCROW nRow;
- SCTAB nTab;
- ScBaseCell* pCell;
- const ScPatternAttr* pPattern;
-
-
- SCSIZE nColPos;
- SCSIZE nAttrPos;
-
- bool GetThis();
- bool GetThisCol();
-
-public:
- ScDocumentIterator( ScDocument* pDocument, SCTAB nStartTable, SCTAB nEndTable );
- ~ScDocumentIterator();
-
- bool GetFirst();
- bool GetNext();
-
- ScCellValue GetCellValue() const;
- const ScPatternAttr* GetPattern();
- void GetPos( SCCOL& rCol, SCROW& rRow, SCTAB& rTab );
-};
-
class ScValueIterator // walk through all values in an area
{
-private:
- double fNextValue;
+ typedef std::pair<sc::CellStoreType::const_iterator, size_t> PositionType;
+
ScDocument* pDoc;
const ScAttrArray* pAttrArray;
sal_uLong nNumFormat; // for CalcAsShown
sal_uLong nNumFmtIndex;
- SCCOL nStartCol;
- SCROW nStartRow;
- SCTAB nStartTab;
- SCCOL nEndCol;
- SCROW nEndRow;
- SCTAB nEndTab;
- SCCOL nCol;
- SCROW nRow;
- SCTAB nTab;
- SCSIZE nColRow;
- SCROW nNextRow;
+ ScAddress maStartPos;
+ ScAddress maEndPos;
+ SCCOL mnCol;
+ SCTAB mnTab;
SCROW nAttrEndRow;
short nNumFmtType;
- bool bNumValid;
- bool bSubTotal;
- bool bNextValid;
- bool bCalcAsShown;
- bool bTextAsZero;
+ bool bNumValid:1;
+ bool bSubTotal:1;
+ bool bCalcAsShown:1;
+ bool bTextAsZero:1;
+
+ const sc::CellStoreType* mpCells;
+ PositionType maCurPos;
+
+ SCROW GetRow() const;
+ void IncBlock();
+ void IncPos();
+ void SetPos(size_t nPos);
+
+ /**
+ * See if the cell at the current position is a non-empty cell. If not,
+ * move to the next non-empty cell position.
+ */
+ bool GetThis( double& rValue, sal_uInt16& rErr );
- bool GetThis(double& rValue, sal_uInt16& rErr);
public:
- ScValueIterator(ScDocument* pDocument,
- const ScRange& rRange, bool bSTotal = false,
- bool bTextAsZero = false );
- void GetCurNumFmtInfo( short& nType, sal_uLong& nIndex );
+ ScValueIterator(
+ ScDocument* pDocument, const ScRange& rRange, bool bSTotal = false,
+ bool bTextAsZero = false );
+
+ void GetCurNumFmtInfo( short& nType, sal_uLong& nIndex );
+
/// Does NOT reset rValue if no value found!
- bool GetFirst(double& rValue, sal_uInt16& rErr);
+ bool GetFirst( double& rValue, sal_uInt16& rErr );
+
/// Does NOT reset rValue if no value found!
- bool GetNext(double& rValue, sal_uInt16& rErr)
- {
- return bNextValid ? ( bNextValid = false, rValue = fNextValue,
- rErr = 0, nRow = nNextRow,
- ++nColRow, bNumValid = false, true )
- : ( ++nRow, GetThis(rValue, rErr) );
- }
+ bool GetNext( double& rValue, sal_uInt16& rErr );
};
class ScDBQueryDataIterator
@@ -141,11 +109,9 @@ public:
};
private:
- static SCROW GetRowByColEntryIndex(ScDocument& rDoc, SCTAB nTab, SCCOL nCol, SCSIZE nColRow);
- static ScBaseCell* GetCellByColEntryIndex(ScDocument& rDoc, SCTAB nTab, SCCOL nCol, SCSIZE nColRow);
+ static const sc::CellStoreType* GetColumnCellStore(ScDocument& rDoc, SCTAB nTab, SCCOL nCol);
static const ScAttrArray* GetAttrArrayByCol(ScDocument& rDoc, SCTAB nTab, SCCOL nCol);
- static bool IsQueryValid(ScDocument& rDoc, const ScQueryParam& rParam, SCTAB nTab, SCROW nRow, ScBaseCell* pCell);
- static SCSIZE SearchColEntryIndex(ScDocument& rDoc, SCTAB nTab, SCROW nRow, SCCOL nCol);
+ static bool IsQueryValid(ScDocument& rDoc, const ScQueryParam& rParam, SCTAB nTab, SCROW nRow, ScRefCellValue& rCell);
class DataAccess
{
@@ -161,6 +127,7 @@ private:
class DataAccessInternal : public DataAccess
{
+ typedef std::pair<sc::CellStoreType::const_iterator,size_t> PositionType;
public:
DataAccessInternal(const ScDBQueryDataIterator* pParent, ScDBQueryParamInternal* pParam, ScDocument* pDoc);
virtual ~DataAccessInternal();
@@ -169,6 +136,12 @@ private:
virtual bool getNext(Value& rValue);
private:
+ void incBlock();
+ void incPos();
+ void setPos(size_t nPos);
+
+ const sc::CellStoreType* mpCells;
+ PositionType maCurPos;
ScDBQueryParamInternal* mpParam;
ScDocument* mpDoc;
const ScAttrArray* pAttrArray;
@@ -176,7 +149,6 @@ private:
sal_uLong nNumFmtIndex;
SCCOL nCol;
SCROW nRow;
- SCSIZE nColRow;
SCROW nAttrEndRow;
SCTAB nTab;
short nNumFmtType;
@@ -212,18 +184,31 @@ public:
bool GetNext(Value& rValue);
};
-class ScCellIterator // walk through all cells in an area
-{ // for SubTotal no hidden and no sub-total lines
-private:
+/**
+ * Walk through all cells in an area. For SubTotal no hidden and no
+ * sub-total lines.
+ **/
+class ScCellIterator
+{
+ typedef std::pair<sc::CellStoreType::const_iterator, size_t> PositionType;
+
ScDocument* mpDoc;
ScAddress maStartPos;
ScAddress maEndPos;
ScAddress maCurPos;
+
+ PositionType maCurColPos;
SCSIZE mnIndex;
bool mbSubTotal;
ScRefCellValue maCurCell;
+ void incBlock();
+ void incPos();
+ void setPos(size_t nPos);
+
+ const ScColumn* getColumn() const;
+
void init();
bool getCurrent();
@@ -269,7 +254,9 @@ class ScQueryCellIterator // walk through all non-empty cells in an ar
nTestEqualConditionFulfilled = nTestEqualConditionEnabled | nTestEqualConditionMatched
};
-private:
+ typedef std::pair<sc::CellStoreType::const_iterator, size_t> PositionType;
+ PositionType maCurPos;
+
boost::scoped_ptr<ScQueryParam> mpParam;
ScDocument* pDoc;
const ScAttrArray* pAttrArray;
@@ -277,14 +264,17 @@ private:
SCTAB nTab;
SCCOL nCol;
SCROW nRow;
- SCSIZE nColRow;
SCROW nAttrEndRow;
sal_uInt8 nStopOnMismatch;
sal_uInt8 nTestEqualCondition;
bool bAdvanceQuery;
bool bIgnoreMismatchOnLeadingStrings;
- ScBaseCell* GetThis();
+ /** Initialize position for new column. */
+ void InitPos();
+ void IncPos();
+ void IncBlock();
+ bool GetThis();
/* Only works if no regular expression is involved, only
searches for rows in one column, and only the first
@@ -295,15 +285,15 @@ private:
GetThis() and GetNext() afterwards. Introduced for
FindEqualOrSortedLastInRange()
*/
- ScBaseCell* BinarySearch();
+ bool BinarySearch();
public:
ScQueryCellIterator(ScDocument* pDocument, SCTAB nTable,
const ScQueryParam& aParam, bool bMod = true);
// for bMod = FALSE the QueryParam has to be filled
// (bIsString)
- ScBaseCell* GetFirst();
- ScBaseCell* GetNext();
+ bool GetFirst();
+ bool GetNext();
SCCOL GetCol() { return nCol; }
SCROW GetRow() { return nRow; }
@@ -420,27 +410,36 @@ public:
class ScHorizontalCellIterator // walk through all non empty cells in an area
{ // row by row
-private:
+ typedef std::pair<sc::CellStoreType::const_iterator,size_t> PositionType;
+
+ struct ColParam
+ {
+ sc::CellStoreType::const_iterator maPos;
+ sc::CellStoreType::const_iterator maEnd;
+ };
+
+ std::vector<ColParam> maColPositions;
+
ScDocument* pDoc;
- SCTAB nTab;
+ SCTAB mnTab;
SCCOL nStartCol;
SCCOL nEndCol;
SCROW nStartRow;
SCROW nEndRow;
SCROW* pNextRows;
SCSIZE* pNextIndices;
- SCCOL nCol;
- SCROW nRow;
+ SCCOL mnCol;
+ SCROW mnRow;
ScRefCellValue maCurCell;
bool bMore;
public:
- ScHorizontalCellIterator(ScDocument* pDocument, SCTAB nTable,
- SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2);
- ~ScHorizontalCellIterator();
+ ScHorizontalCellIterator(ScDocument* pDocument, SCTAB nTable,
+ SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2);
+ ~ScHorizontalCellIterator();
ScRefCellValue* GetNext( SCCOL& rCol, SCROW& rRow );
- bool ReturnNext( SCCOL& rCol, SCROW& rRow );
+ bool GetPos( SCCOL& rCol, SCROW& rRow );
/// Set a(nother) sheet and (re)init.
void SetTab( SCTAB nTab );
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index 427ab2c..59cc997 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -83,7 +83,6 @@ class XColorList;
struct ScAttrEntry;
class ScAutoFormatData;
-class ScBaseCell;
class ScBroadcastAreaSlotMachine;
class ScChangeViewSettings;
class ScChartCollection;
@@ -212,7 +211,6 @@ const sal_uInt8 SC_DDE_IGNOREMODE = 255; /// For usage in FindDdeLink()
class ScDocument
{
-friend class ScDocumentIterator;
friend class ScValueIterator;
friend class ScHorizontalValueIterator;
friend class ScDBQueryDataIterator;
@@ -1624,8 +1622,6 @@ public:
SCCOL nCol, SCROW nRow, SCTAB nTab,
ScMarkData& rMark, bool bIsUndo);
- void DoColResize( SCTAB nTab, SCCOL nCol1, SCCOL nCol2, SCSIZE nAdd );
-
void InvalidateTextWidth( const OUString& rStyleName );
void InvalidateTextWidth( SCTAB nTab );
void InvalidateTextWidth( const ScAddress* pAdrFrom, const ScAddress* pAdrTo, bool bNumFormatChanged );
@@ -1708,6 +1704,11 @@ public:
SC_DLLPUBLIC ScMacroManager* GetMacroManager();
+ /**
+ * See if specified column has any non-empty cells.
+ */
+ bool IsEmptyData( SCTAB nTab, SCCOL nCol ) const;
+
private:
ScDocument(const ScDocument& r); // disabled with no definition
@@ -2020,9 +2021,6 @@ private: // CLOOK-Impl-methods
bool HasPartOfMerged( const ScRange& rRange );
- void PutCell( const ScAddress&, ScBaseCell* pCell, bool bForceTab = false );
- void PutCell(SCCOL nCol, SCROW nRow, SCTAB nTab, ScBaseCell* pCell, sal_uLong nFormatIndex, bool bForceTab = false );
-
ScRefCellValue GetRefCellValue( const ScAddress& rPos );
std::map< SCTAB, ScSortParam > mSheetSortParams;
diff --git a/sc/inc/documentimport.hxx b/sc/inc/documentimport.hxx
index afd954b..9fddf2b 100644
--- a/sc/inc/documentimport.hxx
+++ b/sc/inc/documentimport.hxx
@@ -20,7 +20,6 @@
class ScDocument;
class ScAddress;
class ScTokenArray;
-class ScBaseCell;
struct ScDocumentImportImpl;
/**
@@ -62,9 +61,6 @@ public:
void setFormulaCell(const ScAddress& rPos, const ScTokenArray& rArray);
void finalize();
-
-private:
- void insertCell(const ScAddress& rPos, ScBaseCell* pCell);
};
#endif
diff --git a/sc/inc/editutil.hxx b/sc/inc/editutil.hxx
index c033415..eb7fd56 100644
--- a/sc/inc/editutil.hxx
+++ b/sc/inc/editutil.hxx
@@ -66,6 +66,8 @@ public:
static void RemoveCharAttribs( EditTextObject& rEditText, const ScPatternAttr& rAttr );
+ static EditTextObject* Clone( const EditTextObject& rSrc, ScDocument& rDestDoc );
+
public:
ScEditUtil( ScDocument* pDocument, SCCOL nX, SCROW nY, SCTAB nZ,
const Point& rScrPosPixel,
diff --git a/sc/inc/formulacell.hxx b/sc/inc/formulacell.hxx
index 4760062..af9067e 100644
--- a/sc/inc/formulacell.hxx
+++ b/sc/inc/formulacell.hxx
@@ -211,7 +211,7 @@ public:
const ScMatrix* GetMatrix();
bool GetMatrixOrigin( ScAddress& rPos ) const;
void GetResultDimensions( SCSIZE& rCols, SCSIZE& rRows );
- sal_uInt16 GetMatrixEdge( ScAddress& rOrgPos );
+ sal_uInt16 GetMatrixEdge( ScAddress& rOrgPos ) const;
sal_uInt16 GetErrCode(); // interpret first if necessary
sal_uInt16 GetRawError(); // don't interpret, just return code or result error
short GetFormatType() const { return nFormatType; }
diff --git a/sc/inc/markdata.hxx b/sc/inc/markdata.hxx
index ad7a4b1..75937ed 100644
--- a/sc/inc/markdata.hxx
+++ b/sc/inc/markdata.hxx
@@ -96,6 +96,8 @@ public:
void FillRangeListWithMarks( ScRangeList* pList, bool bClear ) const;
void ExtendRangeListTables( ScRangeList* pList ) const;
+ ScRangeList GetMarkedRanges() const;
+
void MarkFromRangeList( const ScRangeList& rList, bool bReset );
SCCOLROW GetMarkColumnRanges( SCCOLROW* pRanges );
diff --git a/sc/inc/mtvcellfunc.hxx b/sc/inc/mtvcellfunc.hxx
new file mode 100644
index 0000000..9ce3c12
--- /dev/null
+++ b/sc/inc/mtvcellfunc.hxx
@@ -0,0 +1,154 @@
+/* -*- 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/.
+ */
+
+#ifndef SC_MTVCELLFUNC_HXX
+#define SC_MTVCELLFUNC_HXX
+
+#include "mtvelements.hxx"
+#include "mtvfunctions.hxx"
+
+namespace sc {
+
+template<typename _Func>
+void ProcessFormula(CellStoreType& rStore, _Func& rFunc)
+{
+ FuncElseNoOp<size_t> aElse;
+ ProcessElements1<CellStoreType, formula_block, _Func, FuncElseNoOp<size_t> >(rStore, rFunc, aElse);
+}
+
+template<typename _FuncElem>
+typename CellStoreType::iterator
+ProcessFormula(
+ const CellStoreType::iterator& it, CellStoreType& rStore, SCROW nRow1, SCROW nRow2, _FuncElem& rFuncElem)
+{
+ FuncElseNoOp<size_t> aElse;
+ return ProcessElements1<
+ CellStoreType, formula_block, _FuncElem, FuncElseNoOp<size_t> >(it, rStore, nRow1, nRow2, rFuncElem, aElse);
+}
+
+template<typename _FuncElem, typename _FuncElse>
+typename CellStoreType::iterator
+ProcessFormula(
+ const CellStoreType::iterator& it, CellStoreType& rStore, SCROW nRow1, SCROW nRow2, _FuncElem& rFuncElem, _FuncElse& rFuncElse)
+{
+ return ProcessElements1<
+ CellStoreType, formula_block, _FuncElem, _FuncElse>(it, rStore, nRow1, nRow2, rFuncElem, rFuncElse);
+}
+
+template<typename _Func>
+typename CellStoreType::iterator
+ProcessFormulaNumeric(
+ const CellStoreType::iterator& itPos, CellStoreType& rStore, SCROW nRow1, SCROW nRow2, _Func& rFunc)
+{
+ FuncElseNoOp<size_t> aElse;
+ return ProcessElements2<
+ CellStoreType, numeric_block, formula_block, _Func, FuncElseNoOp<size_t> >(
+ itPos, rStore, nRow1, nRow2, rFunc, aElse);
+}
+
+template<typename _Func>
+void ProcessEditText(CellStoreType& rStore, _Func& rFunc)
+{
+ FuncElseNoOp<size_t> aElse;
+ ProcessElements1<CellStoreType, edittext_block, _Func, FuncElseNoOp<size_t> >(rStore, rFunc, aElse);
+}
+
+template<typename _Func>
+CellStoreType::iterator
+ProcessEditText(const CellStoreType::iterator& itPos, CellStoreType& rStore, SCROW nRow1, SCROW nRow2, _Func& rFunc)
+{
+ FuncElseNoOp<size_t> aElse;
+ return ProcessElements1<CellStoreType, edittext_block, _Func, FuncElseNoOp<size_t> >(
+ itPos, rStore, nRow1, nRow2, rFunc, aElse);
+}
+
+template<typename _Func>
+void ParseFormula(
+ const CellStoreType& rStore, _Func& rFunc)
+{
+ FuncElseNoOp<size_t> aElse;
+ ParseElements1<CellStoreType, formula_block, _Func, FuncElseNoOp<size_t> >(rStore, rFunc, aElse);
+}
+
+template<typename _Func>
+typename CellStoreType::const_iterator
+ParseFormula(
+ const CellStoreType::const_iterator& itPos, const CellStoreType& rStore,
+ SCROW nStart, SCROW nEnd, _Func& rFunc)
+{
+ FuncElseNoOp<size_t> aElse;
+ return ParseElements1<CellStoreType, formula_block, _Func, FuncElseNoOp<size_t> >(
+ itPos, rStore, nStart, nEnd, rFunc, aElse);
+}
+
+template<typename _FuncElem, typename _FuncElse>
+typename CellStoreType::const_iterator
+ParseAll(
+ const typename CellStoreType::const_iterator& itPos, const CellStoreType& rCells,
+ SCROW nRow1, SCROW nRow2, _FuncElem& rFuncElem, _FuncElse& rFuncElse)
+{
+ return ParseElements4<CellStoreType,
+ numeric_block, string_block, edittext_block, formula_block,
+ _FuncElem, _FuncElse>(
+ itPos, rCells, nRow1, nRow2, rFuncElem, rFuncElse);
+}
+
+template<typename _Func>
+typename CellStoreType::const_iterator
+ParseAllNonEmpty(
+ const typename CellStoreType::const_iterator& itPos, const CellStoreType& rCells,
+ SCROW nRow1, SCROW nRow2, _Func& rFunc)
+{
+ FuncElseNoOp<size_t> aElse;
+ return ParseElements4<CellStoreType,
+ numeric_block, string_block, edittext_block, formula_block,
+ _Func, FuncElseNoOp<size_t> >(
+ itPos, rCells, nRow1, nRow2, rFunc, aElse);
+}
+
+template<typename _Func>
+typename CellStoreType::const_iterator
+ParseFormulaNumeric(
+ const CellStoreType::const_iterator& itPos, const CellStoreType& rCells,
+ SCROW nRow1, SCROW nRow2, _Func& rFunc)
+{
+ FuncElseNoOp<size_t> aElse;
+ return ParseElements2<CellStoreType,
+ numeric_block, formula_block, _Func, FuncElseNoOp<size_t> >(
+ itPos, rCells, nRow1, nRow2, rFunc, aElse);
+}
+
+template<typename _Func>
+void ProcessFormulaEditText(CellStoreType& rStore, _Func& rFunc)
+{
+ FuncElseNoOp<size_t> aElse;
+ ProcessElements2<CellStoreType, edittext_block, formula_block, _Func, FuncElseNoOp<size_t> >(rStore, rFunc, aElse);
+}
+
+template<typename _Func>
+std::pair<CellStoreType::const_iterator, size_t>
+FindFormula(const CellStoreType& rStore, SCROW nRow1, SCROW nRow2, _Func& rFunc)
+{
+ typedef std::pair<size_t,bool> ElseRetType;
+ FuncElseNoOp<size_t, ElseRetType> aElse;
+ return FindElement1<CellStoreType, formula_block, _Func, FuncElseNoOp<size_t, ElseRetType> >(rStore, nRow1, nRow2, rFunc, aElse);
+}
+
+template<typename _Func>
+std::pair<CellStoreType::const_iterator, size_t>
+FindFormulaEditText(const CellStoreType& rStore, SCROW nRow1, SCROW nRow2, _Func& rFunc)
+{
+ return FindElement2<CellStoreType, edittext_block, formula_block, _Func, _Func>(rStore, nRow1, nRow2, rFunc, rFunc);
+}
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/inc/mtvelements.hxx b/sc/inc/mtvelements.hxx
index 941c1a24a..0ebf8be 100644
--- a/sc/inc/mtvelements.hxx
+++ b/sc/inc/mtvelements.hxx
@@ -54,7 +54,9 @@ const mdds::mtv::element_t element_type_string = mdds::mtv::element_type_user_st
const mdds::mtv::element_t element_type_edittext = mdds::mtv::element_type_user_start + 3;
const mdds::mtv::element_t element_type_formula = mdds::mtv::element_type_user_start + 4;
+// Mapped standard element types (for convenience).
const mdds::mtv::element_t element_type_numeric = mdds::mtv::element_type_numeric;
+const mdds::mtv::element_t element_type_empty = mdds::mtv::element_type_empty;
// Custom element blocks.
@@ -64,6 +66,9 @@ typedef mdds::mtv::default_element_block<element_type_string, rtl::OUString> str
typedef mdds::mtv::noncopyable_managed_element_block<element_type_edittext, EditTextObject> edittext_block;
typedef mdds::mtv::noncopyable_managed_element_block<element_type_formula, ScFormulaCell> formula_block;
+// Mapped standard element blocks (for convenience).
+typedef mdds::mtv::numeric_element_block numeric_block;
+
// This needs to be in the same namespace as CellTextAttr.
MDDS_MTV_DEFINE_ELEMENT_CALLBACKS(CellTextAttr, element_type_celltextattr, CellTextAttr(), celltextattr_block)
@@ -83,18 +88,15 @@ MDDS_MTV_DEFINE_ELEMENT_CALLBACKS(OUString, sc::element_type_string, OUString(),
namespace sc {
// Broadcaster storage container
-typedef mdds::mtv::custom_block_func1<sc::element_type_broadcaster, sc::broadcaster_block> BCBlkFunc;
+typedef mdds::mtv::custom_block_func1<sc::broadcaster_block> BCBlkFunc;
typedef mdds::multi_type_vector<BCBlkFunc> BroadcasterStoreType;
// Cell text attribute container.
-typedef mdds::mtv::custom_block_func1<sc::element_type_celltextattr, sc::celltextattr_block> CTAttrFunc;
+typedef mdds::mtv::custom_block_func1<sc::celltextattr_block> CTAttrFunc;
typedef mdds::multi_type_vector<CTAttrFunc> CellTextAttrStoreType;
// Cell container
-typedef mdds::mtv::custom_block_func3<
- sc::element_type_string, sc::string_block,
- sc::element_type_edittext, sc::edittext_block,
- sc::element_type_formula, sc::formula_block> CellFunc;
+typedef mdds::mtv::custom_block_func3<sc::string_block, sc::edittext_block, sc::formula_block> CellFunc;
typedef mdds::multi_type_vector<CellFunc> CellStoreType;
/**
@@ -104,6 +106,18 @@ struct ColumnBlockPosition
{
BroadcasterStoreType::iterator miBroadcasterPos;
CellTextAttrStoreType::iterator miCellTextAttrPos;
+ CellStoreType::iterator miCellPos;
+
+ ColumnBlockPosition& operator= (const ColumnBlockPosition& r);
+};
+
+struct ColumnBlockConstPosition
+{
+ BroadcasterStoreType::const_iterator miBroadcasterPos;
+ CellTextAttrStoreType::const_iterator miCellTextAttrPos;
+ CellStoreType::const_iterator miCellPos;
+
+ ColumnBlockConstPosition& operator= (const ColumnBlockConstPosition& r);
};
class ColumnBlockPositionSet
@@ -125,3 +139,4 @@ public:
#endif
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
+
diff --git a/sc/inc/mtvfunctions.hxx b/sc/inc/mtvfunctions.hxx
new file mode 100644
index 0000000..03cb55a
--- /dev/null
+++ b/sc/inc/mtvfunctions.hxx
@@ -0,0 +1,786 @@
+/* -*- 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/.
+ */
+
+#ifndef SC_MTVFUNCTIONS_HXX
+#define SC_MTVFUNCTIONS_HXX
+
+#include <cstdlib>
+#include <mdds/multi_type_vector_types.hpp>
+
+namespace sc {
+
+template<typename _SizeT, typename _Ret = bool>
+struct FuncElseNoOp
+{
+ _Ret operator() (mdds::mtv::element_t, _SizeT, _SizeT) const
+ {
+ return _Ret();
+ }
+};
+
+/**
+ * Generic algorithm to parse blocks of multi_type_vector either partially
+ * or fully.
+ */
+template<typename _StoreT, typename _Func>
+typename _StoreT::const_iterator
+ParseBlock(
+ const typename _StoreT::const_iterator& itPos, const _StoreT& rStore, _Func& rFunc,
+ typename _StoreT::size_type nStart, typename _StoreT::size_type nEnd)
+{
+ typedef std::pair<typename _StoreT::const_iterator, typename _StoreT::size_type> PositionType;
+
+ PositionType aPos = rStore.position(itPos, nStart);
+ typename _StoreT::const_iterator it = aPos.first;
+ typename _StoreT::size_type nOffset = aPos.second;
+ typename _StoreT::size_type nDataSize = 0;
+ typename _StoreT::size_type nTopRow = nStart;
+
+ for (; it != rStore.end() && nTopRow <= nEnd; ++it, nOffset = 0, nTopRow += nDataSize)
+ {
+ bool bLastBlock = false;
+ nDataSize = it->size - nOffset;
+ if (nTopRow + nDataSize - 1 > nEnd)
+ {
+ // Truncate the block.
+ nDataSize = nEnd - nTopRow + 1;
+ bLastBlock = true;
+ }
+
+ rFunc(*it, nOffset, nDataSize);
+
+ if (bLastBlock)
+ break;
+ }
+
+ return it;
+}
+
+/**
+ * Non-const variant of the above function. TODO: Find a way to merge these
+ * two in an elegant way.
+ */
+template<typename _StoreT, typename _Func>
+typename _StoreT::iterator
+ProcessBlock(const typename _StoreT::iterator& itPos, _StoreT& rStore, _Func& rFunc, typename _StoreT::size_type nStart, typename _StoreT::size_type nEnd)
+{
+ typedef std::pair<typename _StoreT::iterator, typename _StoreT::size_type> PositionType;
+
+ PositionType aPos = rStore.position(itPos, nStart);
+ typename _StoreT::iterator it = aPos.first;
+ typename _StoreT::size_type nOffset = aPos.second;
+ typename _StoreT::size_type nDataSize = 0;
+ typename _StoreT::size_type nCurRow = nStart;
+
+ for (; it != rStore.end() && nCurRow <= nEnd; ++it, nOffset = 0, nCurRow += nDataSize)
+ {
+ bool bLastBlock = false;
+ nDataSize = it->size - nOffset;
+ if (nCurRow + nDataSize - 1 > nEnd)
+ {
+ // Truncate the block.
+ nDataSize = nEnd - nCurRow + 1;
+ bLastBlock = true;
+ }
+
+ rFunc(*it, nOffset, nDataSize);
+
+ if (bLastBlock)
+ break;
+ }
+
+ return it;
+}
+
+template<typename _StoreT, typename _BlkT, typename _FuncElem, typename _FuncElse>
+void ParseElements1(const _StoreT& rStore, _FuncElem& rFuncElem, _FuncElse& rFuncElse)
+{
+ typename _StoreT::size_type nTopRow = 0, nDataSize = 0;
+ typename _StoreT::const_iterator it = rStore.begin(), itEnd = rStore.end();
+ for (; it != itEnd; ++it, nTopRow += nDataSize)
+ {
+ nDataSize = it->size;
+ if (it->type != _BlkT::block_type)
+ {
+ rFuncElse(it->type, nTopRow, nDataSize);
+ continue;
+ }
+
+ typename _BlkT::const_iterator itf = _BlkT::begin(*it->data);
+ typename _BlkT::const_iterator itfEnd = _BlkT::end(*it->data);
+ typename _StoreT::size_type nRow = nTopRow;
+ for (; itf != itfEnd; ++itf, ++nRow)
+ rFuncElem(nRow, *itf);
+ }
+}
+
+template<typename _StoreT, typename _BlkT, typename _FuncElem, typename _FuncElse>
+typename _StoreT::const_iterator
+ParseElements1(
+ const typename _StoreT::const_iterator& itPos, const _StoreT& rStore,
+ typename _StoreT::size_type nStart, typename _StoreT::size_type nEnd,
+ _FuncElem& rFuncElem, _FuncElse& rFuncElse)
+{
+ typedef std::pair<typename _StoreT::const_iterator, typename _StoreT::size_type> PositionType;
+
+ PositionType aPos = rStore.position(itPos, nStart);
+ typename _StoreT::const_iterator it = aPos.first;
+ typename _StoreT::size_type nOffset = aPos.second;
+ typename _StoreT::size_type nDataSize = 0;
+ typename _StoreT::size_type nTopRow = nStart;
+
+ for (; it != rStore.end() && nTopRow <= nEnd; ++it, nOffset = 0, nTopRow += nDataSize)
+ {
+ bool bLastBlock = false;
+ nDataSize = it->size - nOffset;
+ if (nTopRow + nDataSize - 1 > nEnd)
+ {
+ // Truncate the block.
+ nDataSize = nEnd - nTopRow + 1;
+ bLastBlock = true;
+ }
+
+ if (it->type == _BlkT::block_type)
+ {
+ typename _BlkT::const_iterator itf = _BlkT::begin(*it->data);
+ std::advance(itf, nOffset);
+ typename _BlkT::const_iterator itfEnd = itf;
+ std::advance(itfEnd, nDataSize);
+ typename _StoreT::size_type nRow = nTopRow;
+ for (; itf != itfEnd; ++itf, ++nRow)
+ rFuncElem(nRow, *itf);
+ }
+ else
+ rFuncElse(it->type, nTopRow, nDataSize);
+
+
+ if (bLastBlock)
+ break;
+ }
+
+ return it;
+};
+
+template<typename _StoreT, typename _Blk1, typename _Blk2, typename _FuncElem, typename _FuncElse>
+typename _StoreT::const_iterator
+ParseElements2(
+ const typename _StoreT::const_iterator& itPos, const _StoreT& rStore, typename _StoreT::size_type nStart, typename _StoreT::size_type nEnd,
+ _FuncElem& rFuncElem, _FuncElse& rFuncElse)
+{
+ typedef std::pair<typename _StoreT::const_iterator, typename _StoreT::size_type> PositionType;
+
+ PositionType aPos = rStore.position(itPos, nStart);
+ typename _StoreT::const_iterator it = aPos.first;
+ typename _StoreT::size_type nOffset = aPos.second;
+ typename _StoreT::size_type nDataSize = 0;
+ typename _StoreT::size_type nTopRow = nStart;
+
+ for (; it != rStore.end() && nTopRow <= nEnd; ++it, nOffset = 0, nTopRow += nDataSize)
+ {
+ bool bLastBlock = false;
+ nDataSize = it->size - nOffset;
+ if (nTopRow + nDataSize - 1 > nEnd)
+ {
+ // Truncate the block.
+ nDataSize = nEnd - nTopRow + 1;
+ bLastBlock = true;
+ }
+
+ switch (it->type)
+ {
+ case _Blk1::block_type:
+ {
+ typename _Blk1::const_iterator itData = _Blk1::begin(*it->data);
+ std::advance(itData, nOffset);
+ typename _Blk1::const_iterator itDataEnd = itData;
+ std::advance(itDataEnd, nDataSize);
+ typename _StoreT::size_type nRow = nTopRow;
+ for (; itData != itDataEnd; ++itData, ++nRow)
+ rFuncElem(nRow, *itData);
+ }
+ break;
+ case _Blk2::block_type:
+ {
+ typename _Blk2::const_iterator itData = _Blk2::begin(*it->data);
+ std::advance(itData, nOffset);
+ typename _Blk2::const_iterator itDataEnd = itData;
+ std::advance(itDataEnd, nDataSize);
+ typename _StoreT::size_type nRow = nTopRow;
+ for (; itData != itDataEnd; ++itData, ++nRow)
+ rFuncElem(nRow, *itData);
+ }
+ break;
+ default:
+ rFuncElse(it->type, nTopRow, nDataSize);
+ }
+
+ if (bLastBlock)
+ break;
+ }
+
+ return it;
+}
+
+template<typename _StoreT, typename _Blk1, typename _Blk2, typename _Blk3, typename _Blk4, typename _FuncElem, typename _FuncElse>
+typename _StoreT::const_iterator
+ParseElements4(
+ const typename _StoreT::const_iterator& itPos, const _StoreT& rStore, typename _StoreT::size_type nStart, typename _StoreT::size_type nEnd,
+ _FuncElem& rFuncElem, _FuncElse& rFuncElse)
+{
+ typedef std::pair<typename _StoreT::const_iterator, typename _StoreT::size_type> PositionType;
+
+ PositionType aPos = rStore.position(itPos, nStart);
+ typename _StoreT::const_iterator it = aPos.first;
+ typename _StoreT::size_type nOffset = aPos.second;
+ typename _StoreT::size_type nDataSize = 0;
+ typename _StoreT::size_type nTopRow = nStart;
+
+ for (; it != rStore.end() && nTopRow <= nEnd; ++it, nOffset = 0, nTopRow += nDataSize)
+ {
+ bool bLastBlock = false;
+ nDataSize = it->size - nOffset;
+ if (nTopRow + nDataSize - 1 > nEnd)
+ {
+ // Truncate the block.
+ nDataSize = nEnd - nTopRow + 1;
+ bLastBlock = true;
+ }
+
+ switch (it->type)
+ {
+ case _Blk1::block_type:
+ {
+ typename _Blk1::const_iterator itData = _Blk1::begin(*it->data);
+ std::advance(itData, nOffset);
+ typename _Blk1::const_iterator itDataEnd = itData;
+ std::advance(itDataEnd, nDataSize);
+ typename _StoreT::size_type nRow = nTopRow;
+ for (; itData != itDataEnd; ++itData, ++nRow)
+ rFuncElem(nRow, *itData);
+ }
+ break;
+ case _Blk2::block_type:
+ {
+ typename _Blk2::const_iterator itData = _Blk2::begin(*it->data);
+ std::advance(itData, nOffset);
+ typename _Blk2::const_iterator itDataEnd = itData;
+ std::advance(itDataEnd, nDataSize);
+ typename _StoreT::size_type nRow = nTopRow;
+ for (; itData != itDataEnd; ++itData, ++nRow)
+ rFuncElem(nRow, *itData);
+ }
+ break;
+ case _Blk3::block_type:
+ {
+ typename _Blk3::const_iterator itData = _Blk3::begin(*it->data);
+ std::advance(itData, nOffset);
+ typename _Blk3::const_iterator itDataEnd = itData;
+ std::advance(itDataEnd, nDataSize);
+ typename _StoreT::size_type nRow = nTopRow;
+ for (; itData != itDataEnd; ++itData, ++nRow)
+ rFuncElem(nRow, *itData);
+ }
+ break;
+ case _Blk4::block_type:
+ {
+ typename _Blk4::const_iterator itData = _Blk4::begin(*it->data);
+ std::advance(itData, nOffset);
+ typename _Blk4::const_iterator itDataEnd = itData;
+ std::advance(itDataEnd, nDataSize);
+ typename _StoreT::size_type nRow = nTopRow;
+ for (; itData != itDataEnd; ++itData, ++nRow)
+ rFuncElem(nRow, *itData);
+ }
+ break;
+ default:
+ rFuncElse(it->type, nTopRow, nDataSize);
+ }
+
+ if (bLastBlock)
+ break;
+ }
+
+ return it;
+}
+
+template<typename _StoreT, typename _BlkT, typename _FuncElem, typename _FuncElse>
+void ProcessElements1(_StoreT& rStore, _FuncElem& rFuncElem, _FuncElse& rFuncElse)
+{
+ typename _StoreT::size_type nTopRow = 0, nDataSize = 0;
+ typename _StoreT::iterator it = rStore.begin(), itEnd = rStore.end();
+ for (; it != itEnd; ++it, nTopRow += nDataSize)
+ {
+ nDataSize = it->size;
+ if (it->type != _BlkT::block_type)
+ {
+ rFuncElse(it->type, nTopRow, nDataSize);
+ continue;
+ }
+
+ typename _BlkT::iterator itf = _BlkT::begin(*it->data);
+ typename _BlkT::iterator itfEnd = _BlkT::end(*it->data);
+ typename _StoreT::size_type nRow = nTopRow;
+ for (; itf != itfEnd; ++itf, ++nRow)
+ rFuncElem(nRow, *itf);
+ }
+}
+
+/**
+ * This variant specifies start and end positions.
+ */
+template<typename _StoreT, typename _BlkT, typename _FuncElem, typename _FuncElse>
+typename _StoreT::iterator
+ProcessElements1(
+ const typename _StoreT::iterator& itPos, _StoreT& rStore,
+ typename _StoreT::size_type nStart, typename _StoreT::size_type nEnd,
+ _FuncElem& rFuncElem, _FuncElse& rFuncElse)
+{
+ typedef std::pair<typename _StoreT::iterator, typename _StoreT::size_type> PositionType;
+
+ PositionType aPos = rStore.position(itPos, nStart);
+ typename _StoreT::iterator it = aPos.first;
+ typename _StoreT::size_type nOffset = aPos.second;
+ typename _StoreT::size_type nDataSize = 0;
+ typename _StoreT::size_type nTopRow = nStart;
+
+ for (; it != rStore.end() && nTopRow <= nEnd; ++it, nOffset = 0, nTopRow += nDataSize)
+ {
+ bool bLastBlock = false;
+ nDataSize = it->size - nOffset;
+ if (nTopRow + nDataSize - 1 > nEnd)
+ {
+ // Truncate the block.
+ nDataSize = nEnd - nTopRow + 1;
+ bLastBlock = true;
+ }
+
+ if (it->type == _BlkT::block_type)
+ {
+ typename _BlkT::iterator itf = _BlkT::begin(*it->data);
+ std::advance(itf, nOffset);
+ typename _BlkT::iterator itfEnd = itf;
+ std::advance(itfEnd, nDataSize);
+ typename _StoreT::size_type nRow = nTopRow;
+ for (; itf != itfEnd; ++itf, ++nRow)
+ rFuncElem(nRow, *itf);
+ }
+ else
+ rFuncElse(it->type, nTopRow, nDataSize);
+
+ if (bLastBlock)
+ break;
+ }
+
+ return it;
+};
+
+template<typename _StoreT, typename _Blk1, typename _Blk2, typename _FuncElem, typename _FuncElse>
+void ProcessElements2(_StoreT& rStore, _FuncElem& rFuncElem, _FuncElse& rFuncElse)
+{
+ typename _StoreT::size_type nTopRow = 0, nDataSize = 0;
+ typename _StoreT::iterator it = rStore.begin(), itEnd = rStore.end();
+ for (; it != itEnd; ++it, nTopRow += nDataSize)
+ {
+ nDataSize = it->size;
+ switch (it->type)
+ {
+ case _Blk1::block_type:
+ {
+ typename _Blk1::iterator itData = _Blk1::begin(*it->data);
+ typename _Blk1::iterator itDataEnd = _Blk1::end(*it->data);
+ typename _StoreT::size_type nRow = nTopRow;
+ for (; itData != itDataEnd; ++itData, ++nRow)
+ rFuncElem(nRow, *itData);
+ }
+ break;
+ case _Blk2::block_type:
+ {
+ typename _Blk2::iterator itData = _Blk2::begin(*it->data);
+ typename _Blk2::iterator itDataEnd = _Blk2::end(*it->data);
+ typename _StoreT::size_type nRow = nTopRow;
+ for (; itData != itDataEnd; ++itData, ++nRow)
+ rFuncElem(nRow, *itData);
+ }
+ break;
+ default:
+ rFuncElse(it->type, nTopRow, nDataSize);
+ }
+ }
+}
+
+template<typename _StoreT, typename _Blk1, typename _Blk2, typename _FuncElem, typename _FuncElse>
+typename _StoreT::iterator
+ProcessElements2(
+ const typename _StoreT::iterator& itPos, _StoreT& rStore,
+ typename _StoreT::size_type nStart, typename _StoreT::size_type nEnd,
+ _FuncElem& rFuncElem, _FuncElse& rFuncElse)
+{
+ typedef std::pair<typename _StoreT::iterator, typename _StoreT::size_type> PositionType;
+
+ PositionType aPos = rStore.position(itPos, nStart);
+ typename _StoreT::iterator it = aPos.first;
+ typename _StoreT::size_type nOffset = aPos.second;
+ typename _StoreT::size_type nDataSize = 0;
+ typename _StoreT::size_type nTopRow = nStart;
+
+ for (; it != rStore.end() && nTopRow <= nEnd; ++it, nOffset = 0, nTopRow += nDataSize)
+ {
+ bool bLastBlock = false;
+ nDataSize = it->size - nOffset;
+ if (nTopRow + nDataSize - 1 > nEnd)
+ {
+ // Truncate the block.
+ nDataSize = nEnd - nTopRow + 1;
+ bLastBlock = true;
+ }
+
+ switch (it->type)
+ {
+ case _Blk1::block_type:
+ {
+ typename _Blk1::iterator itData = _Blk1::begin(*it->data);
+ std::advance(itData, nOffset);
+ typename _Blk1::iterator itDataEnd = itData;
+ std::advance(itDataEnd, nDataSize);
+ typename _StoreT::size_type nRow = nTopRow;
+ for (; itData != itDataEnd; ++itData, ++nRow)
+ rFuncElem(nRow, *itData);
+ }
+ break;
+ case _Blk2::block_type:
+ {
+ typename _Blk2::iterator itData = _Blk2::begin(*it->data);
+ std::advance(itData, nOffset);
+ typename _Blk2::iterator itDataEnd = itData;
+ std::advance(itDataEnd, nDataSize);
+ typename _StoreT::size_type nRow = nTopRow;
+ for (; itData != itDataEnd; ++itData, ++nRow)
+ rFuncElem(nRow, *itData);
+ }
+ break;
+ default:
+ rFuncElse(it->type, nTopRow, nDataSize);
+ }
+
+ if (bLastBlock)
+ break;
+ }
+
+ return it;
+}
+
+template<typename _StoreT, typename _Blk1, typename _Blk2, typename _Blk3, typename _FuncElem, typename _FuncElse>
+void ProcessElements3(_StoreT& rStore, _FuncElem& rFuncElem, _FuncElse& rFuncElse)
+{
+ typename _StoreT::size_type nTopRow = 0, nDataSize = 0;
+ typename _StoreT::iterator it = rStore.begin(), itEnd = rStore.end();
+ for (; it != itEnd; ++it, nTopRow += nDataSize)
+ {
+ nDataSize = it->size;
+ switch (it->type)
+ {
+ case _Blk1::block_type:
+ {
+ typename _Blk1::iterator itData = _Blk1::begin(*it->data);
+ typename _Blk1::iterator itDataEnd = _Blk1::end(*it->data);
+ typename _StoreT::size_type nRow = nTopRow;
+ for (; itData != itDataEnd; ++itData, ++nRow)
+ rFuncElem(nRow, *itData);
+ }
+ break;
+ case _Blk2::block_type:
+ {
+ typename _Blk2::iterator itData = _Blk2::begin(*it->data);
+ typename _Blk2::iterator itDataEnd = _Blk2::end(*it->data);
+ typename _StoreT::size_type nRow = nTopRow;
+ for (; itData != itDataEnd; ++itData, ++nRow)
+ rFuncElem(nRow, *itData);
+ }
+ break;
+ case _Blk3::block_type:
+ {
+ typename _Blk3::iterator itData = _Blk3::begin(*it->data);
+ typename _Blk3::iterator itDataEnd = _Blk3::end(*it->data);
+ typename _StoreT::size_type nRow = nTopRow;
+ for (; itData != itDataEnd; ++itData, ++nRow)
+ rFuncElem(nRow, *itData);
+ }
+ break;
+ default:
+ rFuncElse(it->type, nTopRow, nDataSize);
+ }
+ }
+}
+
+template<typename _StoreT, typename _Blk1, typename _Blk2, typename _Blk3, typename _Blk4, typename _FuncElem, typename _FuncElse>
+void ProcessElements4(_StoreT& rStore, _FuncElem& rFuncElem, _FuncElse& rFuncElse)
+{
+ typename _StoreT::size_type nTopRow = 0, nDataSize = 0;
+ typename _StoreT::iterator it = rStore.begin(), itEnd = rStore.end();
+ for (; it != itEnd; ++it, nTopRow += nDataSize)
+ {
+ nDataSize = it->size;
+ switch (it->type)
+ {
+ case _Blk1::block_type:
+ {
+ typename _Blk1::iterator itData = _Blk1::begin(*it->data);
+ typename _Blk1::iterator itDataEnd = _Blk1::end(*it->data);
+ typename _StoreT::size_type nRow = nTopRow;
+ for (; itData != itDataEnd; ++itData, ++nRow)
+ rFuncElem(nRow, *itData);
+ }
+ break;
+ case _Blk2::block_type:
+ {
+ typename _Blk2::iterator itData = _Blk2::begin(*it->data);
+ typename _Blk2::iterator itDataEnd = _Blk2::end(*it->data);
+ typename _StoreT::size_type nRow = nTopRow;
+ for (; itData != itDataEnd; ++itData, ++nRow)
+ rFuncElem(nRow, *itData);
+ }
+ break;
+ case _Blk3::block_type:
+ {
+ typename _Blk3::iterator itData = _Blk3::begin(*it->data);
+ typename _Blk3::iterator itDataEnd = _Blk3::end(*it->data);
+ typename _StoreT::size_type nRow = nTopRow;
+ for (; itData != itDataEnd; ++itData, ++nRow)
+ rFuncElem(nRow, *itData);
+ }
+ break;
+ case _Blk4::block_type:
+ {
+ typename _Blk4::iterator itData = _Blk4::begin(*it->data);
+ typename _Blk4::iterator itDataEnd = _Blk4::end(*it->data);
+ typename _StoreT::size_type nRow = nTopRow;
+ for (; itData != itDataEnd; ++itData, ++nRow)
+ rFuncElem(nRow, *itData);
+ }
+ break;
+ default:
+ rFuncElse(it->type, nTopRow, nDataSize);
+ }
+ }
+}
+
+template<typename _StoreT, typename _Blk1, typename _Blk2, typename _Blk3, typename _Blk4, typename _FuncElem, typename _FuncElse>
+typename _StoreT::iterator
+ProcessElements4(
+ const typename _StoreT::iterator& itPos, _StoreT& rStore,
+ typename _StoreT::size_type nStart, typename _StoreT::size_type nEnd,
+ _FuncElem& rFuncElem, _FuncElse& rFuncElse)
+{
+ typedef std::pair<typename _StoreT::iterator, typename _StoreT::size_type> PositionType;
+
+ PositionType aPos = rStore.position(itPos, nStart);
+ typename _StoreT::iterator it = aPos.first;
+ typename _StoreT::size_type nOffset = aPos.second;
+ typename _StoreT::size_type nDataSize = 0;
+ typename _StoreT::size_type nTopRow = nStart;
+
+ for (; it != rStore.end() && nTopRow <= nEnd; ++it, nOffset = 0, nTopRow += nDataSize)
+ {
+ bool bLastBlock = false;
+ nDataSize = it->size - nOffset;
+ if (nTopRow + nDataSize - 1 > nEnd)
+ {
+ // Truncate the block.
+ nDataSize = nEnd - nTopRow + 1;
+ bLastBlock = true;
+ }
+
+ switch (it->type)
+ {
+ case _Blk1::block_type:
+ {
+ typename _Blk1::iterator itData = _Blk1::begin(*it->data);
+ std::advance(itData, nOffset);
+ typename _Blk1::iterator itDataEnd = itData;
+ std::advance(itDataEnd, nDataSize);
+ typename _StoreT::size_type nRow = nTopRow;
+ for (; itData != itDataEnd; ++itData, ++nRow)
+ rFuncElem(nRow, *itData);
+ }
+ break;
+ case _Blk2::block_type:
+ {
+ typename _Blk2::iterator itData = _Blk2::begin(*it->data);
+ std::advance(itData, nOffset);
+ typename _Blk2::iterator itDataEnd = itData;
+ std::advance(itDataEnd, nDataSize);
+ typename _StoreT::size_type nRow = nTopRow;
+ for (; itData != itDataEnd; ++itData, ++nRow)
+ rFuncElem(nRow, *itData);
+ }
+ break;
+ case _Blk3::block_type:
+ {
+ typename _Blk3::iterator itData = _Blk3::begin(*it->data);
+ std::advance(itData, nOffset);
+ typename _Blk3::iterator itDataEnd = itData;
+ std::advance(itDataEnd, nDataSize);
+ typename _StoreT::size_type nRow = nTopRow;
+ for (; itData != itDataEnd; ++itData, ++nRow)
+ rFuncElem(nRow, *itData);
+ }
+ break;
+ case _Blk4::block_type:
+ {
+ typename _Blk4::iterator itData = _Blk4::begin(*it->data);
+ std::advance(itData, nOffset);
+ typename _Blk4::iterator itDataEnd = itData;
+ std::advance(itDataEnd, nDataSize);
+ typename _StoreT::size_type nRow = nTopRow;
+ for (; itData != itDataEnd; ++itData, ++nRow)
+ rFuncElem(nRow, *itData);
+ }
+ break;
+ default:
+ rFuncElse(it->type, nTopRow, nDataSize);
+ }
+
+ if (bLastBlock)
+ break;
+ }
+
+ return it;
+}
+
+template<typename _StoreT, typename _Blk1, typename _FuncElem, typename _FuncElse>
+std::pair<typename _StoreT::const_iterator, typename _StoreT::size_type>
+FindElement1(
+ const _StoreT& rStore, typename _StoreT::size_type nStart, typename _StoreT::size_type nEnd,
+ _FuncElem& rFuncElem, _FuncElse& rFuncElse)
+{
+ typedef std::pair<typename _StoreT::const_iterator, typename _StoreT::size_type> PositionType;
+ typedef std::pair<typename _StoreT::size_type, bool> ElseRetType;
+
+ PositionType aPos = rStore.position(nStart);
+ typename _StoreT::const_iterator it = aPos.first;
+ typename _StoreT::size_type nOffset = aPos.second;
+ typename _StoreT::size_type nDataSize = 0;
+ typename _StoreT::size_type nTopRow = nStart;
+
+ for (; it != rStore.end() && nTopRow <= nEnd; ++it, nOffset = 0, nTopRow += nDataSize)
+ {
+ bool bLastBlock = false;
+ nDataSize = it->size - nOffset;
+ if (nTopRow + nDataSize - 1 > nEnd)
+ {
+ // Truncate the block.
+ nDataSize = nEnd - nTopRow + 1;
+ bLastBlock = true;
+ }
+
+ switch (it->type)
+ {
+ case _Blk1::block_type:
+ {
+ typename _Blk1::const_iterator itData = _Blk1::begin(*it->data);
+ std::advance(itData, nOffset);
+ typename _Blk1::const_iterator itDataEnd = itData;
+ std::advance(itDataEnd, nDataSize);
+ typename _StoreT::size_type nRow = nTopRow;
+ for (; itData != itDataEnd; ++itData, ++nRow)
+ {
+ if (rFuncElem(nRow, *itData))
+ return PositionType(it, nRow-nTopRow);
+ }
+ }
+ break;
+ default:
+ {
+ ElseRetType aRet = rFuncElse(it->type, nTopRow, nDataSize);
+ if (aRet.second)
+ return PositionType(it, aRet.first);
+ }
+ }
+
+ if (bLastBlock)
+ break;
+ }
+
+ return PositionType(rStore.end(), 0);
+}
+
+template<typename _StoreT, typename _Blk1, typename _Blk2, typename _FuncElem, typename _FuncElse>
+std::pair<typename _StoreT::const_iterator, typename _StoreT::size_type>
+FindElement2(
+ const _StoreT& rStore, typename _StoreT::size_type nStart, typename _StoreT::size_type nEnd,
+ _FuncElem& rFuncElem, _FuncElse& rFuncElse)
+{
+ typedef std::pair<typename _StoreT::const_iterator, typename _StoreT::size_type> PositionType;
+ typedef std::pair<typename _StoreT::size_type, bool> ElseRetType;
+
+ PositionType aPos = rStore.position(nStart);
+ typename _StoreT::const_iterator it = aPos.first;
+ typename _StoreT::size_type nOffset = aPos.second;
+ typename _StoreT::size_type nDataSize = 0;
+ typename _StoreT::size_type nTopRow = nStart;
+
+ for (; it != rStore.end() && nTopRow <= nEnd; ++it, nOffset = 0, nTopRow += nDataSize)
+ {
+ bool bLastBlock = false;
+ nDataSize = it->size - nOffset;
+ if (nTopRow + nDataSize - 1 > nEnd)
+ {
+ // Truncate the block.
+ nDataSize = nEnd - nTopRow + 1;
+ bLastBlock = true;
+ }
+
+ switch (it->type)
+ {
+ case _Blk1::block_type:
+ {
+ typename _Blk1::const_iterator itData = _Blk1::begin(*it->data);
+ std::advance(itData, nOffset);
+ typename _Blk1::const_iterator itDataEnd = itData;
+ std::advance(itDataEnd, nDataSize);
+ typename _StoreT::size_type nRow = nTopRow;
+ for (; itData != itDataEnd; ++itData, ++nRow)
+ {
+ if (rFuncElem(nRow, *itData))
+ return PositionType(it, nRow-nTopRow);
+ }
+ }
+ break;
+ case _Blk2::block_type:
+ {
+ typename _Blk2::const_iterator itData = _Blk2::begin(*it->data);
+ std::advance(itData, nOffset);
+ typename _Blk2::const_iterator itDataEnd = itData;
+ std::advance(itDataEnd, nDataSize);
+ typename _StoreT::size_type nRow = nTopRow;
+ for (; itData != itDataEnd; ++itData, ++nRow)
+ if (rFuncElem(nRow, *itData))
+ return PositionType(it, nRow-nTopRow);
+ }
+ break;
+ default:
+ {
+ ElseRetType aRet = rFuncElse(it->type, nTopRow, nDataSize);
+ if (aRet.second)
+ return PositionType(it, aRet.first);
+ }
+ }
+
+ if (bLastBlock)
+ break;
+ }
+
+ return PositionType(rStore.end(), 0);
+}
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/inc/scopetools.hxx b/sc/inc/scopetools.hxx
new file mode 100644
index 0000000..590ccbf
--- /dev/null
+++ b/sc/inc/scopetools.hxx
@@ -0,0 +1,33 @@
+/* -*- 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/.
+ */
+
+#ifndef SC_SCOPETOOLS_HXX
+#define SC_SCOPETOOLS_HXX
+
+class ScDocument;
+
+namespace sc {
+
+/**
+ * Temporarily switch on/off auto calculation mode.
+ */
+class AutoCalcSwitch
+{
+ ScDocument& mrDoc;
+ bool mbOldValue;
+public:
+ AutoCalcSwitch(ScDocument& rDoc, bool bAutoCalc);
+ ~AutoCalcSwitch();
+};
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index b62fa1e..c5c0286 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -30,6 +30,7 @@
#include "compressedarray.hxx"
#include "postit.hxx"
#include "types.hxx"
+#include "cellvalue.hxx"
#include "formula/types.hxx"
#include <set>
@@ -65,7 +66,6 @@ class SvxBoxItem;
class SvxSearchItem;
class ScAutoFormatData;
-class ScBaseCell;
class ScDocument;
class ScEditDataArray;
class ScFormulaCell;
@@ -191,7 +191,6 @@ private:
bool mbPageBreaksValid:1;
friend class ScDocument; // for FillInfo
-friend class ScDocumentIterator;
friend class ScValueIterator;
friend class ScHorizontalValueIterator;
friend class ScDBQueryDataIterator;
@@ -209,6 +208,10 @@ public:
bool bColInfo = true, bool bRowInfo = true );
~ScTable();
+ ScDocument& GetDoc();
+ const ScDocument& GetDoc() const;
+ SCTAB GetTab() const { return nTab; }
+
ScOutlineTable* GetOutlineTable() { return pOutlineTable; }
SCSIZE GetCellCount(SCCOL nCol) const;
@@ -310,10 +313,6 @@ public:
bool IsBlockEmpty( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, bool bIgnoreNotes = false ) const;
- void PutCell( const ScAddress&, ScBaseCell* pCell );
- void PutCell( SCCOL nCol, SCROW nRow, ScBaseCell* pCell );
- void PutCell(SCCOL nCol, SCROW nRow, sal_uLong nFormatIndex, ScBaseCell* pCell);
-
bool SetString( SCCOL nCol, SCROW nRow, SCTAB nTab, const String& rString,
ScSetStringParam* pParam = NULL );
@@ -331,6 +330,7 @@ public:
void SetValue( SCCOL nCol, SCROW nRow, const double& rVal );
void SetError( SCCOL nCol, SCROW nRow, sal_uInt16 nError);
+ void SetRawString( SCCOL nCol, SCROW nRow, const OUString& rStr );
void GetString( SCCOL nCol, SCROW nRow, OUString& rString ) const;
const OUString* GetStringCell( SCCOL nCol, SCROW nRow ) const;
double* GetValueCell( SCCOL nCol, SCROW nRow );
@@ -356,13 +356,7 @@ public:
CELLTYPE_NONE;
}
CellType GetCellType( SCCOL nCol, SCROW nRow ) const;
- ScBaseCell* GetCell( const ScAddress& rPos ) const
- {
- return ValidColRow(rPos.Col(),rPos.Row()) ?
- aCol[rPos.Col()].GetCell( rPos.Row() ) :
- NULL;
- }
- ScBaseCell* GetCell( SCCOL nCol, SCROW nRow ) const;
+ ScRefCellValue GetCellValue( SCCOL nCol, SCROW nRow ) const;
void GetFirstDataPos(SCCOL& rCol, SCROW& rRow) const;
void GetLastDataPos(SCCOL& rCol, SCROW& rRow) const;
@@ -372,7 +366,7 @@ public:
@param bForced True = always create all captions, false = skip when Undo is disabled. */
void InitializeNoteCaptions( bool bForced = false );
- bool TestInsertRow( SCCOL nStartCol, SCCOL nEndCol, SCSIZE nSize ) const;
+ bool TestInsertRow( SCCOL nStartCol, SCCOL nEndCol, SCROW nStartRow, SCSIZE nSize ) const;
void InsertRow( SCCOL nStartCol, SCCOL nEndCol, SCROW nStartRow, SCSIZE nSize );
void DeleteRow( SCCOL nStartCol, SCCOL nEndCol, SCROW nStartRow, SCSIZE nSize,
bool* pUndoOutline = NULL );
@@ -480,6 +474,8 @@ public:
0;
}
+ bool IsEmptyData( SCCOL nCol ) const;
+
void ResetChanged( const ScRange& rRange );
void SetDirty();
@@ -793,8 +789,8 @@ public:
void ExtendHidden( SCCOL& rX1, SCROW& rY1, SCCOL& rX2, SCROW& rY2 );
void Sort(const ScSortParam& rSortParam, bool bKeepQuery, ScProgress* pProgress);
- bool ValidQuery(
- SCROW nRow, const ScQueryParam& rQueryParam, ScBaseCell* pCell = NULL,
+ bool ValidQuery(
+ SCROW nRow, const ScQueryParam& rQueryParam, ScRefCellValue* pCell = NULL,
bool* pbTestEqualCondition = NULL);
void TopTenQuery( ScQueryParam& );
SCSIZE Query(ScQueryParam& rQueryParam, bool bKeepSub);
@@ -807,9 +803,6 @@ public:
bool HasColHeader( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow ) const;
bool HasRowHeader( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow ) const;
- void DoColResize( SCCOL nCol1, SCCOL nCol2, SCSIZE nAdd );
-
-
sal_Int32 GetMaxStringLen( SCCOL nCol,
SCROW nRowStart, SCROW nRowEnd, CharSet eCharSet ) const;
xub_StrLen GetMaxNumberStringLen( sal_uInt16& nPrecision,
@@ -918,9 +911,10 @@ private:
void DecoladeRow( ScSortInfoArray*, SCROW nRow1, SCROW nRow2 );
void SwapCol(SCCOL nCol1, SCCOL nCol2);
void SwapRow(SCROW nRow1, SCROW nRow2);
- short CompareCell( sal_uInt16 nSort,
- ScBaseCell* pCell1, SCCOL nCell1Col, SCROW nCell1Row,
- ScBaseCell* pCell2, SCCOL nCell2Col, SCROW nCell2Row ) const;
+ short CompareCell(
+ sal_uInt16 nSort,
+ ScRefCellValue& rCell1, SCCOL nCell1Col, SCROW nCell1Row,
+ ScRefCellValue& rCell2, SCCOL nCell2Col, SCROW nCell2Row ) const;
short Compare(SCCOLROW nIndex1, SCCOLROW nIndex2) const;
short Compare( ScSortInfoArray*, SCCOLROW nIndex1, SCCOLROW nIndex2) const;
ScSortInfoArray* CreateSortInfoArray( SCCOLROW nInd1, SCCOLROW nInd2 );
@@ -1000,14 +994,14 @@ private:
*
* @return First visible data cell if found, or NULL otherwise.
*/
- ScBaseCell* reset(SCROW nRow);
+ ScRefCellValue reset(SCROW nRow);
/**
* Find the next visible data cell position.
*
* @return Next visible data cell if found, or NULL otherwise.
*/
- ScBaseCell* next();
+ ScRefCellValue next();
/**
* Get the current row position.
@@ -1020,7 +1014,7 @@ private:
private:
ScFlatBoolRowSegments& mrRowSegs;
ScColumn& mrColumn;
- ScBaseCell* mpCell;
+ ScRefCellValue maCell;
SCROW mnCurRow;
SCROW mnUBound;
};
diff --git a/sc/inc/types.hxx b/sc/inc/types.hxx
index 9654271c4..629ab72 100644
--- a/sc/inc/types.hxx
+++ b/sc/inc/types.hxx
@@ -7,8 +7,8 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
-#ifndef __SC_TYPES_HXX__
-#define __SC_TYPES_HXX__
+#ifndef SC_TYPES_HXX
+#define SC_TYPES_HXX
#include <boost/intrusive_ptr.hpp>
@@ -36,6 +36,18 @@ enum ScFormulaVectorState
FormulaVectorUnknown
};
+namespace sc {
+
+const sal_uInt16 MatrixEdgeNothing = 0;
+const sal_uInt16 MatrixEdgeInside = 1;
+const sal_uInt16 MatrixEdgeBottom = 2;
+const sal_uInt16 MatrixEdgeLeft = 4;
+const sal_uInt16 MatrixEdgeTop = 8;
+const sal_uInt16 MatrixEdgeRight = 16;
+const sal_uInt16 MatrixEdgeOpen = 32;
+
+}
+
#endif
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx
index 12fb593..fde5c16 100644
--- a/sc/qa/unit/ucalc.cxx
+++ b/sc/qa/unit/ucalc.cxx
@@ -52,6 +52,7 @@
#include "conditio.hxx"
#include "globstr.hrc"
#include "tokenarray.hxx"
+#include "scopetools.hxx"
#include "formula/IFunctionDescription.hxx"
@@ -397,25 +398,6 @@ ScRange insertRangeData(ScDocument* pDoc, const ScAddress& rPos, const char* aDa
}
/**
- * Temporarily switch on/off auto calculation mode.
- */
-class AutoCalcSwitch
-{
- ScDocument* mpDoc;
- bool mbOldValue;
-public:
- AutoCalcSwitch(ScDocument* pDoc, bool bAutoCalc) : mpDoc(pDoc), mbOldValue(pDoc->GetAutoCalc())
- {
- mpDoc->SetAutoCalc(bAutoCalc);
- }
-
- ~AutoCalcSwitch()
- {
- mpDoc->SetAutoCalc(mbOldValue);
- }
-};
-
-/**
* Temporarily set formula grammar.
*/
class FormulaGrammarSwitch
@@ -1736,7 +1718,7 @@ void Test::testFormulaDepTracking()
{
CPPUNIT_ASSERT_MESSAGE ("failed to insert sheet", m_pDoc->InsertTab (0, "foo"));
- AutoCalcSwitch aACSwitch(m_pDoc, true); // turn on auto calculation.
+ sc::AutoCalcSwitch aACSwitch(*m_pDoc, true); // turn on auto calculation.
// B2 listens on D2.
m_pDoc->SetString(1, 1, 0, "=D2");
@@ -1844,7 +1826,7 @@ void Test::testFormulaDepTracking2()
{
CPPUNIT_ASSERT_MESSAGE ("failed to insert sheet", m_pDoc->InsertTab (0, "foo"));
- AutoCalcSwitch aACSwitch(m_pDoc, true); // turn on auto calculation.
+ sc::AutoCalcSwitch aACSwitch(*m_pDoc, true); // turn on auto calculation.
double val = 2.0;
m_pDoc->SetValue(0, 0, 0, val);
@@ -1954,7 +1936,7 @@ void Test::testCellBroadcaster()
{
CPPUNIT_ASSERT_MESSAGE ("failed to insert sheet", m_pDoc->InsertTab (0, "foo"));
- AutoCalcSwitch aACSwitch(m_pDoc, true); // turn on auto calculation.
+ sc::AutoCalcSwitch aACSwitch(*m_pDoc, true); // turn on auto calculation.
m_pDoc->SetString(ScAddress(1,0,0), "=A1"); // B1 depends on A1.
double val = m_pDoc->GetValue(ScAddress(1,0,0)); // A1 is empty, so the result should be 0.
CPPUNIT_ASSERT_EQUAL(0.0, val);
@@ -2995,7 +2977,7 @@ void Test::testPivotTableFilters()
CPPUNIT_ASSERT_MESSAGE("Table output check failed", bSuccess);
}
- AutoCalcSwitch aACSwitch(m_pDoc, true); // turn on auto calculation.
+ sc::AutoCalcSwitch aACSwitch(*m_pDoc, true); // turn on auto calculation.
ScAddress aFormulaAddr = aOutRange.aEnd;
aFormulaAddr.IncRow(2);
@@ -6879,31 +6861,39 @@ void Test::testFormulaGrouping()
const char *pFormula[3];
bool bGroup[3];
} aGroupTests[] = {
- { { "=SUM(B1)", "=SUM(C1)", "" }, // single increments
- { true, true, false } },
- { { "=SUM(B1)", "=SUM(D1)", "=SUM(F1)" }, // tripple increments
- { true, true, true } },
- { { "=SUM(B1)", "", "=SUM(C1)" }, // a gap
- { false, false, false } },
- { { "=SUM(B1)", "=SUM(C1;3)", "=SUM(D1;3)" }, // similar foo
- { false, true, true } },
+ { { "=B1", "=B2", "" }, // relative reference
+ { true, true, false } },
+ { { "=B1", "=B2", "=B3" },
+ { true, true, true } },
+ { { "=B1", "", "=B3" }, // a gap
+ { false, false, false } },
+ { { "=$B$1", "=$B$1", "" }, // absolute reference
+ { true, true, false } },
+ { { "=$Z$10", "=$Z$10", "=$Z$10" },
+ { true, true, true } },
+ { { "=C1+$Z$10", "=C2+$Z$10", "=C3+$Z$10" }, // mixture
+ { true, true, true } },
+ { { "=C1+$Z$11", "=C2+$Z$12", "=C3+$Z$12" }, // mixture
+ { false, true, true } },
+ { { "=SUM(B1)", "", "=SUM(B3)" }, // a gap
+ { false, false, false } },
};
m_pDoc->InsertTab( 0, "sheet" );
- for (unsigned i = 0; i < SAL_N_ELEMENTS( aGroupTests ); i++)
+ for (size_t i = 0; i < SAL_N_ELEMENTS(aGroupTests); ++i)
{
- for (unsigned j = 0; j < SAL_N_ELEMENTS( aGroupTests[0].pFormula ); j++)
+ for (size_t j = 0; j < SAL_N_ELEMENTS(aGroupTests[0].pFormula); ++j)
{
OUString aFormula = OUString::createFromAscii(aGroupTests[i].pFormula[j]);
- m_pDoc->SetString(0, (SCROW)j, 0, aFormula);
+ m_pDoc->SetString(0, static_cast<SCROW>(j), 0, aFormula);
}
m_pDoc->RebuildFormulaGroups();
- for (unsigned j = 0; j < SAL_N_ELEMENTS( aGroupTests[0].pFormula ); j++)
+ for (size_t j = 0; j < SAL_N_ELEMENTS(aGroupTests[0].pFormula); ++j)
{
ScRefCellValue aCell;
- aCell.assign(*m_pDoc, ScAddress(0, (SCROW)j, 0));
+ aCell.assign(*m_pDoc, ScAddress(0, static_cast<SCROW>(j), 0));
if (aCell.isEmpty())
{
CPPUNIT_ASSERT_MESSAGE("invalid empty cell", !aGroupTests[i].bGroup[j]);
@@ -6916,9 +6906,9 @@ void Test::testFormulaGrouping()
if( !!pCur->GetCellGroup().get() ^ aGroupTests[i].bGroup[j] )
{
- printf("expected group test %u at row %u to be %d but is %d\n",
- i, j, aGroupTests[i].bGroup[j], !!pCur->GetCellGroup().get());
- CPPUNIT_ASSERT_MESSAGE("Failed", false);
+ cout << "expected group test " << i << " at row " << j << " to be "
+ << aGroupTests[i].bGroup[j] << " but is " << !!pCur->GetCellGroup().get() << endl;
+ CPPUNIT_FAIL("Failed");
}
}
}
diff --git a/sc/source/core/data/cell2.cxx b/sc/source/core/data/cell2.cxx
index 8345e48..0d46036 100644
--- a/sc/source/core/data/cell2.cxx
+++ b/sc/source/core/data/cell2.cxx
@@ -135,39 +135,22 @@ void ScEditCell::UpdateFields(SCTAB nTab)
aUpdater.updateTableFields(nTab);
}
-void ScEditCell::SetTextObject( const EditTextObject* pObject,
- const SfxItemPool* pFromPool )
+void ScEditCell::SetTextObject(
+ const EditTextObject* pObject, const SfxItemPool* pFromPool )
{
- if ( pObject )
+ if (!pObject)
{
- if ( pFromPool && mpDoc->GetEditPool() == pFromPool )
- mpData = pObject->Clone();
- else
- { //! another "spool"
- // Sadly there is no other way to change the Pool than to
- // "spool" the Object through a corresponding Engine
- EditEngine& rEngine = mpDoc->GetEditEngine();
- if ( pObject->HasOnlineSpellErrors() )
- {
- sal_uLong nControl = rEngine.GetControlWord();
- const sal_uLong nSpellControl = EE_CNTRL_ONLINESPELLING | EE_CNTRL_ALLOWBIGOBJS;
- bool bNewControl = ( (nControl & nSpellControl) != nSpellControl );
- if ( bNewControl )
- rEngine.SetControlWord( nControl | nSpellControl );
- rEngine.SetText( *pObject );
- mpData = rEngine.CreateTextObject();
- if ( bNewControl )
- rEngine.SetControlWord( nControl );
- }
- else
- {
- rEngine.SetText( *pObject );
- mpData = rEngine.CreateTextObject();
- }
- }
- }
- else
mpData = NULL;
+ return;
+ }
+
+ if ( pFromPool && mpDoc->GetEditPool() == pFromPool )
+ {
+ mpData = pObject->Clone();
+ return;
+ }
+
+ mpData = ScEditUtil::Clone(*pObject, *mpDoc);
}
ScEditDataArray::ScEditDataArray()
diff --git a/sc/source/core/data/cellclonehandler.cxx b/sc/source/core/data/cellclonehandler.cxx
new file mode 100644
index 0000000..1f1d75c
--- /dev/null
+++ b/sc/source/core/data/cellclonehandler.cxx
@@ -0,0 +1,89 @@
+/* -*- 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/.
+ */
+
+#include "cellclonehandler.hxx"
+#include "editutil.hxx"
+#include "document.hxx"
+
+namespace sc {
+
+CellBlockCloneHandler::CellBlockCloneHandler(
+ ScDocument& rSrcDoc, ScDocument& rDestDoc, CellStoreType& rDestCellStore) :
+ mrSrcDoc(rSrcDoc), mrDestDoc(rDestDoc), mrDestCellStore(rDestCellStore) {}
+
+CellBlockCloneHandler::~CellBlockCloneHandler() {}
+
+ScDocument& CellBlockCloneHandler::getSrcDoc()
+{
+ return mrSrcDoc;
+}
+
+ScDocument& CellBlockCloneHandler::getDestDoc()
+{
+ return mrDestDoc;
+}
+
+const ScDocument& CellBlockCloneHandler::getDestDoc() const
+{
+ return mrDestDoc;
+}
+
+CellStoreType& CellBlockCloneHandler::getDestCellStore()
+{
+ return mrDestCellStore;
+}
+
+void CellBlockCloneHandler::cloneDoubleBlock(
+ CellStoreType::iterator& itPos, const ScAddress& /*rSrcPos*/, const ScAddress& rDestPos,
+ const numeric_block::const_iterator& itBegin, const numeric_block::const_iterator& itEnd)
+{
+ itPos = mrDestCellStore.set(itPos, rDestPos.Row(), itBegin, itEnd);
+}
+
+void CellBlockCloneHandler::cloneStringBlock(
+ CellStoreType::iterator& itPos, const ScAddress& /*rSrcPos*/, const ScAddress& rDestPos,
+ const string_block::const_iterator& itBegin, const string_block::const_iterator& itEnd)
+{
+ itPos = mrDestCellStore.set(itPos, rDestPos.Row(), itBegin, itEnd);
+}
+
+void CellBlockCloneHandler::cloneEditTextBlock(
+ CellStoreType::iterator& itPos, const ScAddress& /*rSrcPos*/, const ScAddress& rDestPos,
+ const edittext_block::const_iterator& itBegin, const edittext_block::const_iterator& itEnd)
+{
+ std::vector<EditTextObject*> aCloned;
+ aCloned.reserve(std::distance(itBegin, itEnd));
+ for (edittext_block::const_iterator it = itBegin; it != itEnd; ++it)
+ aCloned.push_back(ScEditUtil::Clone(**it, getDestDoc()));
+
+ itPos = getDestCellStore().set(itPos, rDestPos.Row(), aCloned.begin(), aCloned.end());
+}
+
+void CellBlockCloneHandler::cloneFormulaBlock(
+ CellStoreType::iterator& itPos, const ScAddress& /*rSrcPos*/, const ScAddress& rDestPos,
+ const formula_block::const_iterator& itBegin, const formula_block::const_iterator& itEnd)
+{
+ std::vector<ScFormulaCell*> aCloned;
+ aCloned.reserve(std::distance(itBegin, itEnd));
+ ScAddress aDestPos = rDestPos;
+ for (formula_block::const_iterator it = itBegin; it != itEnd; ++it, aDestPos.IncRow())
+ {
+ const ScFormulaCell& rOld = **it;
+ if (rOld.GetDirty() && getSrcDoc().GetAutoCalc())
+ const_cast<ScFormulaCell&>(rOld).Interpret();
+
+ aCloned.push_back(new ScFormulaCell(rOld, getDestDoc(), aDestPos));
+ }
+
+ itPos = getDestCellStore().set(itPos, rDestPos.Row(), aCloned.begin(), aCloned.end());
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/data/cellvalue.cxx b/sc/source/core/data/cellvalue.cxx
index 75362ba..169d2f7 100644
--- a/sc/source/core/data/cellvalue.cxx
+++ b/sc/source/core/data/cellvalue.cxx
@@ -9,6 +9,7 @@
#include "cellvalue.hxx"
#include "document.hxx"
+#include "column.hxx"
#include "cell.hxx"
#include "formulacell.hxx"
#include "editeng/editobj.hxx"
@@ -182,6 +183,41 @@ void ScCellValue::clear()
mfValue = 0.0;
}
+void ScCellValue::set( double fValue )
+{
+ clear();
+ meType = CELLTYPE_VALUE;
+ mfValue = fValue;
+}
+
+void ScCellValue::set( const OUString& rStr )
+{
+ clear();
+ meType = CELLTYPE_STRING;
+ mpString = new OUString(rStr);
+}
+
+void ScCellValue::set( const EditTextObject& rEditText )
+{
+ clear();
+ meType = CELLTYPE_EDIT;
+ mpEditText = rEditText.Clone();
+}
+
+void ScCellValue::set( const ScFormulaCell& rFormula )
+{
+ clear();
+ meType = CELLTYPE_FORMULA;
+ mpFormula = rFormula.Clone();
+}
+
+void ScCellValue::set( ScFormulaCell* pFormula )
+{
+ clear();
+ meType = CELLTYPE_FORMULA;
+ mpFormula = pFormula;
+}
+
void ScCellValue::assign( const ScDocument& rDoc, const ScAddress& rPos )
{
clear();
@@ -255,85 +291,87 @@ void ScCellValue::assign( const ScCellValue& rOther, ScDocument& rDestDoc, int n
}
}
-void ScCellValue::assign( const ScBaseCell& rCell )
+void ScCellValue::commit( ScDocument& rDoc, const ScAddress& rPos ) const
{
- clear();
-
- meType = rCell.GetCellType();
switch (meType)
{
case CELLTYPE_STRING:
- mpString = new OUString(static_cast<const ScStringCell&>(rCell).GetString());
- break;
- case CELLTYPE_EDIT:
{
- const EditTextObject* p = static_cast<const ScEditCell&>(rCell).GetData();
- if (p)
- mpEditText = p->Clone();
+ ScSetStringParam aParam;
+ aParam.setTextInput();
+ rDoc.SetString(rPos, *mpString, &aParam);
}
break;
+ case CELLTYPE_EDIT:
+ rDoc.SetEditText(rPos, mpEditText->Clone());
+ break;
case CELLTYPE_VALUE:
- mfValue = static_cast<const ScValueCell&>(rCell).GetValue();
+ rDoc.SetValue(rPos, mfValue);
break;
case CELLTYPE_FORMULA:
- mpFormula = static_cast<const ScFormulaCell&>(rCell).Clone();
+ rDoc.SetFormulaCell(rPos, mpFormula->Clone());
break;
default:
- meType = CELLTYPE_NONE; // reset to empty.
+ rDoc.SetEmptyCell(rPos);
}
}
-void ScCellValue::commit( ScDocument& rDoc, const ScAddress& rPos ) const
+void ScCellValue::release( ScDocument& rDoc, const ScAddress& rPos )
{
switch (meType)
{
case CELLTYPE_STRING:
{
+ // Currently, string cannot be placed without copying.
ScSetStringParam aParam;
aParam.setTextInput();
rDoc.SetString(rPos, *mpString, &aParam);
+ delete mpString;
}
break;
case CELLTYPE_EDIT:
- rDoc.SetEditText(rPos, mpEditText->Clone());
+ // Cell takes the ownership of the text object.
+ rDoc.SetEditText(rPos, mpEditText);
break;
case CELLTYPE_VALUE:
rDoc.SetValue(rPos, mfValue);
break;
case CELLTYPE_FORMULA:
- rDoc.SetFormulaCell(rPos, mpFormula->Clone());
+ // This formula cell instance is directly placed in the document without copying.
+ rDoc.SetFormulaCell(rPos, mpFormula);
break;
default:
rDoc.SetEmptyCell(rPos);
}
+
+ meType = CELLTYPE_NONE;
+ mfValue = 0.0;
}
-void ScCellValue::release( ScDocument& rDoc, const ScAddress& rPos )
+void ScCellValue::release( ScColumn& rColumn, SCROW nRow )
{
switch (meType)
{
case CELLTYPE_STRING:
{
// Currently, string cannot be placed without copying.
- ScSetStringParam aParam;
- aParam.setTextInput();
- rDoc.SetString(rPos, *mpString, &aParam);
+ rColumn.SetRawString(nRow, *mpString);
delete mpString;
}
break;
case CELLTYPE_EDIT:
// Cell takes the ownership of the text object.
- rDoc.SetEditText(rPos, mpEditText);
+ rColumn.SetEditText(nRow, mpEditText);
break;
case CELLTYPE_VALUE:
- rDoc.SetValue(rPos, mfValue);
+ rColumn.SetValue(nRow, mfValue);
break;
case CELLTYPE_FORMULA:
// This formula cell instance is directly placed in the document without copying.
- rDoc.SetFormulaCell(rPos, mpFormula);
+ rColumn.SetFormulaCell(nRow, mpFormula);
break;
default:
- rDoc.SetEmptyCell(rPos);
+ rColumn.Delete(nRow);
}
meType = CELLTYPE_NONE;
@@ -403,52 +441,81 @@ void ScRefCellValue::assign( ScDocument& rDoc, const ScAddress& rPos )
*this = rDoc.GetRefCellValue(rPos);
}
-void ScRefCellValue::assign( ScBaseCell& rCell )
+void ScRefCellValue::assign( const sc::CellStoreType::const_iterator& itPos, size_t nOffset )
{
- clear();
+ switch (itPos->type)
+ {
+ case sc::element_type_numeric:
+ // Numeric cell
+ mfValue = sc::numeric_block::at(*itPos->data, nOffset);
+ meType = CELLTYPE_VALUE;
+ break;
+ case sc::element_type_string:
+ // String cell
... etc. - the rest is truncated
More information about the Libreoffice-commits
mailing list