diff options
author | Kohei Yoshida <kohei.yoshida@collabora.com> | 2014-04-07 14:13:20 -0400 |
---|---|---|
committer | Fridrich Strba <fridrich@documentfoundation.org> | 2014-04-08 16:32:43 +0000 |
commit | 3a9b9a41c567c4e8f6c6bec0a4bb35dc581d577e (patch) | |
tree | af593f5f7761f576e96411adc47626a008bfa123 | |
parent | bcba071c0d583a0b3a62d6d718829b906ecc37f2 (diff) |
fdo#75741: Re-implement CompileNameFormula for formula groups.
(cherry picked from commit 355baf573425165cbc1c789a6271eb29940e1f76)
(cherry picked from commit 615f6aa293a6da90da94e6e78828198ffbc0ca5e)
Conflicts:
sc/inc/document.hxx
sc/source/core/data/column4.cxx
sc/source/core/data/document10.cxx
sc/source/core/data/table7.cxx
sc/source/ui/docshell/docfunc.cxx
sc/source/ui/undo/undocell.cxx
sc/source/ui/unoobj/nameuno.cxx
Change-Id: I57e1e464ac5f7abc10ce5ea5752e036ddb6cf6d7
Reviewed-on: https://gerrit.libreoffice.org/8889
Reviewed-by: Fridrich Strba <fridrich@documentfoundation.org>
Tested-by: Fridrich Strba <fridrich@documentfoundation.org>
-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 | 13 | ||||
-rw-r--r-- | sc/inc/document.hxx | 12 | ||||
-rw-r--r-- | sc/inc/formulacell.hxx | 8 | ||||
-rw-r--r-- | sc/inc/formulagroup.hxx | 18 | ||||
-rw-r--r-- | sc/inc/table.hxx | 6 | ||||
-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 | 152 | ||||
-rw-r--r-- | sc/source/core/data/documen4.cxx | 11 | ||||
-rw-r--r-- | sc/source/core/data/document10.cxx | 26 | ||||
-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 | 13 | ||||
-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, 334 insertions, 137 deletions
diff --git a/formula/source/core/api/token.cxx b/formula/source/core/api/token.cxx index ae1655eb9365..7499a2b1230b 100644 --- a/formula/source/core/api/token.cxx +++ b/formula/source/core/api/token.cxx @@ -605,6 +605,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 9f8fed0ab27d..a479c10ad842 100644 --- a/include/formula/tokenarray.hxx +++ b/include/formula/tokenarray.hxx @@ -26,6 +26,8 @@ #include <tools/solar.h> #include <com/sun/star/sheet/FormulaToken.hpp> +#include <boost/unordered_set.hpp> + namespace formula { @@ -124,6 +126,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 33a1bf7ff64d..edf6acae15c1 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; @@ -362,6 +363,11 @@ public: void SetTabNo(SCTAB nNewTab); void FindRangeNamesInUse(SCROW nRow1, SCROW nRow2, std::set<sal_uInt16>& rIndexes) const; + void PreprocessRangeNameUpdate( + sc::EndListeningContext& rEndListenCxt, sc::CompileFormulaContext& rCompileCxt ); + + void PostprocessRangeNameUpdate( sc::CompileFormulaContext& rCompileCxt ); + const SfxPoolItem* GetAttr( SCROW nRow, sal_uInt16 nWhich ) const; const ScPatternAttr* GetPattern( SCROW nRow ) const; const ScPatternAttr* GetMostUsedPattern( SCROW nStartRow, SCROW nEndRow ) const; @@ -463,7 +469,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; @@ -584,6 +589,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 809689bca86f..b4e86f3e93b6 100644 --- a/sc/inc/document.hxx +++ b/sc/inc/document.hxx @@ -507,6 +507,17 @@ public: SC_DLLPUBLIC ScRangeName* GetRangeName() const; void SetRangeName(SCTAB nTab, ScRangeName* pNew); 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(); + SCTAB GetMaxTableNumber() { return static_cast<SCTAB>(maTabs.size()) - 1; } void SetMaxTableNumber(SCTAB nNumber) { nMaxTableNumber = nNumber; } @@ -1948,7 +1959,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 2d696c36b07c..69023a7a4cde 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 bb0e0b42e4e4..4761c0a456f9 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 77e5996064b0..f6d9a32956cf 100644 --- a/sc/inc/table.hxx +++ b/sc/inc/table.hxx @@ -849,6 +849,11 @@ public: void SetRangeName(ScRangeName* pNew); ScRangeName* GetRangeName() const; + void PreprocessRangeNameUpdate( + sc::EndListeningContext& rEndListenCxt, sc::CompileFormulaContext& rCompileCxt ); + + void PostprocessRangeNameUpdate( sc::CompileFormulaContext& rCompileCxt ); + ScConditionalFormatList* GetCondFormList(); const ScConditionalFormatList* GetCondFormList() const; void SetCondFormList( ScConditionalFormatList* pList ); @@ -1007,7 +1012,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 RebuildFormulaGroups(); diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx index 518766dde6a0..a4a38dff30c5 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> @@ -2331,23 +2332,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: @@ -2422,7 +2406,7 @@ public: } }; -class UpdateRefOnNonCopy : std::unary_function<FormulaGroup, void> +class UpdateRefOnNonCopy : std::unary_function<sc::FormulaGroupEntry, void> { SCCOL mnCol; SCROW mnTab; @@ -2430,7 +2414,7 @@ class UpdateRefOnNonCopy : std::unary_function<FormulaGroup, void> ScDocument* mpUndoDoc; bool mbUpdated; - void updateRefOnShift( FormulaGroup& rGroup ) + void updateRefOnShift( sc::FormulaGroupEntry& rGroup ) { if (!rGroup.mbShared) { @@ -2492,7 +2476,7 @@ class UpdateRefOnNonCopy : std::unary_function<FormulaGroup, void> } } - void updateRefOnMove( FormulaGroup& rGroup ) + void updateRefOnMove( sc::FormulaGroupEntry& rGroup ) { if (!rGroup.mbShared) { @@ -2603,7 +2587,7 @@ public: mnCol(nCol), mnTab(nTab), mpCxt(pCxt), mpUndoDoc(pUndoDoc), mbUpdated(false) {} - void operator() ( FormulaGroup& rGroup ) + void operator() ( sc::FormulaGroupEntry& rGroup ) { switch (mpCxt->meMode) { @@ -2661,21 +2645,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 ) { - mrGroups.push_back(FormulaGroup(pCell, nRow)); + mrGroups.push_back(sc::FormulaGroupEntry(pCell, nRow)); } virtual void processSharedTop( ScFormulaCell** ppCells, size_t nRow, size_t nLength ) { - mrGroups.push_back(FormulaGroup(ppCells, nRow, nLength)); + mrGroups.push_back(sc::FormulaGroupEntry(ppCells, nRow, nLength)); } }; @@ -2748,8 +2732,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); @@ -2760,6 +2743,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 1c18affb3924..f6825e253d18 100644 --- a/sc/source/core/data/column2.cxx +++ b/sc/source/core/data/column2.cxx @@ -3199,21 +3199,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; @@ -3242,12 +3227,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 a02466563a47..e25de1654c3a 100644 --- a/sc/source/core/data/column4.cxx +++ b/sc/source/core/data/column4.cxx @@ -15,18 +15,23 @@ #include <document.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> + void ScColumn::DeleteBeforeCopyFromClip( sc::CopyFromClipContext& rCxt, const ScColumn& rClipCol ) { sc::CopyFromClipContext::Range aRange = rCxt.getDestRange(); @@ -120,4 +125,151 @@ void ScColumn::DeleteBeforeCopyFromClip( sc::CopyFromClipContext& rCxt, const Sc BroadcastCells(aDeletedRows, SC_HINT_DATACHANGED); } +namespace { + +class PreRangeNameUpdateHandler +{ + ScDocument* mpDoc; + sc::EndListeningContext& mrEndListenCxt; + sc::CompileFormulaContext& mrCompileFormulaCxt; + +public: + PreRangeNameUpdateHandler( ScDocument* pDoc, sc::EndListeningContext& rEndListenCxt, sc::CompileFormulaContext& rCompileCxt ) : + mpDoc(pDoc), + mrEndListenCxt(rEndListenCxt), + mrCompileFormulaCxt(rCompileCxt) {} + + 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(mrCompileFormulaCxt); + 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(mrEndListenCxt); + mpDoc->RemoveFromFormulaTree(p); + } + } + else + { + rEntry.mpCell->EndListeningTo(mrEndListenCxt); + mpDoc->RemoveFromFormulaTree(rEntry.mpCell); + } + + pCode->Clear(); + pTop->SetHybridFormula(aFormula, mpDoc->GetGrammar()); + } + } +}; + +class PostRangeNameUpdateHandler +{ + ScDocument* mpDoc; + sc::CompileFormulaContext& mrCompileFormulaCxt; + +public: + PostRangeNameUpdateHandler( ScDocument* pDoc, sc::CompileFormulaContext& rCompileCxt ) : + mpDoc(pDoc), + mrCompileFormulaCxt(rCompileCxt) {} + + 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(mrCompileFormulaCxt, 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(mrCompileFormulaCxt, 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( + sc::EndListeningContext& rEndListenCxt, sc::CompileFormulaContext& rCompileCxt ) +{ + // Collect all formula groups. + std::vector<sc::FormulaGroupEntry> aGroups = GetFormulaGroupEntries(); + + PreRangeNameUpdateHandler aFunc(pDocument, rEndListenCxt, rCompileCxt); + std::for_each(aGroups.begin(), aGroups.end(), aFunc); +} + +void ScColumn::PostprocessRangeNameUpdate( sc::CompileFormulaContext& rCompileCxt ) +{ + // Collect all formula groups. + std::vector<sc::FormulaGroupEntry> aGroups = GetFormulaGroupEntries(); + + PostRangeNameUpdateHandler aFunc(pDocument, rCompileCxt); + 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 fb4538581c73..8a4e3ec1f6d1 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 00640b347316..ba95499f0d56 100644 --- a/sc/source/core/data/document10.cxx +++ b/sc/source/core/data/document10.cxx @@ -14,6 +14,8 @@ #include <table.hxx> #include <tokenarray.hxx> #include <editutil.hxx> +#include <listenercontext.hxx> +#include <tokenstringcontext.hxx> // Add totally brand-new methods to this source file. @@ -41,4 +43,28 @@ void ScDocument::DeleteBeforeCopyFromClip( sc::CopyFromClipContext& rCxt, const } } +void ScDocument::PreprocessRangeNameUpdate() +{ + sc::EndListeningContext aEndListenCxt(*this); + sc::CompileFormulaContext aCompileCxt(this); + + TableContainer::iterator it = maTabs.begin(), itEnd = maTabs.end(); + for (; it != itEnd; ++it) + { + ScTable* p = *it; + p->PreprocessRangeNameUpdate(aEndListenCxt, aCompileCxt); + } +} + +void ScDocument::PostprocessRangeNameUpdate() +{ + sc::CompileFormulaContext aCompileCxt(this); + TableContainer::iterator it = maTabs.begin(), itEnd = maTabs.end(); + for (; it != itEnd; ++it) + { + ScTable* p = *it; + p->PostprocessRangeNameUpdate(aCompileCxt); + } +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx index 10c4c14c88af..78c4fb066eb6 100644 --- a/sc/source/core/data/formulacell.cxx +++ b/sc/source/core/data/formulacell.cxx @@ -473,6 +473,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 ) { @@ -2057,6 +2065,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 ) { @@ -3385,6 +3398,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; @@ -3461,53 +3481,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(); @@ -4066,6 +4039,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 9a50176a890d..bfefd3066aaa 100644 --- a/sc/source/core/data/table4.cxx +++ b/sc/source/core/data/table4.cxx @@ -2068,12 +2068,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 858514c7685a..e8e82d4d64f1 100644 --- a/sc/source/core/data/table7.cxx +++ b/sc/source/core/data/table7.cxx @@ -41,4 +41,17 @@ void ScTable::DeleteBeforeCopyFromClip( sc::CopyFromClipContext& rCxt, const ScT SetStreamValid(false); } +void ScTable::PreprocessRangeNameUpdate( + sc::EndListeningContext& rEndListenCxt, sc::CompileFormulaContext& rCompileCxt ) +{ + for (SCCOL i = 0; i <= MAXCOL; ++i) + aCol[i].PreprocessRangeNameUpdate(rEndListenCxt, rCompileCxt); +} + +void ScTable::PostprocessRangeNameUpdate( sc::CompileFormulaContext& rCompileCxt ) +{ + for (SCCOL i = 0; i <= MAXCOL; ++i) + aCol[i].PostprocessRangeNameUpdate(rCompileCxt); +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/core/tool/formulagroup.cxx b/sc/source/core/tool/formulagroup.cxx index e662195de50d..736d48c6f600 100644 --- a/sc/source/core/tool/formulagroup.cxx +++ b/sc/source/core/tool/formulagroup.cxx @@ -40,6 +40,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 32c8bd62cc19..fba445f50c51 100644 --- a/sc/source/filter/oox/workbookhelper.cxx +++ b/sc/source/filter/oox/workbookhelper.cxx @@ -601,8 +601,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 ) ); @@ -637,8 +635,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 72e7e469db62..bcb45b661637 100644 --- a/sc/source/ui/docshell/docfunc.cxx +++ b/sc/source/ui/docshell/docfunc.cxx @@ -4865,13 +4865,13 @@ bool ScDocFunc::SetNewRangeNames( ScRangeName* pNewRanges, bool bModifyDoc, SCTA sal_Bool bCompile = ( !pDoc->IsImportingXML() && pDoc->GetNamedRangesLockCount() == 0 ); if ( bCompile ) - pDoc->CompileNameFormula( sal_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) { @@ -4895,12 +4895,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 2a22f5991e37..02f67a9c8c44 100644 --- a/sc/source/ui/undo/undocell.cxx +++ b/sc/source/ui/undo/undocell.cxx @@ -1042,7 +1042,7 @@ OUString ScUndoRangeNames::GetComment() const void ScUndoRangeNames::DoChange( sal_Bool bUndo ) { ScDocument* pDoc = pDocShell->GetDocument(); - pDoc->CompileNameFormula( sal_True ); // CreateFormulaString + pDoc->PreprocessRangeNameUpdate(); if ( bUndo ) { @@ -1059,7 +1059,7 @@ void ScUndoRangeNames::DoChange( sal_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 c67e577d6156..87ed766967e8 100644 --- a/sc/source/ui/unoobj/nameuno.cxx +++ b/sc/source/ui/unoobj/nameuno.cxx @@ -745,13 +745,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( sal_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 b96752606c46..dd4e56234885 100644 --- a/sc/source/ui/view/viewfunc.cxx +++ b/sc/source/ui/view/viewfunc.cxx @@ -2765,7 +2765,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)); @@ -2779,7 +2779,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 ) ); } |