[ooo-build-commit] Branch 'ooo-build-3-1' - patches/dev300
Kohei Yoshida
kohei at kemper.freedesktop.org
Wed Jul 15 12:09:05 PDT 2009
patches/dev300/apply | 12
patches/dev300/calc-formula-externref-countif-fix.diff | 728 +++++++++++++++++
2 files changed, 729 insertions(+), 11 deletions(-)
New commits:
commit 4f3e960ad1ededa86c8ed75d7703fa921029673d
Author: Kohei Yoshida <kyoshida at novell.com>
Date: Wed Jul 15 14:34:16 2009 -0400
COUNTIF now works with external references.
* patches/dev300/apply: removed all patches but the one below from
the CalcExperimental section. All the other patches are already
enabled on master.
* patches/dev300/calc-formula-externref-countif-fix.diff: external
reference tokens are pre-processed and pushed as static values.
So, ScCountIf() needs to handle static values (which are in fact
external reference values) in order to handle them properly.
(n#521624, i#102750)
diff --git a/patches/dev300/apply b/patches/dev300/apply
index b69c882..c339400 100644
--- a/patches/dev300/apply
+++ b/patches/dev300/apply
@@ -3027,17 +3027,7 @@ calc-delete-note-cell-crasher.diff, n#517566, kohei
[ CalcExperimental ]
-# speed up sheet switch operation.
-calc-perf-sheet-switch.diff, n#495140, kohei
-
-# support custom sort in datapilot tables.
-calc-dp-custom-sort.diff, n#443361, kohei
-
-# support ods import/export of sheet options and password hash.
-calc-ods-sheet-protection-sc.diff, i#60305, i#71468, kohei
-calc-ods-sheet-protection-xmloff.diff, i#60305, i#71468, kohei
-calc-ods-sheet-protection-svtools.diff, i#60305, i#71468, kohei
-
+calc-formula-externref-countif-fix.diff, n#521624, i#102750, kohei
[ UbuntuHardyOnly ]
# Add patch to only show local files needed when gnome-vfs/gio is disabled
diff --git a/patches/dev300/calc-formula-externref-countif-fix.diff b/patches/dev300/calc-formula-externref-countif-fix.diff
new file mode 100644
index 0000000..2be4194
--- /dev/null
+++ b/patches/dev300/calc-formula-externref-countif-fix.diff
@@ -0,0 +1,728 @@
+diff --git sc/source/core/inc/funcqueryhandler.hxx sc/source/core/inc/funcqueryhandler.hxx
+new file mode 100644
+index 0000000..2cb28c5
+--- /dev/null
++++ sc/source/core/inc/funcqueryhandler.hxx
+@@ -0,0 +1,140 @@
++/*************************************************************************
++ *
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * Copyright 2008 by Sun Microsystems, Inc.
++ *
++ * OpenOffice.org - a multi-platform office productivity suite
++ *
++ * $RCSfile: opcode.hxx,v $
++ * $Revision: 1.23.134.2 $
++ *
++ * This file is part of OpenOffice.org.
++ *
++ * OpenOffice.org is free software: you can redistribute it and/or modify
++ * it under the terms of the GNU Lesser General Public License version 3
++ * only, as published by the Free Software Foundation.
++ *
++ * OpenOffice.org is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU Lesser General Public License version 3 for more details
++ * (a copy is included in the LICENSE file that accompanied this code).
++ *
++ * You should have received a copy of the GNU Lesser General Public License
++ * version 3 along with OpenOffice.org. If not, see
++ * <http://www.openoffice.org/license.html>
++ * for a copy of the LGPLv3 License.
++ *
++ ************************************************************************/
++
++#ifndef SC_FUNC_QUERY_HANDLER_HXX
++#define SC_FUNC_QUERY_HANDLER_HXX
++
++#include "global.hxx"
++#include <vector>
++#include <boost/shared_ptr.hpp>
++
++namespace utl {
++ class SearchParam;
++ class TextSearch;
++}
++
++class ScBaseCell;
++
++class ScFunctionQueryHandler
++{
++public:
++
++ struct QueryOption
++ {
++ ScQueryOp meOp;
++ ::rtl::OUString maMatchString;
++ double mfMatchValue;
++ bool mbQueryByString;
++ bool mbRegExp;
++
++ // Caching these instances for regexp searches.
++ ::boost::shared_ptr< ::utl::SearchParam> mpSearchParam;
++ ::boost::shared_ptr< ::utl::TextSearch> mpTextSearch;
++
++ void parseCriterion(const ::rtl::OUString& rStr);
++
++ QueryOption();
++ };
++
++ class DataArrayBase
++ {
++ public:
++ virtual ~DataArrayBase() = 0;
++ virtual bool runQuery(const QueryOption& rOption) = 0;
++ virtual size_t countMatchedCells() const = 0;
++ };
++
++ /** Individual cell of StaticDataArray */
++ struct Cell
++ {
++ ::rtl::OUString maString;
++ double mfValue;
++ bool mbIsValue;
++
++ bool match(const QueryOption& rOption) const;
++
++ Cell();
++ };
++
++ /** Data array consisting of static values. */
++ class StaticDataArray : public DataArrayBase
++ {
++ public:
++ virtual ~StaticDataArray();
++
++ void addCell(const ::rtl::OUString& rStr);
++ void addCell(double fVal);
++
++ virtual bool runQuery(const QueryOption& rOption);
++ virtual size_t countMatchedCells() const;
++ private:
++ ::std::vector<Cell> maDataArray;
++ ::std::vector<size_t> maMatchedCells;
++ };
++
++ /** Data array for internal cell range. */
++ class RangeDataArray : public DataArrayBase
++ {
++ public:
++ explicit RangeDataArray(ScDocument* pDoc, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, SCTAB nTab);
++ virtual ~RangeDataArray();
++
++ virtual bool runQuery(const QueryOption &rOption);
++ virtual size_t countMatchedCells() const;
++ private:
++ ::std::vector<ScBaseCell*> maMatchedCells;
++ ScRange maRange;
++ ScDocument* mpDoc;
++ };
++
++ ScFunctionQueryHandler();
++ ~ScFunctionQueryHandler();
++
++ /**
++ * @param pArray pointer to <i>unmanaged</i> instance of DataArrayBase.
++ * Don't delete this instance in the client code since the
++ * query handler instance manages the life cycle of this
++ * data array instance.
++ */
++ void setDataArray(DataArrayBase* pArray);
++ void setQueryOption(const QueryOption& rOption);
++
++ /**
++ * @return bool true if the query is successful, false otherwise.
++ */
++ bool runQuery();
++ size_t countMatchedCells() const;
++
++private:
++ ::boost::shared_ptr<DataArrayBase> mpDataArray;
++ QueryOption maOption;
++};
++
++#endif
+diff --git sc/source/core/tool/funcqueryhandler.cxx sc/source/core/tool/funcqueryhandler.cxx
+new file mode 100644
+index 0000000..48fdb5a
+--- /dev/null
++++ sc/source/core/tool/funcqueryhandler.cxx
+@@ -0,0 +1,353 @@
++/*************************************************************************
++ *
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * Copyright 2008 by Sun Microsystems, Inc.
++ *
++ * OpenOffice.org - a multi-platform office productivity suite
++ *
++ * $RCSfile: opcode.hxx,v $
++ * $Revision: 1.23.134.2 $
++ *
++ * This file is part of OpenOffice.org.
++ *
++ * OpenOffice.org is free software: you can redistribute it and/or modify
++ * it under the terms of the GNU Lesser General Public License version 3
++ * only, as published by the Free Software Foundation.
++ *
++ * OpenOffice.org is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU Lesser General Public License version 3 for more details
++ * (a copy is included in the LICENSE file that accompanied this code).
++ *
++ * You should have received a copy of the GNU Lesser General Public License
++ * version 3 along with OpenOffice.org. If not, see
++ * <http://www.openoffice.org/license.html>
++ * for a copy of the LGPLv3 License.
++ *
++ ************************************************************************/
++
++// MARKER(update_precomp.py): autogen include statement, do not remove
++#include "precompiled_sc.hxx"
++
++// INCLUDE ---------------------------------------------------------------
++
++#include "funcqueryhandler.hxx"
++#include "dociter.hxx"
++#include "cell.hxx"
++#include "document.hxx"
++#include "unotools/textsearch.hxx"
++#include "rtl/math.hxx"
++
++#include <memory>
++
++using ::utl::SearchParam;
++using ::utl::TextSearch;
++using ::rtl::OUString;
++using ::std::vector;
++using ::std::auto_ptr;
++
++
++namespace {
++
++bool evaluateValue(const ScFunctionQueryHandler::QueryOption& rOption, double fVal)
++{
++ bool bMatch = false;
++ switch (rOption.meOp)
++ {
++ using ::rtl::math::approxEqual;
++
++ case SC_EQUAL:
++ bMatch = approxEqual(rOption.mfMatchValue, fVal);
++ break;
++ case SC_NOT_EQUAL:
++ bMatch = !approxEqual(rOption.mfMatchValue, fVal);
++ break;
++ case SC_GREATER:
++ bMatch = rOption.mfMatchValue < fVal && !approxEqual(rOption.mfMatchValue, fVal);
++ break;
++ case SC_LESS:
++ bMatch = rOption.mfMatchValue > fVal && !approxEqual(rOption.mfMatchValue, fVal);
++ break;
++ case SC_GREATER_EQUAL:
++ bMatch = rOption.mfMatchValue < fVal || approxEqual(rOption.mfMatchValue, fVal);
++ break;
++ case SC_LESS_EQUAL:
++ bMatch = rOption.mfMatchValue > fVal || approxEqual(rOption.mfMatchValue, fVal);
++ break;
++ default:
++ ;
++ }
++ return bMatch;
++}
++
++bool evaluateString(const ScFunctionQueryHandler::QueryOption& rOption, const OUString& rStr)
++{
++ bool bMatch = false;
++ if (rOption.mbRegExp && rOption.mpTextSearch)
++ {
++ // Regular expression search always uses equal condition. Note also
++ // that the matched segment equals the whole string.
++ sal_Int32 nLen = rStr.getLength();
++ xub_StrLen nStart = 0, nEnd = 0;
++ bMatch = rOption.mpTextSearch->SearchFrwrd(rStr, &nStart, &nEnd) && nStart == 0 && nEnd == nLen;
++ }
++ else
++ {
++ switch (rOption.meOp)
++ {
++ case SC_EQUAL:
++ bMatch = rOption.maMatchString.equals(rStr);
++ break;
++ case SC_NOT_EQUAL:
++ bMatch = !rOption.maMatchString.equals(rStr);
++ break;
++ default:
++ ;
++ }
++ }
++ return bMatch;
++}
++
++}
++
++// ============================================================================
++
++void ScFunctionQueryHandler::QueryOption::parseCriterion(const OUString& rStr)
++{
++ // This function is largely inspired by & functionally equivalent to
++ // ScQueryParam::FillInExcelSyntax().
++
++ maMatchString = rStr;
++ const sal_Unicode* p = rStr.getStr();
++ sal_Int32 n = rStr.getLength();
++ if (!n)
++ return;
++
++ QueryOption aNewOption;
++
++ const sal_Unicode c0 = p[0];
++ if (c0 == '<')
++ {
++ if (n < 2)
++ return;
++
++ const sal_Unicode c1 = p[1];
++ if (c1 == '>')
++ {
++ aNewOption.maMatchString = rStr.copy(2);
++ aNewOption.meOp = SC_NOT_EQUAL;
++ }
++ else if (c1 == '=')
++ {
++ aNewOption.maMatchString = rStr.copy(2);
++ aNewOption.meOp = SC_LESS_EQUAL;
++ }
++ else
++ {
++ aNewOption.maMatchString = rStr.copy(1);
++ aNewOption.meOp = SC_LESS;
++ }
++ }
++ else if (c0 == '>')
++ {
++ if (n < 2)
++ return;
++
++ const sal_Unicode c1 = p[1];
++ if (c1 == '=')
++ {
++ aNewOption.maMatchString = rStr.copy(2);
++ aNewOption.meOp = SC_GREATER_EQUAL;
++ }
++ else
++ {
++ aNewOption.maMatchString = rStr.copy(1);
++ aNewOption.meOp = SC_GREATER;
++ }
++ }
++ else
++ {
++ aNewOption.meOp = SC_EQUAL;
++ if (c0 == '=')
++ aNewOption.maMatchString = rStr.copy(1);
++ else
++ aNewOption.maMatchString = rStr;
++ }
++
++ maMatchString = aNewOption.maMatchString;
++ meOp = aNewOption.meOp;
++}
++
++ScFunctionQueryHandler::QueryOption::QueryOption() :
++ meOp(SC_EQUAL),
++ mbQueryByString(true),
++ mbRegExp(false),
++ mpSearchParam(static_cast<SearchParam*>(NULL)),
++ mpTextSearch(static_cast<TextSearch*>(NULL))
++{
++}
++
++// ----------------------------------------------------------------------------
++
++ScFunctionQueryHandler::DataArrayBase::~DataArrayBase() {}
++
++// ----------------------------------------------------------------------------
++
++bool ScFunctionQueryHandler::Cell::match(const QueryOption& rOption) const
++{
++ if (rOption.mbQueryByString)
++ {
++ if (mbIsValue)
++ return false;
++
++ return evaluateString(rOption, maString);
++ }
++ else
++ {
++ if (!mbIsValue)
++ return false;
++
++ return evaluateValue(rOption, mfValue);
++ }
++}
++
++ScFunctionQueryHandler::Cell::Cell() :
++ mfValue(0.0),
++ mbIsValue(false)
++{
++}
++
++// ----------------------------------------------------------------------------
++
++ScFunctionQueryHandler::StaticDataArray::~StaticDataArray() {}
++
++void ScFunctionQueryHandler::StaticDataArray::addCell(const OUString& rStr)
++{
++ Cell cell;
++ cell.maString = rStr;
++ cell.mfValue = 0.0;
++ cell.mbIsValue = false;
++ maDataArray.push_back(cell);
++}
++
++void ScFunctionQueryHandler::StaticDataArray::addCell(double fVal)
++{
++ Cell cell;
++ cell.mfValue = fVal;
++ cell.mbIsValue = true;
++ maDataArray.push_back(cell);
++}
++
++bool ScFunctionQueryHandler::StaticDataArray::runQuery(const QueryOption& rOption)
++{
++ using ::std::distance;
++
++ maMatchedCells.clear();
++ vector<Cell>::const_iterator itrBeg = maDataArray.begin(), itrEnd = maDataArray.end();
++ for (vector<Cell>::const_iterator itr = itrBeg; itr != itrEnd; ++itr)
++ {
++ if ((*itr).match(rOption))
++ {
++ size_t index = distance(itrBeg, itr);
++ maMatchedCells.push_back(index);
++ }
++ }
++ return true;
++}
++
++size_t ScFunctionQueryHandler::StaticDataArray::countMatchedCells() const
++{
++ return maMatchedCells.size();
++}
++
++// ----------------------------------------------------------------------------
++
++ScFunctionQueryHandler::RangeDataArray::RangeDataArray(ScDocument* pDoc, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, SCTAB nTab) :
++ maRange(nCol1, nRow1, nTab, nCol2, nRow2, nTab),
++ mpDoc(pDoc)
++{
++}
++
++ScFunctionQueryHandler::RangeDataArray::~RangeDataArray() {}
++
++bool ScFunctionQueryHandler::RangeDataArray::runQuery(const QueryOption& rOption)
++{
++ ScCellIterator aIter(mpDoc, maRange);
++ for (ScBaseCell* pCell = aIter.GetFirst(); pCell; pCell = aIter.GetNext())
++ {
++ bool bMatch = false;
++ if (!rOption.mbQueryByString && mpDoc->HasValueData(aIter.GetCol(), aIter.GetRow(), aIter.GetTab()))
++ {
++ // By Value
++ double fVal = 0.0;
++ mpDoc->GetValue(aIter.GetCol(), aIter.GetRow(), aIter.GetTab(), fVal);
++ bMatch = evaluateValue(rOption, fVal);
++ }
++ else
++ {
++ String aCellStr;
++ mpDoc->GetString(aIter.GetCol(), aIter.GetRow(), aIter.GetTab(), aCellStr);
++ bMatch = evaluateString(rOption, aCellStr);
++ }
++ if (bMatch)
++ maMatchedCells.push_back(pCell);
++ }
++ return true;
++}
++
++size_t ScFunctionQueryHandler::RangeDataArray::countMatchedCells() const
++{
++ return maMatchedCells.size();
++}
++
++// ----------------------------------------------------------------------------
++
++ScFunctionQueryHandler::ScFunctionQueryHandler()
++{
++}
++
++ScFunctionQueryHandler::~ScFunctionQueryHandler()
++{
++}
++
++void ScFunctionQueryHandler::setDataArray(DataArrayBase* pArray)
++{
++ mpDataArray.reset(pArray);
++}
++
++void ScFunctionQueryHandler::setQueryOption(const QueryOption& rOption)
++{
++ maOption = rOption;
++}
++
++bool ScFunctionQueryHandler::runQuery()
++{
++ using ::std::distance;
++
++ if (!mpDataArray)
++ // No data array.
++ return false;
++
++ if (maOption.mbRegExp)
++ {
++ if (!maOption.mpSearchParam)
++ maOption.mpSearchParam.reset(
++ new SearchParam(maOption.maMatchString, ::utl::SearchParam::SRCH_REGEXP, false, false, false));
++ if (!maOption.mpTextSearch)
++ maOption.mpTextSearch.reset(
++ new TextSearch(*maOption.mpSearchParam, *ScGlobal::pCharClass));
++ }
++
++ return mpDataArray->runQuery(maOption);
++}
++
++size_t ScFunctionQueryHandler::countMatchedCells() const
++{
++ if (!mpDataArray)
++ return 0;
++
++ return mpDataArray->countMatchedCells();
++}
++
+diff --git sc/source/core/tool/interpr1.cxx sc/source/core/tool/interpr1.cxx
+index a22d157..9f3bdeb 100644
+--- sc/source/core/tool/interpr1.cxx
++++ sc/source/core/tool/interpr1.cxx
+@@ -67,10 +67,12 @@
+ #include <string.h>
+ #include <math.h>
+ #include <vector>
++#include <memory>
+ #include "cellkeytranslator.hxx"
+ #include "lookupcache.hxx"
+ #include "rangenam.hxx"
+ #include "compiler.hxx"
++#include "funcqueryhandler.hxx"
+ #include <basic/sbstar.hxx>
+
+ #define SC_DOUBLE_MAXVALUE 1.7e307
+@@ -4306,85 +4308,125 @@ void ScInterpreter::ScCountIf()
+ size_t nRefInList = 0;
+ while (nParam-- > 0)
+ {
+- SCCOL nCol1;
+- SCROW nRow1;
+- SCTAB nTab1;
+- SCCOL nCol2;
+- SCROW nRow2;
+- SCTAB nTab2;
+- switch ( GetStackType() )
++ ScFunctionQueryHandler aQueryHdl;
++
++ // Query option first.
++ ScFunctionQueryHandler::QueryOption aOption;
++ if (!bIsString)
+ {
+- case svDoubleRef :
+- case svRefList :
+- {
+- ScRange aRange;
+- PopDoubleRef( aRange, nParam, nRefInList);
+- aRange.GetVars( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
+- }
+- break;
+- case svSingleRef :
+- PopSingleRef( nCol1, nRow1, nTab1 );
+- nCol2 = nCol1;
+- nRow2 = nRow1;
+- nTab2 = nTab1;
+- break;
+- default:
+- PushIllegalParameter();
+- return ;
++ aOption.meOp = SC_EQUAL;
++ aOption.mfMatchValue = fVal;
++ aOption.mbQueryByString = false;
+ }
+- if ( nTab1 != nTab2 )
++ else
+ {
+- PushIllegalParameter();
+- return;
++ aOption.parseCriterion(rString);
++ sal_uInt32 nIndex = 0;
++ aOption.mbQueryByString =
++ !(pFormatter->IsNumberFormat(aOption.maMatchString, nIndex, aOption.mfMatchValue));
++ if (aOption.mbQueryByString)
++ aOption.mbRegExp = MayBeRegExp(aOption.maMatchString, pDok);
+ }
+- if (nCol1 > nCol2)
++ aQueryHdl.setQueryOption(aOption);
++
++ StackVar eParamType = GetStackType();
++ bool bInternalRef = false;
++ switch (eParamType)
+ {
+- PushIllegalParameter();
+- return;
++ case svDoubleRef:
++ case svRefList:
++ case svSingleRef:
++ bInternalRef = true;
++ break;
+ }
+- if (nGlobalError == 0)
++ if (bInternalRef)
+ {
+- ScQueryParam rParam;
+- rParam.nRow1 = nRow1;
+- rParam.nRow2 = nRow2;
++ SCCOL nCol1;
++ SCROW nRow1;
++ SCTAB nTab1;
++ SCCOL nCol2;
++ SCROW nRow2;
++ SCTAB nTab2;
+
+- ScQueryEntry& rEntry = rParam.GetEntry(0);
+- rEntry.bDoQuery = TRUE;
+- if (!bIsString)
++ switch (eParamType)
+ {
+- rEntry.bQueryByString = FALSE;
+- rEntry.nVal = fVal;
+- rEntry.eOp = SC_EQUAL;
++ case svDoubleRef :
++ case svRefList :
++ {
++ ScRange aRange;
++ PopDoubleRef( aRange, nParam, nRefInList);
++ aRange.GetVars( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
++ }
++ break;
++ case svSingleRef :
++ PopSingleRef( nCol1, nRow1, nTab1 );
++ nCol2 = nCol1;
++ nRow2 = nRow1;
++ nTab2 = nTab1;
++ break;
++ break;
++ PushIllegalParameter();
++ return ;
+ }
+- else
++ if ( nTab1 != nTab2 )
+ {
+- rParam.FillInExcelSyntax(rString, 0);
+- sal_uInt32 nIndex = 0;
+- rEntry.bQueryByString =
+- !(pFormatter->IsNumberFormat(
+- *rEntry.pStr, nIndex, rEntry.nVal));
+- if ( rEntry.bQueryByString )
+- rParam.bRegExp = MayBeRegExp( *rEntry.pStr, pDok );
++ PushIllegalParameter();
++ return;
+ }
+- rParam.nCol1 = nCol1;
+- rParam.nCol2 = nCol2;
+- rEntry.nField = nCol1;
+- ScQueryCellIterator aCellIter(pDok, nTab1, rParam, FALSE);
+- // Entry.nField im Iterator bei Spaltenwechsel weiterschalten
+- aCellIter.SetAdvanceQueryParamEntryField( TRUE );
+- if ( aCellIter.GetFirst() )
++ if (nCol1 > nCol2)
+ {
+- do
+- {
+- fSum++;
+- } while ( aCellIter.GetNext() );
++ PushIllegalParameter();
++ return;
++ }
++ if (nGlobalError)
++ {
++ PushIllegalParameter();
++ return;
+ }
++
++ aQueryHdl.setDataArray(
++ new ScFunctionQueryHandler::RangeDataArray(pDok, nCol1, nRow1, nCol2, nRow2, nTab1));
+ }
+ else
+ {
+- PushIllegalParameter();
+- return;
++ // Not an internal reference. Use static data array.
++ ::std::auto_ptr<ScFunctionQueryHandler::DataArrayBase> pDataArray(
++ new ScFunctionQueryHandler::StaticDataArray);
++ ScFunctionQueryHandler::StaticDataArray* pStaticArray =
++ static_cast<ScFunctionQueryHandler::StaticDataArray*>(pDataArray.get());
++ switch (eParamType)
++ {
++ case svString:
++ pStaticArray->addCell(GetString());
++ break;
++ case svDouble:
++ pStaticArray->addCell(GetDouble());
++ break;
++ case svMatrix:
++ {
++ ScMatrixRef xMat = GetMatrix();
++ SCSIZE n = xMat->GetElementCount();
++ for (SCSIZE i = 0; i < n; ++i)
++ {
++ if (xMat->IsEmpty(i))
++ // empty cells are not taken into account.
++ continue;
++
++ if (xMat->IsValue(i))
++ pStaticArray->addCell(xMat->GetDouble(i));
++ else
++ pStaticArray->addCell(xMat->GetString(i));
++ }
++ }
++ break;
++ default:
++ ;
++ }
++ aQueryHdl.setDataArray(pDataArray.release());
+ }
++
++ if (aQueryHdl.runQuery())
++ fSum += aQueryHdl.countMatchedCells();
+ }
+ PushDouble(fSum);
+ }
+diff --git sc/source/core/tool/makefile.mk sc/source/core/tool/makefile.mk
+index 898c2ef..85065d9 100644
+--- sc/source/core/tool/makefile.mk
++++ sc/source/core/tool/makefile.mk
+@@ -107,6 +107,7 @@ SLOFILES = \
+ $(SLO)$/refupdat.obj \
+ $(SLO)$/scmatrix.obj \
+ $(SLO)$/sctictac.obj \
++ $(SLO)$/funcqueryhandler.obj \
+ $(SLO)$/subtotal.obj \
+ $(SLO)$/token.obj \
+ $(SLO)$/unitconv.obj \
+@@ -131,5 +132,6 @@ EXCEPTIONSFILES= \
+ $(SLO)$/lookupcache.obj \
+ $(SLO)$/prnsave.obj \
+ $(SLO)$/reftokenhelper.obj \
++ $(SLO)$/funcqueryhandler.obj \
+ $(SLO)$/token.obj
+
More information about the ooo-build-commit
mailing list