diff options
author | Kohei Yoshida <kohei.yoshida@collabora.com> | 2014-04-07 14:13:20 -0400 |
---|---|---|
committer | Kohei Yoshida <kohei.yoshida@collabora.com> | 2014-04-07 14:43:16 -0400 |
commit | 355baf573425165cbc1c789a6271eb29940e1f76 (patch) | |
tree | 42050f8ac0a293b75e3745d511fe2e086e88cd42 | |
parent | 137c288978fb8f4aee259fabfdcb9252b1b011d3 (diff) |
fdo#75741: Re-implement CompileNameFormula for formula groups.
Change-Id: I57e1e464ac5f7abc10ce5ea5752e036ddb6cf6d7
-rw-r--r-- | formula/source/core/api/token.cxx | 13 | ||||
-rw-r--r-- | include/formula/tokenarray.hxx | 12 | ||||
-rw-r--r-- | sc/inc/column.hxx | 11 | ||||
-rw-r--r-- | sc/inc/document.hxx | 11 | ||||
-rw-r--r-- | sc/inc/formulacell.hxx | 8 | ||||
-rw-r--r-- | sc/inc/formulagroup.hxx | 18 | ||||
-rw-r--r-- | sc/inc/table.hxx | 4 | ||||
-rw-r--r-- | sc/source/core/data/column.cxx | 44 | ||||
-rw-r--r-- | sc/source/core/data/column2.cxx | 21 | ||||
-rw-r--r-- | sc/source/core/data/column4.cxx | 151 | ||||
-rw-r--r-- | sc/source/core/data/documen4.cxx | 11 | ||||
-rw-r--r-- | sc/source/core/data/document10.cxx | 20 | ||||
-rw-r--r-- | sc/source/core/data/formulacell.cxx | 76 | ||||
-rw-r--r-- | sc/source/core/data/table4.cxx | 6 | ||||
-rw-r--r-- | sc/source/core/data/table7.cxx | 12 | ||||
-rw-r--r-- | sc/source/core/tool/formulagroup.cxx | 6 | ||||
-rw-r--r-- | sc/source/filter/oox/workbookhelper.cxx | 4 | ||||
-rw-r--r-- | sc/source/ui/docshell/docfunc.cxx | 11 | ||||
-rw-r--r-- | sc/source/ui/undo/undocell.cxx | 4 | ||||
-rw-r--r-- | sc/source/ui/undo/undorangename.cxx | 6 | ||||
-rw-r--r-- | sc/source/ui/unoobj/nameuno.cxx | 4 | ||||
-rw-r--r-- | sc/source/ui/view/viewfunc.cxx | 5 |
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 ) ); } |