[Libreoffice-commits] core.git: Branch 'feature/formula-core-rework' - 236 commits - avmedia/inc avmedia/source basctl/source basic/qa basic/source bin/module-deps.pl bridges/Library_cc50_solaris_intel.mk bridges/Library_cc50_solaris_sparc.mk bridges/Library_cc5_solaris_sparc64.mk bridges/Library_cpp_uno.mk bridges/Library_gcc3_aix_powerpc.mk bridges/Library_gcc3_ios_arm.mk bridges/Library_gcc3_linux_alpha.mk bridges/Library_gcc3_linux_arm.mk bridges/Library_gcc3_linux_hppa.mk bridges/Library_gcc3_linux_ia64.mk bridges/Library_gcc3_linux_intel.mk bridges/Library_gcc3_linux_m68k.mk bridges/Library_gcc3_linux_mips.mk bridges/Library_gcc3_linux_powerpc64.mk bridges/Library_gcc3_linux_powerpc.mk bridges/Library_gcc3_linux_s390.mk bridges/Library_gcc3_linux_s390x.mk bridges/Library_gcc3_linux_sparc.mk bridges/Library_gcc3_linux_x86-64.mk bridges/Library_gcc3_macosx_intel.mk bridges/Library_gcc3_macosx_powerpc.mk bridges/Library_gcc3_macosx_x86-64.mk bridges/Library_gcc3_solaris_intel.mk bridge s/Library_gcc3_solaris_sparc.mk bridges/Library_mingw_intel.mk bridges/Library_msvc_win32_intel.mk bridges/Library_msvc_win32_x86-64.mk bridges/Module_bridges.mk bridges/source bridges/test canvas/source chart2/source cli_ure/source clucene/Library_clucene.mk codemaker/source comphelper/source compilerplugins/clang compilerplugins/Makefile-clang.mk config_host/config_kde4.h.in config_host/README configmgr/qa configmgr/source configure.ac connectivity/Library_dbtools.mk connectivity/Library_tdeabdrv1.mk connectivity/source cppcanvas/source cppuhelper/inc cppuhelper/qa cppuhelper/source cppuhelper/test cppu/inc cppunit/UnpackedTarball_cppunit.mk cppunit/wundef.patch cppu/qa cppu/source cpputools/source crashrep/source cui/source cui/uiconfig cui/UI_cui.mk dbaccess/qa dbaccess/source desktop/qa desktop/source desktop/test desktop/unx desktop/win32 dictionaries drawinglayer/inc drawinglayer/Library_drawinglayer.mk drawinglayer/Package_inc.mk drawinglayer/source dtrans/source edi teng/source embeddedobj/source embeddedobj/test embedserv/source extensions/qa extensions/source extensions/test filter/Configuration_filter.mk filter/inc filter/source forms/source formula/inc formula/source fpicker/source fpicker/test framework/inc framework/source helpcompiler/source helpcontent2 hwpfilter/qa hwpfilter/source i18npool/qa i18npool/source icon-themes/galaxy icon-themes/hicontrast icon-themes/human icon-themes/oxygen icu/icu4c-warnings.patch idlc/source ios/CustomTarget_Viewer_app.mk ios/Executable_Viewer.mk ios/experimental io/source io/test javaunohelper/com javaunohelper/source jvmaccess/source jvmfwk/plugins jvmfwk/source l10ntools/inc l10ntools/source libcdr/ExternalProject_libcdr.mk libmariadb/ExternalPackage_libmariadb.mk libmariadb/mariadb-static-inline.patch libmariadb/UnpackedTarball_mariadb.mk liborcus/ExternalPackage_liborcus.mk liborcus/ExternalProject_liborcus.mk liborcus/liborcus_0.1.0-boost_disable_auto_lib.patch liborcus/Module_liborcus.mk l iborcus/Package_liborcus.mk liborcus/UnpackedTarball_orcus.mk liborcus/vsprojects libwpd/ExternalPackage_libwpd.mk libwpd/ExternalProject_libwpd.mk libwpg/StaticLibrary_wpg.mk linguistic/workben lotuswordpro/source mdds/UnpackedTarball_mdds.mk mdds/wundef.patch mysqlc/source np_sdk/mozsrc odk/CustomTarget_autodoc.mk odk/CustomTarget_doxygen.mk odk/CustomTarget_javadoc.mk odk/CustomTarget_settings.mk odk/examples odk/pack offapi/com offapi/type_reference officecfg/Configuration_officecfg.mk officecfg/CustomTarget_registry.mk officecfg/files.mk officecfg/Module_officecfg.mk officecfg/registry oox/inc oox/source padmin/source postprocess/CustomTarget_registry.mk postprocess/Rdb_services.mk pyuno/source README.Android README.cross registry/inc registry/source registry/workben remotebridges/source reportbuilder/Configuration_reportbuilder.mk reportbuilder/Extension_reportbuilder.mk reportbuilder/Jar_reportbuilder.mk reportbuilder/java reportbuilder/license reportbuilder/Module_re portbuilder.mk reportbuilder/Package_readme.mk reportbuilder/registry reportbuilder/util reportdesign/source Repository.mk rsc/source sal/inc sal/osl sal/qa sal/rtl sal/test sax/source sax/test scaddins/source sc/inc sc/Library_sc.mk scp2/InstallModule_base.mk scp2/InstallModule_ooo.mk scp2/source sc/qa scripting/source sc/source sc/uiconfig sdext/source sd/qa sd/source sd/workben setup_native/source sfx2/inc sfx2/source sfx2/workben shell/source slideshow/source smoketest/smoketest.cxx solenv/bin solenv/gbuild solenv/gcc-wrappers solenv/src soltools/cpp soltools/mkdepend stoc/source stoc/test store/inc store/workben svgio/source svl/qa svl/source svtools/inc svtools/source svx/inc svx/source svx/workben sw/CppunitTest_sw_odfexport.mk sw/CppunitTest_sw_odfimport.mk sw/CppunitTest_sw_ooxmlexport.mk sw/CppunitTest_sw_ooxmlimport.mk sw/CppunitTest_sw_rtfexport.mk sw/CppunitTest_sw_rtfimport.mk sw/CppunitTest_sw_subsequent_odfexport.mk sw/CppunitTest_sw_subsequent_odfimport.mk s w/CppunitTest_sw_subsequent_ooxmlexport.mk sw/CppunitTest_sw_subsequent_ooxmlimport.mk sw/CppunitTest_sw_subsequent_rtfexport.mk sw/CppunitTest_sw_subsequent_rtfimport.mk sw/CppunitTest_sw_subsequent_ww8export.mk sw/CppunitTest_sw_subsequent_ww8import.mk sw/CppunitTest_sw_ww8export.mk sw/CppunitTest_sw_ww8import.mk sw/inc sw/Module_sw.mk sw/qa sw/source test/source testtools/source toolkit/inc toolkit/source tools/inc tools/qa tools/source translations tubes/source ucbhelper/source ucb/source ucb/workben unotools/source vcl/android vcl/aqua vcl/coretext vcl/generic vcl/inc vcl/ios vcl/Library_vcl.mk vcl/Library_vclplug_tde.mk vcl/source vcl/unx vcl/win vcl/workben writerfilter/qa writerfilter/source writerperfect/source xmlhelp/source xmloff/inc xmloff/source xmlreader/source xmlscript/source xmlsecurity/source xmlsecurity/uiconfig
Michael Meeks
michael.meeks at suse.com
Tue Mar 19 10:41:01 PDT 2013
Rebased ref, commits from common ancestor:
commit 42d3adbce63493039e6013f6f3ea15149f2f7507
Author: Michael Meeks <michael.meeks at suse.com>
Date: Tue Mar 19 17:04:08 2013 +0000
calm debug, and disable unless SC_FORMULAGROUP=1
Change-Id: I091d43dfa33f440edd50a1c937ef6e6f1930be4e
diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx
index 81fa1ea..ec2711f 100644
--- a/sc/qa/unit/ucalc.cxx
+++ b/sc/qa/unit/ucalc.cxx
@@ -6224,6 +6224,9 @@ void Test::testCellTextWidth()
void Test::testFormulaGrouping()
{
+ if ( !getenv("SC_FORMULAGROUP") )
+ return;
+
static const struct {
const char *pFormula[3];
const bool bGroup[3];
diff --git a/sc/source/core/data/cell2.cxx b/sc/source/core/data/cell2.cxx
index 0724501..5bd3846 100644
--- a/sc/source/core/data/cell2.cxx
+++ b/sc/source/core/data/cell2.cxx
@@ -1748,7 +1748,7 @@ ScSimilarFormulaDelta *ScFormulaCell::BuildDeltaTo( ScFormulaCell *pOtherCell )
if ( !pThis || !pOther )
{
- fprintf( stderr, "Error: no compiled code for cells !" );
+// fprintf( stderr, "Error: no compiled code for cells !" );
return NULL;
}
@@ -1817,12 +1817,12 @@ bool ScFormulaCell::InterpretFormulaGroup()
if( !xGroup.get() )
return false;
- fprintf( stderr, "Interpret cell %d, %d\n", (int)aPos.Col(), (int)aPos.Row() );
+// fprintf( stderr, "Interpret cell %d, %d\n", (int)aPos.Col(), (int)aPos.Row() );
if ( xGroup->mpDelta->IsInvariant() )
{
- fprintf( stderr, "struck gold - completely invariant for %d items !\n",
- (int)xGroup->mnLength );
+// fprintf( stderr, "struck gold - completely invariant for %d items !\n",
+// (int)xGroup->mnLength );
// calculate ourselves:
InterpretTail( SCITP_NORMAL );
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index 4397834..c4c4ec6 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -2119,7 +2119,7 @@ void ScColumn::RebuildFormulaGroups()
}
}
-#if 1 // OSL_DEBUG_LEVEL > 0
+#if OSL_DEBUG_LEVEL > 0
if ( maDoubles.size() + maFnGroups.size() > 0 )
{
rtl::OUString aStr;
diff --git a/sc/source/core/data/documen9.cxx b/sc/source/core/data/documen9.cxx
index 4a261e8..54e3a08 100644
--- a/sc/source/core/data/documen9.cxx
+++ b/sc/source/core/data/documen9.cxx
@@ -697,6 +697,11 @@ void ScDocument::ApplyAsianEditSettings( ScEditEngineDefaulter& rEngine )
void ScDocument::RebuildFormulaGroups()
{
+ static const char *pEnableFormulaGroups = getenv("SC_FORMULAGROUP");
+
+ if ( !pEnableFormulaGroups )
+ return;
+
SCTAB nTab;
for (nTab=0; nTab < static_cast<SCTAB>(maTabs.size()); nTab++)
if (maTabs[nTab])
commit 20c4921e901d84a7ef8835ee192e1a7a4b62ee61
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date: Tue Mar 19 12:51:47 2013 -0400
Remove use of ScBaseCell and its derivatives outside ScDocument.
This is still work in progress.
Change-Id: Ifcdbefbdd307a2a8819b073d896e90a16980781e
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 4776a70..d8e4a38 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -257,10 +257,12 @@ public:
bool HasEditCells(SCROW nStartRow, SCROW nEndRow, SCROW& rFirst) const;
- // TRUE = format for numbers is set
bool SetString(
SCROW nRow, SCTAB nTab, const String& rString, formula::FormulaGrammar::AddressConvention eConv,
ScSetStringParam* pParam = NULL );
+
+ void SetEditText( SCROW nRow, EditTextObject* pEditText );
+
void SetValue( SCROW nRow, const double& rVal);
void SetError( SCROW nRow, const sal_uInt16 nError);
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index 98b21eb..91e003e 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -750,7 +750,18 @@ public:
SC_DLLPUBLIC bool SetString(
SCCOL nCol, SCROW nRow, SCTAB nTab, const rtl::OUString& rString,
ScSetStringParam* pParam = NULL );
- bool SetString( const ScAddress& rPos, const OUString& rString, ScSetStringParam* pParam = NULL );
+ SC_DLLPUBLIC bool SetString( const ScAddress& rPos, const OUString& rString, ScSetStringParam* pParam = NULL );
+
+ /**
+ * This method manages the lifecycle of the passed edit text object. When
+ * the text is successfully inserted, the cell takes over the ownership of
+ * the text object. If not, the text object gets deleted.
+ *
+ * <p>The caller must ensure that the passed edit text object <i>uses the
+ * SfxItemPool instance returned from ScDocument::GetEditPool()</i>.
+ * This is very important.</p>
+ */
+ SC_DLLPUBLIC void SetEditText( const ScAddress& rPos, EditTextObject* pEditText );
SC_DLLPUBLIC void SetValue( SCCOL nCol, SCROW nRow, SCTAB nTab, const double& rVal );
void SetError( SCCOL nCol, SCROW nRow, SCTAB nTab, const sal_uInt16 nError);
@@ -1875,6 +1886,8 @@ private: // CLOOK-Impl-methods
ScDocument* mpDoc;
};
+ bool TableExists( SCTAB nTab ) const;
+
void MergeNumberFormatter(ScDocument* pSrcDoc);
void ImplCreateOptions(); // Suggestion: switch to on-demand?
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index 036dcca..990b0fc 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -299,9 +299,12 @@ public:
void PutCell( const ScAddress&, ScBaseCell* pCell );
void PutCell( SCCOL nCol, SCROW nRow, ScBaseCell* pCell );
void PutCell(SCCOL nCol, SCROW nRow, sal_uLong nFormatIndex, ScBaseCell* pCell);
- // TRUE = numberformat set
+
bool SetString( SCCOL nCol, SCROW nRow, SCTAB nTab, const String& rString,
ScSetStringParam* pParam = NULL );
+
+ void SetEditText( SCCOL nCol, SCROW nRow, EditTextObject* pEditText );
+
void SetValue( SCCOL nCol, SCROW nRow, const double& rVal );
void SetError( SCCOL nCol, SCROW nRow, sal_uInt16 nError);
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index fb6c212..4397834 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -1490,6 +1490,10 @@ bool ScColumn::SetString( SCROW nRow, SCTAB nTabP, const String& rString,
return bNumFmtSet;
}
+void ScColumn::SetEditText( SCROW nRow, EditTextObject* pEditText )
+{
+ Insert(nRow, new ScEditCell(pEditText, pDocument));
+}
void ScColumn::GetFilterEntries(SCROW nStartRow, SCROW nEndRow, std::vector<ScTypedStrData>& rStrings, bool& rHasDates)
{
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index f4ef72c..71f4a1f 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -22,6 +22,7 @@
#include <editeng/boxitem.hxx>
#include <editeng/frmdiritem.hxx>
+#include "editeng/editobj.hxx"
#include <svx/pageitem.hxx>
#include <editeng/editeng.hxx>
#include <svx/svditer.hxx>
@@ -2158,6 +2159,11 @@ ScDocument::NumFmtMergeHandler::~NumFmtMergeHandler()
mpDoc->pFormatExchangeList = NULL;
}
+bool ScDocument::TableExists( SCTAB nTab ) const
+{
+ return ValidTab(nTab) && static_cast<size_t>(nTab) < maTabs.size() && maTabs[nTab];
+}
+
void ScDocument::MergeNumberFormatter(ScDocument* pSrcDoc)
{
SvNumberFormatter* pThisFormatter = xPoolHelper->GetFormTable();
@@ -2962,6 +2968,17 @@ bool ScDocument::SetString(
return SetString(rPos.Col(), rPos.Row(), rPos.Tab(), rString, pParam);
}
+void ScDocument::SetEditText( const ScAddress& rPos, EditTextObject* pEditText )
+{
+ if (!TableExists(rPos.Tab()))
+ {
+ delete pEditText;
+ return;
+ }
+
+ maTabs[rPos.Tab()]->SetEditText(rPos.Col(), rPos.Row(), pEditText);
+}
+
void ScDocument::SetValue( SCCOL nCol, SCROW nRow, SCTAB nTab, const double& rVal )
{
if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()))
diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx
index c0815c0..015fa67 100644
--- a/sc/source/core/data/table2.cxx
+++ b/sc/source/core/data/table2.cxx
@@ -19,6 +19,7 @@
#include "scitems.hxx"
#include <editeng/boxitem.hxx>
+#include "editeng/editobj.hxx"
#include <svl/poolcach.hxx>
#include <unotools/charclass.hxx>
#include <math.h>
@@ -1322,6 +1323,16 @@ bool ScTable::SetString( SCCOL nCol, SCROW nRow, SCTAB nTabP, const String& rStr
return false;
}
+void ScTable::SetEditText( SCCOL nCol, SCROW nRow, EditTextObject* pEditText )
+{
+ if (!ValidColRow(nCol, nRow))
+ {
+ delete pEditText;
+ return;
+ }
+
+ aCol[nCol].SetEditText(nRow, pEditText);
+}
void ScTable::SetValue( SCCOL nCol, SCROW nRow, const double& rVal )
{
diff --git a/sc/source/core/data/table6.cxx b/sc/source/core/data/table6.cxx
index f4a5d25..640ed59 100644
--- a/sc/source/core/data/table6.cxx
+++ b/sc/source/core/data/table6.cxx
@@ -222,7 +222,11 @@ bool ScTable::SearchCell(const SvxSearchItem& rSearchItem, SCCOL nCol, SCROW nRo
aCol[nCol].Insert( nRow, pFCell );
}
else if ( bMultiLine && aString.indexOf('\n') != -1 )
- PutCell( nCol, nRow, new ScEditCell( aString, pDocument ) );
+ {
+ ScFieldEditEngine& rEngine = pDocument->GetEditEngine();
+ rEngine.SetText(aString);
+ SetEditText(nCol, nRow, rEngine.CreateTextObject());
+ }
else
aCol[nCol].SetString(nRow, nTab, aString, pDocument->GetAddressConvention());
// pCell is invalid now (deleted)
diff --git a/sc/source/filter/excel/excimp8.cxx b/sc/source/filter/excel/excimp8.cxx
index 5285247..68ceed5 100644
--- a/sc/source/filter/excel/excimp8.cxx
+++ b/sc/source/filter/excel/excimp8.cxx
@@ -296,8 +296,9 @@ void ImportExcel8::Labelsst( void )
if( GetAddressConverter().ConvertAddress( aScPos, aXclPos, GetCurrScTab(), true ) )
{
GetXFRangeBuffer().SetXF( aScPos, nXF );
- if( ScBaseCell* pCell = GetSst().CreateCell( nSst, nXF ) )
- GetDoc().PutCell( aScPos.Col(), aScPos.Row(), aScPos.Tab(), pCell );
+ const XclImpString* pXclStr = GetSst().GetString(nSst);
+ if (pXclStr)
+ XclImpStringHelper::SetToDocument(GetDoc(), aScPos, *this, *pXclStr, nXF);
}
}
diff --git a/sc/source/filter/excel/impop.cxx b/sc/source/filter/excel/impop.cxx
index 41250619..662e426 100644
--- a/sc/source/filter/excel/impop.cxx
+++ b/sc/source/filter/excel/impop.cxx
@@ -338,8 +338,7 @@ void ImportExcel::ReadLabel()
SetTextEncoding( eOldTextEnc );
GetXFRangeBuffer().SetXF( aScPos, nXFIdx );
- if( ScBaseCell* pCell = XclImpStringHelper::CreateCell( GetRoot(), aString, nXFIdx ) )
- GetDoc().PutCell( aScPos, pCell );
+ XclImpStringHelper::SetToDocument(GetDoc(), aScPos, GetRoot(), aString, nXFIdx);
}
}
@@ -902,8 +901,7 @@ void ImportExcel::Rstring( void )
aString.ReadFormats( maStrm );
GetXFRangeBuffer().SetXF( aScPos, nXFIdx );
- if( ScBaseCell* pCell = XclImpStringHelper::CreateCell( *this, aString, nXFIdx ) )
- GetDoc().PutCell( aScPos, pCell );
+ XclImpStringHelper::SetToDocument(GetDoc(), aScPos, *this, aString, nXFIdx);
}
}
diff --git a/sc/source/filter/excel/xicontent.cxx b/sc/source/filter/excel/xicontent.cxx
index de6fd13..86ed9de 100644
--- a/sc/source/filter/excel/xicontent.cxx
+++ b/sc/source/filter/excel/xicontent.cxx
@@ -91,14 +91,6 @@ const XclImpString* XclImpSst::GetString( sal_uInt32 nSstIndex ) const
return (nSstIndex < maStrings.size()) ? &maStrings[ nSstIndex ] : 0;
}
-ScBaseCell* XclImpSst::CreateCell( sal_uInt32 nSstIndex, sal_uInt16 nXFIndex ) const
-{
- ScBaseCell* pCell = 0;
- if( const XclImpString* pString = GetString( nSstIndex ) )
- pCell = XclImpStringHelper::CreateCell( *this, *pString, nXFIndex );
- return pCell;
-}
-
// Hyperlinks =================================================================
namespace {
@@ -197,8 +189,7 @@ void lclInsertUrl( const XclImpRoot& rRoot, const String& rUrl, SCCOL nScCol, SC
}
// The cell will own the text object instance.
- ScEditCell* pCell = new ScEditCell(rEE.CreateTextObject(), &rDoc);
- rDoc.PutCell( aScPos, pCell );
+ rDoc.SetEditText(aScPos, rEE.CreateTextObject());
}
break;
diff --git a/sc/source/filter/excel/xihelper.cxx b/sc/source/filter/excel/xihelper.cxx
index ef840f9..4f114a9 100644
--- a/sc/source/filter/excel/xihelper.cxx
+++ b/sc/source/filter/excel/xihelper.cxx
@@ -25,15 +25,14 @@
#include <editeng/eeitem.hxx>
#include <editeng/flditem.hxx>
#include "document.hxx"
-#include "cell.hxx"
#include "rangelst.hxx"
#include "editutil.hxx"
#include "attrib.hxx"
#include "xltracer.hxx"
#include "xistream.hxx"
#include "xistyle.hxx"
-
#include "excform.hxx"
+#include "stringutil.hxx"
// Excel->Calc cell address/range conversion ==================================
@@ -220,24 +219,39 @@ EditTextObject* XclImpStringHelper::CreateTextObject(
return lclCreateTextObject( rRoot, rString, EXC_FONTITEM_EDITENG, 0 );
}
-ScBaseCell* XclImpStringHelper::CreateCell(
- const XclImpRoot& rRoot, const XclImpString& rString, sal_uInt16 nXFIndex )
+void XclImpStringHelper::SetToDocument(
+ ScDocument& rDoc, const ScAddress& rPos, const XclImpRoot& rRoot,
+ const XclImpString& rString, sal_uInt16 nXFIndex )
{
- ScBaseCell* pCell = 0;
+ if (!rString.GetText().Len())
+ return;
- if( rString.GetText().Len() )
- {
- ::std::auto_ptr< EditTextObject > pTextObj( lclCreateTextObject( rRoot, rString, EXC_FONTITEM_EDITENG, nXFIndex ) );
- ScDocument& rDoc = rRoot.GetDoc();
+ ::std::auto_ptr< EditTextObject > pTextObj( lclCreateTextObject( rRoot, rString, EXC_FONTITEM_EDITENG, nXFIndex ) );
- if( pTextObj.get() )
- // ScEditCell will own the text object instance.
- pCell = new ScEditCell(pTextObj.release(), &rDoc);
+ if (pTextObj.get())
+ {
+ rDoc.SetEditText(rPos, pTextObj.release());
+ }
+ else
+ {
+ OUString aStr = rString.GetText();
+ if (aStr.indexOf('\n') != -1 || aStr.indexOf(CHAR_CR) != -1)
+ {
+ // Multiline content.
+ ScFieldEditEngine& rEngine = rDoc.GetEditEngine();
+ rEngine.SetText(aStr);
+ rDoc.SetEditText(rPos, rEngine.CreateTextObject());
+ }
else
- pCell = ScBaseCell::CreateTextCell( rString.GetText(), &rDoc );
+ {
+ // Normal text cell.
+ ScSetStringParam aParam;
+ aParam.mbDetectNumberFormat = false;
+ aParam.mbHandleApostrophe = false;
+ aParam.meSetTextNumFormat = ScSetStringParam::Always;
+ rDoc.SetString(rPos, aStr, &aParam);
+ }
}
-
- return pCell;
}
// Header/footer conversion ===================================================
diff --git a/sc/source/filter/inc/xicontent.hxx b/sc/source/filter/inc/xicontent.hxx
index f4128ad..c5d7aae 100644
--- a/sc/source/filter/inc/xicontent.hxx
+++ b/sc/source/filter/inc/xicontent.hxx
@@ -64,10 +64,6 @@ public:
/** Returns a pointer to the string with the passed index. */
const XclImpString* GetString( sal_uInt32 nSstIndex ) const;
- /** Creates a new text cell or edit cell for a Calc document.
- @param nXFIndex Index to XF for first text portion (checks escapement). */
- ScBaseCell* CreateCell( sal_uInt32 nSstIndex, sal_uInt16 nXFIndex = 0 ) const;
-
private:
typedef ::std::vector< XclImpString > XclImpStringVec;
XclImpStringVec maStrings; /// List with all strings in the SST.
diff --git a/sc/source/filter/inc/xihelper.hxx b/sc/source/filter/inc/xihelper.hxx
index 8917a7d..84eb924 100644
--- a/sc/source/filter/inc/xihelper.hxx
+++ b/sc/source/filter/inc/xihelper.hxx
@@ -109,12 +109,10 @@ public:
const XclImpRoot& rRoot,
const XclImpString& rString );
- /** Creates a new text cell or edit cell for a Calc document.
- @param nXFIndex Index to XF for first text portion (for escapement). */
- static ScBaseCell* CreateCell(
- const XclImpRoot& rRoot,
- const XclImpString& rString,
- sal_uInt16 nXFIndex = 0 );
+ static void SetToDocument(
+ ScDocument& rDoc, const ScAddress& rPos, const XclImpRoot& rRoot,
+ const XclImpString& rString, sal_uInt16 nXFIndex = 0 );
+
private:
/** We don't want anybody to instantiate this class, since it is just a
collection of static methods. To enforce this, the default constructor
diff --git a/sc/source/filter/oox/worksheethelper.cxx b/sc/source/filter/oox/worksheethelper.cxx
index 3f93056..c83e3c0 100644
--- a/sc/source/filter/oox/worksheethelper.cxx
+++ b/sc/source/filter/oox/worksheethelper.cxx
@@ -1572,10 +1572,9 @@ void WorksheetHelper::putRichString( const CellAddress& rAddress, const RichStri
ScEditEngineDefaulter& rEE = getEditEngine();
// The cell will own the text object instance returned from convert().
- ScBaseCell* pNewCell = new ScEditCell(rString.convert(rEE, pFirstPortionFont), &rDoc);
ScAddress aAddress;
ScUnoConversion::FillScAddress( aAddress, rAddress );
- rDoc.PutCell( aAddress, pNewCell );
+ rDoc.SetEditText(aAddress, rString.convert(rEE, pFirstPortionFont));
}
void WorksheetHelper::putFormulaTokens( const CellAddress& rAddress, const ApiTokenSequence& rTokens ) const
diff --git a/sc/source/filter/rtf/eeimpars.cxx b/sc/source/filter/rtf/eeimpars.cxx
index 5e3dd69..23a4c3c 100644
--- a/sc/source/filter/rtf/eeimpars.cxx
+++ b/sc/source/filter/rtf/eeimpars.cxx
@@ -47,7 +47,6 @@
#include "docpool.hxx"
#include "attrib.hxx"
#include "patattr.hxx"
-#include "cell.hxx"
#include "eeparser.hxx"
#include "drwlayer.hxx"
#include "rangenam.hxx"
@@ -386,19 +385,20 @@ void ScEEImport::WriteToDocument( bool bSizeColsRows, double nOutputFactor, SvNu
aStr.SearchAndReplaceAll( (sal_Unicode)'\n', (sal_Unicode)' ' );
if (bTextFormat)
- mpDoc->PutCell( nCol, nRow, nTab, new ScStringCell( aStr));
- else
{
- aParam.mbDetectNumberFormat = bConvertDate;
- mpDoc->SetString( nCol, nRow, nTab, aStr, &aParam );
+ aParam.mbDetectNumberFormat = false;
+ aParam.meSetTextNumFormat = ScSetStringParam::Always;
}
+ else
+ aParam.mbDetectNumberFormat = bConvertDate;
+
+ mpDoc->SetString(nCol, nRow, nTab, aStr, &aParam);
}
}
else
{
// The cell will own the text object instance.
- mpDoc->PutCell(
- nCol, nRow, nTab, new ScEditCell(mpEngine->CreateTextObject(pE->aSel), mpDoc));
+ mpDoc->SetEditText(ScAddress(nCol,nRow,nTab), mpEngine->CreateTextObject(pE->aSel));
}
if ( pE->maImageList.size() )
bHasGraphics |= GraphicSize( nCol, nRow, nTab, pE );
diff --git a/sc/source/filter/xml/xmlcelli.cxx b/sc/source/filter/xml/xmlcelli.cxx
index 7126f14..19b9041 100644
--- a/sc/source/filter/xml/xmlcelli.cxx
+++ b/sc/source/filter/xml/xmlcelli.cxx
@@ -1053,14 +1053,14 @@ void ScXMLTableRowCellContext::PutTextCell( const ScAddress& rCurrentPos,
// This edit engine uses the SfxItemPool instance returned
// from pDoc->GetEditPool() to create the text object, which
// is a prerequisite for using this constructor of ScEditCell.
- pNewCell = new ScEditCell(mpEditEngine->CreateTextObject(), pDoc);
+ pDoc->SetEditText(rCurrentPos, mpEditEngine->CreateTextObject());
}
}
else if ( nCurrentCol > 0 && pOUText && !pOUText->isEmpty() )
pNewCell = ScBaseCell::CreateTextCell( *pOUText, pDoc );
bDoIncrement = pNewCell != NULL;
- if ( bDoIncrement )
+ if (bDoIncrement && pNewCell)
pDoc->PutCell( rCurrentPos, pNewCell );
}
// #i56027# This is about setting simple text, not edit cells,
diff --git a/sc/source/ui/app/transobj.cxx b/sc/source/ui/app/transobj.cxx
index 5325fac..b756000 100644
--- a/sc/source/ui/app/transobj.cxx
+++ b/sc/source/ui/app/transobj.cxx
@@ -817,11 +817,17 @@ void ScTransferObj::StripRefs( ScDocument* pDoc,
{
String aStr = pFCell->GetString();
if ( pFCell->IsMultilineResult() )
- pNew = new ScEditCell( aStr, pDestDoc );
+ {
+ ScFieldEditEngine& rEngine = pDestDoc->GetEditEngine();
+ rEngine.SetText(aStr);
+ pDestDoc->SetEditText(ScAddress(nCol,nRow,nDestTab), rEngine.CreateTextObject());
+ }
else
pNew = new ScStringCell( aStr );
}
- pDestDoc->PutCell( nCol,nRow,nDestTab, pNew );
+
+ if (pNew)
+ pDestDoc->PutCell(nCol, nRow, nDestTab, pNew);
// number formats
diff --git a/sc/source/ui/docshell/impex.cxx b/sc/source/ui/docshell/impex.cxx
index 92a38de..b94146c 100644
--- a/sc/source/ui/docshell/impex.cxx
+++ b/sc/source/ui/docshell/impex.cxx
@@ -1204,7 +1204,9 @@ static bool lcl_PutString(
else
{
bMultiLine = true;
- pDoc->PutCell( nCol, nRow, nTab, new ScEditCell( rStr, pDoc ) );
+ ScFieldEditEngine& rEngine = pDoc->GetEditEngine();
+ rEngine.SetText(rStr);
+ pDoc->SetEditText(ScAddress(nCol,nRow,nTab), rEngine.CreateTextObject());
}
return bMultiLine;
}
diff --git a/sc/source/ui/undo/undoblk3.cxx b/sc/source/ui/undo/undoblk3.cxx
index e3b3c64..fa3a56c 100644
--- a/sc/source/ui/undo/undoblk3.cxx
+++ b/sc/source/ui/undo/undoblk3.cxx
@@ -49,6 +49,7 @@
#include "postit.hxx"
#include "docuno.hxx"
#include "progress.hxx"
+#include "editutil.hxx"
// STATIC DATA ---------------------------------------------------------------
@@ -1023,7 +1024,11 @@ void ScUndoReplace::Undo()
{
// aUndoStr may contain line breaks
if ( aUndoStr.Search('\n') != STRING_NOTFOUND )
- pDoc->PutCell( aCursorPos, new ScEditCell( aUndoStr, pDoc ) );
+ {
+ ScFieldEditEngine& rEngine = pDoc->GetEditEngine();
+ rEngine.SetText(aUndoStr);
+ pDoc->SetEditText(aCursorPos, rEngine.CreateTextObject());
+ }
else
pDoc->SetString( aCursorPos.Col(), aCursorPos.Row(), aCursorPos.Tab(), aUndoStr );
if (pViewShell)
diff --git a/sc/source/ui/unoobj/cellsuno.cxx b/sc/source/ui/unoobj/cellsuno.cxx
index 90511ae..cfd864a 100644
--- a/sc/source/ui/unoobj/cellsuno.cxx
+++ b/sc/source/ui/unoobj/cellsuno.cxx
@@ -2359,7 +2359,7 @@ void ScCellRangesBase::SetOnePropertyValue( const SfxItemPropertySimpleEntry* pE
aEngine.QuickSetAttribs( aAttr, ESelection( 0, 0, 0, aStr.Len()));
// The cell will own the text object instance.
- pDoc->PutCell(aRanges[0]->aStart, new ScEditCell(aEngine.CreateTextObject(), pDoc));
+ pDoc->SetEditText(aRanges[0]->aStart, aEngine.CreateTextObject());
}
}
}
diff --git a/sc/source/ui/view/viewfun4.cxx b/sc/source/ui/view/viewfun4.cxx
index 33ac576..ea05778 100644
--- a/sc/source/ui/view/viewfun4.cxx
+++ b/sc/source/ui/view/viewfun4.cxx
@@ -414,9 +414,8 @@ void ScViewFunc::DoThesaurus( sal_Bool bRecord )
if (pCell && pTObject)
{
// The cell will own the text object instance.
- pDoc->PutCell(
- nCol, nRow, nTab,
- new ScEditCell(pThesaurusEngine->CreateTextObject(), pDoc));
+ pDoc->SetEditText(
+ ScAddress(nCol,nRow,nTab), pThesaurusEngine->CreateTextObject());
}
else
{
commit d0314afa2fef363eba06e98c70ecdc83e690dcd0
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date: Tue Mar 19 10:00:07 2013 -0400
This ScFormulaCell member is not used. Also remove cell.hxx include...
Change-Id: I5d188bb080943acc4b8e4ae44a4c8ef01a837c2f
diff --git a/sc/source/ui/inc/anyrefdg.hxx b/sc/source/ui/inc/anyrefdg.hxx
index 760879a..bba97a7 100644
--- a/sc/source/ui/inc/anyrefdg.hxx
+++ b/sc/source/ui/inc/anyrefdg.hxx
@@ -26,7 +26,6 @@
#include <sfx2/basedlgs.hxx>
#include <sfx2/tabdlg.hxx>
#include "address.hxx"
-#include "cell.hxx"
#include "compiler.hxx"
#include "formula/funcutl.hxx"
#include "IAnyRefDialog.hxx"
@@ -45,7 +44,6 @@ class ScRangeList;
class ScFormulaReferenceHelper
{
IAnyRefDialog* m_pDlg;
- ::std::auto_ptr<ScFormulaCell> pRefCell;
::std::auto_ptr<ScCompiler> pRefComp;
formula::RefEdit* pRefEdit; // active input field
formula::RefButton* pRefBtn; // associated button
diff --git a/sc/source/ui/inc/formula.hxx b/sc/source/ui/inc/formula.hxx
index 1b3790e..997e198 100644
--- a/sc/source/ui/inc/formula.hxx
+++ b/sc/source/ui/inc/formula.hxx
@@ -38,6 +38,7 @@ class ScDocument;
class ScFuncDesc;
class ScInputHandler;
class ScDocShell;
+class ScFormulaCell;
//============================================================================
typedef ScTabViewShell* PtrTabViewShell;
diff --git a/sc/source/ui/miscdlgs/anyrefdg.cxx b/sc/source/ui/miscdlgs/anyrefdg.cxx
index e1b60ba..cec4522 100644
--- a/sc/source/ui/miscdlgs/anyrefdg.cxx
+++ b/sc/source/ui/miscdlgs/anyrefdg.cxx
@@ -323,7 +323,6 @@ void ScFormulaReferenceHelper::Init()
ScAddress aCursorPos( nCol, nRow, nTab );
String rStrExp;
- pRefCell.reset( new ScFormulaCell( pDoc, aCursorPos, rStrExp ) );
pRefComp.reset( new ScCompiler( pDoc, aCursorPos) );
pRefComp->SetGrammar( pDoc->GetGrammar() );
pRefComp->SetCompileForFAP(true);
commit c27b2fb8433758240c00bcd76c7fa322eccdee9c
Author: Michael Meeks <michael.meeks at suse.com>
Date: Tue Mar 19 16:33:17 2013 +0000
start of InterpretFormulaGroup.
handle column invariant formulae, sketch comment more work,
elide Matrix formulae.
Change-Id: I9ce4da26b0ad2407021a10f21c81ada80442c76d
diff --git a/sc/inc/cell.hxx b/sc/inc/cell.hxx
index a096c37..fa5cf23 100644
--- a/sc/inc/cell.hxx
+++ b/sc/inc/cell.hxx
@@ -598,6 +598,7 @@ public:
{ xGroup = xRef; }
ScSimilarFormulaDelta *BuildDeltaTo( ScFormulaCell *pOther );
void ReleaseDelta( ScSimilarFormulaDelta *pDelta );
+ bool InterpretFormulaGroup();
};
// Iterator for references in a formula cell
diff --git a/sc/source/core/data/cell.cxx b/sc/source/core/data/cell.cxx
index 5dfd8e5..8305127 100644
--- a/sc/source/core/data/cell.cxx
+++ b/sc/source/core/data/cell.cxx
@@ -1198,11 +1198,6 @@ void ScFormulaCell::Interpret()
if (!IsDirtyOrInTableOpDirty() || pDocument->GetRecursionHelper().IsInReturn())
return; // no double/triple processing
- // Re-build formulae groups - ideally this is done at import / insert / delete etc.
- // and is reflected in the dependency data ...
- pDocument->RebuildFormulaGroups();
-
-
//! HACK:
// If the call originates from a Reschedule in DdeLink update, leave dirty
// Better: Do a Dde Link Update without Reschedule or do it completely asynchronously!
@@ -1243,7 +1238,8 @@ void ScFormulaCell::Interpret()
}
else
{
- InterpretTail( SCITP_NORMAL);
+ if ( ! InterpretFormulaGroup() )
+ InterpretTail( SCITP_NORMAL);
}
// While leaving a recursion or iteration stack, insert its cells to the
diff --git a/sc/source/core/data/cell2.cxx b/sc/source/core/data/cell2.cxx
index ca21710..0724501 100644
--- a/sc/source/core/data/cell2.cxx
+++ b/sc/source/core/data/cell2.cxx
@@ -1689,9 +1689,9 @@ void ScFormulaCell::CompileColRowNameFormula()
}
}
+// we really want to be a lot more descriptive than this
struct ScSimilarFormulaDelta : std::vector< size_t >
{
- // we really want to be a lot more descriptive than this
bool IsCompatible( ScSimilarFormulaDelta *pDelta )
{
if ( size() != pDelta->size() )
@@ -1710,6 +1710,17 @@ struct ScSimilarFormulaDelta : std::vector< size_t >
push_back( b.nRow - a.nRow );
push_back( b.nTab - a.nTab );
}
+
+ /// if the vector is zero then nothing changes down the column.
+ bool IsInvariant() const
+ {
+ for ( size_t i = 0; i < size(); i++ )
+ {
+ if ( (*this)[ i ] != 0 )
+ return false;
+ }
+ return true;
+ }
};
bool ScFormulaCellGroup::IsCompatible( ScSimilarFormulaDelta *pDelta )
@@ -1722,6 +1733,10 @@ bool ScFormulaCellGroup::IsCompatible( ScSimilarFormulaDelta *pDelta )
/// formulae should produce pOther
ScSimilarFormulaDelta *ScFormulaCell::BuildDeltaTo( ScFormulaCell *pOtherCell )
{
+ // no Matrix formulae yet.
+ if ( GetMatrixFlag() != MM_NONE )
+ return NULL;
+
// are these formule at all similar ?
if ( GetHash() != pOtherCell->GetHash() )
return NULL;
@@ -1787,11 +1802,84 @@ ScSimilarFormulaDelta *ScFormulaCell::BuildDeltaTo( ScFormulaCell *pOtherCell )
return pDelta;
}
+/// To avoid exposing impl. details of ScSimilarFormulaDelta publicly
void ScFormulaCell::ReleaseDelta( ScSimilarFormulaDelta *pDelta )
{
delete pDelta;
}
+bool ScFormulaCell::InterpretFormulaGroup()
+{
+ // Re-build formulae groups if necessary - ideally this is done at
+ // import / insert / delete etc. and is integral to the data structures
+ pDocument->RebuildFormulaGroups();
+
+ if( !xGroup.get() )
+ return false;
+
+ fprintf( stderr, "Interpret cell %d, %d\n", (int)aPos.Col(), (int)aPos.Row() );
+
+ if ( xGroup->mpDelta->IsInvariant() )
+ {
+ fprintf( stderr, "struck gold - completely invariant for %d items !\n",
+ (int)xGroup->mnLength );
+
+ // calculate ourselves:
+ InterpretTail( SCITP_NORMAL );
+ for ( sal_Int32 i = 0; i < xGroup->mnLength; i++ )
+ {
+ ScBaseCell *pBaseCell = NULL;
+ pDocument->GetCell( aPos.Col(),
+ xGroup->mnStart + i,
+ aPos.Tab(), pBaseCell );
+ assert( pBaseCell != NULL );
+ assert( pBaseCell->GetCellType() == CELLTYPE_FORMULA );
+ ScFormulaCell *pCell = static_cast<ScFormulaCell *>( pBaseCell );
+
+ // FIXME: this set of horrors is unclear to me ... certainly
+ // the above GetCell is profoundly nasty & slow ...
+
+ // Ensure the cell truly has a result:
+ pCell->aResult = aResult;
+ pCell->ResetDirty();
+
+ // FIXME: there is a view / refresh missing here it appears.
+ }
+ return true;
+ }
+ else
+ {
+ // scan the formula ...
+ // have a document method: "Get2DRangeAsDoublesArray" that does the
+ // column-based heavy lifting call it for each absolute range from the
+ // first cell pos in the formula group.
+ //
+ // Project single references to ranges by adding their vector * xGroup->mnLength
+ //
+ // TODO:
+ // elide multiple dimensional movement in vectors eg. =SUM(A1<1,1>)
+ // produces a diagonal 'column' that serves no useful purpose for us.
+ // these should be very rare. Should elide in GetDeltas anyway and
+ // assert here.
+ //
+ // Having built our input data ...
+ // Throw it, and the formula over to some 'OpenCLCalculage' hook
+ //
+ // on return - release references on these double buffers
+ //
+ // transfer the result to the formula cells (as above)
+ // store the doubles in the columns' maDoubles array for
+ // dependent formulae
+ //
+ // TODO:
+ // need to abort/fail when we get errors returned and fallback to
+ // stock interpreting [ I guess ], unless we can use NaN etc. to
+ // signal errors.
+
+ return false;
+ }
+}
+
// ============================================================================
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit 244033d7148e0badbf5915e21b7f2d67e41bf4eb
Author: Michael Meeks <michael.meeks at suse.com>
Date: Tue Mar 19 15:52:07 2013 +0000
get row offset calculation right for groups.
Change-Id: Id65174bbb70a4387cddb985d0556a3bcd692d671
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index f702b25..fb6c212 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -2028,6 +2028,7 @@ void ScColumn::RebuildFormulaGroups()
if ( rCur.pCell && rCur.pCell->GetCellType() == CELLTYPE_FORMULA )
static_cast<ScFormulaCell *>( rCur.pCell )->SetCellGroup( xNone );
}
+ maFnGroups.clear();
// re-build groups
ColDoubleEntry *pLastDouble = NULL;
@@ -2049,7 +2050,7 @@ void ScColumn::RebuildFormulaGroups()
if ( !pLastDouble )
{
pLastDouble = new ColDoubleEntry();
- pLastDouble->mnStart = i - 1;
+ pLastDouble->mnStart = rPrev.nRow;
pLastDouble->maData.push_back(
static_cast< ScValueCell * >( rPrev.pCell )->GetValue() );
maDoubles.push_back( pLastDouble );
@@ -2081,7 +2082,7 @@ void ScColumn::RebuildFormulaGroups()
// create a new group ...
ScFormulaCellGroup *pGroup = new ScFormulaCellGroup();
pGroup->mpDelta = pDelta;
- pGroup->mnStart = i - 1;
+ pGroup->mnStart = rPrev.nRow;
pGroup->mnLength = 2;
xGroup.reset( pGroup );
commit 290d192a9e7f1877b08537da379d09a8a557c94f
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date: Tue Mar 19 09:40:43 2013 -0400
Tweak hash generation code to NOT rely on 'i' to shift bits.
Because 'i' can get very large.
Change-Id: I1c7fcafaa60b14f709861f32c56defc7bcaee451
diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx
index 6368ba7..85d6e9a 100644
--- a/sc/source/core/tool/token.cxx
+++ b/sc/source/core/tool/token.cxx
@@ -1386,45 +1386,48 @@ void ScTokenArray::GenHash()
{
// Constant value.
sal_uInt8 nVal = p->GetByte();
- nHash += (static_cast<size_t>(nVal) << i);
- continue;
+ nHash += static_cast<size_t>(nVal);
}
+ break;
case svDouble:
{
// Constant value.
double fVal = p->GetDouble();
- nHash += (static_cast<size_t>(fVal) << i);
- continue;
+ nHash += static_cast<size_t>(fVal);
}
+ break;
case svString:
{
// Constant string.
const String& rStr = p->GetString();
- nHash += (aHasher(rStr) << i);
- continue;
+ nHash += aHasher(rStr);
}
+ break;
case svSingleRef:
{
size_t nVal = HashSingleRef(p->GetSingleRef());
- nHash += (nVal << i);
- continue;
+ nHash += nVal;
}
+ break;
case svDoubleRef:
{
const ScComplexRefData& rRef = p->GetDoubleRef();
size_t nVal1 = HashSingleRef(rRef.Ref1);
size_t nVal2 = HashSingleRef(rRef.Ref2);
- nHash += (nVal1 << i);
- nHash += (nVal2 << i);
- continue;
+ nHash += nVal1;
+ nHash += nVal2;
}
+ break;
default:
- ;
+ // Use the opcode value in all the other cases.
+ nHash += static_cast<size_t>(eOp);
}
}
+ else
+ // Use the opcode value in all the other cases.
+ nHash += static_cast<size_t>(eOp);
- // Use the opcode value in all the other cases.
- nHash += (static_cast<size_t>(eOp) << i);
+ nHash = (nHash << 4) - nHash;
}
mnHashValue = nHash;
commit 5a637138c0271357619629947e9cc6f90de2c03a
Author: Michael Meeks <michael.meeks at suse.com>
Date: Tue Mar 19 12:56:51 2013 +0000
build spans of doubles and cleanup excessive debug.
Change-Id: Ib76596cae12c87825118903cc61b12c251f0c1b7
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 18543f0..4776a70 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -25,6 +25,7 @@
#include "address.hxx"
#include "rangenam.hxx"
#include "types.hxx"
+#include <boost/intrusive_ptr.hpp>
#include <set>
#include <vector>
@@ -71,6 +72,8 @@ class ScFlatBoolRowSegments;
struct ScSetStringParam;
struct ScColWidthParam;
class ScColumnTextWidthIterator;
+class ScFormulaCellGroup;
+typedef ::boost::intrusive_ptr<ScFormulaCellGroup> ScFormulaCellGroupRef;
struct ScNeededSizeOptions
{
@@ -89,6 +92,12 @@ struct ColEntry
ScBaseCell* pCell;
};
+struct ColDoubleEntry
+{
+ SCROW mnStart;
+ std::vector<double> maData;
+};
+
class ScColumn
{
typedef mdds::multi_type_vector<mdds::mtv::element_block_func> TextWidthType;
@@ -109,6 +118,10 @@ class ScColumn
std::vector<ColEntry> maItems;
+ // temporary until we switch to mdds container
+ std::vector<ColDoubleEntry *> maDoubles;
+ std::vector<ScFormulaCellGroupRef> maFnGroups;
+
ScAttrArray* pAttrArray;
ScDocument* pDocument;
bool bDirtyGroups; /// formula groups are dirty.
diff --git a/sc/source/core/data/cell2.cxx b/sc/source/core/data/cell2.cxx
index f450f75..ca21710 100644
--- a/sc/source/core/data/cell2.cxx
+++ b/sc/source/core/data/cell2.cxx
@@ -1733,15 +1733,12 @@ ScSimilarFormulaDelta *ScFormulaCell::BuildDeltaTo( ScFormulaCell *pOtherCell )
if ( !pThis || !pOther )
{
- fprintf( stderr, "no compiled code for cells !" );
+ fprintf( stderr, "Error: no compiled code for cells !" );
return NULL;
}
if ( pThisLen != pOtherLen )
- {
- fprintf( stderr, "different length formulae !" );
return NULL;
- }
// check we are basically the same function
for ( sal_uInt16 i = 0; i < pThisLen; i++ )
@@ -1750,7 +1747,7 @@ ScSimilarFormulaDelta *ScFormulaCell::BuildDeltaTo( ScFormulaCell *pOtherCell )
pThis[ i ]->GetOpCode() != pOther[ i ]->GetOpCode() ||
pThis[ i ]->GetParamCount() != pOther[ i ]->GetParamCount() )
{
- fprintf( stderr, "Incompatible type, op-code or param counts\n" );
+// fprintf( stderr, "Incompatible type, op-code or param counts\n" );
return NULL;
}
switch( pThis[ i ]->GetType() )
@@ -1758,32 +1755,33 @@ ScSimilarFormulaDelta *ScFormulaCell::BuildDeltaTo( ScFormulaCell *pOtherCell )
case formula::svMatrix:
case formula::svExternalSingleRef:
case formula::svExternalDoubleRef:
- fprintf( stderr, "Ignoring matrix and external references for now\n" );
+// fprintf( stderr, "Ignoring matrix and external references for now\n" );
return NULL;
default:
break;
}
}
- fprintf( stderr, "matching formulae !\n" );
ScSimilarFormulaDelta *pDelta = new ScSimilarFormulaDelta();
for ( sal_uInt16 i = 0; i < pThisLen; i++ )
{
- if ( pThis[i]->GetType() != formula::svSingleRef &&
- pThis[i]->GetType() != formula::svDoubleRef )
- continue;
-
ScToken *pThisTok = static_cast< ScToken * >( pThis[ i ] );
ScToken *pOtherTok = static_cast< ScToken * >( pOther[ i ] );
- const ScSingleRefData& aThisRef = pThisTok->GetSingleRef();
- const ScSingleRefData& aOtherRef = pOtherTok->GetSingleRef();
- pDelta->push_delta( aThisRef, aOtherRef );
-
- const ScSingleRefData& aThisRef2 = pThisTok->GetSingleRef2();
- const ScSingleRefData& aOtherRef2 = pOtherTok->GetSingleRef2();
- pDelta->push_delta( aThisRef2, aOtherRef2 );
+ if ( pThis[i]->GetType() == formula::svSingleRef ||
+ pThis[i]->GetType() == formula::svDoubleRef )
+ {
+ const ScSingleRefData& aThisRef = pThisTok->GetSingleRef();
+ const ScSingleRefData& aOtherRef = pOtherTok->GetSingleRef();
+ pDelta->push_delta( aThisRef, aOtherRef );
+ }
+ if ( pThis[i]->GetType() == formula::svDoubleRef )
+ {
+ const ScSingleRefData& aThisRef2 = pThisTok->GetSingleRef2();
+ const ScSingleRefData& aOtherRef2 = pOtherTok->GetSingleRef2();
+ pDelta->push_delta( aThisRef2, aOtherRef2 );
+ }
}
return pDelta;
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index 6305747..ff8aa35 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -2022,7 +2022,6 @@ void ScColumn::UpdateCompile( bool bForceIfNameInUse )
{
if ( !maItems.empty() )
{
- fprintf( stderr, "UpdateCompile - column !?\n" );
for (SCSIZE i = 0; i < maItems.size(); i++)
{
ScFormulaCell* p = (ScFormulaCell*) maItems[i].pCell;
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index 6ee4495..f702b25 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -2014,6 +2014,12 @@ void ScColumn::RebuildFormulaGroups()
if ( maItems.empty() || !bDirtyGroups )
return;
+ // clear double groups
+ for (std::vector< ColDoubleEntry *>::iterator it = maDoubles.begin();
+ it != maDoubles.end(); ++it )
+ delete *it;
+ maDoubles.clear();
+
// clear previous groups
ScFormulaCellGroupRef xNone;
for (size_t i = 0; i < maItems.size(); i++)
@@ -2024,21 +2030,42 @@ void ScColumn::RebuildFormulaGroups()
}
// re-build groups
+ ColDoubleEntry *pLastDouble = NULL;
for (size_t i = 1; i < maItems.size(); i++)
{
ColEntry &rCur = maItems[ i ];
ColEntry &rPrev = maItems[ i - 1 ];
- if ( ( rPrev.nRow != rCur.nRow - 1 ) || // not contiguous
- !rCur.pCell || !rPrev.pCell || // paranoia
- rCur.pCell->GetCellType() != CELLTYPE_FORMULA || // not formulae
- rPrev.pCell->GetCellType() != CELLTYPE_FORMULA )
+ if ( ( rPrev.nRow != rCur.nRow - 1 ) || // not contiguous
+ !rCur.pCell || !rPrev.pCell || // paranoia
+ rCur.pCell->GetCellType() != rPrev.pCell->GetCellType() ) // same type
+ {
+ pLastDouble = NULL;
+ continue;
+ }
+
+ // collate doubles
+ if ( rCur.pCell->GetCellType() == CELLTYPE_VALUE )
+ {
+ if ( !pLastDouble )
+ {
+ pLastDouble = new ColDoubleEntry();
+ pLastDouble->mnStart = i - 1;
+ pLastDouble->maData.push_back(
+ static_cast< ScValueCell * >( rPrev.pCell )->GetValue() );
+ maDoubles.push_back( pLastDouble );
+ }
+ pLastDouble->maData.push_back(
+ static_cast< ScValueCell * >( rCur.pCell )->GetValue() );
+ continue;
+ }
+
+ if ( rCur.pCell->GetCellType() != CELLTYPE_FORMULA )
continue;
// see if these formulae are similar
ScFormulaCell *pCur = static_cast< ScFormulaCell *>( rCur.pCell );
ScFormulaCell *pPrev = static_cast< ScFormulaCell *>( rPrev.pCell );
- fprintf( stderr, "column has contiguous formulae\n" );
ScSimilarFormulaDelta *pDelta = pPrev->BuildDeltaTo( pCur );
if ( !pDelta )
@@ -2058,6 +2085,8 @@ void ScColumn::RebuildFormulaGroups()
pGroup->mnLength = 2;
xGroup.reset( pGroup );
+ maFnGroups.push_back( xGroup );
+
pCur->SetCellGroup( xGroup );
pPrev->SetCellGroup( xGroup );
}
@@ -2070,6 +2099,7 @@ void ScColumn::RebuildFormulaGroups()
}
else
{
+#if OSL_DEBUG_LEVEL > 1
OUString aFormula;
pCur->GetFormula( aFormula );
ScAddress aAddr( nCol, rCur.nRow, nTab );
@@ -2079,11 +2109,40 @@ void ScColumn::RebuildFormulaGroups()
fprintf( stderr, "unusual incompatible extension in cell '%s' of formulae '%s'\n" ,
OUStringToOString( aCellAddr, RTL_TEXTENCODING_UTF8 ).getStr(),
OUStringToOString( aFormula, RTL_TEXTENCODING_UTF8 ).getStr() );
-
+#endif
pCur->ReleaseDelta( pDelta );
}
}
+#if 1 // OSL_DEBUG_LEVEL > 0
+ if ( maDoubles.size() + maFnGroups.size() > 0 )
+ {
+ rtl::OUString aStr;
+ fprintf( stderr, "column %2d has %2d double span(s): ", (int)nCol, (int)maDoubles.size() );
+ for (std::vector< ColDoubleEntry *>::iterator it = maDoubles.begin();
+ it != maDoubles.end(); ++it )
+ {
+ ScRange aDoubleRange( nCol, (*it)->mnStart, nTab,
+ nCol, (*it)->mnStart + (*it)->maData.size() - 1, nTab );
+ aDoubleRange.Format( aStr, SCA_VALID | SCA_VALID_COL | SCA_VALID_ROW, pDocument );
+ fprintf( stderr, "%s, ", OUStringToOString( aStr, RTL_TEXTENCODING_UTF8 ).getStr() );
+ }
+ fprintf( stderr, "\n" );
+
+ fprintf( stderr, "column %2d has %2d formula span(s): ", (int)nCol, (int)maFnGroups.size() );
+ for (std::vector< ScFormulaCellGroupRef>::iterator it = maFnGroups.begin();
+ it != maFnGroups.end(); ++it )
+ {
+ ScRange aDoubleRange( nCol, (*it)->mnStart, nTab,
+ nCol, (*it)->mnStart + (*it)->mnLength - 1, nTab );
+ aDoubleRange.Format( aStr, SCA_VALID | SCA_VALID_COL | SCA_VALID_ROW, pDocument );
+ fprintf( stderr, "%s, ", OUStringToOString( aStr, RTL_TEXTENCODING_UTF8 ).getStr() );
+ }
+ fprintf( stderr, "\n" );
+ }
+#endif
+
+
bDirtyGroups = false;
}
commit 9d269e1820efc532a0271f04505c590805a6c48b
Author: Michael Meeks <michael.meeks at suse.com>
Date: Tue Mar 19 11:52:14 2013 +0000
use cell hashing algorithm for computing groups.
Update unit tests, dumb-down hashing to compare more for similiarity
rather than identicality - we want to use this down columns.
Change-Id: Icea731daeb301e1febb2df48b6b46c9faba74e9d
diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx
index 63b740b..81fa1ea 100644
--- a/sc/qa/unit/ucalc.cxx
+++ b/sc/qa/unit/ucalc.cxx
@@ -1222,6 +1222,13 @@ void Test::testFormulaHashAndTag()
{ "=X20", "=X$20", false }, // absolute vs relative
{ "=X20", "=$X20", false }, // absolute vs relative
{ "=X$20", "=$X20", false }, // column absolute vs row absolute
+ // similar enough for merging ...
+ { "=A1", "=B1", true },
+ { "=$A$1", "=$B$1", true },
+ { "=A1", "=C2", true },
+ { "=SUM(A1)", "=SUM(B1)", true },
+ { "=A1+3", "=B1+3", true },
+ { "=A1+7", "=B1+42", false },
};
for (size_t i = 0; i < SAL_N_ELEMENTS(aHashTests); ++i)
@@ -6221,14 +6228,14 @@ void Test::testFormulaGrouping()
const char *pFormula[3];
const bool bGroup[3];
} aGroupTests[] = {
- { { "=B1", "=C1", "" }, // single increments
- { true, true, false } },
- { { "=B1", "=D1", "=F1" }, // tripple increments
- { true, true, true } },
- { { "=B1", "", "=C1" }, // a gap
- { false, false, false } },
- { { "=B1", "=C1+3", "=C1+D1" }, // confusion: FIXME: =C1+7
- { false, false, false } },
+ { { "=SUM(B1)", "=SUM(C1)", "" }, // single increments
+ { true, true, false } },
+ { { "=SUM(B1)", "=SUM(D1)", "=SUM(F1)" }, // tripple increments
+ { true, true, true } },
+ { { "=SUM(B1)", "", "=SUM(C1)" }, // a gap
+ { false, false, false } },
+ { { "=SUM(B1)", "=SUM(C1;3)", "=SUM(D1;3)" }, // similar foo
+ { false, true, true } },
};
m_pDoc->InsertTab( 0, "sheet" );
@@ -6259,7 +6266,7 @@ void Test::testFormulaGrouping()
if( !!pCur->GetCellGroup().get() ^ aGroupTests[i].bGroup[j] )
{
printf("expected group test %d at row %d to be %d but is %d\n",
- i, j, !!pCur->GetCellGroup().get(), aGroupTests[i].bGroup[j]);
+ i, j, aGroupTests[i].bGroup[j], !!pCur->GetCellGroup().get());
CPPUNIT_ASSERT_MESSAGE("Failed", false);
}
}
diff --git a/sc/source/core/data/cell2.cxx b/sc/source/core/data/cell2.cxx
index 412f85d..f450f75 100644
--- a/sc/source/core/data/cell2.cxx
+++ b/sc/source/core/data/cell2.cxx
@@ -1722,10 +1722,9 @@ bool ScFormulaCellGroup::IsCompatible( ScSimilarFormulaDelta *pDelta )
/// formulae should produce pOther
ScSimilarFormulaDelta *ScFormulaCell::BuildDeltaTo( ScFormulaCell *pOtherCell )
{
-
-// FIXME: TODO - M1
-// if ( kohei_comparison_hash_not_equal( mnHash, pOther->mnHash )
-// return NULL;
+ // are these formule at all similar ?
+ if ( GetHash() != pOtherCell->GetHash() )
+ return NULL;
FormulaToken **pThis = pCode->GetCode();
sal_uInt16 pThisLen = pCode->GetCodeLen();
diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx
index 23a2241..6368ba7 100644
--- a/sc/source/core/tool/token.cxx
+++ b/sc/source/core/tool/token.cxx
@@ -1348,19 +1348,16 @@ bool ScTokenArray::ImplGetReference( ScRange& rRange, bool bValidOnly ) const
namespace {
+// we want to compare for similar not identical formulae
+// so we can't use actual row & column indices.
size_t HashSingleRef( const ScSingleRefData& rRef )
{
- SCsCOL nCol = rRef.Flags.bColRel ? rRef.nRelCol : rRef.nCol;
- SCsROW nRow = rRef.Flags.bRowRel ? rRef.nRelRow : rRef.nRow;
- SCsTAB nTab = rRef.Flags.bTabRel ? rRef.nRelTab : rRef.nTab;
- size_t nVal = nCol;
- nVal += (nRow << 8);
- nVal += (nTab << 16);
+ size_t nVal = 0;
- // Embed flag values too.
nVal += rRef.Flags.bColRel;
nVal += (rRef.Flags.bRowRel << 1);
nVal += (rRef.Flags.bTabRel << 2);
+
return nVal;
}
commit b13550ed57ec438a57f6482d9ea6d16f354eec14
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date: Mon Mar 18 23:36:55 2013 -0400
Unit test for formula token array vectorization state.
Change-Id: I91dce36e56d86899ba506beb29df6188f10966c0
diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx
index f255781..63b740b 100644
--- a/sc/qa/unit/ucalc.cxx
+++ b/sc/qa/unit/ucalc.cxx
@@ -67,6 +67,7 @@
#include "calcconfig.hxx"
#include "interpre.hxx"
#include "columniterator.hxx"
+#include "types.hxx"
#include "formula/IFunctionDescription.hxx"
@@ -1203,6 +1204,8 @@ void Test::testFormulaHashAndTag()
ScAddress aPos1(0,0,0), aPos2(1,0,0);
+ // Test formula hashing.
+
struct {
const char* pFormula1; const char* pFormula2; bool bEqual;
} aHashTests[] = {
@@ -1245,6 +1248,37 @@ void Test::testFormulaHashAndTag()
aPos2.IncRow();
}
+ // Go back to row 1.
+ aPos1.SetRow(0);
+ aPos2.SetRow(0);
+
+ // Test formula vectorization state.
+
+ struct {
+ const char* pFormula; ScFormulaVectorState eState;
+ } aVectorTests[] = {
+ { "=SUM(1;2;3;4;5)", FormulaVectorEnabled },
+ { "=NOW()", FormulaVectorDisabled },
+ { "=AVERAGE(X1:Y200)", FormulaVectorCheckReference },
+ { "=MAX(X1:Y200;10;20)", FormulaVectorCheckReference },
+ { "=MIN(10;11;22)", FormulaVectorEnabled },
+ { "=H4", FormulaVectorCheckReference },
+ };
+
+ for (size_t i = 0; i < SAL_N_ELEMENTS(aVectorTests); ++i)
+ {
+ m_pDoc->SetString(aPos1, OUString::createFromAscii(aVectorTests[i].pFormula));
+ ScFormulaVectorState eState = m_pDoc->GetFormulaVectorState(aPos1);
+
+ if (eState != aVectorTests[i].eState)
+ {
+ std::ostringstream os;
+ os << "Unexpected vectorization state: expr:" << aVectorTests[i].pFormula;
+ CPPUNIT_ASSERT_MESSAGE(os.str().c_str(), false);
+ }
+ aPos1.IncRow();
+ }
+
m_pDoc->DeleteTab(0);
}
commit 307b9bfd17d34bcfc9a2ecdef7802413d79f3694
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date: Mon Mar 18 23:15:26 2013 -0400
Reduce dependency on document.hxx. Prefer forward declaration.
Change-Id: I9b0c86735284ec435cceb3acd9bad97a6e523a74
diff --git a/sc/Library_sc.mk b/sc/Library_sc.mk
index 066e0b6..48ebfd2 100644
--- a/sc/Library_sc.mk
+++ b/sc/Library_sc.mk
@@ -98,6 +98,7 @@ $(eval $(call gb_Library_add_exception_objects,sc,\
sc/source/core/data/attrib \
sc/source/core/data/autonamecache \
sc/source/core/data/bcaslot \
+ sc/source/core/data/bigrange \
sc/source/core/data/cell \
sc/source/core/data/cell2 \
sc/source/core/data/clipparam \
diff --git a/sc/inc/bigrange.hxx b/sc/inc/bigrange.hxx
index 09aaf3b..d36fa9a 100644
--- a/sc/inc/bigrange.hxx
+++ b/sc/inc/bigrange.hxx
@@ -20,14 +20,12 @@
#ifndef SC_BIGRANGE_HXX
#define SC_BIGRANGE_HXX
-
#include "global.hxx"
-#include "document.hxx"
-
static const sal_Int32 nInt32Min = 0x80000000;
static const sal_Int32 nInt32Max = 0x7fffffff;
+class ScDocument;
class ScBigAddress
{
@@ -61,7 +59,7 @@ public:
{ nColP = nCol; nRowP = nRow; nTabP = nTab; }
inline void PutInOrder( ScBigAddress& r );
- inline sal_Bool IsValid( const ScDocument* ) const;
+ bool IsValid( const ScDocument* pDoc ) const;
inline ScAddress MakeAddress() const;
ScBigAddress& operator=( const ScBigAddress& r )
@@ -101,20 +99,6 @@ inline void ScBigAddress::PutInOrder( ScBigAddress& r )
}
}
-
-inline sal_Bool ScBigAddress::IsValid( const ScDocument* pDoc ) const
-{ // min/max interval bounds define whole col/row/tab
- return
- ((0 <= nCol && nCol <= MAXCOL)
- || nCol == nInt32Min || nCol == nInt32Max) &&
- ((0 <= nRow && nRow <= MAXROW)
- || nRow == nInt32Min || nRow == nInt32Max) &&
- ((0 <= nTab && nTab < pDoc->GetTableCount())
- || nTab == nInt32Min || nTab == nInt32Max)
- ;
-}
-
-
inline ScAddress ScBigAddress::MakeAddress() const
{
SCCOL nColA;
diff --git a/sc/inc/chgtrack.hxx b/sc/inc/chgtrack.hxx
index 4c94932..c4c22a9 100644
--- a/sc/inc/chgtrack.hxx
+++ b/sc/inc/chgtrack.hxx
@@ -27,6 +27,7 @@
#include <tools/datetime.hxx>
#include <tools/mempool.hxx>
+#include "tools/link.hxx"
#include <unotools/options.hxx>
#include "global.hxx"
#include "bigrange.hxx"
@@ -39,7 +40,7 @@
class ScBaseCell;
class ScDocument;
-
+class ScFormulaCell;
enum ScChangeActionType
{
diff --git a/sc/qa/unit/helper/debughelper.hxx b/sc/qa/unit/helper/debughelper.hxx
index 2a560c6..4de5c9d 100644
--- a/sc/qa/unit/helper/debughelper.hxx
+++ b/sc/qa/unit/helper/debughelper.hxx
@@ -36,7 +36,6 @@
#include <rtl/strbuf.hxx>
#include <rtl/ustring.hxx>
-#include "document.hxx"
#ifdef WNT
#if !defined NOMINMAX
diff --git a/sc/source/core/data/bigrange.cxx b/sc/source/core/data/bigrange.cxx
new file mode 100644
index 0000000..a48e020
--- /dev/null
+++ b/sc/source/core/data/bigrange.cxx
@@ -0,0 +1,30 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef __SC_BIGRANGE_CXX__
+#define __SC_BIGRANGE_CXX__
+
+#include "bigrange.hxx"
+#include "document.hxx"
+
+bool ScBigAddress::IsValid( const ScDocument* pDoc ) const
+{ // min/max interval bounds define whole col/row/tab
+ return
+ ((0 <= nCol && nCol <= MAXCOL)
+ || nCol == nInt32Min || nCol == nInt32Max) &&
+ ((0 <= nRow && nRow <= MAXROW)
+ || nRow == nInt32Min || nRow == nInt32Max) &&
+ ((0 <= nTab && nTab < pDoc->GetTableCount())
+ || nTab == nInt32Min || nTab == nInt32Max)
+ ;
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/inc/interpre.hxx b/sc/source/core/inc/interpre.hxx
index 16eb22c..906f4d6 100644
--- a/sc/source/core/inc/interpre.hxx
+++ b/sc/source/core/inc/interpre.hxx
@@ -26,7 +26,6 @@
#include "formula/errorcodes.hxx"
#include "formula/tokenarray.hxx"
#include "scdll.hxx"
-#include "document.hxx"
#include "scmatrix.hxx"
#include "externalrefmgr.hxx"
#include "calcconfig.hxx"
@@ -189,8 +188,7 @@ double ConvertStringToValue( const String& );
double GetCellValue( const ScAddress&, const ScBaseCell* );
double GetCellValueOrZero( const ScAddress&, const ScBaseCell* );
double GetValueCellValue( const ScAddress&, const ScValueCell* );
-ScBaseCell* GetCell( const ScAddress& rPos )
- { return pDok->GetCell( rPos ); }
+ScBaseCell* GetCell( const ScAddress& rPos );
void GetCellString( String& rStr, const ScBaseCell* pCell );
sal_uInt16 GetCellErrCode( const ScBaseCell* pCell );
CellType GetCellType( const ScBaseCell* pCell );
diff --git a/sc/source/core/tool/chgviset.cxx b/sc/source/core/tool/chgviset.cxx
index 1f8547f..2a63d4c 100644
--- a/sc/source/core/tool/chgviset.cxx
+++ b/sc/source/core/tool/chgviset.cxx
@@ -22,6 +22,7 @@
#include "chgviset.hxx"
#include "rechead.hxx"
#include "chgtrack.hxx"
+#include "document.hxx"
// -----------------------------------------------------------------------
ScChangeViewSettings::~ScChangeViewSettings()
diff --git a/sc/source/core/tool/interpr4.cxx b/sc/source/core/tool/interpr4.cxx
index 34e4d2b..d78efe6 100644
--- a/sc/source/core/tool/interpr4.cxx
+++ b/sc/source/core/tool/interpr4.cxx
@@ -545,6 +545,10 @@ double ScInterpreter::GetCellValueOrZero( const ScAddress& rPos, const ScBaseCel
return fValue;
}
+ScBaseCell* ScInterpreter::GetCell( const ScAddress& rPos )
+{
+ return pDok->GetCell( rPos );
+}
void ScInterpreter::GetCellString( String& rStr, const ScBaseCell* pCell )
{
diff --git a/sc/source/filter/inc/biff.hxx b/sc/source/filter/inc/biff.hxx
index 89ceb72..ed739df 100644
--- a/sc/source/filter/inc/biff.hxx
+++ b/sc/source/filter/inc/biff.hxx
@@ -23,7 +23,6 @@
#include <sal/config.h>
#include "filter.hxx"
-#include "document.hxx"
#include "flttypes.hxx"
#include "ftools.hxx"
diff --git a/sc/source/filter/inc/qpro.hxx b/sc/source/filter/inc/qpro.hxx
index 5133952..4e6d376 100644
--- a/sc/source/filter/inc/qpro.hxx
+++ b/sc/source/filter/inc/qpro.hxx
@@ -22,7 +22,6 @@
#include <sal/config.h>
#include "filter.hxx"
-#include "document.hxx"
#include <tools/string.hxx>
#include "flttypes.hxx"
@@ -30,6 +29,8 @@
#include "qprostyle.hxx"
#include "biff.hxx"
+class ScDocument;
+
// Stream wrapper class
class ScQProReader : public ScBiffReader
{
diff --git a/sc/source/filter/inc/qprostyle.hxx b/sc/source/filter/inc/qprostyle.hxx
index 482687c..145d146 100644
--- a/sc/source/filter/inc/qprostyle.hxx
+++ b/sc/source/filter/inc/qprostyle.hxx
@@ -23,11 +23,13 @@
#include <sal/config.h>
#include "filter.hxx"
-#include "document.hxx"
#include <tools/string.hxx>
#include "flttypes.hxx"
#include "ftools.hxx"
+#include "address.hxx"
+
+class ScDocument;
class ScQProStyle
{
diff --git a/sc/source/filter/xcl97/XclExpChangeTrack.cxx b/sc/source/filter/xcl97/XclExpChangeTrack.cxx
index 79a47fb..684d5e1 100644
--- a/sc/source/filter/xcl97/XclExpChangeTrack.cxx
+++ b/sc/source/filter/xcl97/XclExpChangeTrack.cxx
@@ -27,6 +27,7 @@
#include "xeformula.hxx"
#include "cell.hxx"
#include "xcl97rec.hxx"
+#include "document.hxx"
#include <oox/token/tokens.hxx>
#include <rtl/strbuf.hxx>
diff --git a/sc/source/filter/xcl97/XclImpChangeTrack.cxx b/sc/source/filter/xcl97/XclImpChangeTrack.cxx
index 040b005..e3e31a6 100644
--- a/sc/source/filter/xcl97/XclImpChangeTrack.cxx
+++ b/sc/source/filter/xcl97/XclImpChangeTrack.cxx
@@ -27,6 +27,7 @@
#include "xihelper.hxx"
#include "xilink.hxx"
#include "externalrefmgr.hxx"
+#include "document.hxx"
//___________________________________________________________________
// class XclImpChangeTrack
diff --git a/sc/source/filter/xml/XMLTrackedChangesContext.cxx b/sc/source/filter/xml/XMLTrackedChangesContext.cxx
index eea74ac..d3b67dd 100644
--- a/sc/source/filter/xml/XMLTrackedChangesContext.cxx
+++ b/sc/source/filter/xml/XMLTrackedChangesContext.cxx
@@ -25,6 +25,7 @@
#include "cell.hxx"
#include "textuno.hxx"
#include "editutil.hxx"
+#include "document.hxx"
#include <xmloff/xmltoken.hxx>
#include <xmloff/xmlnmspe.hxx>
#include <xmloff/nmspmap.hxx>
diff --git a/sc/source/ui/condformat/condformatmgr.cxx b/sc/source/ui/condformat/condformatmgr.cxx
index 977cc36..a18a0ca 100644
--- a/sc/source/ui/condformat/condformatmgr.cxx
+++ b/sc/source/ui/condformat/condformatmgr.cxx
@@ -32,6 +32,7 @@
#include "globstr.hrc"
#include "condformatdlg.hxx"
#include "vcl/msgbox.hxx"
+#include "document.hxx"
#define ITEMID_RANGE 1
#define ITEMID_CONDITION 2
diff --git a/sc/source/ui/inc/condformatmgr.hxx b/sc/source/ui/inc/condformatmgr.hxx
index d3c9099..be73652 100644
--- a/sc/source/ui/inc/condformatmgr.hxx
+++ b/sc/source/ui/inc/condformatmgr.hxx
@@ -35,7 +35,6 @@
#include <svtools/headbar.hxx>
#include "conditio.hxx"
-#include "document.hxx"
#include <map>
diff --git a/sc/source/ui/view/viewutil.cxx b/sc/source/ui/view/viewutil.cxx
index d24d080..9aa5068 100644
--- a/sc/source/ui/view/viewutil.cxx
+++ b/sc/source/ui/view/viewutil.cxx
@@ -44,6 +44,7 @@
#include "chgtrack.hxx"
#include "chgviset.hxx"
#include "markdata.hxx"
+#include "document.hxx"
#include <svx/svxdlg.hxx>
#include <svx/dialogs.hrc>
commit d6dbf417850e75cc3d4ac9e45ed9db3ffac507ed
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date: Mon Mar 18 22:55:26 2013 -0400
Add accessor to ScDocument for formula cell's vectorization state.
Change-Id: I3c781764c6375dadb173bc5ab3cfb79857e2aeca
diff --git a/sc/inc/cell.hxx b/sc/inc/cell.hxx
index 944c8dc..a096c37 100644
--- a/sc/inc/cell.hxx
+++ b/sc/inc/cell.hxx
@@ -429,6 +429,8 @@ public:
size_t GetHash() const;
+ ScFormulaVectorState GetVectorState() const;
+
void GetFormula( rtl::OUString& rFormula,
const formula::FormulaGrammar::Grammar = formula::FormulaGrammar::GRAM_DEFAULT ) const;
void GetFormula( rtl::OUStringBuffer& rBuffer,
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 8147c06..18543f0 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -24,6 +24,7 @@
#include "global.hxx"
#include "address.hxx"
#include "rangenam.hxx"
+#include "types.hxx"
#include <set>
#include <vector>
@@ -410,7 +411,11 @@ public:
size_t GetFormulaHash( SCROW nRow ) const;
+ ScFormulaVectorState GetFormulaVectorState( SCROW nRow ) const;
+
private:
+ const ScFormulaCell* FetchFormulaCell( SCROW nRow ) const;
+
ScBaseCell* CloneCell(SCSIZE nIndex, sal_uInt16 nFlags, ScDocument& rDestDoc, const ScAddress& rDestPos) const;
SCROW FindNextVisibleRowWithContent(SCROW nRow, bool bForward) const;
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index 7d23b89..98b21eb 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -1856,6 +1856,8 @@ public:
size_t GetFormulaHash( const ScAddress& rPos ) const;
+ ScFormulaVectorState GetFormulaVectorState( const ScAddress& rPos ) const;
+
private: // CLOOK-Impl-methods
/**
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index 2e8b697..036dcca 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -29,6 +29,7 @@
#include "sortparam.hxx"
#include "compressedarray.hxx"
#include "postit.hxx"
+#include "types.hxx"
#include <set>
#include <map>
@@ -798,6 +799,8 @@ public:
size_t GetFormulaHash( SCCOL nCol, SCROW nRow ) const;
+ ScFormulaVectorState GetFormulaVectorState( SCCOL nCol, SCROW nRow ) const;
+
private:
void FillSeries( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
sal_uLong nFillCount, FillDir eFillDir, FillCmd eFillCmd,
diff --git a/sc/inc/tokenarray.hxx b/sc/inc/tokenarray.hxx
index 5c09d28..2449074 100644
--- a/sc/inc/tokenarray.hxx
+++ b/sc/inc/tokenarray.hxx
@@ -24,6 +24,7 @@
#include "scmatrix.hxx"
#include <tools/solar.h>
#include "scdllapi.h"
+#include "types.hxx"
#include <formula/tokenarray.hxx>
struct ScRawToken;
@@ -34,17 +35,10 @@ class SC_DLLPUBLIC ScTokenArray : public formula::FormulaTokenArray
{
friend class ScCompiler;
- /**
- * When vectorization is enabled, we could potentially mass-calculate a
- * series of formula token arrays in adjacent formula cells in one step,
- * provided that they all contain identical set of tokens.
- */
- enum VectorState { Disabled = 0, Enabled, CheckReference };
-
bool ImplGetReference( ScRange& rRange, bool bValidOnly ) const;
size_t mnHashValue;
- VectorState meVectorState;
+ ScFormulaVectorState meVectorState;
public:
ScTokenArray();
@@ -56,6 +50,8 @@ public:
void GenHash();
size_t GetHash() const;
+ ScFormulaVectorState GetVectorState() const;
+
/// Exactly and only one range (valid or deleted)
bool IsReference( ScRange& rRange ) const;
/// Exactly and only one valid range (no #REF!s)
diff --git a/sc/inc/types.hxx b/sc/inc/types.hxx
index bb454a9..99d78f4 100644
--- a/sc/inc/types.hxx
+++ b/sc/inc/types.hxx
@@ -36,6 +36,19 @@ class ScMatrix;
typedef ::boost::intrusive_ptr<ScMatrix> ScMatrixRef;
typedef ::boost::intrusive_ptr<const ScMatrix> ScConstMatrixRef;
+/**
+ * When vectorization is enabled, we could potentially mass-calculate a
+ * series of formula token arrays in adjacent formula cells in one step,
+ * provided that they all contain identical set of tokens.
+ */
+enum ScFormulaVectorState
+{
+ FormulaVectorDisabled = 0,
+ FormulaVectorEnabled,
+ FormulaVectorCheckReference,
+ FormulaVectorUnknown
+};
+
#endif
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx
index 6bde797..f255781 100644
--- a/sc/qa/unit/ucalc.cxx
+++ b/sc/qa/unit/ucalc.cxx
@@ -1205,7 +1205,7 @@ void Test::testFormulaHashAndTag()
struct {
const char* pFormula1; const char* pFormula2; bool bEqual;
- } aTests[] = {
+ } aHashTests[] = {
{ "=1", "=2", false }, // different constants
{ "=SUM(1;2;3;4;5)", "=AVERAGE(1;2;3;4;5)", false }, // different functions
{ "=C2*3", "=D2*3", true }, // relative references
@@ -1221,16 +1221,16 @@ void Test::testFormulaHashAndTag()
{ "=X$20", "=$X20", false }, // column absolute vs row absolute
};
- for (size_t i = 0; i < SAL_N_ELEMENTS(aTests); ++i)
+ for (size_t i = 0; i < SAL_N_ELEMENTS(aHashTests); ++i)
{
- m_pDoc->SetString(aPos1, OUString::createFromAscii(aTests[i].pFormula1));
- m_pDoc->SetString(aPos2, OUString::createFromAscii(aTests[i].pFormula2));
+ m_pDoc->SetString(aPos1, OUString::createFromAscii(aHashTests[i].pFormula1));
+ m_pDoc->SetString(aPos2, OUString::createFromAscii(aHashTests[i].pFormula2));
size_t nHashVal1 = m_pDoc->GetFormulaHash(aPos1);
size_t nHashVal2 = m_pDoc->GetFormulaHash(aPos2);
std::ostringstream os;
- os << "(expr1:" << aTests[i].pFormula1 << "; expr2:" << aTests[i].pFormula2 << ")";
- if (aTests[i].bEqual)
+ os << "(expr1:" << aHashTests[i].pFormula1 << "; expr2:" << aHashTests[i].pFormula2 << ")";
+ if (aHashTests[i].bEqual)
{
os << " Error: these hashes should be equal." << endl;
CPPUNIT_ASSERT_MESSAGE(os.str().c_str(), nHashVal1 == nHashVal2);
diff --git a/sc/source/core/data/cell.cxx b/sc/source/core/data/cell.cxx
index c2247c1..5dfd8e5 100644
--- a/sc/source/core/data/cell.cxx
+++ b/sc/source/core/data/cell.cxx
@@ -889,6 +889,11 @@ size_t ScFormulaCell::GetHash() const
return pCode->GetHash();
}
+ScFormulaVectorState ScFormulaCell::GetVectorState() const
+{
+ return pCode->GetVectorState();
+}
+
void ScFormulaCell::GetFormula( rtl::OUStringBuffer& rBuffer,
const FormulaGrammar::Grammar eGrammar ) const
{
diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx
index ea4be5b..17d951d 100644
--- a/sc/source/core/data/column2.cxx
+++ b/sc/source/core/data/column2.cxx
@@ -1527,20 +1527,32 @@ void ScColumn::SetScriptType( SCROW nRow, sal_uInt8 nType )
size_t ScColumn::GetFormulaHash( SCROW nRow ) const
{
+ const ScFormulaCell* pCell = FetchFormulaCell(nRow);
+ return pCell ? pCell->GetHash() : 0;
+}
+
+ScFormulaVectorState ScColumn::GetFormulaVectorState( SCROW nRow ) const
+{
+ const ScFormulaCell* pCell = FetchFormulaCell(nRow);
+ return pCell ? pCell->GetVectorState() : FormulaVectorUnknown;
+}
+
+const ScFormulaCell* ScColumn::FetchFormulaCell( SCROW nRow ) const
+{
if (!ValidRow(nRow))
- return 0;
+ return NULL;
SCSIZE nIndex;
if (!Search(nRow, nIndex))
// cell not found.
- return 0;
+ return NULL;
const ScBaseCell* pCell = maItems[nIndex].pCell;
if (pCell->GetCellType() != CELLTYPE_FORMULA)
// Not a formula cell.
- return 0;
+ return NULL;
- return static_cast<const ScFormulaCell*>(pCell)->GetHash();
+ return static_cast<const ScFormulaCell*>(pCell);
}
void ScColumn::FindDataAreaPos(SCROW& rRow, bool bDown) const
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index 1f237d1..f4ef72c 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -1561,6 +1561,15 @@ size_t ScDocument::GetFormulaHash( const ScAddress& rPos ) const
return maTabs[nTab]->GetFormulaHash(rPos.Col(), rPos.Row());
}
+ScFormulaVectorState ScDocument::GetFormulaVectorState( const ScAddress& rPos ) const
+{
+ SCTAB nTab = rPos.Tab();
+ if (!ValidTab(nTab) || static_cast<size_t>(nTab) >= maTabs.size() || !maTabs[nTab])
+ return FormulaVectorUnknown;
+
+ return maTabs[nTab]->GetFormulaVectorState(rPos.Col(), rPos.Row());
+}
+
bool ScDocument::CanFitBlock( const ScRange& rOld, const ScRange& rNew )
{
if ( rOld == rNew )
diff --git a/sc/source/core/data/table1.cxx b/sc/source/core/data/table1.cxx
index ee90ae4..12ab3d3 100644
--- a/sc/source/core/data/table1.cxx
+++ b/sc/source/core/data/table1.cxx
@@ -2104,6 +2104,14 @@ size_t ScTable::GetFormulaHash( SCCOL nCol, SCROW nRow ) const
return aCol[nCol].GetFormulaHash(nRow);
}
+ScFormulaVectorState ScTable::GetFormulaVectorState( SCCOL nCol, SCROW nRow ) const
+{
+ if (!ValidCol(nCol))
+ return FormulaVectorUnknown;
+
+ return aCol[nCol].GetFormulaVectorState(nRow);
+}
+
void ScTable::DeleteConditionalFormat( sal_uLong nIndex )
{
mpCondFormatList->erase(nIndex);
diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx
index a5eb796..23a2241 100644
--- a/sc/source/core/tool/token.cxx
+++ b/sc/source/core/tool/token.cxx
@@ -1249,7 +1249,7 @@ bool ScTokenArray::AddFormulaToken(const com::sun::star::sheet::FormulaToken& _a
void ScTokenArray::CheckToken( const FormulaToken& r )
{
- if (meVectorState == Disabled)
+ if (meVectorState == FormulaVectorDisabled)
// It's already disabled. No more checking needed.
return;
@@ -1270,7 +1270,7 @@ void ScTokenArray::CheckToken( const FormulaToken& r )
// Don't change the state.
break;
default:
- meVectorState = Disabled;
+ meVectorState = FormulaVectorDisabled;
}
return;
}
@@ -1289,7 +1289,7 @@ void ScTokenArray::CheckToken( const FormulaToken& r )
case svSingleRef:
case svDoubleRef:
// Depends on the reference state.
- meVectorState = CheckReference;
+ meVectorState = FormulaVectorCheckReference;
break;
case svError:
case svEmptyCell:
@@ -1311,7 +1311,7 @@ void ScTokenArray::CheckToken( const FormulaToken& r )
case svSubroutine:
case svUnknown:
// We don't support vectorization on these.
- meVectorState = Disabled;
+ meVectorState = FormulaVectorDisabled;
default:
;
}
@@ -1438,6 +1438,11 @@ size_t ScTokenArray::GetHash() const
return mnHashValue;
}
+ScFormulaVectorState ScTokenArray::GetVectorState() const
+{
+ return meVectorState;
+}
+
bool ScTokenArray::IsReference( ScRange& rRange ) const
{
return ImplGetReference( rRange, false );
@@ -1453,7 +1458,7 @@ bool ScTokenArray::IsValidReference( ScRange& rRange ) const
ScTokenArray::ScTokenArray() :
FormulaTokenArray(),
mnHashValue(0),
- meVectorState(Enabled)
+ meVectorState(FormulaVectorEnabled)
{
}
commit 292ffa80bc2665107d7011b2180c2659835d6c26
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date: Mon Mar 18 22:10:49 2013 -0400
First cut on checking the token array on whether we could do vectorization.
Not tested yet.
Change-Id: I87f8a8595229d8d8e83526dc0334891d253cf2c7
diff --git a/formula/inc/formula/compiler.hrc b/formula/inc/formula/compiler.hrc
index 8acfff6..053947c 100644
--- a/formula/inc/formula/compiler.hrc
+++ b/formula/inc/formula/compiler.hrc
@@ -94,6 +94,8 @@
#define SC_OPCODE_NEG_SUB 62
#define SC_OPCODE_STOP_UN_OP 63
+#define SC_OPCODE_START_FUNCTION 65
+
/*** Functions without parameters ***/
#define SC_OPCODE_START_NO_PAR 65
#define SC_OPCODE_PI 65
@@ -403,6 +405,8 @@
#define SC_OPCODE_STOP_2_PAR 407
#define SC_OPCODE_LAST_OPCODE_ID 406 /* last OpCode */
+#define SC_OPCODE_STOP_FUNCTION 407
+
/*** Internal ***/
#define SC_OPCODE_INTERNAL_BEGIN 9999
#define SC_OPCODE_TTT 9999
diff --git a/formula/inc/formula/tokenarray.hxx b/formula/inc/formula/tokenarray.hxx
index 42c9212..875b055 100644
--- a/formula/inc/formula/tokenarray.hxx
+++ b/formula/inc/formula/tokenarray.hxx
@@ -192,6 +192,12 @@ public:
*/
bool Fill(const com::sun::star::uno::Sequence< com::sun::star::sheet::FormulaToken >& _aSequence, ExternalReferenceHelper* _pRef = NULL);
+ /**
+ * Do some checking based on the individual tokens. For now, we use this
+ * only to check whether we can vectorize the token array.
+ */
+ virtual void CheckToken( const FormulaToken& t );
+
FormulaToken* AddToken( const FormulaToken& );
FormulaToken* AddString( const sal_Unicode* pStr );
FormulaToken* AddString( const String& rStr );
diff --git a/formula/source/core/api/token.cxx b/formula/source/core/api/token.cxx
index 8750555..84180f0 100644
--- a/formula/source/core/api/token.cxx
+++ b/formula/source/core/api/token.cxx
@@ -708,6 +708,11 @@ void FormulaTokenArray::Clear()
ClearRecalcMode();
}
+void FormulaTokenArray::CheckToken( const FormulaToken& /*r*/ )
+{
+ // Do nothing.
+}
+
FormulaToken* FormulaTokenArray::AddToken( const FormulaToken& r )
{
return Add( r.Clone() );
@@ -724,6 +729,7 @@ FormulaToken* FormulaTokenArray::Add( FormulaToken* t )
pCode = new FormulaToken*[ MAXCODE ];
if( nLen < MAXCODE-1 )
{
+ CheckToken(*t);
pCode[ nLen++ ] = t;
if( t->GetOpCode() == ocPush
&& ( t->GetType() == svSingleRef || t->GetType() == svDoubleRef ) )
diff --git a/sc/inc/tokenarray.hxx b/sc/inc/tokenarray.hxx
index e3b7d56..5c09d28 100644
--- a/sc/inc/tokenarray.hxx
+++ b/sc/inc/tokenarray.hxx
@@ -33,9 +33,18 @@ struct ScComplexRefData;
class SC_DLLPUBLIC ScTokenArray : public formula::FormulaTokenArray
{
friend class ScCompiler;
+
+ /**
+ * When vectorization is enabled, we could potentially mass-calculate a
+ * series of formula token arrays in adjacent formula cells in one step,
+ * provided that they all contain identical set of tokens.
+ */
+ enum VectorState { Disabled = 0, Enabled, CheckReference };
+
bool ImplGetReference( ScRange& rRange, bool bValidOnly ) const;
size_t mnHashValue;
+ VectorState meVectorState;
public:
ScTokenArray();
@@ -61,6 +70,7 @@ public:
formula::FormulaToken* AddRawToken( const ScRawToken& );
virtual bool AddFormulaToken(const com::sun::star::sheet::FormulaToken& _aToken,formula::ExternalReferenceHelper* _pRef);
+ virtual void CheckToken( const formula::FormulaToken& r );
virtual formula::FormulaToken* AddOpCode( OpCode eCode );
/** ScSingleRefToken with ocPush. */
formula::FormulaToken* AddSingleReference( const ScSingleRefData& rRef );
diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx
index b595177..a5eb796 100644
--- a/sc/source/core/tool/token.cxx
+++ b/sc/source/core/tool/token.cxx
@@ -1246,6 +1246,78 @@ bool ScTokenArray::AddFormulaToken(const com::sun::star::sheet::FormulaToken& _a
}
return bError;
}
+
+void ScTokenArray::CheckToken( const FormulaToken& r )
+{
+ if (meVectorState == Disabled)
+ // It's already disabled. No more checking needed.
+ return;
+
+ OpCode eOp = r.GetOpCode();
+
+ if (SC_OPCODE_START_FUNCTION <= eOp && eOp < SC_OPCODE_STOP_FUNCTION)
+ {
+ // This is a function opcode. For now, we only support vectorization
+ // for min, max, sum and average.
+ switch (eOp)
+ {
+ case ocAverage:
+ case ocMin:
+ case ocMinA:
+ case ocMax:
+ case ocMaxA:
+ case ocSum:
+ // Don't change the state.
+ break;
+ default:
+ meVectorState = Disabled;
+ }
+ return;
+ }
+
+ if (eOp == ocPush)
+ {
+ // This is a stack variable. See if this is a reference.
+
+ switch (r.GetType())
+ {
+ case svByte:
+ case svDouble:
+ case svString:
+ // Don't change the state.
+ break;
+ case svSingleRef:
+ case svDoubleRef:
+ // Depends on the reference state.
+ meVectorState = CheckReference;
+ break;
+ case svError:
+ case svEmptyCell:
+ case svExternal:
+ case svExternalDoubleRef:
+ case svExternalName:
+ case svExternalSingleRef:
+ case svFAP:
+ case svHybridCell:
+ case svHybridValueCell:
+ case svIndex:
+ case svJump:
+ case svJumpMatrix:
+ case svMatrix:
+ case svMatrixCell:
+ case svMissing:
+ case svRefList:
+ case svSep:
+ case svSubroutine:
+ case svUnknown:
+ // We don't support vectorization on these.
+ meVectorState = Disabled;
+ default:
+ ;
+ }
+ }
+}
+
bool ScTokenArray::ImplGetReference( ScRange& rRange, bool bValidOnly ) const
{
bool bIs = false;
@@ -1380,13 +1452,15 @@ bool ScTokenArray::IsValidReference( ScRange& rRange ) const
ScTokenArray::ScTokenArray() :
FormulaTokenArray(),
- mnHashValue(0)
+ mnHashValue(0),
+ meVectorState(Enabled)
{
}
ScTokenArray::ScTokenArray( const ScTokenArray& rArr ) :
FormulaTokenArray(rArr),
- mnHashValue(rArr.mnHashValue)
+ mnHashValue(rArr.mnHashValue),
+ meVectorState(rArr.meVectorState)
{
}
@@ -1411,6 +1485,8 @@ ScTokenArray* ScTokenArray::Clone() const
p->nError = nError;
p->bHyperLink = bHyperLink;
p->mnHashValue = mnHashValue;
+ p->meVectorState = meVectorState;
+
FormulaToken** pp;
if( nLen )
{
commit 3a09e0078ae0e25c7317baed471a9c7c1f729794
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date: Mon Mar 18 21:11:53 2013 -0400
Use initializer in ctor.
Change-Id: I2721c083e26654f5ce5cc636d652cb4d50a158ad
diff --git a/formula/source/core/api/token.cxx b/formula/source/core/api/token.cxx
index 150be29..8750555 100644
--- a/formula/source/core/api/token.cxx
+++ b/formula/source/core/api/token.cxx
@@ -581,12 +581,17 @@ bool FormulaTokenArray::HasNameOrColRowName() const
}
-FormulaTokenArray::FormulaTokenArray()
+FormulaTokenArray::FormulaTokenArray() :
+ pCode(NULL),
+ pRPN(NULL),
+ nLen(0),
+ nRPN(0),
+ nIndex(0),
+ nError(0),
+ nRefs(0),
+ nMode(RECALCMODE_NORMAL),
+ bHyperLink(false)
{
- pCode = NULL; pRPN = NULL;
- nError = nLen = nIndex = nRPN = nRefs = 0;
- bHyperLink = false;
- ClearRecalcMode();
}
FormulaTokenArray::FormulaTokenArray( const FormulaTokenArray& rArr )
commit d65e83b32f7cf8227984b843a783d55c384c373b
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date: Mon Mar 18 19:40:08 2013 -0400
Generate token array hash exactly once, when the string is tokenized.
And CompileString() is the place to do it, to the best of my knowledge.
Change-Id: I249df5d09aa288eacc2b2c7ad6e5fc947a3c225f
diff --git a/sc/inc/tokenarray.hxx b/sc/inc/tokenarray.hxx
index 01993e9..e3b7d56 100644
--- a/sc/inc/tokenarray.hxx
+++ b/sc/inc/tokenarray.hxx
@@ -35,6 +35,8 @@ class SC_DLLPUBLIC ScTokenArray : public formula::FormulaTokenArray
friend class ScCompiler;
bool ImplGetReference( ScRange& rRange, bool bValidOnly ) const;
+ size_t mnHashValue;
+
public:
ScTokenArray();
/// Assignment with references to ScToken entries (not copied!)
@@ -42,6 +44,7 @@ public:
virtual ~ScTokenArray();
ScTokenArray* Clone() const; /// True copy!
+ void GenHash();
size_t GetHash() const;
/// Exactly and only one range (valid or deleted)
diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx
index b4850ca..07f4673 100644
--- a/sc/source/core/tool/compiler.cxx
+++ b/sc/source/core/tool/compiler.cxx
@@ -3951,6 +3951,7 @@ ScTokenArray* ScCompiler::CompileString( const String& rFormula )
// remember pArr, in case a subsequent CompileTokenArray() is executed.
ScTokenArray* pNew = new ScTokenArray( aArr );
+ pNew->GenHash();
pArr = pNew;
if (!maExternalFiles.empty())
diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx
index a19f2e3..b595177 100644
--- a/sc/source/core/tool/token.cxx
+++ b/sc/source/core/tool/token.cxx
@@ -1294,7 +1294,7 @@ size_t HashSingleRef( const ScSingleRefData& rRef )
}
-size_t ScTokenArray::GetHash() const
+void ScTokenArray::GenHash()
{
static OUStringHash aHasher;
@@ -1357,7 +1357,13 @@ size_t ScTokenArray::GetHash() const
// Use the opcode value in all the other cases.
nHash += (static_cast<size_t>(eOp) << i);
}
- return nHash;
+
+ mnHashValue = nHash;
+}
+
+size_t ScTokenArray::GetHash() const
+{
+ return mnHashValue;
}
bool ScTokenArray::IsReference( ScRange& rRange ) const
@@ -1372,11 +1378,15 @@ bool ScTokenArray::IsValidReference( ScRange& rRange ) const
////////////////////////////////////////////////////////////////////////////
-ScTokenArray::ScTokenArray()
+ScTokenArray::ScTokenArray() :
+ FormulaTokenArray(),
+ mnHashValue(0)
{
}
-ScTokenArray::ScTokenArray( const ScTokenArray& rArr ) : FormulaTokenArray(rArr)
+ScTokenArray::ScTokenArray( const ScTokenArray& rArr ) :
+ FormulaTokenArray(rArr),
+ mnHashValue(rArr.mnHashValue)
{
}
@@ -1384,8 +1394,6 @@ ScTokenArray::~ScTokenArray()
{
}
-
-
ScTokenArray& ScTokenArray::operator=( const ScTokenArray& rArr )
{
Clear();
@@ -1402,6 +1410,7 @@ ScTokenArray* ScTokenArray::Clone() const
p->nMode = nMode;
p->nError = nError;
p->bHyperLink = bHyperLink;
+ p->mnHashValue = mnHashValue;
FormulaToken** pp;
if( nLen )
{
commit 0a0deec6f1e5c3e3100673daa6ef244b2d8ff8bf
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date: Mon Mar 18 17:14:51 2013 -0400
Fix indentation.
Change-Id: Ia277ac4e9eeb34a2b0244ebb5f09c428f5cf2b64
diff --git a/formula/source/core/api/FormulaCompiler.cxx b/formula/source/core/api/FormulaCompiler.cxx
index 3cfb903..3e990cb 100644
--- a/formula/source/core/api/FormulaCompiler.cxx
+++ b/formula/source/core/api/FormulaCompiler.cxx
@@ -2018,7 +2018,7 @@ void FormulaCompiler::LocalizeString( String& /*rName*/ )
void FormulaCompiler::PushTokenArray( FormulaTokenArray* pa, bool bTemp )
{
if ( bAutoCorrect && !pStack )
- { // don't merge stacked subroutine code into entered formula
+ { // don't merge stacked subroutine code into entered formula
aCorrectedFormula += aCorrectedSymbol;
aCorrectedSymbol.Erase();
}
commit 945853ba9e9f1188c87f527866e7e8a1fd967a35
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date: Mon Mar 18 18:29:22 2013 -0400
Fix build breakage.
Change-Id: I94b9d17a045a9c17d9e97aa582d7572e0a21809b
diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx
index f530890..6bde797 100644
--- a/sc/qa/unit/ucalc.cxx
+++ b/sc/qa/unit/ucalc.cxx
@@ -117,7 +117,7 @@ public:
void testCollator();
void testRangeList();
void testInput();
- void testFormulaGrouping();
+ void testFormulaHashAndTag();
void testCellFunctions();
void testCopyToDocument();
/**
@@ -276,7 +276,7 @@ public:
CPPUNIT_TEST(testCollator);
CPPUNIT_TEST(testRangeList);
CPPUNIT_TEST(testInput);
- CPPUNIT_TEST(testFormulaGrouping);
+ CPPUNIT_TEST(testFormulaHashAndTag);
CPPUNIT_TEST(testCellFunctions);
CPPUNIT_TEST(testCopyToDocument);
CPPUNIT_TEST(testSheetsFunc);
@@ -1197,7 +1197,7 @@ void testFuncINDIRECT(ScDocument* pDoc)
}
}
-void Test::testFormulaGrouping()
+void Test::testFormulaHashAndTag()
{
m_pDoc->InsertTab(0, "Test");
diff --git a/sc/source/core/data/cell2.cxx b/sc/source/core/data/cell2.cxx
index db14d58..412f85d 100644
--- a/sc/source/core/data/cell2.cxx
+++ b/sc/source/core/data/cell2.cxx
@@ -42,6 +42,8 @@
#include "patattr.hxx"
#include <rtl/strbuf.hxx>
+#include <cstdio>
+
using namespace formula;
// STATIC DATA -----------------------------------------------------------
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index ede8b92..6305747 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -37,6 +37,7 @@
#include <cstring>
#include <map>
+#include <cstdio>
using ::editeng::SvxBorderLine;
using namespace formula;
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index 5ddb3f1..6ee4495 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -48,6 +48,8 @@
#include <com/sun/star/i18n/LocaleDataItem.hpp>
+#include <cstdio>
+
using ::com::sun::star::i18n::LocaleDataItem;
using ::rtl::OUString;
using ::rtl::OUStringBuffer;
commit fedb28e84614ac6c0f6076cca56b6c2c8b832198
Author: Michael Meeks <michael.meeks at suse.com>
Date: Mon Mar 18 21:29:58 2013 +0000
add initial formula group unit tests.
Change-Id: Id4dd3cc0d3d8a4db641e316d2eda44a5b94105c7
diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx
index 3e9a14d..f530890 100644
--- a/sc/qa/unit/ucalc.cxx
+++ b/sc/qa/unit/ucalc.cxx
@@ -33,6 +33,7 @@
#include <osl/file.hxx>
#include "scdll.hxx"
+#include "cell.hxx"
#include "document.hxx"
#include "stringutil.hxx"
#include "scmatrix.hxx"
@@ -266,6 +267,11 @@ public:
void testAnchoredRotatedShape();
void testCellTextWidth();
+ /**
+ * Test formula & formula grouping
+ */
+ void testFormulaGrouping();
+
CPPUNIT_TEST_SUITE(Test);
CPPUNIT_TEST(testCollator);
CPPUNIT_TEST(testRangeList);
@@ -328,6 +334,7 @@ public:
CPPUNIT_TEST(testDeleteCol);
CPPUNIT_TEST(testAnchoredRotatedShape);
CPPUNIT_TEST(testCellTextWidth);
+ CPPUNIT_TEST(testFormulaGrouping);
CPPUNIT_TEST_SUITE_END();
private:
@@ -6174,6 +6181,57 @@ void Test::testCellTextWidth()
m_pDoc->DeleteTab(0);
}
+void Test::testFormulaGrouping()
+{
+ static const struct {
+ const char *pFormula[3];
+ const bool bGroup[3];
+ } aGroupTests[] = {
+ { { "=B1", "=C1", "" }, // single increments
+ { true, true, false } },
+ { { "=B1", "=D1", "=F1" }, // tripple increments
+ { true, true, true } },
+ { { "=B1", "", "=C1" }, // a gap
+ { false, false, false } },
+ { { "=B1", "=C1+3", "=C1+D1" }, // confusion: FIXME: =C1+7
+ { false, false, false } },
+ };
+
+ m_pDoc->InsertTab( 0, "sheet" );
+
+ for (size_t i = 0; i < SAL_N_ELEMENTS( aGroupTests ); i++)
+ {
+ for (size_t j = 0; j < SAL_N_ELEMENTS( aGroupTests[0].pFormula ); j++)
+ {
+ OUString aFormula = OUString::createFromAscii(aGroupTests[i].pFormula[j]);
+ m_pDoc->SetString(0, (SCROW)j, 0, aFormula);
+ }
+ m_pDoc->RebuildFormulaGroups();
+
+ for (size_t j = 0; j < SAL_N_ELEMENTS( aGroupTests[0].pFormula ); j++)
+ {
+ ScBaseCell *pCell = NULL;
+ m_pDoc->GetCell( 0, (SCROW)j, 0, pCell );
+ if( !pCell )
+ {
+ CPPUNIT_ASSERT_MESSAGE("invalid empty cell", !aGroupTests[i].bGroup[j]);
+ continue;
+ }
+ CPPUNIT_ASSERT_MESSAGE("Cell expected, but not there.", pCell != NULL);
+ CPPUNIT_ASSERT_MESSAGE("Cell wrong type.",
+ pCell->GetCellType() == CELLTYPE_FORMULA);
+ ScFormulaCell *pCur = static_cast< ScFormulaCell *>( pCell );
+
+ if( !!pCur->GetCellGroup().get() ^ aGroupTests[i].bGroup[j] )
+ {
+ printf("expected group test %d at row %d to be %d but is %d\n",
+ i, j, !!pCur->GetCellGroup().get(), aGroupTests[i].bGroup[j]);
+ CPPUNIT_ASSERT_MESSAGE("Failed", false);
+ }
+ }
+ }
+}
+
CPPUNIT_TEST_SUITE_REGISTRATION(Test);
}
diff --git a/sc/source/core/data/cell2.cxx b/sc/source/core/data/cell2.cxx
index 4cb4eb8..db14d58 100644
--- a/sc/source/core/data/cell2.cxx
+++ b/sc/source/core/data/cell2.cxx
@@ -1752,11 +1752,15 @@ ScSimilarFormulaDelta *ScFormulaCell::BuildDeltaTo( ScFormulaCell *pOtherCell )
fprintf( stderr, "Incompatible type, op-code or param counts\n" );
return NULL;
}
- if( pThis[ i ]->GetType() == formula::svMatrix ||
- pOther[ i ]->GetType() == formula::svMatrix )
+ switch( pThis[ i ]->GetType() )
{
- fprintf( stderr, "Ignoring matrix formulae for now\n" );
+ case formula::svMatrix:
+ case formula::svExternalSingleRef:
+ case formula::svExternalDoubleRef:
+ fprintf( stderr, "Ignoring matrix and external references for now\n" );
return NULL;
+ default:
+ break;
}
}
@@ -1765,6 +1769,10 @@ ScSimilarFormulaDelta *ScFormulaCell::BuildDeltaTo( ScFormulaCell *pOtherCell )
for ( sal_uInt16 i = 0; i < pThisLen; i++ )
{
+ if ( pThis[i]->GetType() != formula::svSingleRef &&
+ pThis[i]->GetType() != formula::svDoubleRef )
+ continue;
+
ScToken *pThisTok = static_cast< ScToken * >( pThis[ i ] );
ScToken *pOtherTok = static_cast< ScToken * >( pOther[ i ] );
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index d288625..5ddb3f1 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -2036,7 +2036,6 @@ void ScColumn::RebuildFormulaGroups()
ScFormulaCell *pCur = static_cast< ScFormulaCell *>( rCur.pCell );
ScFormulaCell *pPrev = static_cast< ScFormulaCell *>( rPrev.pCell );
-#ifdef BUILD_FORMULA_GROUPS
fprintf( stderr, "column has contiguous formulae\n" );
ScSimilarFormulaDelta *pDelta = pPrev->BuildDeltaTo( pCur );
@@ -2081,9 +2080,6 @@ void ScColumn::RebuildFormulaGroups()
pCur->ReleaseDelta( pDelta );
}
-#else
- (void)pCur; (void) pPrev;
-#endif
}
bDirtyGroups = false;
commit aed58c04a8483881e4592565587aaf08e6239672
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date: Mon Mar 18 16:28:11 2013 -0400
Embed reference tokens in the generated hash values.
Also make the test code a bit easier to extend.
Change-Id: Ib4e381cc139231884999c9d0dc9f51201e11f807
diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx
index b6addd1..3e9a14d 100644
--- a/sc/qa/unit/ucalc.cxx
+++ b/sc/qa/unit/ucalc.cxx
@@ -1196,47 +1196,47 @@ void Test::testFormulaGrouping()
ScAddress aPos1(0,0,0), aPos2(1,0,0);
- // simplest cases.
- m_pDoc->SetString(aPos1, "=1");
- size_t nHashVal1 = m_pDoc->GetFormulaHash(aPos1);
- m_pDoc->SetString(aPos2, "=2");
- size_t nHashVal2 = m_pDoc->GetFormulaHash(aPos2);
- CPPUNIT_ASSERT_MESSAGE("These hashes should differ.", nHashVal1 != nHashVal2);
-
- // different cell functions.
- aPos1.IncRow();
- aPos2.IncRow();
- m_pDoc->SetString(aPos1, "=SUM(1;2;3;4;5)");
- m_pDoc->SetString(aPos2, "=AVERAGE(1;2;3;4;5)");
- nHashVal1 = m_pDoc->GetFormulaHash(aPos1);
- nHashVal2 = m_pDoc->GetFormulaHash(aPos2);
- CPPUNIT_ASSERT_MESSAGE("These hashes should differ.", nHashVal1 != nHashVal2);
-
- // same relative references.
- aPos1.IncRow();
- aPos2.IncRow();
- m_pDoc->SetString(aPos1, "=A2*3");
- m_pDoc->SetString(aPos2, "=B2*3");
- nHashVal1 = m_pDoc->GetFormulaHash(aPos1);
- nHashVal2 = m_pDoc->GetFormulaHash(aPos2);
- CPPUNIT_ASSERT_MESSAGE("These hashes should be equal.", nHashVal1 == nHashVal2);
-
- m_pDoc->SetString(aPos2, "=B2*4"); // Change the constant.
- nHashVal2 = m_pDoc->GetFormulaHash(aPos2);
- CPPUNIT_ASSERT_MESSAGE("These hashes should differ.", nHashVal1 != nHashVal2);
-
- m_pDoc->SetString(aPos1, "=A2*4"); // Change the constant again to make it "equal".
- nHashVal1 = m_pDoc->GetFormulaHash(aPos1);
- CPPUNIT_ASSERT_MESSAGE("These hashes should be equal.", nHashVal1 == nHashVal2);
-
- // string constant vs numeric constant.
- aPos1.IncRow();
- aPos2.IncRow();
- m_pDoc->SetString(aPos1, "=3*4*5");
- m_pDoc->SetString(aPos2, "=3*4*\"foo\"");
- nHashVal1 = m_pDoc->GetFormulaHash(aPos1);
- nHashVal2 = m_pDoc->GetFormulaHash(aPos2);
- CPPUNIT_ASSERT_MESSAGE("These hashes should differ.", nHashVal1 != nHashVal2);
+ struct {
+ const char* pFormula1; const char* pFormula2; bool bEqual;
+ } aTests[] = {
+ { "=1", "=2", false }, // different constants
+ { "=SUM(1;2;3;4;5)", "=AVERAGE(1;2;3;4;5)", false }, // different functions
+ { "=C2*3", "=D2*3", true }, // relative references
+ { "=C2*3", "=D2*4", false }, // different constants
+ { "=C2*4", "=D2*4", true }, // relative references
+ { "=3*4*5", "=3*4*\"foo\"", false }, // numeric vs string constants
+ { "=$C3/2", "=$C3/2", true }, // absolute column references
+ { "=C$3/2", "=D$3/2", true }, // absolute row references
+ { "=$E$30/2", "=$E$30/2", true }, // absolute references
+ { "=X20", "=$X$20", false }, // absolute vs relative
+ { "=X20", "=X$20", false }, // absolute vs relative
+ { "=X20", "=$X20", false }, // absolute vs relative
+ { "=X$20", "=$X20", false }, // column absolute vs row absolute
+ };
+
+ for (size_t i = 0; i < SAL_N_ELEMENTS(aTests); ++i)
+ {
+ m_pDoc->SetString(aPos1, OUString::createFromAscii(aTests[i].pFormula1));
+ m_pDoc->SetString(aPos2, OUString::createFromAscii(aTests[i].pFormula2));
+ size_t nHashVal1 = m_pDoc->GetFormulaHash(aPos1);
+ size_t nHashVal2 = m_pDoc->GetFormulaHash(aPos2);
+
+ std::ostringstream os;
+ os << "(expr1:" << aTests[i].pFormula1 << "; expr2:" << aTests[i].pFormula2 << ")";
+ if (aTests[i].bEqual)
+ {
+ os << " Error: these hashes should be equal." << endl;
+ CPPUNIT_ASSERT_MESSAGE(os.str().c_str(), nHashVal1 == nHashVal2);
+ }
+ else
+ {
+ os << " Error: these hashes should differ." << endl;
+ CPPUNIT_ASSERT_MESSAGE(os.str().c_str(), nHashVal1 != nHashVal2);
+ }
+
+ aPos1.IncRow();
+ aPos2.IncRow();
+ }
m_pDoc->DeleteTab(0);
}
diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx
index b400f6d..a19f2e3 100644
--- a/sc/source/core/tool/token.cxx
+++ b/sc/source/core/tool/token.cxx
@@ -1274,6 +1274,26 @@ bool ScTokenArray::ImplGetReference( ScRange& rRange, bool bValidOnly ) const
return bIs;
}
+namespace {
+
+size_t HashSingleRef( const ScSingleRefData& rRef )
+{
+ SCsCOL nCol = rRef.Flags.bColRel ? rRef.nRelCol : rRef.nCol;
+ SCsROW nRow = rRef.Flags.bRowRel ? rRef.nRelRow : rRef.nRow;
+ SCsTAB nTab = rRef.Flags.bTabRel ? rRef.nRelTab : rRef.nTab;
+ size_t nVal = nCol;
+ nVal += (nRow << 8);
+ nVal += (nTab << 16);
+
+ // Embed flag values too.
+ nVal += rRef.Flags.bColRel;
+ nVal += (rRef.Flags.bRowRel << 1);
+ nVal += (rRef.Flags.bTabRel << 2);
+ return nVal;
+}
+
+}
+
size_t ScTokenArray::GetHash() const
{
static OUStringHash aHasher;
@@ -1281,11 +1301,11 @@ size_t ScTokenArray::GetHash() const
size_t nHash = 1;
OpCode eOp;
StackVar eType;
- const FormulaToken* p;
+ const ScToken* p;
sal_uInt16 n = std::min<sal_uInt16>(nLen, 20);
for (sal_uInt16 i = 0; i < n; ++i)
{
- p = pCode[i];
+ p = static_cast<const ScToken*>(pCode[i]);
eOp = p->GetOpCode();
if (eOp == ocPush)
{
@@ -1314,8 +1334,22 @@ size_t ScTokenArray::GetHash() const
nHash += (aHasher(rStr) << i);
continue;
}
+ case svSingleRef:
+ {
... etc. - the rest is truncated
More information about the Libreoffice-commits
mailing list