fdo#74747: Make use of cached string formula results.

Just like we do with cached numeric formula results.

Change-Id: Ib8b311b540caeb47d8c2162a456f7490c5882ad5
This commit is contained in:
Kohei Yoshida
2014-03-10 17:03:52 -04:00
parent 304e6144c6
commit aa5ad7b809
5 changed files with 54 additions and 20 deletions

View File

@@ -77,13 +77,19 @@ public:
TokenRangeAddressItem( const TokenAddressItem& rTokenAndAddress, const ::com::sun::star::table::CellRangeAddress& rCellRangeAddress ) : maTokenAndAddress( rTokenAndAddress ), maCellRangeAddress( rCellRangeAddress ) {}
};
struct FormulaValue
{
com::sun::star::table::CellAddress maCellAddress;
OUString maValueStr;
sal_Int32 mnCellType;
};
typedef std::pair<com::sun::star::table::CellAddress, double> ValueAddressPair;
struct SheetItem
{
std::vector<TokenAddressItem>* mpCellFormulas;
std::vector<TokenRangeAddressItem>* mpArrayFormulas;
std::vector<ValueAddressPair>* mpCellFormulaValues;
std::vector<FormulaValue>* mpCellFormulaValues;
std::vector<SharedFormulaEntry>* mpSharedFormulaEntries;
std::vector<SharedFormulaDesc>* mpSharedFormulaIDs;
@@ -98,7 +104,7 @@ private:
typedef ::std::vector< std::vector<SharedFormulaDesc> > SheetToSharedFormulaid;
// sheet -> stuff needed to create shared formulae
typedef ::std::vector< std::vector<SharedFormulaEntry> > SheetToFormulaEntryArray;
typedef ::std::vector< std::vector<ValueAddressPair> > FormulaValueArray;
typedef ::std::vector< std::vector<FormulaValue> > FormulaValueArray;
osl::Mutex maMtxData;
FormulaDataArray maCellFormulas;
@@ -118,8 +124,9 @@ public:
const ::com::sun::star::table::CellAddress& rAddress, sal_Int32 nSharedId,
const OUString& rCellValue, sal_Int32 nValueType );
void setCellFormulaValue( const ::css::table::CellAddress& rAddress,
double fValue );
void setCellFormulaValue(
const css::table::CellAddress& rAddress, const OUString& rValueStr, sal_Int32 nCellType );
void setCellArrayFormula( const ::css::table::CellRangeAddress& rRangeAddress,
const ::css::table::CellAddress& rTokenAddress,
const OUString& );

View File

@@ -325,8 +325,9 @@ public:
const com::sun::star::table::CellRangeAddress& rRange,
sal_Int32 nSharedId, const OUString& rTokens );
void setCellFormulaValue( const ::com::sun::star::table::CellAddress& rAddress,
double fValue );
void setCellFormulaValue(
const css::table::CellAddress& rAddress, const OUString& rValueStr, sal_Int32 nCellType );
private:
WorksheetGlobals& mrSheetGlob;
};

View File

@@ -28,6 +28,7 @@
#include "externalrefmgr.hxx"
#include "tokenstringcontext.hxx"
#include "oox/token/tokens.hxx"
#include <svl/sharedstringpool.hxx>
using namespace com::sun::star;
using namespace ::com::sun::star::uno;
@@ -256,19 +257,39 @@ void applyArrayFormulas(
}
void applyCellFormulaValues(
ScDocumentImport& rDoc, const std::vector<FormulaBuffer::ValueAddressPair>& rVector )
ScDocumentImport& rDoc, const std::vector<FormulaBuffer::FormulaValue>& rVector )
{
std::vector<FormulaBuffer::ValueAddressPair>::const_iterator it = rVector.begin(), itEnd = rVector.end();
svl::SharedStringPool& rStrPool = rDoc.getDoc().GetSharedStringPool();
std::vector<FormulaBuffer::FormulaValue>::const_iterator it = rVector.begin(), itEnd = rVector.end();
for (; it != itEnd; ++it)
{
ScAddress aCellPos;
ScUnoConversion::FillScAddress(aCellPos, it->first);
ScUnoConversion::FillScAddress(aCellPos, it->maCellAddress);
ScFormulaCell* pCell = rDoc.getDoc().GetFormulaCell(aCellPos);
if (pCell)
const OUString& rValueStr = it->maValueStr;
if (!pCell)
continue;
switch (it->mnCellType)
{
pCell->SetHybridDouble(it->second);
pCell->ResetDirty();
pCell->SetChanged(false);
case XML_n:
{
pCell->SetResultDouble(rValueStr.toDouble());
pCell->ResetDirty();
pCell->SetChanged(false);
}
break;
case XML_str:
{
svl::SharedString aSS = rStrPool.intern(rValueStr);
pCell->SetResultToken(new formula::FormulaStringToken(aSS));
pCell->ResetDirty();
pCell->SetChanged(false);
}
break;
default:
;
}
}
}
@@ -470,10 +491,15 @@ void FormulaBuffer::setCellArrayFormula( const ::com::sun::star::table::CellRang
maCellArrayFormulas[ rRangeAddress.Sheet ].push_back( TokenRangeAddressItem( tokenPair, rRangeAddress ) );
}
void FormulaBuffer::setCellFormulaValue( const ::com::sun::star::table::CellAddress& rAddress, double fValue )
void FormulaBuffer::setCellFormulaValue(
const css::table::CellAddress& rAddress, const OUString& rValueStr, sal_Int32 nCellType )
{
assert( rAddress.Sheet >= 0 && (size_t)rAddress.Sheet < maCellFormulaValues.size() );
maCellFormulaValues[ rAddress.Sheet ].push_back( ValueAddressPair( rAddress, fValue ) );
FormulaValue aVal;
aVal.maCellAddress = rAddress;
aVal.maValueStr = rValueStr;
aVal.mnCellType = nCellType;
maCellFormulaValues[rAddress.Sheet].push_back(aVal);
}
}}

View File

@@ -161,8 +161,8 @@ void SheetDataContext::onEndElement()
// If a number cell has some preloaded value, stick it into the buffer
// but do this only for real cell formulas (not array, shared etc.)
if( !( maCellValue.isEmpty() ) && ( maCellData.mnCellType == XML_n ) )
setCellFormulaValue( maCellData.maCellAddr, maCellValue.toDouble() );
if (!maCellValue.isEmpty())
setCellFormulaValue(maCellData.maCellAddr, maCellValue, maCellData.mnCellType);
break;
case XML_shared:

View File

@@ -1567,10 +1567,10 @@ void WorksheetHelper::putValue( const CellAddress& rAddress, double fValue )
getDocImport().setNumericCell(aAddress, fValue);
}
void WorksheetHelper::setCellFormulaValue( const ::com::sun::star::table::CellAddress& rAddress,
double fValue )
void WorksheetHelper::setCellFormulaValue(
const css::table::CellAddress& rAddress, const OUString& rValueStr, sal_Int32 nCellType )
{
getFormulaBuffer().setCellFormulaValue( rAddress, fValue );
getFormulaBuffer().setCellFormulaValue(rAddress, rValueStr, nCellType);
}
void WorksheetHelper::putString( const CellAddress& rAddress, const OUString& rText )