summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKohei Yoshida <kohei.yoshida@collabora.com>2014-04-07 14:13:20 -0400
committerKohei Yoshida <kohei.yoshida@collabora.com>2014-04-07 14:43:16 -0400
commit355baf573425165cbc1c789a6271eb29940e1f76 (patch)
tree42050f8ac0a293b75e3745d511fe2e086e88cd42
parent137c288978fb8f4aee259fabfdcb9252b1b011d3 (diff)
fdo#75741: Re-implement CompileNameFormula for formula groups.
Change-Id: I57e1e464ac5f7abc10ce5ea5752e036ddb6cf6d7
-rw-r--r--formula/source/core/api/token.cxx13
-rw-r--r--include/formula/tokenarray.hxx12
-rw-r--r--sc/inc/column.hxx11
-rw-r--r--sc/inc/document.hxx11
-rw-r--r--sc/inc/formulacell.hxx8
-rw-r--r--sc/inc/formulagroup.hxx18
-rw-r--r--sc/inc/table.hxx4
-rw-r--r--sc/source/core/data/column.cxx44
-rw-r--r--sc/source/core/data/column2.cxx21
-rw-r--r--sc/source/core/data/column4.cxx151
-rw-r--r--sc/source/core/data/documen4.cxx11
-rw-r--r--sc/source/core/data/document10.cxx20
-rw-r--r--sc/source/core/data/formulacell.cxx76
-rw-r--r--sc/source/core/data/table4.cxx6
-rw-r--r--sc/source/core/data/table7.cxx12
-rw-r--r--sc/source/core/tool/formulagroup.cxx6
-rw-r--r--sc/source/filter/oox/workbookhelper.cxx4
-rw-r--r--sc/source/ui/docshell/docfunc.cxx11
-rw-r--r--sc/source/ui/undo/undocell.cxx4
-rw-r--r--sc/source/ui/undo/undorangename.cxx6
-rw-r--r--sc/source/ui/unoobj/nameuno.cxx4
-rw-r--r--sc/source/ui/view/viewfunc.cxx5
22 files changed, 321 insertions, 137 deletions
diff --git a/formula/source/core/api/token.cxx b/formula/source/core/api/token.cxx
index 4f8b8aa60eb3..da98d0e5da4d 100644
--- a/formula/source/core/api/token.cxx
+++ b/formula/source/core/api/token.cxx
@@ -616,6 +616,19 @@ bool FormulaTokenArray::HasNameOrColRowName() const
return false;
}
+bool FormulaTokenArray::HasOpCodes( const boost::unordered_set<OpCode>& rOpCodes ) const
+{
+ FormulaToken** p = pCode;
+ FormulaToken** pEnd = p + static_cast<size_t>(nLen);
+ for (; p != pEnd; ++p)
+ {
+ OpCode eOp = (*p)->GetOpCode();
+ if (rOpCodes.count(eOp) > 0)
+ return true;
+ }
+
+ return false;
+}
FormulaTokenArray::FormulaTokenArray() :
pCode(NULL),
diff --git a/include/formula/tokenarray.hxx b/include/formula/tokenarray.hxx
index e5d0282d3603..7370e43e373a 100644
--- a/include/formula/tokenarray.hxx
+++ b/include/formula/tokenarray.hxx
@@ -25,6 +25,8 @@
#include <formula/ExternalReferenceHelper.hxx>
#include <limits.h>
+#include <boost/unordered_set.hpp>
+
namespace formula
{
@@ -123,6 +125,16 @@ public:
/// Token of type svIndex or opcode ocColRowName
bool HasNameOrColRowName() const;
+ /**
+ * Check if the token array contains any of specified opcode tokens.
+ *
+ * @param rOpCodes collection of opcodes to check against.
+ *
+ * @return true if the token array contains at least one of the specified
+ * opcode tokens, false otherwise.
+ */
+ bool HasOpCodes( const boost::unordered_set<OpCode>& rOpCodes ) const;
+
FormulaToken** GetArray() const { return pCode; }
FormulaToken** GetCode() const { return pRPN; }
sal_uInt16 GetLen() const { return nLen; }
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index a84f83612b47..42f27796c476 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -40,6 +40,7 @@ namespace formula { struct VectorRefArray; }
namespace sc {
struct FormulaGroupContext;
+struct FormulaGroupEntry;
class StartListeningContext;
class EndListeningContext;
class CopyFromClipContext;
@@ -371,6 +372,9 @@ public:
void SetTabNo(SCTAB nNewTab);
void FindRangeNamesInUse(SCROW nRow1, SCROW nRow2, std::set<sal_uInt16>& rIndexes) const;
+ void PreprocessRangeNameUpdate();
+ void PostprocessRangeNameUpdate();
+
const SfxPoolItem* GetAttr( SCROW nRow, sal_uInt16 nWhich ) const;
const ScPatternAttr* GetPattern( SCROW nRow ) const;
const ScPatternAttr* GetMostUsedPattern( SCROW nStartRow, SCROW nEndRow ) const;
@@ -470,7 +474,6 @@ public:
void CompileDBFormula( sc::CompileFormulaContext& rCxt );
void CompileDBFormula( sc::CompileFormulaContext& rCxt, bool bCreateFormulaString );
- void CompileNameFormula( sc::CompileFormulaContext& rCxt, bool bCreateFormulaString );
void CompileColRowNameFormula( sc::CompileFormulaContext& rCxt );
sal_Int32 GetMaxStringLen( SCROW nRowStart, SCROW nRowEnd, rtl_TextEncoding eCharSet ) const;
@@ -599,6 +602,12 @@ private:
void DeleteCells(
sc::ColumnBlockPosition& rBlockPos, SCROW nRow1, SCROW nRow2, sal_uInt16 nDelFlag,
std::vector<SCROW>& rDeleted );
+
+ /**
+ * Get all non-grouped formula cells and formula cell groups in the whole
+ * column.
+ */
+ std::vector<sc::FormulaGroupEntry> GetFormulaGroupEntries();
};
#endif
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index 5b8579b57492..6fe5f9f128bf 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -516,6 +516,16 @@ public:
void SetRangeName( ScRangeName* pNewRangeName );
/**
+ * Call this immediately before updating all named ranges.
+ */
+ SC_DLLPUBLIC void PreprocessRangeNameUpdate();
+
+ /**
+ * Call this immediately after all named ranges have been updated.
+ */
+ SC_DLLPUBLIC void PostprocessRangeNameUpdate();
+
+ /**
* Insert a new named expression to the global scope.
*
* @param rName name for the expression.
@@ -1967,7 +1977,6 @@ public:
void CompileDBFormula();
void CompileDBFormula( bool bCreateFormulaString );
- SC_DLLPUBLIC void CompileNameFormula( bool bCreateFormulaString );
void CompileColRowNameFormula();
/** Maximum string length of a column, e.g. for dBase export.
diff --git a/sc/inc/formulacell.hxx b/sc/inc/formulacell.hxx
index 15b5adbac7c8..57f249de65f7 100644
--- a/sc/inc/formulacell.hxx
+++ b/sc/inc/formulacell.hxx
@@ -76,6 +76,7 @@ struct SC_DLLPUBLIC ScFormulaCellGroup : boost::noncopyable
void scheduleCompilation();
void setCode( const ScTokenArray& rCode );
+ void setCode( ScTokenArray* pCode );
void compileCode(
ScDocument& rDoc, const ScAddress& rPos, formula::FormulaGrammar::Grammar eGram );
void compileOpenCLKernel();
@@ -303,11 +304,12 @@ public:
ScTokenArray* GetCode();
const ScTokenArray* GetCode() const;
+ void SetCode( ScTokenArray* pNew );
+
bool IsRunning() const;
void SetRunning( bool bVal );
void CompileDBFormula( sc::CompileFormulaContext& rCxt );
void CompileDBFormula( sc::CompileFormulaContext& rCxt, bool bCreateFormulaString );
- void CompileNameFormula( sc::CompileFormulaContext& rCxt, bool bCreateFormulaString );
void CompileColRowNameFormula( sc::CompileFormulaContext& rCxt );
ScFormulaCell* GetPrevious() const;
ScFormulaCell* GetNext() const;
@@ -344,6 +346,8 @@ public:
void SetHybridFormula(
const OUString& r, const formula::FormulaGrammar::Grammar eGrammar );
+ OUString GetHybridFormula() const;
+
void SetResultMatrix( SCCOL nCols, SCROW nRows, const ScConstMatrixRef& pMat, formula::FormulaToken* pUL );
/** For import only: set a double result.
@@ -393,6 +397,8 @@ public:
ScTokenArray* GetSharedCode();
const ScTokenArray* GetSharedCode() const;
+ void SyncSharedCode();
+
bool IsPostponedDirty() const;
};
diff --git a/sc/inc/formulagroup.hxx b/sc/inc/formulagroup.hxx
index 4cca9c88a739..311653a31fbd 100644
--- a/sc/inc/formulagroup.hxx
+++ b/sc/inc/formulagroup.hxx
@@ -24,9 +24,27 @@
class ScDocument;
class ScTokenArray;
+class ScFormulaCell;
namespace sc {
+struct FormulaGroupEntry
+{
+ union
+ {
+ ScFormulaCell* mpCell; // non-shared formula cell
+ ScFormulaCell** mpCells; // pointer to the top formula cell in a shared group.
+ };
+
+ size_t mnRow;
+ size_t mnLength;
+ bool mbShared;
+
+ FormulaGroupEntry( ScFormulaCell** pCells, size_t nRow, size_t nLength );
+
+ FormulaGroupEntry( ScFormulaCell* pCell, size_t nRow );
+};
+
struct FormulaGroupContext : boost::noncopyable
{
typedef AlignedAllocator<double,256> DoubleAllocType;
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index 59a8f58d8b28..b325c802ebec 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -847,6 +847,9 @@ public:
void SetRangeName(ScRangeName* pNew);
ScRangeName* GetRangeName() const;
+ void PreprocessRangeNameUpdate();
+ void PostprocessRangeNameUpdate();
+
ScConditionalFormatList* GetCondFormList();
const ScConditionalFormatList* GetCondFormList() const;
void SetCondFormList( ScConditionalFormatList* pList );
@@ -1025,7 +1028,6 @@ private:
bool TestTabRefAbs(SCTAB nTable) const;
void CompileDBFormula( sc::CompileFormulaContext& rCxt );
void CompileDBFormula( sc::CompileFormulaContext& rCxt, bool bCreateFormulaString );
- void CompileNameFormula( sc::CompileFormulaContext& rCxt, bool bCreateFormulaString );
void CompileColRowNameFormula( sc::CompileFormulaContext& rCxt );
void StartListening( const ScAddress& rAddress, SvtListener* pListener );
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index f48a961e831a..2d2c44e5e5ce 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -44,6 +44,7 @@
#include <listenercontext.hxx>
#include <refhint.hxx>
#include <stlalgorithm.hxx>
+#include <formulagroup.hxx>
#include <svl/poolcach.hxx>
#include <svl/zforlist.hxx>
@@ -2339,23 +2340,6 @@ void ScColumn::MarkSubTotalCells( sc::ColumnSpanSet& rSet, SCROW nRow1, SCROW nR
namespace {
-struct FormulaGroup
-{
- struct {
- ScFormulaCell* mpCell; // non-shared formula cell
- ScFormulaCell** mpCells; // pointer to the top formula cell in a shared group.
- };
- size_t mnRow;
- size_t mnLength;
- bool mbShared;
-
- FormulaGroup( ScFormulaCell** pCells, size_t nRow, size_t nLength ) :
- mpCells(pCells), mnRow(nRow), mnLength(nLength), mbShared(true) {}
-
- FormulaGroup( ScFormulaCell* pCell, size_t nRow ) :
- mpCell(pCell), mnRow(nRow), mnLength(0), mbShared(false) {}
-};
-
class SharedTopFormulaCellPicker : std::unary_function<sc::CellStoreType::value_type, void>
{
public:
@@ -2430,7 +2414,7 @@ public:
}
};
-class UpdateRefOnNonCopy : std::unary_function<FormulaGroup, void>
+class UpdateRefOnNonCopy : std::unary_function<sc::FormulaGroupEntry, void>
{
SCCOL mnCol;
SCROW mnTab;
@@ -2438,7 +2422,7 @@ class UpdateRefOnNonCopy : std::unary_function<FormulaGroup, void>
ScDocument* mpUndoDoc;
bool mbUpdated;
- void updateRefOnShift( FormulaGroup& rGroup )
+ void updateRefOnShift( sc::FormulaGroupEntry& rGroup )
{
if (!rGroup.mbShared)
{
@@ -2500,7 +2484,7 @@ class UpdateRefOnNonCopy : std::unary_function<FormulaGroup, void>
}
}
- void updateRefOnMove( FormulaGroup& rGroup )
+ void updateRefOnMove( sc::FormulaGroupEntry& rGroup )
{
if (!rGroup.mbShared)
{
@@ -2611,7 +2595,7 @@ public:
mnCol(nCol), mnTab(nTab), mpCxt(pCxt),
mpUndoDoc(pUndoDoc), mbUpdated(false) {}
- void operator() ( FormulaGroup& rGroup )
+ void operator() ( sc::FormulaGroupEntry& rGroup )
{
switch (mpCxt->meMode)
{
@@ -2669,21 +2653,21 @@ public:
class FormulaGroupPicker : public SharedTopFormulaCellPicker
{
- std::vector<FormulaGroup>& mrGroups;
+ std::vector<sc::FormulaGroupEntry>& mrGroups;
public:
- FormulaGroupPicker( std::vector<FormulaGroup>& rGroups ) : mrGroups(rGroups) {}
+ FormulaGroupPicker( std::vector<sc::FormulaGroupEntry>& rGroups ) : mrGroups(rGroups) {}
virtual ~FormulaGroupPicker() {}
virtual void processNonShared( ScFormulaCell* pCell, size_t nRow ) SAL_OVERRIDE
{
- mrGroups.push_back(FormulaGroup(pCell, nRow));
+ mrGroups.push_back(sc::FormulaGroupEntry(pCell, nRow));
}
virtual void processSharedTop( ScFormulaCell** ppCells, size_t nRow, size_t nLength ) SAL_OVERRIDE
{
- mrGroups.push_back(FormulaGroup(ppCells, nRow, nLength));
+ mrGroups.push_back(sc::FormulaGroupEntry(ppCells, nRow, nLength));
}
};
@@ -2756,8 +2740,7 @@ bool ScColumn::UpdateReference( sc::RefUpdateContext& rCxt, ScDocument* pUndoDoc
sc::SharedFormulaUtil::splitFormulaCellGroups(maCells, aBounds);
// Collect all formula groups.
- std::vector<FormulaGroup> aGroups;
- std::for_each(maCells.begin(), maCells.end(), FormulaGroupPicker(aGroups));
+ std::vector<sc::FormulaGroupEntry> aGroups = GetFormulaGroupEntries();
// Process all collected formula groups.
UpdateRefOnNonCopy aHandler(nCol, nTab, &rCxt, pUndoDoc);
@@ -2768,6 +2751,13 @@ bool ScColumn::UpdateReference( sc::RefUpdateContext& rCxt, ScDocument* pUndoDoc
return aHandler.isUpdated();
}
+std::vector<sc::FormulaGroupEntry> ScColumn::GetFormulaGroupEntries()
+{
+ std::vector<sc::FormulaGroupEntry> aGroups;
+ std::for_each(maCells.begin(), maCells.end(), FormulaGroupPicker(aGroups));
+ return aGroups;
+}
+
namespace {
class UpdateTransHandler
diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx
index a5d982f9eedb..aea1277b29a3 100644
--- a/sc/source/core/data/column2.cxx
+++ b/sc/source/core/data/column2.cxx
@@ -3009,21 +3009,6 @@ public:
}
};
-class CompileNameFormulaHandler
-{
- sc::CompileFormulaContext& mrCxt;
- bool mbCreateFormulaString;
-
-public:
- CompileNameFormulaHandler( sc::CompileFormulaContext& rCxt, bool bCreateFormulaString) :
- mrCxt(rCxt), mbCreateFormulaString(bCreateFormulaString) {}
-
- void operator() (size_t, ScFormulaCell* p)
- {
- p->CompileNameFormula(mrCxt, mbCreateFormulaString);
- }
-};
-
struct CompileColRowNameFormulaHandler
{
sc::CompileFormulaContext& mrCxt;
@@ -3052,12 +3037,6 @@ void ScColumn::CompileDBFormula( sc::CompileFormulaContext& rCxt, bool bCreateFo
RegroupFormulaCells();
}
-void ScColumn::CompileNameFormula( sc::CompileFormulaContext& rCxt, bool bCreateFormulaString )
-{
- CompileNameFormulaHandler aFunc(rCxt, bCreateFormulaString);
- sc::ProcessFormula(maCells, aFunc);
-}
-
void ScColumn::CompileColRowNameFormula( sc::CompileFormulaContext& rCxt )
{
CompileColRowNameFormulaHandler aFunc(rCxt);
diff --git a/sc/source/core/data/column4.cxx b/sc/source/core/data/column4.cxx
index 2f216233e800..7a360d09a673 100644
--- a/sc/source/core/data/column4.cxx
+++ b/sc/source/core/data/column4.cxx
@@ -16,18 +16,23 @@
#include <cellvalues.hxx>
#include <columnspanset.hxx>
#include <listenercontext.hxx>
+#include <tokenstringcontext.hxx>
#include <mtvcellfunc.hxx>
#include <clipcontext.hxx>
#include <attrib.hxx>
#include <patattr.hxx>
#include <docpool.hxx>
#include <conditio.hxx>
+#include <formulagroup.hxx>
+#include <tokenarray.hxx>
#include <svl/sharedstringpool.hxx>
#include <vector>
#include <cassert>
+#include <boost/shared_ptr.hpp>
+
bool ScColumn::IsMerged( SCROW nRow ) const
{
return pAttrArray->IsMerged(nRow);
@@ -544,4 +549,150 @@ void ScColumn::GetNotesInRange(SCROW nStartRow, SCROW nEndRow,
std::for_each(it, itEnd, NoteEntryCollector(rNotes, nTab, nCol, nStartRow, nEndRow));
}
+namespace {
+
+class PreRangeNameUpdateHandler
+{
+ ScDocument* mpDoc;
+ boost::shared_ptr<sc::EndListeningContext> mpEndListenCxt;
+ boost::shared_ptr<sc::CompileFormulaContext> mpCompileFormulaCxt;
+
+public:
+ PreRangeNameUpdateHandler( ScDocument* pDoc ) :
+ mpDoc(pDoc),
+ mpEndListenCxt(new sc::EndListeningContext(*pDoc)),
+ mpCompileFormulaCxt(new sc::CompileFormulaContext(pDoc)) {}
+
+ void operator() ( sc::FormulaGroupEntry& rEntry )
+ {
+ // Perform end listening, remove from formula tree, and set them up
+ // for re-compilation.
+
+ ScFormulaCell* pTop = NULL;
+
+ if (rEntry.mbShared)
+ {
+ // Only inspect the code from the top cell.
+ pTop = *rEntry.mpCells;
+ }
+ else
+ pTop = rEntry.mpCell;
+
+ ScTokenArray* pCode = pTop->GetCode();
+
+ boost::unordered_set<OpCode> aOps;
+ aOps.insert(ocBad);
+ aOps.insert(ocColRowName);
+ aOps.insert(ocName);
+ bool bRecompile = pCode->HasOpCodes(aOps);
+
+ if (bRecompile)
+ {
+ // Get the formula string.
+ OUString aFormula = pTop->GetFormula(*mpCompileFormulaCxt);
+ sal_Int32 n = aFormula.getLength();
+ if (pTop->GetMatrixFlag() != MM_NONE && n > 0)
+ {
+ if (aFormula[0] == '{' && aFormula[n-1] == '}')
+ aFormula = aFormula.copy(1, n-2);
+ }
+
+ if (rEntry.mbShared)
+ {
+ ScFormulaCell** pp = rEntry.mpCells;
+ ScFormulaCell** ppEnd = pp + rEntry.mnLength;
+ for (; pp != ppEnd; ++pp)
+ {
+ ScFormulaCell* p = *pp;
+ p->EndListeningTo(*mpEndListenCxt);
+ mpDoc->RemoveFromFormulaTree(p);
+ }
+ }
+ else
+ {
+ rEntry.mpCell->EndListeningTo(*mpEndListenCxt);
+ mpDoc->RemoveFromFormulaTree(rEntry.mpCell);
+ }
+
+ pCode->Clear();
+ pTop->SetHybridFormula(aFormula, mpDoc->GetGrammar());
+ }
+ }
+};
+
+class PostRangeNameUpdateHandler
+{
+ ScDocument* mpDoc;
+ boost::shared_ptr<sc::CompileFormulaContext> mpCompileFormulaCxt;
+
+public:
+ PostRangeNameUpdateHandler( ScDocument* pDoc ) :
+ mpDoc(pDoc),
+ mpCompileFormulaCxt(new sc::CompileFormulaContext(pDoc)) {}
+
+ void operator() ( sc::FormulaGroupEntry& rEntry )
+ {
+ if (rEntry.mbShared)
+ {
+ ScFormulaCell* pTop = *rEntry.mpCells;
+ OUString aFormula = pTop->GetHybridFormula();
+
+ // Create a new token array from the hybrid formula string, and
+ // set it to the group.
+ ScCompiler aComp(*mpCompileFormulaCxt, pTop->aPos);
+ ScTokenArray* pNewCode = aComp.CompileString(aFormula);
+ ScFormulaCellGroupRef xGroup = pTop->GetCellGroup();
+ assert(xGroup);
+ xGroup->setCode(pNewCode);
+ xGroup->compileCode(*mpDoc, pTop->aPos, mpDoc->GetGrammar());
+
+ // Propagate the new token array to all formula cells in the group.
+ ScFormulaCell** pp = rEntry.mpCells;
+ ScFormulaCell** ppEnd = pp + rEntry.mnLength;
+ for (; pp != ppEnd; ++pp)
+ {
+ ScFormulaCell* p = *pp;
+ p->SyncSharedCode();
+ p->SetDirty();
+ }
+ }
+ else
+ {
+ ScFormulaCell* pCell = rEntry.mpCell;
+ OUString aFormula = pCell->GetHybridFormula();
+
+ // Create token array from formula string.
+ ScCompiler aComp(*mpCompileFormulaCxt, pCell->aPos);
+ ScTokenArray* pNewCode = aComp.CompileString(aFormula);
+
+ // Generate RPN tokens.
+ ScCompiler aComp2(mpDoc, pCell->aPos, *pNewCode);
+ aComp2.CompileTokenArray();
+
+ pCell->SetCode(pNewCode);
+ pCell->SetDirty();
+ }
+ }
+};
+
+}
+
+void ScColumn::PreprocessRangeNameUpdate()
+{
+ // Collect all formula groups.
+ std::vector<sc::FormulaGroupEntry> aGroups = GetFormulaGroupEntries();
+
+ PreRangeNameUpdateHandler aFunc(pDocument);
+ std::for_each(aGroups.begin(), aGroups.end(), aFunc);
+}
+
+void ScColumn::PostprocessRangeNameUpdate()
+{
+ // Collect all formula groups.
+ std::vector<sc::FormulaGroupEntry> aGroups = GetFormulaGroupEntries();
+
+ PostRangeNameUpdateHandler aFunc(pDocument);
+ std::for_each(aGroups.begin(), aGroups.end(), aFunc);
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/data/documen4.cxx b/sc/source/core/data/documen4.cxx
index 6e3cd333b685..7e378c1c7955 100644
--- a/sc/source/core/data/documen4.cxx
+++ b/sc/source/core/data/documen4.cxx
@@ -559,17 +559,6 @@ void ScDocument::CompileDBFormula( bool bCreateFormulaString )
}
}
-void ScDocument::CompileNameFormula( bool bCreateFormulaString )
-{
- sc::CompileFormulaContext aCxt(this);
- TableContainer::iterator it = maTabs.begin();
- for (;it != maTabs.end(); ++it)
- {
- if (*it)
- (*it)->CompileNameFormula(aCxt, bCreateFormulaString);
- }
-}
-
void ScDocument::CompileColRowNameFormula()
{
sc::CompileFormulaContext aCxt(this);
diff --git a/sc/source/core/data/document10.cxx b/sc/source/core/data/document10.cxx
index 5030128236f4..84410ab5486c 100644
--- a/sc/source/core/data/document10.cxx
+++ b/sc/source/core/data/document10.cxx
@@ -237,4 +237,24 @@ const ScCalcConfig& ScDocument::GetCalcConfig() const
return maCalcConfig;
}
+void ScDocument::PreprocessRangeNameUpdate()
+{
+ TableContainer::iterator it = maTabs.begin(), itEnd = maTabs.end();
+ for (; it != itEnd; ++it)
+ {
+ ScTable* p = *it;
+ p->PreprocessRangeNameUpdate();
+ }
+}
+
+void ScDocument::PostprocessRangeNameUpdate()
+{
+ TableContainer::iterator it = maTabs.begin(), itEnd = maTabs.end();
+ for (; it != itEnd; ++it)
+ {
+ ScTable* p = *it;
+ p->PostprocessRangeNameUpdate();
+ }
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx
index e7d566aaf85f..9a2106604ba1 100644
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -477,6 +477,14 @@ void ScFormulaCellGroup::setCode( const ScTokenArray& rCode )
mpCode->GenHash();
}
+void ScFormulaCellGroup::setCode( ScTokenArray* pCode )
+{
+ delete mpCode;
+ mpCode = pCode; // takes ownership of the token array.
+ mbInvariant = mpCode->IsInvariant();
+ mpCode->GenHash();
+}
+
void ScFormulaCellGroup::compileCode(
ScDocument& rDoc, const ScAddress& rPos, FormulaGrammar::Grammar eGram )
{
@@ -2107,6 +2115,11 @@ void ScFormulaCell::SetHybridFormula( const OUString& r,
aResult.SetHybridFormula( r); eTempGrammar = eGrammar;
}
+OUString ScFormulaCell::GetHybridFormula() const
+{
+ return aResult.GetHybridFormula();
+}
+
// Dynamically create the URLField on a mouse-over action on a hyperlink() cell.
void ScFormulaCell::GetURLResult( OUString& rURL, OUString& rCellText )
{
@@ -3372,6 +3385,13 @@ const ScTokenArray* ScFormulaCell::GetCode() const
return pCode;
}
+void ScFormulaCell::SetCode( ScTokenArray* pNew )
+{
+ assert(!mxGroup); // Don't call this if it's shared.
+ delete pCode;
+ pCode = pNew; // takes ownership.
+}
+
bool ScFormulaCell::IsRunning() const
{
return bRunning;
@@ -3448,53 +3468,6 @@ void ScFormulaCell::CompileDBFormula( sc::CompileFormulaContext& rCxt, bool bCre
}
}
-void ScFormulaCell::CompileNameFormula( sc::CompileFormulaContext& rCxt, bool bCreateFormulaString )
-{
- // Two phases must be called after each other
- // 1. Formula String with old generated names
- // 2. Formula String with new generated names
- if ( bCreateFormulaString )
- {
- bool bRecompile = false;
- pCode->Reset();
- for ( FormulaToken* p = pCode->First(); p && !bRecompile; p = pCode->Next() )
- {
- switch ( p->GetOpCode() )
- {
- case ocBad: // in case RangeName goes bad
- case ocColRowName: // in case the names are the same
- bRecompile = true;
- break;
- default:
- if ( p->GetType() == svIndex )
- bRecompile = true; // RangeName
- }
- }
- if ( bRecompile )
- {
- OUString aFormula = GetFormula(rCxt);
- if ( GetMatrixFlag() != MM_NONE && !aFormula.isEmpty() )
- {
- if ( aFormula[ aFormula.getLength()-1 ] == '}' )
- aFormula = aFormula.copy( 0, aFormula.getLength()-1 );
- if ( aFormula[0] == '{' )
- aFormula = aFormula.copy( 1 );
- }
- EndListeningTo( pDocument );
- pDocument->RemoveFromFormulaTree( this );
- pCode->Clear();
- SetHybridFormula(aFormula, rCxt.getGrammar());
- }
- }
- else if ( !pCode->GetLen() && !aResult.GetHybridFormula().isEmpty() )
- {
- rCxt.setGrammar(eTempGrammar);
- Compile(rCxt, aResult.GetHybridFormula(), false);
- aResult.SetToken( NULL);
- SetDirty();
- }
-}
-
void ScFormulaCell::CompileColRowNameFormula( sc::CompileFormulaContext& rCxt )
{
pCode->Reset();
@@ -4053,6 +4026,15 @@ const ScTokenArray* ScFormulaCell::GetSharedCode() const
return mxGroup ? mxGroup->mpCode : NULL;
}
+void ScFormulaCell::SyncSharedCode()
+{
+ if (!mxGroup)
+ // Not a shared formula cell.
+ return;
+
+ pCode = mxGroup->mpCode;
+}
+
bool ScFormulaCell::IsPostponedDirty() const
{
return mbPostponedDirty;
diff --git a/sc/source/core/data/table4.cxx b/sc/source/core/data/table4.cxx
index f24889ed5521..96acd2c2f5ca 100644
--- a/sc/source/core/data/table4.cxx
+++ b/sc/source/core/data/table4.cxx
@@ -2184,12 +2184,6 @@ void ScTable::CompileDBFormula( sc::CompileFormulaContext& rCxt, bool bCreateFor
aCol[i].CompileDBFormula(rCxt, bCreateFormulaString);
}
-void ScTable::CompileNameFormula( sc::CompileFormulaContext& rCxt, bool bCreateFormulaString )
-{
- for (SCCOL i = 0; i <= MAXCOL; ++i)
- aCol[i].CompileNameFormula(rCxt, bCreateFormulaString);
-}
-
void ScTable::CompileColRowNameFormula( sc::CompileFormulaContext& rCxt )
{
for (SCCOL i = 0; i <= MAXCOL; ++i)
diff --git a/sc/source/core/data/table7.cxx b/sc/source/core/data/table7.cxx
index a5936cbeeef9..9406326e4699 100644
--- a/sc/source/core/data/table7.cxx
+++ b/sc/source/core/data/table7.cxx
@@ -80,4 +80,16 @@ void ScTable::CopyCellValuesFrom( SCCOL nCol, SCROW nRow, const sc::CellValues&
aCol[nCol].CopyCellValuesFrom(nRow, rSrc);
}
+void ScTable::PreprocessRangeNameUpdate()
+{
+ for (SCCOL i = 0; i <= MAXCOL; ++i)
+ aCol[i].PreprocessRangeNameUpdate();
+}
+
+void ScTable::PostprocessRangeNameUpdate()
+{
+ for (SCCOL i = 0; i <= MAXCOL; ++i)
+ aCol[i].PostprocessRangeNameUpdate();
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/tool/formulagroup.cxx b/sc/source/core/tool/formulagroup.cxx
index e0a580c9150c..289563aaa333 100644
--- a/sc/source/core/tool/formulagroup.cxx
+++ b/sc/source/core/tool/formulagroup.cxx
@@ -43,6 +43,12 @@ extern "C" void getOpenCLDeviceInfo(size_t*, size_t*);
namespace sc {
+FormulaGroupEntry::FormulaGroupEntry( ScFormulaCell** pCells, size_t nRow, size_t nLength ) :
+ mpCells(pCells), mnRow(nRow), mnLength(nLength), mbShared(true) {}
+
+FormulaGroupEntry::FormulaGroupEntry( ScFormulaCell* pCell, size_t nRow ) :
+ mpCell(pCell), mnRow(nRow), mnLength(0), mbShared(false) {}
+
size_t FormulaGroupContext::ColKey::Hash::operator ()( const FormulaGroupContext::ColKey& rKey ) const
{
return rKey.mnTab * MAXCOLCOUNT + rKey.mnCol;
diff --git a/sc/source/filter/oox/workbookhelper.cxx b/sc/source/filter/oox/workbookhelper.cxx
index 9bb9f3ce3b8c..57e6b08efff4 100644
--- a/sc/source/filter/oox/workbookhelper.cxx
+++ b/sc/source/filter/oox/workbookhelper.cxx
@@ -593,8 +593,6 @@ void WorkbookGlobals::initialize( bool bWorkbookFile )
mpDoc->EnableAdjustHeight(true);
// disable automatic update of linked sheets and DDE links
mpDoc->EnableExecuteLink(false);
- // #i79890# disable automatic update of defined names
- mpDoc->CompileNameFormula(true);
mxProgressBar.reset( new SegmentProgressBar( mrBaseFilter.getStatusIndicator(), ScGlobal::GetRscString(STR_LOAD_DOC) ) );
mxFmlaParser.reset( new FormulaParser( *this ) );
@@ -629,8 +627,6 @@ void WorkbookGlobals::finalize()
{
// #i74668# do not insert default sheets
mpDocShell->SetEmpty(false);
- // #i79890# Compile named ranges before re-enabling row height adjustment. (no idea why).
- mpDoc->CompileNameFormula(false);
// enable automatic update of linked sheets and DDE links
mpDoc->EnableExecuteLink(true);
// #i79826# enable updating automatic row height after loading the document
diff --git a/sc/source/ui/docshell/docfunc.cxx b/sc/source/ui/docshell/docfunc.cxx
index 74c34673531f..5950a9ddd111 100644
--- a/sc/source/ui/docshell/docfunc.cxx
+++ b/sc/source/ui/docshell/docfunc.cxx
@@ -4846,13 +4846,13 @@ bool ScDocFunc::SetNewRangeNames( ScRangeName* pNewRanges, bool bModifyDoc, SCTA
bool bCompile = ( !pDoc->IsImportingXML() && pDoc->GetNamedRangesLockCount() == 0 );
if ( bCompile )
- pDoc->CompileNameFormula( true ); // CreateFormulaString
+ pDoc->PreprocessRangeNameUpdate();
if (nTab >= 0)
pDoc->SetRangeName( nTab, pNewRanges ); // takes ownership
else
pDoc->SetRangeName( pNewRanges ); // takes ownership
if ( bCompile )
- pDoc->CompileNameFormula( false ); // CompileFormulaString
+ pDoc->PostprocessRangeNameUpdate();
if (bModifyDoc)
{
@@ -4876,12 +4876,9 @@ void ScDocFunc::ModifyAllRangeNames( const boost::ptr_map<OUString, ScRangeName>
new ScUndoAllRangeNames(&rDocShell, aOldRangeMap, rRangeMap));
}
- pDoc->CompileNameFormula(true);
-
- // set all range names
+ pDoc->PreprocessRangeNameUpdate();
pDoc->SetAllRangeNames(rRangeMap);
-
- pDoc->CompileNameFormula(false);
+ pDoc->PostprocessRangeNameUpdate();
aModificator.SetDocumentModified();
SFX_APP()->Broadcast(SfxSimpleHint(SC_HINT_AREAS_CHANGED));
diff --git a/sc/source/ui/undo/undocell.cxx b/sc/source/ui/undo/undocell.cxx
index 60f659458396..f0e680310642 100644
--- a/sc/source/ui/undo/undocell.cxx
+++ b/sc/source/ui/undo/undocell.cxx
@@ -992,7 +992,7 @@ OUString ScUndoRangeNames::GetComment() const
void ScUndoRangeNames::DoChange( bool bUndo )
{
ScDocument* pDoc = pDocShell->GetDocument();
- pDoc->CompileNameFormula( true ); // CreateFormulaString
+ pDoc->PreprocessRangeNameUpdate();
if ( bUndo )
{
@@ -1009,7 +1009,7 @@ void ScUndoRangeNames::DoChange( bool bUndo )
pDoc->SetRangeName( new ScRangeName( *pNewRanges ) );
}
- pDoc->CompileNameFormula( false ); // CompileFormulaString
+ pDoc->PostprocessRangeNameUpdate();
SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREAS_CHANGED ) );
}
diff --git a/sc/source/ui/undo/undorangename.cxx b/sc/source/ui/undo/undorangename.cxx
index baf39b2f4914..172f802dcbd0 100644
--- a/sc/source/ui/undo/undorangename.cxx
+++ b/sc/source/ui/undo/undorangename.cxx
@@ -77,11 +77,9 @@ void ScUndoAllRangeNames::DoChange(const boost::ptr_map<OUString, ScRangeName>&
{
ScDocument& rDoc = *pDocShell->GetDocument();
- rDoc.CompileNameFormula(true);
-
+ rDoc.PreprocessRangeNameUpdate();
rDoc.SetAllRangeNames(rNames);
-
- rDoc.CompileNameFormula(true);
+ rDoc.PostprocessRangeNameUpdate();
SFX_APP()->Broadcast(SfxSimpleHint(SC_HINT_AREAS_CHANGED));
}
diff --git a/sc/source/ui/unoobj/nameuno.cxx b/sc/source/ui/unoobj/nameuno.cxx
index 14f8a56803d6..9386c11292be 100644
--- a/sc/source/ui/unoobj/nameuno.cxx
+++ b/sc/source/ui/unoobj/nameuno.cxx
@@ -743,13 +743,13 @@ sal_Bool SAL_CALL ScNamedRangesObj::hasByName( const OUString& aName )
/** called from the XActionLockable interface methods on initial locking */
void ScNamedRangesObj::lock()
{
- pDocShell->GetDocument()->CompileNameFormula( true ); // CreateFormulaString
+ pDocShell->GetDocument()->PreprocessRangeNameUpdate();
}
/** called from the XActionLockable interface methods on final unlock */
void ScNamedRangesObj::unlock()
{
- pDocShell->GetDocument()->CompileNameFormula( false ); // CompileFormulaString
+ pDocShell->GetDocument()->PostprocessRangeNameUpdate();
}
// document::XActionLockable
diff --git a/sc/source/ui/view/viewfunc.cxx b/sc/source/ui/view/viewfunc.cxx
index 3eddb54742a7..41a2109d328e 100644
--- a/sc/source/ui/view/viewfunc.cxx
+++ b/sc/source/ui/view/viewfunc.cxx
@@ -2755,7 +2755,7 @@ bool ScViewFunc::InsertName( const OUString& rName, const OUString& rSymbol,
{
ScDocShellModificator aModificator( *pDocSh );
- pDoc->CompileNameFormula( true ); // CreateFormulaString
+ pDoc->PreprocessRangeNameUpdate();
// input available yet? Then remove beforehand (=change)
ScRangeData* pData = pList->findByUpperName(ScGlobal::pCharClass->uppercase(rName));
@@ -2769,7 +2769,8 @@ bool ScViewFunc::InsertName( const OUString& rName, const OUString& rSymbol,
bOk = true;
pNewEntry = NULL; // never delete, insert took ownership
- pDoc->CompileNameFormula( false ); // CompileFormulaString
+ pDoc->PostprocessRangeNameUpdate();
+
aModificator.SetDocumentModified();
SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREAS_CHANGED ) );
}