diff options
author | Kohei Yoshida <kyoshida@novell.com> | 2009-09-09 10:57:16 -0400 |
---|---|---|
committer | Kohei Yoshida <kyoshida@novell.com> | 2009-09-09 10:57:16 -0400 |
commit | f371fca09ddff5d5d32a0dcec05931be04b1b8c9 (patch) | |
tree | 4d144cec484c37fc76793e626087c495699e7690 | |
parent | 3db13d25ca7c79cbc53ecba722453571451b96e9 (diff) |
#i102750# initial refactoring in an effort to support external references in DSUM, DGET etc. Not finished yet.
32 files changed, 1179 insertions, 165 deletions
diff --git a/sc/inc/datauno.hxx b/sc/inc/datauno.hxx index a93bfc341573..045e98d3161b 100644 --- a/sc/inc/datauno.hxx +++ b/sc/inc/datauno.hxx @@ -32,6 +32,8 @@ #define SC_DATAUNO_HXX #include "global.hxx" +#include "queryparam.hxx" + #include <svtools/itemprop.hxx> #include <svtools/lstner.hxx> #include <com/sun/star/sheet/TableFilterField.hpp> diff --git a/sc/inc/dociter.hxx b/sc/inc/dociter.hxx index 3f9e77a82378..d4f0ee7660af 100644 --- a/sc/inc/dociter.hxx +++ b/sc/inc/dociter.hxx @@ -35,6 +35,9 @@ #include <tools/solar.h> #include "global.hxx" #include "scdllapi.h" +#include "queryparam.hxx" + +#include <memory> class ScDocument; class ScBaseCell; @@ -127,34 +130,72 @@ public: } }; +// ============================================================================ + class ScQueryValueIterator // alle Zahlenwerte in einem Bereich durchgehen { private: - ScQueryParam aParam; - ScDocument* pDoc; - const ScAttrArray* pAttrArray; - ULONG nNumFormat; // fuer CalcAsShown - ULONG nNumFmtIndex; - SCCOL nCol; - SCROW nRow; - SCSIZE nColRow; - SCROW nAttrEndRow; - SCTAB nTab; - short nNumFmtType; - BOOL bCalcAsShown; + class DataAccess + { + public: + DataAccess(); + virtual ~DataAccess() = 0; + virtual bool getCurrent(double& rValue, USHORT& rErr) = 0; + virtual bool getFirst(double& rValue, USHORT& rErr) = 0; + virtual bool getNext(double& rValue, USHORT& rErr) = 0; + }; - BOOL GetThis(double& rValue, USHORT& rErr); + class DataAccessInternal : public DataAccess + { + public: + DataAccessInternal(const ScQueryParam* pParam, ScDocument* pDoc); + virtual ~DataAccessInternal(); + virtual bool getCurrent(double &rValue, USHORT &rErr); + virtual bool getFirst(double &rValue, USHORT &rErr); + virtual bool getNext(double& rValue, USHORT& rErr); + + private: + const ScQueryParam* mpParam; + ScDocument* mpDoc; + const ScAttrArray* pAttrArray; + ULONG nNumFormat; // fuer CalcAsShown + ULONG nNumFmtIndex; + SCCOL nCol; + SCROW nRow; + SCSIZE nColRow; + SCROW nAttrEndRow; + SCTAB nTab; + short nNumFmtType; + bool bCalcAsShown; + }; + + class DataAccessMatrix : public DataAccess + { + public: + DataAccessMatrix(const ScQueryParamMatrix* pParam); + virtual ~DataAccessMatrix(); + virtual bool getCurrent(double &rValue, USHORT &rErr); + virtual bool getFirst(double &rValue, USHORT &rErr); + virtual bool getNext(double &rValue, USHORT &rErr); + + private: + const ScQueryParamMatrix* mpParam; + }; + + ::std::auto_ptr<ScQueryParamBase> mpParam; + ::std::auto_ptr<DataAccess> mpData; + + bool GetThis(double& rValue, USHORT& rErr); public: - ScQueryValueIterator(ScDocument* pDocument, SCTAB nTable, - const ScQueryParam& aParam); + ScQueryValueIterator(ScDocument* pDocument, ScQueryParamBase* pParam); /// Does NOT reset rValue if no value found! BOOL GetFirst(double& rValue, USHORT& rErr); /// Does NOT reset rValue if no value found! BOOL GetNext(double& rValue, USHORT& rErr); - void GetCurNumFmtInfo( short& nType, ULONG& nIndex ) - { nType = nNumFmtType; nIndex = nNumFmtIndex; } }; +// ============================================================================ + class ScCellIterator // alle Zellen in einem Bereich durchgehen { // bei SubTotal aber keine ausgeblendeten und private: // SubTotalZeilen diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx index c8d3751a7aaf..e43653036ae9 100644 --- a/sc/inc/document.hxx +++ b/sc/inc/document.hxx @@ -140,6 +140,7 @@ class ScLookupCache; struct ScLookupCacheMapImpl; class SfxUndoManager; class ScFormulaParserPool; +class ScDoubleRefBase; namespace com { namespace sun { namespace star { namespace lang { @@ -1382,6 +1383,7 @@ public: BOOL ValidQuery( SCROW nRow, SCTAB nTab, const ScQueryParam& rQueryParam, BOOL* pSpecial = NULL ); SC_DLLPUBLIC BOOL CreateQueryParam( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, SCTAB nTab, ScQueryParam& rQueryParam ); + bool CreateQueryParam(const ScDoubleRefBase* pDoubleRef, ScQueryParam& rQueryParam); void GetUpperCellString(SCCOL nCol, SCROW nRow, SCTAB nTab, String& rStr); BOOL GetFilterEntries( SCCOL nCol, SCROW nRow, SCTAB nTab, diff --git a/sc/inc/dpcachetable.hxx b/sc/inc/dpcachetable.hxx index 93cd12c4c937..301b77aae14c 100644 --- a/sc/inc/dpcachetable.hxx +++ b/sc/inc/dpcachetable.hxx @@ -60,6 +60,7 @@ class ScDPDimension; class ScDPCollection; struct ScDPCacheCell; struct ScDPItemData; +struct ScQueryParam; class Date; // ---------------------------------------------------------------------------- diff --git a/sc/inc/dpshttab.hxx b/sc/inc/dpshttab.hxx index 0bcdbeee517e..b8ccd3b31f64 100644 --- a/sc/inc/dpshttab.hxx +++ b/sc/inc/dpshttab.hxx @@ -35,6 +35,7 @@ #include "global.hxx" #include "address.hxx" #include "scdllapi.h" +#include "queryparam.hxx" #include <vector> diff --git a/sc/inc/global.hxx b/sc/inc/global.hxx index e329f477d824..9ad45feb717a 100644 --- a/sc/inc/global.hxx +++ b/sc/inc/global.hxx @@ -819,7 +819,7 @@ struct ScQueryEntry ScQueryEntry& operator=( const ScQueryEntry& r ); BOOL operator==( const ScQueryEntry& r ) const; }; - +#if 0 struct SC_DLLPUBLIC ScQueryParam { SCCOL nCol1; @@ -860,7 +860,7 @@ public: void MoveToDest(); void FillInExcelSyntax(String& aCellStr, SCSIZE nIndex); }; - +#endif // ----------------------------------------------------------------------- struct SC_DLLPUBLIC ScSubTotalParam diff --git a/sc/inc/queryparam.hxx b/sc/inc/queryparam.hxx new file mode 100644 index 000000000000..3e106647b58b --- /dev/null +++ b/sc/inc/queryparam.hxx @@ -0,0 +1,105 @@ +/************************************************************************* + * + * 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: interpre.hxx,v $ + * $Revision: 1.35.44.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_QUERYPARAM_HXX +#define SC_QUERYPARAM_HXX + +#include "global.hxx" +#include "scmatrix.hxx" + +struct ScQueryParamBase +{ + enum DataType { INTERNAL, MATRIX }; + + bool bHasHeader; + bool bByRow; + bool bInplace; + bool bCaseSens; + bool bRegExp; + bool bDuplicate; + + virtual ~ScQueryParamBase(); + + SCSIZE GetEntryCount() const { return nEntryCount; } + ScQueryEntry& GetEntry(SCSIZE n) const { return pEntries[n]; } + void Resize(SCSIZE nNew); + SC_DLLPUBLIC void DeleteQuery( SCSIZE nPos ); + void FillInExcelSyntax(String& aCellStr, SCSIZE nIndex); + + DataType GetType() const; + +protected: + ScQueryParamBase(DataType eType); + ScQueryParamBase(const ScQueryParamBase& r); + + SCSIZE nEntryCount; + ScQueryEntry* pEntries; + +private: + ScQueryParamBase(); + DataType meType; +}; + +// ============================================================================ + +struct SC_DLLPUBLIC ScQueryParam : public ScQueryParamBase +{ + SCCOL nCol1; + SCROW nRow1; + SCCOL nCol2; + SCROW nRow2; + SCTAB nTab; + BOOL bMixedComparison; // whether numbers are smaller than strings + BOOL bDestPers; // nicht gespeichert + SCTAB nDestTab; + SCCOL nDestCol; + SCROW nDestRow; + + ScQueryParam(); + ScQueryParam( const ScQueryParam& r ); + virtual ~ScQueryParam(); + + ScQueryParam& operator= ( const ScQueryParam& r ); + BOOL operator== ( const ScQueryParam& rOther ) const; + void Clear (); + void MoveToDest(); +}; + +// ============================================================================ + +struct ScQueryParamMatrix : public ScQueryParamBase +{ + ScMatrixRef mpMatrix; + + ScQueryParamMatrix(); + virtual ~ScQueryParamMatrix(); +}; + +#endif diff --git a/sc/source/core/data/autonamecache.cxx b/sc/source/core/data/autonamecache.cxx index d106e5824571..d1d54bc54536 100644 --- a/sc/source/core/data/autonamecache.cxx +++ b/sc/source/core/data/autonamecache.cxx @@ -40,6 +40,7 @@ #include "autonamecache.hxx" #include "dociter.hxx" #include "cell.hxx" +#include "queryparam.hxx" // ----------------------------------------------------------------------- diff --git a/sc/source/core/data/dociter.cxx b/sc/source/core/data/dociter.cxx index 3b650f5d8ca4..de34ebf2439c 100644 --- a/sc/source/core/data/dociter.cxx +++ b/sc/source/core/data/dociter.cxx @@ -482,55 +482,66 @@ BOOL ScValueIterator::GetNext(double& rValue, USHORT& rErr) } */ -//------------------------------------------------------------------------ -//------------------------------------------------------------------------ +// ============================================================================ -ScQueryValueIterator::ScQueryValueIterator(ScDocument* pDocument, SCTAB nTable, const ScQueryParam& rParam) : - aParam (rParam), - pDoc( pDocument ), - nNumFmtIndex(0), - nTab( nTable), - nNumFmtType( NUMBERFORMAT_UNDEFINED ), - bCalcAsShown( pDocument->GetDocOptions().IsCalcAsShown() ) +ScQueryValueIterator::DataAccess::DataAccess() { - nCol = aParam.nCol1; - nRow = aParam.nRow1; +} + +ScQueryValueIterator::DataAccess::~DataAccess() +{ +} + +// ---------------------------------------------------------------------------- + +ScQueryValueIterator::DataAccessInternal::DataAccessInternal(const ScQueryParam* pParam, ScDocument* pDoc) : + mpParam(pParam), + mpDoc(pDoc) +{ + nCol = mpParam->nCol1; + nRow = mpParam->nRow1; + nTab = mpParam->nTab; + nColRow = 0; // wird bei GetFirst initialisiert SCSIZE i; - SCSIZE nCount = aParam.GetEntryCount(); - for (i=0; (i<nCount) && (aParam.GetEntry(i).bDoQuery); i++) + SCSIZE nCount = mpParam->GetEntryCount(); + for (i=0; (i<nCount) && (mpParam->GetEntry(i).bDoQuery); i++) { - ScQueryEntry& rEntry = aParam.GetEntry(i); + ScQueryEntry& rEntry = mpParam->GetEntry(i); sal_uInt32 nIndex = 0; rEntry.bQueryByString = - !(pDoc->GetFormatTable()->IsNumberFormat(*rEntry.pStr, nIndex, rEntry.nVal)); + !(mpDoc->GetFormatTable()->IsNumberFormat(*rEntry.pStr, nIndex, rEntry.nVal)); } nNumFormat = 0; // werden bei GetNumberFormat initialisiert pAttrArray = 0; nAttrEndRow = 0; } -BOOL ScQueryValueIterator::GetThis(double& rValue, USHORT& rErr) +ScQueryValueIterator::DataAccessInternal::~DataAccessInternal() { - ScColumn* pCol = &(pDoc->pTab[nTab])->aCol[nCol]; - SCCOLROW nFirstQueryField = aParam.GetEntry(0).nField; +} + +bool ScQueryValueIterator::DataAccessInternal::getCurrent(double& rValue, USHORT& rErr) +{ + ScColumn* pCol = &(mpDoc->pTab[nTab])->aCol[nCol]; + SCCOLROW nFirstQueryField = mpParam->GetEntry(0).nField; for ( ;; ) { - if ( nRow > aParam.nRow2 ) + if ( nRow > mpParam->nRow2 ) { - nRow = aParam.nRow1; - if (aParam.bHasHeader) + nRow = mpParam->nRow1; + if (mpParam->bHasHeader) nRow++; do { nCol++; - if ( nCol > aParam.nCol2 ) + if ( nCol > mpParam->nCol2 ) { // rValue = 0.0; // do not change caller's value! rErr = 0; return FALSE; // Ende und Aus } - pCol = &(pDoc->pTab[nTab])->aCol[nCol]; + pCol = &(mpDoc->pTab[nTab])->aCol[nCol]; } while ( pCol->nCount == 0 ); pCol->Search( nRow, nColRow ); } @@ -538,11 +549,11 @@ BOOL ScQueryValueIterator::GetThis(double& rValue, USHORT& rErr) while ( (nColRow < pCol->nCount) && (pCol->pItems[nColRow].nRow < nRow) ) nColRow++; - if ( nColRow < pCol->nCount && pCol->pItems[nColRow].nRow <= aParam.nRow2 ) + if ( nColRow < pCol->nCount && pCol->pItems[nColRow].nRow <= mpParam->nRow2 ) { nRow = pCol->pItems[nColRow].nRow; ScBaseCell* pCell = pCol->pItems[nColRow].pCell; - if ( (pDoc->pTab[nTab])->ValidQuery( nRow, aParam, NULL, + if ( (mpDoc->pTab[nTab])->ValidQuery( nRow, *mpParam, NULL, (nCol == static_cast<SCCOL>(nFirstQueryField) ? pCell : NULL) ) ) { switch (pCell->GetCellType()) @@ -553,8 +564,8 @@ BOOL ScQueryValueIterator::GetThis(double& rValue, USHORT& rErr) if ( bCalcAsShown ) { lcl_IterGetNumberFormat( nNumFormat, pAttrArray, - nAttrEndRow, pCol->pAttrArray, nRow, pDoc ); - rValue = pDoc->RoundValueAsShown( rValue, nNumFormat ); + nAttrEndRow, pCol->pAttrArray, nRow, mpDoc ); + rValue = mpDoc->RoundValueAsShown( rValue, nNumFormat ); } nNumFmtType = NUMBERFORMAT_NUMBER; nNumFmtIndex = 0; @@ -567,7 +578,7 @@ BOOL ScQueryValueIterator::GetThis(double& rValue, USHORT& rErr) if (((ScFormulaCell*)pCell)->IsValue()) { rValue = ((ScFormulaCell*)pCell)->GetValue(); - pDoc->GetNumberFormatInfo( nNumFmtType, + mpDoc->GetNumberFormatInfo( nNumFmtType, nNumFmtIndex, ScAddress( nCol, nRow, nTab ), pCell ); rErr = ((ScFormulaCell*)pCell)->GetErrCode(); @@ -586,30 +597,90 @@ BOOL ScQueryValueIterator::GetThis(double& rValue, USHORT& rErr) nRow++; } else - nRow = aParam.nRow2 + 1; // Naechste Spalte + nRow = mpParam->nRow2 + 1; // Naechste Spalte } -// return FALSE; + return false; } -BOOL ScQueryValueIterator::GetFirst(double& rValue, USHORT& rErr) +bool ScQueryValueIterator::DataAccessInternal::getFirst(double& rValue, USHORT& rErr) { - nCol = aParam.nCol1; - nRow = aParam.nRow1; - if (aParam.bHasHeader) + if (mpParam->bHasHeader) nRow++; // nColRow = 0; - ScColumn* pCol = &(pDoc->pTab[nTab])->aCol[nCol]; + ScColumn* pCol = &(mpDoc->pTab[nTab])->aCol[nCol]; pCol->Search( nRow, nColRow ); - return GetThis(rValue, rErr); + return getCurrent(rValue, rErr); } -BOOL ScQueryValueIterator::GetNext(double& rValue, USHORT& rErr) +bool ScQueryValueIterator::DataAccessInternal::getNext(double& rValue, USHORT& rErr) { ++nRow; - return GetThis(rValue, rErr); + return getCurrent(rValue, rErr); } -//------------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- + +ScQueryValueIterator::DataAccessMatrix::DataAccessMatrix(const ScQueryParamMatrix* pParam) : + mpParam(pParam) +{ +} + +ScQueryValueIterator::DataAccessMatrix::~DataAccessMatrix() +{ +} + +bool ScQueryValueIterator::DataAccessMatrix::getCurrent(double& rValue, USHORT& rErr) +{ + return false; +} + +bool ScQueryValueIterator::DataAccessMatrix::getFirst(double& rValue, USHORT& rErr) +{ + return false; +} + +bool ScQueryValueIterator::DataAccessMatrix::getNext(double& rValue, USHORT& rErr) +{ + return false; +} + +// ---------------------------------------------------------------------------- + +ScQueryValueIterator::ScQueryValueIterator(ScDocument* pDocument, ScQueryParamBase* pParam) : + mpParam (pParam) +{ + switch (mpParam->GetType()) + { + case ScQueryParamBase::INTERNAL: + { + const ScQueryParam* p = static_cast<const ScQueryParam*>(pParam); + mpData.reset(new DataAccessInternal(p, pDocument)); + } + break; + case ScQueryParamBase::MATRIX: + { + const ScQueryParamMatrix* p = static_cast<const ScQueryParamMatrix*>(pParam); + mpData.reset(new DataAccessMatrix(p)); + } + } +} + +bool ScQueryValueIterator::GetThis(double& rValue, USHORT& rErr) +{ + return mpData->getCurrent(rValue, rErr); +} + +BOOL ScQueryValueIterator::GetFirst(double& rValue, USHORT& rErr) +{ + return mpData->getFirst(rValue, rErr); +} + +BOOL ScQueryValueIterator::GetNext(double& rValue, USHORT& rErr) +{ + return mpData->getNext(rValue, rErr); +} + +// ============================================================================ ScCellIterator::ScCellIterator( ScDocument* pDocument, SCCOL nSCol, SCROW nSRow, SCTAB nSTab, diff --git a/sc/source/core/data/documen3.cxx b/sc/source/core/data/documen3.cxx index 08170fd6cdc9..f256c99c8806 100644 --- a/sc/source/core/data/documen3.cxx +++ b/sc/source/core/data/documen3.cxx @@ -80,6 +80,7 @@ #include "listenercalls.hxx" #include "tabprotection.hxx" #include "formulaparserpool.hxx" +#include "doubleref.hxx" #include <memory> @@ -1242,6 +1243,28 @@ BOOL ScDocument::CreateQueryParam(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW n return FALSE; } +bool ScDocument::CreateQueryParam(const ScDoubleRefBase* pDoubleRef, ScQueryParam& rQueryParam) +{ + if (!pDoubleRef) + return false; + + switch (pDoubleRef->getType()) + { + case ScDoubleRefBase::INTERNAL: + { + const ScRange& rRange = static_cast<const ScInternalDoubleRef*>(pDoubleRef)->getRange(); + const ScAddress& s = rRange.aStart; + const ScAddress& e = rRange.aEnd; + if (ValidTab(s.Tab()) && pTab[s.Tab()]) + return pTab[s.Tab()]->CreateQueryParam(s.Col(), s.Row(), e.Col(), e.Row(), rQueryParam); + } + break; + case ScDoubleRefBase::EXTERNAL: + break; + } + return false; +} + BOOL ScDocument::HasAutoFilter( SCCOL nCurCol, SCROW nCurRow, SCTAB nCurTab ) { ScDBData* pDBData = GetDBAtCursor( nCurCol, nCurRow, nCurTab ); diff --git a/sc/source/core/data/dpcachetable.cxx b/sc/source/core/data/dpcachetable.cxx index 2a1b4481ccaa..99dc02630eb6 100644 --- a/sc/source/core/data/dpcachetable.cxx +++ b/sc/source/core/data/dpcachetable.cxx @@ -38,6 +38,7 @@ #include "dptabdat.hxx" #include "dptabsrc.hxx" #include "dpobject.hxx" +#include "queryparam.hxx" #include <com/sun/star/i18n/LocaleDataItem.hpp> #include <com/sun/star/sdbc/DataType.hpp> diff --git a/sc/source/core/data/global2.cxx b/sc/source/core/data/global2.cxx index c352dbb550d6..1f3305f83cdd 100644 --- a/sc/source/core/data/global2.cxx +++ b/sc/source/core/data/global2.cxx @@ -242,7 +242,7 @@ utl::TextSearch* ScQueryEntry::GetSearchTextPtr( BOOL bCaseSens ) } //------------------------------------------------------------------------ - +#if 0 ScQueryParam::ScQueryParam() { nEntryCount = 0; @@ -472,7 +472,7 @@ void ScQueryParam::FillInExcelSyntax(String& aCellStr, SCSIZE nIndex) } } } - +#endif //------------------------------------------------------------------------ // struct ScSubTotalParam: diff --git a/sc/source/core/data/sortparam.cxx b/sc/source/core/data/sortparam.cxx index 15691a642d7e..d210b3b015f3 100644 --- a/sc/source/core/data/sortparam.cxx +++ b/sc/source/core/data/sortparam.cxx @@ -36,6 +36,7 @@ #include "sortparam.hxx" #include "global.hxx" #include "address.hxx" +#include "queryparam.hxx" #include <tools/debug.hxx> diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx index ae299fdf5fca..54cfa4c81dea 100644 --- a/sc/source/core/data/table3.cxx +++ b/sc/source/core/data/table3.cxx @@ -60,6 +60,7 @@ #include "progress.hxx" #include "cellform.hxx" #include "postit.hxx" +#include "queryparam.hxx" #include <vector> diff --git a/sc/source/core/inc/doubleref.hxx b/sc/source/core/inc/doubleref.hxx new file mode 100644 index 000000000000..d61dd35fcc6d --- /dev/null +++ b/sc/source/core/inc/doubleref.hxx @@ -0,0 +1,106 @@ +/************************************************************************* + * + * 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: interpre.hxx,v $ + * $Revision: 1.35.44.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_DOUBLEREF_HXX +#define SC_DOUBLEREF_HXX + +#include "address.hxx" + +class ScDocument; +class ScBaseCell; +class ScQueryParam; + +// ============================================================================ + +class ScDoubleRefBase +{ +public: + enum RefType { INTERNAL, EXTERNAL }; + + virtual ~ScDoubleRefBase() = 0; + + RefType getType() const; + + virtual SCCOL getFirstFieldColumn() = 0; + virtual SCCOL findFieldColumn(SCCOL nColIndex) = 0; + virtual SCCOL findFieldColumn(const ::rtl::OUString& rStr, sal_uInt16& rErr) = 0; + virtual void initQueryParam(ScQueryParam& rParam) const = 0; + virtual bool isRangeEqual(const ScRange& rRange) const = 0; + +protected: + ScDoubleRefBase(ScDocument* pDoc, RefType eType); + ScDocument* getDoc(); + +private: + ScDoubleRefBase(); // disabled + + ScDocument* mpDoc; + RefType meType; +}; + +// ============================================================================ + +class ScInternalDoubleRef : public ScDoubleRefBase +{ +public: + explicit ScInternalDoubleRef(ScDocument* pDoc, const ScRange& rRange); + virtual ~ScInternalDoubleRef(); + + const ScRange& getRange() const; + + virtual SCCOL getFirstFieldColumn(); + virtual SCCOL findFieldColumn(SCCOL nColIndex); + virtual SCCOL findFieldColumn(const ::rtl::OUString& rStr, sal_uInt16& rErr); + virtual void initQueryParam(ScQueryParam& rParam) const; + virtual bool isRangeEqual(const ScRange& rRange) const; + +private: + sal_uInt16 getCellString(String& rStr, ScBaseCell* pCell); + +private: + ScRange maRange; +}; + +// ============================================================================ + +class ScExternalDoubleRef : public ScDoubleRefBase +{ +public: + explicit ScExternalDoubleRef(ScDocument* pDoc); + virtual ~ScExternalDoubleRef(); + + virtual SCCOL getFirstFieldColumn(); + virtual SCCOL findFieldColumn(SCCOL nColIndex); + virtual SCCOL findFieldColumn(const ::rtl::OUString& rStr, sal_uInt16& rErr); + virtual void initQueryParam(ScQueryParam& rParam) const; + virtual bool isRangeEqual(const ScRange& rRange) const; +}; + +#endif diff --git a/sc/source/core/inc/interpre.hxx b/sc/source/core/inc/interpre.hxx index 9fcf743c1e85..525f3b5f587f 100644 --- a/sc/source/core/inc/interpre.hxx +++ b/sc/source/core/inc/interpre.hxx @@ -53,7 +53,9 @@ class SbxVariable; class ScBaseCell; class ScFormulaCell; class SvNumberFormatter; +class ScDoubleRefBase; struct MatrixDoubleOp; +struct ScQueryParam; struct ScCompare { @@ -301,6 +303,7 @@ void DoubleRefToVars( const ScToken* p, SCCOL& rCol1, SCROW &rRow1, SCTAB& rTab1, SCCOL& rCol2, SCROW &rRow2, SCTAB& rTab2, BOOL bDontCheckForTableOp = FALSE ); +ScDoubleRefBase* PopDoubleRef(); void PopDoubleRef(SCCOL& rCol1, SCROW &rRow1, SCTAB& rTab1, SCCOL& rCol2, SCROW &rRow2, SCTAB& rTab2, BOOL bDontCheckForTableOp = FALSE ); @@ -488,7 +491,7 @@ void ScSubTotal(); // compatibility). If this was the case then rMissingField is set to TRUE upon // return. If rMissingField==FALSE upon call all "missing cases" are considered // to be an error. -BOOL GetDBParams( SCTAB& rTab, ScQueryParam& rParam, BOOL& rMissingField ); +BOOL GetDBParams( ScQueryParam& rParam, BOOL& rMissingField ); void DBIterator( ScIterFunc ); void ScDBSum(); diff --git a/sc/source/core/tool/dbcolect.cxx b/sc/source/core/tool/dbcolect.cxx index e6c039b5d79f..e7f4bd26eca9 100644 --- a/sc/source/core/tool/dbcolect.cxx +++ b/sc/source/core/tool/dbcolect.cxx @@ -40,6 +40,7 @@ #include "refupdat.hxx" #include "rechead.hxx" #include "document.hxx" +#include "queryparam.hxx" #include "globstr.hrc" diff --git a/sc/source/core/tool/doubleref.cxx b/sc/source/core/tool/doubleref.cxx new file mode 100644 index 000000000000..2eb61c6be38e --- /dev/null +++ b/sc/source/core/tool/doubleref.cxx @@ -0,0 +1,236 @@ +/************************************************************************* + * + * 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: interpre.hxx,v $ + * $Revision: 1.35.44.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 "doubleref.hxx" +#include "cell.hxx" +#include "global.hxx" +#include "document.hxx" +#include "queryparam.hxx" + +using ::rtl::OUString; + +// ============================================================================ + +ScDoubleRefBase::ScDoubleRefBase(ScDocument* pDoc, RefType eType) : + mpDoc(pDoc), meType(eType) +{ +} + +ScDoubleRefBase::~ScDoubleRefBase() +{ +} + +ScDoubleRefBase::RefType ScDoubleRefBase::getType() const +{ + return meType; +} + +ScDocument* ScDoubleRefBase::getDoc() +{ + return mpDoc; +} + +// ============================================================================ + +ScInternalDoubleRef::ScInternalDoubleRef(ScDocument* pDoc, const ScRange& rRange) : + ScDoubleRefBase(pDoc, INTERNAL), maRange(rRange) +{ +} + +ScInternalDoubleRef::~ScInternalDoubleRef() +{ +} + +const ScRange& ScInternalDoubleRef::getRange() const +{ + return maRange; +} + +SCCOL ScInternalDoubleRef::getFirstFieldColumn() +{ + return getRange().aStart.Col(); +} + +SCCOL ScInternalDoubleRef::findFieldColumn(SCCOL nColIndex) +{ + const ScRange& rRange = getRange(); + const ScAddress& s = rRange.aStart; + const ScAddress& e = rRange.aEnd; + + SCCOL nDBCol1 = s.Col(); + SCCOL nDBCol2 = e.Col(); + + if ( nColIndex <= 0 || nColIndex > (nDBCol2 - nDBCol1 + 1) ) + return nDBCol1; + + return Min(nDBCol2, static_cast<SCCOL>(nDBCol1 + nColIndex - 1)); +} + +sal_uInt16 ScInternalDoubleRef::getCellString(String& rStr, ScBaseCell* pCell) +{ + sal_uInt16 nErr = 0; + if (pCell) + { + SvNumberFormatter* pFormatter = getDoc()->GetFormatTable(); + switch (pCell->GetCellType()) + { + case CELLTYPE_STRING: + ((ScStringCell*) pCell)->GetString(rStr); + break; + case CELLTYPE_EDIT: + ((ScEditCell*) pCell)->GetString(rStr); + break; + case CELLTYPE_FORMULA: + { + ScFormulaCell* pFCell = (ScFormulaCell*) pCell; + nErr = pFCell->GetErrCode(); + if (pFCell->IsValue()) + { + double fVal = pFCell->GetValue(); + ULONG nIndex = pFormatter->GetStandardFormat( + NUMBERFORMAT_NUMBER, + ScGlobal::eLnge); + pFormatter->GetInputLineString(fVal, nIndex, rStr); + } + else + pFCell->GetString(rStr); + } + break; + case CELLTYPE_VALUE: + { + double fVal = ((ScValueCell*) pCell)->GetValue(); + ULONG nIndex = pFormatter->GetStandardFormat( + NUMBERFORMAT_NUMBER, + ScGlobal::eLnge); + pFormatter->GetInputLineString(fVal, nIndex, rStr); + } + break; + default: + rStr = ScGlobal::GetEmptyString(); + break; + } + } + else + rStr = ScGlobal::GetEmptyString(); + + return nErr; +} + +SCCOL ScInternalDoubleRef::findFieldColumn(const OUString& rStr, sal_uInt16& rErr) +{ + const ScRange& rRange = getRange(); + const ScAddress& s = rRange.aStart; + const ScAddress& e = rRange.aEnd; + + SCCOL nDBCol1 = s.Col(); + SCROW nDBRow1 = s.Row(); + SCTAB nDBTab1 = s.Tab(); + SCCOL nDBCol2 = e.Col(); + + SCCOL nField = nDBCol1; + BOOL bFound = TRUE; + + bFound = FALSE; + String aCellStr; + ScAddress aLook( nDBCol1, nDBRow1, nDBTab1 ); + while (!bFound && (aLook.Col() <= nDBCol2)) + { + ScBaseCell* pCell = getDoc()->GetCell( aLook ); + rErr = getCellString( aCellStr, pCell ); + bFound = ScGlobal::pTransliteration->isEqual(aCellStr, rStr); + if (!bFound) + aLook.IncCol(); + } + nField = aLook.Col(); + + return bFound ? nField : -1; +} + +void ScInternalDoubleRef::initQueryParam(ScQueryParam& rParam) const +{ + const ScAddress& s = maRange.aStart; + const ScAddress& e = maRange.aEnd; + rParam.nCol1 = s.Col(); + rParam.nRow1 = s.Row(); + rParam.nCol2 = e.Col(); + rParam.nRow2 = e.Row(); + rParam.nTab = s.Tab(); + rParam.bHasHeader = TRUE; + rParam.bByRow = TRUE; + rParam.bInplace = TRUE; + rParam.bCaseSens = FALSE; + rParam.bRegExp = FALSE; + rParam.bDuplicate = TRUE; +} + +bool ScInternalDoubleRef::isRangeEqual(const ScRange& rRange) const +{ + return maRange == rRange; +} + +// ============================================================================ + +ScExternalDoubleRef::ScExternalDoubleRef(ScDocument* pDoc) : + ScDoubleRefBase(pDoc, EXTERNAL) +{ +} + +ScExternalDoubleRef::~ScExternalDoubleRef() +{ +} + +SCCOL ScExternalDoubleRef::getFirstFieldColumn() +{ + return -1; +} + +SCCOL ScExternalDoubleRef::findFieldColumn(SCCOL nColIndex) +{ + return -1; +} + +SCCOL ScExternalDoubleRef::findFieldColumn(const OUString& rStr, sal_uInt16& rErr) +{ + return -1; +} + +void ScExternalDoubleRef::initQueryParam(ScQueryParam& rParam) const +{ +} + +bool ScExternalDoubleRef::isRangeEqual(const ScRange& /*rRange*/) const +{ + return false; +} diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx index 195366271f0d..63d1cd638b23 100644 --- a/sc/source/core/tool/interpr1.cxx +++ b/sc/source/core/tool/interpr1.cxx @@ -67,14 +67,54 @@ #include <string.h> #include <math.h> #include <vector> +#include <memory> #include "cellkeytranslator.hxx" #include "lookupcache.hxx" #include "rangenam.hxx" #include "compiler.hxx" #include "externalrefmgr.hxx" +#include "doubleref.hxx" +#include "queryparam.hxx" #define SC_DOUBLE_MAXVALUE 1.7e307 + +#include <stdio.h> +#include <string> +#include <sys/time.h> + +namespace { + +class StackPrinter +{ +public: + explicit StackPrinter(const char* msg) : + msMsg(msg) + { + fprintf(stdout, "%s: --begin\n", msMsg.c_str()); + mfStartTime = getTime(); + } + + ~StackPrinter() + { + double fEndTime = getTime(); + fprintf(stdout, "%s: --end (duration: %g sec)\n", msMsg.c_str(), (fEndTime-mfStartTime)); + } + +private: + double getTime() const + { + timeval tv; + gettimeofday(&tv, NULL); + return tv.tv_sec + tv.tv_usec / 1000000.0; + } + + ::std::string msMsg; + double mfStartTime; +}; + +} + IMPL_FIXEDMEMPOOL_NEWDEL( ScTokenStack, 8, 4 ) IMPL_FIXEDMEMPOOL_NEWDEL( ScInterpreter, 32, 16 ) @@ -5618,9 +5658,9 @@ void ScInterpreter::ScSubTotal() #endif -BOOL ScInterpreter::GetDBParams(SCTAB& rTab, ScQueryParam& rParam, - BOOL& rMissingField ) +BOOL ScInterpreter::GetDBParams( ScQueryParam& rParam, BOOL& rMissingField ) { + StackPrinter __stack_printer__("ScInterpreter::GetDBParams"); RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::GetDBParams" ); BOOL bRet = FALSE; BOOL bAllowMissingField = FALSE; @@ -5631,14 +5671,10 @@ BOOL ScInterpreter::GetDBParams(SCTAB& rTab, ScQueryParam& rParam, } if ( GetByte() == 3 ) { - - SCCOL nQCol1; - SCROW nQRow1; - SCTAB nQTab1; - SCCOL nQCol2; - SCROW nQRow2; - SCTAB nQTab2; - PopDoubleRef(nQCol1, nQRow1, nQTab1, nQCol2, nQRow2, nQTab2); + // First, get the query criteria range. + ::std::auto_ptr<ScDoubleRefBase> pQueryRef( PopDoubleRef() ); + if (!pQueryRef.get()) + return false; BOOL bByVal = TRUE; double nVal = 0.0; @@ -5648,16 +5684,20 @@ BOOL ScInterpreter::GetDBParams(SCTAB& rTab, ScQueryParam& rParam, switch (GetStackType()) { case svDouble : + fprintf(stdout, "ScInterpreter::GetDBParams: double\n"); nVal = ::rtl::math::approxFloor( GetDouble() ); + fprintf(stdout, "ScInterpreter::GetDBParams: value = %g\n", nVal); if ( bAllowMissingField && nVal == 0.0 ) rMissingField = TRUE; // fake missing parameter break; case svString : bByVal = FALSE; aStr = GetString(); + fprintf(stdout, "ScInterpreter::GetDBParams: str = '%s'\n", rtl::OUStringToOString(aStr, RTL_TEXTENCODING_UTF8).getStr()); break; case svSingleRef : { + fprintf(stdout, "ScInterpreter::GetDBParams: single ref\n"); ScAddress aAdr; PopSingleRef( aAdr ); ScBaseCell* pCell = GetCell( aAdr ); @@ -5671,6 +5711,7 @@ BOOL ScInterpreter::GetDBParams(SCTAB& rTab, ScQueryParam& rParam, } break; case svDoubleRef : + fprintf(stdout, "ScInterpreter::GetDBParams: double ref\n"); if ( bAllowMissingField ) { // fake missing parameter for old SO compatibility bRangeFake = TRUE; @@ -5683,6 +5724,7 @@ BOOL ScInterpreter::GetDBParams(SCTAB& rTab, ScQueryParam& rParam, } break; case svMissing : + fprintf(stdout, "ScInterpreter::GetDBParams: missing\n"); PopError(); if ( bAllowMissingField ) rMissingField = TRUE; @@ -5690,98 +5732,74 @@ BOOL ScInterpreter::GetDBParams(SCTAB& rTab, ScQueryParam& rParam, SetError( errIllegalParameter ); break; default: + fprintf(stdout, "ScInterpreter::GetDBParams: pop error (%d)\n", __LINE__); PopError(); SetError( errIllegalParameter ); } - SCCOL nDBCol1; - SCROW nDBRow1; - SCTAB nDBTab1; - SCCOL nDBCol2; - SCROW nDBRow2; - SCTAB nDBTab2; - PopDoubleRef(nDBCol1, nDBRow1, nDBTab1, nDBCol2, nDBRow2, nDBTab2); + ::std::auto_ptr<ScDoubleRefBase> pDBRef( PopDoubleRef() ); - if ( nGlobalError == 0 && bRangeFake ) + if (nGlobalError || !pDBRef.get()) + return false; + + if ( bRangeFake ) { // range parameter must match entire database range - if ( aMissingRange == ScRange( nDBCol1, nDBRow1, nDBTab1, nDBCol2, - nDBRow2, nDBTab2) ) + if (pDBRef->isRangeEqual(aMissingRange)) rMissingField = TRUE; else SetError( errIllegalParameter ); } - if (nGlobalError == 0) + if (nGlobalError) + return false; + + SCCOL nField = pDBRef->getFirstFieldColumn(); + if (rMissingField) + ; // special case + else if (bByVal) + nField = pDBRef->findFieldColumn(static_cast<SCCOL>(nVal)); + else { - SCCOL nField = nDBCol1; - BOOL bFound = TRUE; + sal_uInt16 nErr = 0; + nField = pDBRef->findFieldColumn(aStr, nErr); + SetError(nErr); + } + + if (!ValidCol(nField)) + return false; + + pDBRef->initQueryParam(rParam); + bool bCreated = pDok->CreateQueryParam(pQueryRef.get(), rParam); + + if (bCreated) + { + fprintf(stdout, "ScInterpreter::GetDBParams: query param created\n"); + // An allowed missing field parameter sets the result field + // to any of the query fields, just to be able to return + // some cell from the iterator. if ( rMissingField ) - ; // special case - else if ( bByVal ) - { - if ( nVal <= 0 || nVal > (nDBCol2 - nDBCol1 + 1) ) - bFound = FALSE; - else - nField = Min(nDBCol2, (SCCOL)(nDBCol1 + (SCCOL)nVal - 1)); - } - else + nField = static_cast<SCCOL>(rParam.GetEntry(0).nField); + + rParam.nCol1 = nField; + rParam.nCol2 = nField; + + SCSIZE nCount = rParam.GetEntryCount(); + for ( SCSIZE i=0; i < nCount; i++ ) { - bFound = FALSE; - String aCellStr; - ScAddress aLook( nDBCol1, nDBRow1, nDBTab1 ); - while (!bFound && (aLook.Col() <= nDBCol2)) - { - ScBaseCell* pCell = GetCell( aLook ); - GetCellString( aCellStr, pCell ); - bFound = ScGlobal::pTransliteration->isEqual( aCellStr, aStr ); - if (!bFound) - aLook.IncCol(); - } - nField = aLook.Col(); - } - if (bFound) - { - rParam.nCol1 = nDBCol1; - rParam.nRow1 = nDBRow1; - rParam.nCol2 = nDBCol2; - rParam.nRow2 = nDBRow2; - rParam.nTab = nDBTab1; - rParam.bHasHeader = TRUE; - rParam.bByRow = TRUE; - rParam.bInplace = TRUE; - rParam.bCaseSens = FALSE; - rParam.bRegExp = FALSE; - rParam.bDuplicate = TRUE; - if (pDok->CreateQueryParam(nQCol1, nQRow1, nQCol2, nQRow2, nQTab1, rParam)) - { - // An allowed missing field parameter sets the result field - // to any of the query fields, just to be able to return - // some cell from the iterator. - if ( rMissingField ) - nField = static_cast<SCCOL>(rParam.GetEntry(0).nField); - - rParam.nCol1 = nField; - rParam.nCol2 = nField; - rTab = nDBTab1; - bRet = TRUE; - SCSIZE nCount = rParam.GetEntryCount(); - for ( SCSIZE i=0; i < nCount; i++ ) - { - ScQueryEntry& rEntry = rParam.GetEntry(i); - if ( rEntry.bDoQuery ) - { - sal_uInt32 nIndex = 0; - rEntry.bQueryByString = !pFormatter->IsNumberFormat( - *rEntry.pStr, nIndex, rEntry.nVal ); - if ( rEntry.bQueryByString && !rParam.bRegExp ) - rParam.bRegExp = MayBeRegExp( *rEntry.pStr, pDok ); - } - else - break; // for - } + ScQueryEntry& rEntry = rParam.GetEntry(i); + if ( rEntry.bDoQuery ) + { + sal_uInt32 nIndex = 0; + rEntry.bQueryByString = !pFormatter->IsNumberFormat( + *rEntry.pStr, nIndex, rEntry.nVal ); + if ( rEntry.bQueryByString && !rParam.bRegExp ) + rParam.bRegExp = MayBeRegExp( *rEntry.pStr, pDok ); } + else + break; // for } + bRet = true; } } return bRet; @@ -5790,19 +5808,21 @@ BOOL ScInterpreter::GetDBParams(SCTAB& rTab, ScQueryParam& rParam, void ScInterpreter::DBIterator( ScIterFunc eFunc ) { + StackPrinter __stack_printer__("ScInterpreter::DBIterator"); + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::DBIterator" ); - SCTAB nTab1; double nErg = 0.0; double fMem = 0.0; BOOL bNull = TRUE; ULONG nCount = 0; - ScQueryParam aQueryParam; + ::std::auto_ptr<ScQueryParam> pQueryParam(new ScQueryParam); BOOL bMissingField = FALSE; - if ( GetDBParams( nTab1, aQueryParam, bMissingField) ) + if ( GetDBParams( *pQueryParam, bMissingField) ) { + fprintf(stdout, "ScInterpreter::DBIterator: dp param is good\n"); double nVal; USHORT nErr; - ScQueryValueIterator aValIter(pDok, nTab1, aQueryParam); + ScQueryValueIterator aValIter(pDok, pQueryParam.release()); if ( aValIter.GetFirst(nVal, nErr) && !nErr ) { switch( eFunc ) @@ -5836,10 +5856,14 @@ void ScInterpreter::DBIterator( ScIterFunc eFunc ) } while ( aValIter.GetNext(nVal, nErr) && !nErr ); } + fprintf(stdout, "ScInterpreter::DBIterator: error = %d\n", nErr); SetError(nErr); } else + { + fprintf(stdout, "ScInterpreter::DBIterator: dp params failed!\n"); SetError( errIllegalParameter); + } switch( eFunc ) { case ifCOUNT: nErg = nCount; break; @@ -5853,6 +5877,7 @@ void ScInterpreter::DBIterator( ScIterFunc eFunc ) void ScInterpreter::ScDBSum() { + StackPrinter __stack_printer__("ScInterpreter::ScDBSum"); RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScDBSum" ); DBIterator( ifSUM ); } @@ -5861,13 +5886,12 @@ void ScInterpreter::ScDBSum() void ScInterpreter::ScDBCount() { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScDBCount" ); - SCTAB nTab; - ScQueryParam aQueryParam; + ::std::auto_ptr<ScQueryParam> pQueryParam(new ScQueryParam); BOOL bMissingField = TRUE; - if ( GetDBParams( nTab, aQueryParam, bMissingField) ) + if ( GetDBParams(*pQueryParam, bMissingField) ) { ULONG nCount = 0; - if ( bMissingField ) + if ( bMissingField && pQueryParam->GetType() == ScQueryParamBase::INTERNAL ) { // count all matching records // TODO: currently the QueryIterators only return cell pointers of // existing cells, so if a query matches an empty cell there's @@ -5877,7 +5901,8 @@ void ScInterpreter::ScDBCount() // have to live with it until we reimplement the iterators to also // return empty cells, which would mean to adapt all callers of // iterators. - ScQueryCellIterator aCellIter( pDok, nTab, aQueryParam); + SCTAB nTab = pQueryParam->nTab; + ScQueryCellIterator aCellIter( pDok, nTab, *pQueryParam); if ( aCellIter.GetFirst() ) { do @@ -5890,7 +5915,7 @@ void ScInterpreter::ScDBCount() { // count only matching records with a value in the "result" field double nVal; USHORT nErr = 0; - ScQueryValueIterator aValIter( pDok, nTab, aQueryParam); + ScQueryValueIterator aValIter( pDok, pQueryParam.release()); if ( aValIter.GetFirst( nVal, nErr) && !nErr ) { do @@ -5910,11 +5935,11 @@ void ScInterpreter::ScDBCount() void ScInterpreter::ScDBCount2() { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScDBCount2" ); - SCTAB nTab; ScQueryParam aQueryParam; BOOL bMissingField = TRUE; - if (GetDBParams( nTab, aQueryParam, bMissingField)) + if (GetDBParams(aQueryParam, bMissingField)) { + SCTAB nTab = aQueryParam.nTab; ULONG nCount = 0; ScQueryCellIterator aCellIter(pDok, nTab, aQueryParam); if ( aCellIter.GetFirst() ) @@ -5968,14 +5993,13 @@ void ScInterpreter::GetDBStVarParams( double& rVal, double& rValCount ) rValCount = 0.0; double fSum = 0.0; - SCTAB nTab; - ScQueryParam aQueryParam; + ::std::auto_ptr<ScQueryParam> pQueryParam(new ScQueryParam); BOOL bMissingField = FALSE; - if (GetDBParams( nTab, aQueryParam, bMissingField)) + if (GetDBParams(*pQueryParam, bMissingField)) { double fVal; USHORT nErr; - ScQueryValueIterator aValIter(pDok, nTab, aQueryParam); + ScQueryValueIterator aValIter(pDok, pQueryParam.release()); if (aValIter.GetFirst(fVal, nErr) && !nErr) { do diff --git a/sc/source/core/tool/interpr4.cxx b/sc/source/core/tool/interpr4.cxx index a73fe62998a6..2d552b0e13a3 100644 --- a/sc/source/core/tool/interpr4.cxx +++ b/sc/source/core/tool/interpr4.cxx @@ -68,6 +68,7 @@ #include "jumpmatrix.hxx" #include "parclass.hxx" #include "externalrefmgr.hxx" +#include "doubleref.hxx" #include <math.h> #include <float.h> @@ -80,6 +81,42 @@ using namespace formula; #define ADDIN_MAXSTRLEN 256 +#include <stdio.h> +#include <string> +#include <sys/time.h> + +namespace { + +class StackPrinter +{ +public: + explicit StackPrinter(const char* msg) : + msMsg(msg) + { + fprintf(stdout, "%s: --begin\n", msMsg.c_str()); + mfStartTime = getTime(); + } + + ~StackPrinter() + { + double fEndTime = getTime(); + fprintf(stdout, "%s: --end (duration: %g sec)\n", msMsg.c_str(), (fEndTime-mfStartTime)); + } + +private: + double getTime() const + { + timeval tv; + gettimeofday(&tv, NULL); + return tv.tv_sec + tv.tv_usec / 1000000.0; + } + + ::std::string msMsg; + double mfStartTime; +}; + +} + // Implementiert in ui\miscdlgs\teamdlg.cxx extern void ShowTheTeam(); @@ -1021,6 +1058,46 @@ void ScInterpreter::DoubleRefToVars( const ScToken* p, } } +ScDoubleRefBase* ScInterpreter::PopDoubleRef() +{ + if (!sp) + { + SetError(errUnknownStackVariable); + return NULL; + } + + --sp; + FormulaToken* p = pStack[sp]; + switch (p->GetType()) + { + case svError: + fprintf(stdout, "ScInterpreter::PopDoubleRef: error\n"); + nGlobalError = p->GetError(); + break; + case svDoubleRef: + { + fprintf(stdout, "ScInterpreter::PopDoubleRef: double ref\n"); + SCCOL nCol1, nCol2; + SCROW nRow1, nRow2; + SCTAB nTab1, nTab2; + DoubleRefToVars(static_cast<ScToken*>(p), + nCol1, nRow1, nTab1, nCol2, nRow2, nTab2, false); + + return new ScInternalDoubleRef(pDok, + ScRange(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2)); + } + break; + case svMatrix: + { + fprintf(stdout, "ScInterpreter::PopDoubleRef: matrix\n"); + } + break; + default: + fprintf(stdout, "ScInterpreter::PopDoubleRef: other\n"); + SetError( errIllegalParameter); + } + return NULL; +} void ScInterpreter::PopDoubleRef(SCCOL& rCol1, SCROW &rRow1, SCTAB& rTab1, SCCOL& rCol2, SCROW &rRow2, SCTAB& rTab2, @@ -1034,13 +1111,16 @@ void ScInterpreter::PopDoubleRef(SCCOL& rCol1, SCROW &rRow1, SCTAB& rTab1, switch (p->GetType()) { case svError: + fprintf(stdout, "ScInterpreter::PopDoubleRef: error\n"); nGlobalError = p->GetError(); break; case svDoubleRef: + fprintf(stdout, "ScInterpreter::PopDoubleRef: double ref\n"); DoubleRefToVars( static_cast<ScToken*>(p), rCol1, rRow1, rTab1, rCol2, rRow2, rTab2, bDontCheckForTableOp); break; default: + fprintf(stdout, "ScInterpreter::PopDoubleRef: other\n"); SetError( errIllegalParameter); } } @@ -1860,11 +1940,11 @@ ScMatValType ScInterpreter::GetDoubleOrStringFromMatrix( double& rDouble, void ScInterpreter::ScDBGet() { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScDBGet" ); - SCTAB nTab; ScQueryParam aQueryParam; BOOL bMissingField = FALSE; - if (GetDBParams( nTab, aQueryParam, bMissingField)) + if (GetDBParams(aQueryParam, bMissingField)) { + SCTAB nTab = aQueryParam.nTab; ScBaseCell* pCell; ScQueryCellIterator aCellIter(pDok, nTab, aQueryParam); if ( (pCell = aCellIter.GetFirst()) != NULL ) @@ -2986,6 +3066,7 @@ void ScInterpreter::ScColRowNameAuto() void ScInterpreter::ScExternalRef() { + StackPrinter __stack_printer__("ScInterpreter::ScExternalRef"); ScExternalRefManager* pRefMgr = pDok->GetExternalRefManager(); const String* pFile = pRefMgr->getExternalFileName(pCur->GetIndex()); if (!pFile) @@ -2995,6 +3076,7 @@ void ScInterpreter::ScExternalRef() { case svExternalSingleRef: { + fprintf(stdout, "ScInterpreter::ScExternalRef: single ref\n"); ScSingleRefData aData(static_cast<const ScToken*>(pCur)->GetSingleRef()); if (aData.IsTabRel()) { @@ -3012,6 +3094,7 @@ void ScInterpreter::ScExternalRef() break; PushTempToken( *xNew); // push a clone + fprintf(stdout, "ScInterpreter::ScExternalRef: token pushed\n"); if (aFmt.mbIsSet) { @@ -3023,6 +3106,7 @@ void ScInterpreter::ScExternalRef() //break; // unreachable, prevent compiler warning case svExternalDoubleRef: { + fprintf(stdout, "ScInterpreter::ScExternalRef: double ref\n"); ScComplexRefData aData(static_cast<const ScToken*>(pCur)->GetDoubleRef()); if (aData.Ref1.IsTabRel() || aData.Ref2.IsTabRel()) { @@ -3051,6 +3135,7 @@ void ScInterpreter::ScExternalRef() } PushMatrix(p->GetMatrix()); + fprintf(stdout, "ScInterpreter::ScExternalRef: matrix pushed\n"); return; } //break; // unreachable, prevent compiler warning diff --git a/sc/source/core/tool/makefile.mk b/sc/source/core/tool/makefile.mk index ac0aa23fc044..e8a2e0fb70bf 100644 --- a/sc/source/core/tool/makefile.mk +++ b/sc/source/core/tool/makefile.mk @@ -76,6 +76,7 @@ SLOFILES = \ $(SLO)$/detdata.obj \ $(SLO)$/detfunc.obj \ $(SLO)$/docoptio.obj \ + $(SLO)$/doubleref.obj \ $(SLO)$/editutil.obj \ $(SLO)$/filtopt.obj \ $(SLO)$/formulaparserpool.obj \ @@ -96,6 +97,7 @@ SLOFILES = \ $(SLO)$/printopt.obj \ $(SLO)$/prnsave.obj \ $(SLO)$/progress.obj \ + $(SLO)$/queryparam.obj \ $(SLO)$/rangelst.obj \ $(SLO)$/rangenam.obj \ $(SLO)$/rangeseq.obj \ @@ -123,6 +125,7 @@ EXCEPTIONSFILES= \ $(SLO)$/chartlock.obj \ $(SLO)$/chgtrack.obj \ $(SLO)$/compiler.obj \ + $(SLO)$/doubleref.obj \ $(SLO)$/formulaparserpool.obj \ $(SLO)$/interpr1.obj \ $(SLO)$/interpr2.obj \ @@ -131,6 +134,7 @@ EXCEPTIONSFILES= \ $(SLO)$/interpr5.obj \ $(SLO)$/lookupcache.obj \ $(SLO)$/prnsave.obj \ + $(SLO)$/queryparam.obj \ $(SLO)$/reftokenhelper.obj \ $(SLO)$/token.obj diff --git a/sc/source/core/tool/queryparam.cxx b/sc/source/core/tool/queryparam.cxx new file mode 100644 index 000000000000..3433d2724c19 --- /dev/null +++ b/sc/source/core/tool/queryparam.cxx @@ -0,0 +1,296 @@ +/************************************************************************* + * + * 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: interpr4.cxx,v $ + * $Revision: 1.57.92.5 $ + * + * 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 "queryparam.hxx" + +// ============================================================================ + +ScQueryParamBase::ScQueryParamBase(DataType eType) : + nEntryCount(0), meType(eType) +{ +} + +ScQueryParamBase::ScQueryParamBase(const ScQueryParamBase& r) : + bHasHeader(r.bHasHeader), bByRow(r.bByRow), bInplace(r.bInplace), bCaseSens(r.bCaseSens), + bRegExp(r.bRegExp), bDuplicate(r.bDuplicate), + meType(r.meType) +{ +} + +ScQueryParamBase::~ScQueryParamBase() +{ + delete[] pEntries; +} + +void ScQueryParamBase::Resize(SCSIZE nNew) +{ + if ( nNew < MAXQUERY ) + nNew = MAXQUERY; // nie weniger als MAXQUERY + + ScQueryEntry* pNewEntries = NULL; + if ( nNew ) + pNewEntries = new ScQueryEntry[nNew]; + + SCSIZE nCopy = Min( nEntryCount, nNew ); + for (SCSIZE i=0; i<nCopy; i++) + pNewEntries[i] = pEntries[i]; + + if ( nEntryCount ) + delete[] pEntries; + nEntryCount = nNew; + pEntries = pNewEntries; +} + +void ScQueryParamBase::DeleteQuery( SCSIZE nPos ) +{ + if (nPos<nEntryCount) + { + for (SCSIZE i=nPos; i+1<nEntryCount; i++) + pEntries[i] = pEntries[i+1]; + + pEntries[nEntryCount-1].Clear(); + } + else + { + DBG_ERROR("Falscher Parameter bei ScQueryParam2::DeleteQuery"); + } +} + +void ScQueryParamBase::FillInExcelSyntax(String& aCellStr, SCSIZE nIndex) +{ + if (aCellStr.Len() > 0) + { + if ( nIndex >= nEntryCount ) + Resize( nIndex+1 ); + + ScQueryEntry& rEntry = pEntries[nIndex]; + + rEntry.bDoQuery = TRUE; + // Operatoren herausfiltern + if (aCellStr.GetChar(0) == '<') + { + if (aCellStr.GetChar(1) == '>') + { + *rEntry.pStr = aCellStr.Copy(2); + rEntry.eOp = SC_NOT_EQUAL; + } + else if (aCellStr.GetChar(1) == '=') + { + *rEntry.pStr = aCellStr.Copy(2); + rEntry.eOp = SC_LESS_EQUAL; + } + else + { + *rEntry.pStr = aCellStr.Copy(1); + rEntry.eOp = SC_LESS; + } + } + else if (aCellStr.GetChar(0) == '>') + { + if (aCellStr.GetChar(1) == '=') + { + *rEntry.pStr = aCellStr.Copy(2); + rEntry.eOp = SC_GREATER_EQUAL; + } + else + { + *rEntry.pStr = aCellStr.Copy(1); + rEntry.eOp = SC_GREATER; + } + } + else + { + if (aCellStr.GetChar(0) == '=') + *rEntry.pStr = aCellStr.Copy(1); + else + *rEntry.pStr = aCellStr; + rEntry.eOp = SC_EQUAL; + } + } +} + +ScQueryParamBase::DataType ScQueryParamBase::GetType() const +{ + return meType; +} + +// ============================================================================ + +ScQueryParam::ScQueryParam() : + ScQueryParamBase(ScQueryParamBase::INTERNAL) +{ + Clear(); +} + +//------------------------------------------------------------------------ + +ScQueryParam::ScQueryParam( const ScQueryParam& r ) : + ScQueryParamBase(r), + nCol1(r.nCol1),nRow1(r.nRow1),nCol2(r.nCol2),nRow2(r.nRow2),nTab(r.nTab), + bMixedComparison(r.bMixedComparison), bDestPers(r.bDestPers), + nDestTab(r.nDestTab), nDestCol(r.nDestCol), nDestRow(r.nDestRow) +{ + nEntryCount = 0; + + Resize( r.nEntryCount ); + for (USHORT i=0; i<nEntryCount; i++) + pEntries[i] = r.pEntries[i]; +} + +//------------------------------------------------------------------------ + +ScQueryParam::~ScQueryParam() +{ +} + +//------------------------------------------------------------------------ + +void ScQueryParam::Clear() +{ + nCol1=nCol2=nDestCol = 0; + nRow1=nRow2=nDestRow = 0; + nDestTab = 0; + nTab = SCTAB_MAX; + bHasHeader = bCaseSens = bRegExp = bMixedComparison = FALSE; + bInplace = bByRow = bDuplicate = bDestPers = TRUE; + + Resize( MAXQUERY ); + for (USHORT i=0; i<MAXQUERY; i++) + pEntries[i].Clear(); +} + +//------------------------------------------------------------------------ + +ScQueryParam& ScQueryParam::operator=( const ScQueryParam& r ) +{ + nCol1 = r.nCol1; + nRow1 = r.nRow1; + nCol2 = r.nCol2; + nRow2 = r.nRow2; + nTab = r.nTab; + nDestTab = r.nDestTab; + nDestCol = r.nDestCol; + nDestRow = r.nDestRow; + bHasHeader = r.bHasHeader; + bInplace = r.bInplace; + bCaseSens = r.bCaseSens; + bRegExp = r.bRegExp; + bMixedComparison = r.bMixedComparison; + bDuplicate = r.bDuplicate; + bByRow = r.bByRow; + bDestPers = r.bDestPers; + + Resize( r.nEntryCount ); + for (USHORT i=0; i<nEntryCount; i++) + pEntries[i] = r.pEntries[i]; + + return *this; +} + +//------------------------------------------------------------------------ + +BOOL ScQueryParam::operator==( const ScQueryParam& rOther ) const +{ + BOOL bEqual = FALSE; + + // Anzahl der Queries gleich? + USHORT nUsed = 0; + USHORT nOtherUsed = 0; + while ( nUsed<nEntryCount && pEntries[nUsed].bDoQuery ) ++nUsed; + while ( nOtherUsed<rOther.nEntryCount && rOther.pEntries[nOtherUsed].bDoQuery ) + ++nOtherUsed; + + if ( (nUsed == nOtherUsed) + && (nCol1 == rOther.nCol1) + && (nRow1 == rOther.nRow1) + && (nCol2 == rOther.nCol2) + && (nRow2 == rOther.nRow2) + && (nTab == rOther.nTab) + && (bHasHeader == rOther.bHasHeader) + && (bByRow == rOther.bByRow) + && (bInplace == rOther.bInplace) + && (bCaseSens == rOther.bCaseSens) + && (bRegExp == rOther.bRegExp) + && (bMixedComparison == rOther.bMixedComparison) + && (bDuplicate == rOther.bDuplicate) + && (bDestPers == rOther.bDestPers) + && (nDestTab == rOther.nDestTab) + && (nDestCol == rOther.nDestCol) + && (nDestRow == rOther.nDestRow) ) + { + bEqual = TRUE; + for ( USHORT i=0; i<nUsed && bEqual; i++ ) + bEqual = pEntries[i] == rOther.pEntries[i]; + } + return bEqual; +} + +//------------------------------------------------------------------------ + +void ScQueryParam::MoveToDest() +{ + if (!bInplace) + { + SCsCOL nDifX = ((SCsCOL) nDestCol) - ((SCsCOL) nCol1); + SCsROW nDifY = ((SCsROW) nDestRow) - ((SCsROW) nRow1); + SCsTAB nDifZ = ((SCsTAB) nDestTab) - ((SCsTAB) nTab); + + nCol1 = sal::static_int_cast<SCCOL>( nCol1 + nDifX ); + nRow1 = sal::static_int_cast<SCROW>( nRow1 + nDifY ); + nCol2 = sal::static_int_cast<SCCOL>( nCol2 + nDifX ); + nRow2 = sal::static_int_cast<SCROW>( nRow2 + nDifY ); + nTab = sal::static_int_cast<SCTAB>( nTab + nDifZ ); + for (USHORT i=0; i<nEntryCount; i++) + pEntries[i].nField += nDifX; + + bInplace = TRUE; + } + else + { + DBG_ERROR("MoveToDest, bInplace == TRUE"); + } +} + +// ============================================================================ + +ScQueryParamMatrix::ScQueryParamMatrix() : + ScQueryParamBase(ScQueryParamBase::MATRIX) +{ +} + +ScQueryParamMatrix::~ScQueryParamMatrix() +{ +} + diff --git a/sc/source/filter/excel/colrowst.cxx b/sc/source/filter/excel/colrowst.cxx index b1ec8752de7b..617adc891962 100644 --- a/sc/source/filter/excel/colrowst.cxx +++ b/sc/source/filter/excel/colrowst.cxx @@ -43,6 +43,7 @@ #include "xltable.hxx" #include "xistream.hxx" #include "xistyle.hxx" +#include "queryparam.hxx" // for filter manager #include "excimp8.hxx" diff --git a/sc/source/filter/inc/excimp8.hxx b/sc/source/filter/inc/excimp8.hxx index 9bd633eae879..f715c96a7bfc 100644 --- a/sc/source/filter/inc/excimp8.hxx +++ b/sc/source/filter/inc/excimp8.hxx @@ -37,6 +37,7 @@ #include "excscen.hxx" #include "excdefs.hxx" #include "ftools.hxx" +#include "queryparam.hxx" class SotStorage; diff --git a/sc/source/filter/xml/XMLExportDataPilot.hxx b/sc/source/filter/xml/XMLExportDataPilot.hxx index fb78a59d616b..0c7fb57d3926 100644 --- a/sc/source/filter/xml/XMLExportDataPilot.hxx +++ b/sc/source/filter/xml/XMLExportDataPilot.hxx @@ -43,6 +43,7 @@ class ScDPDimensionSaveData; class ScDPSaveGroupDimension; class ScDPSaveNumGroupDimension; struct ScDPNumGroupInfo; +struct ScQueryParam; class ScXMLExportDataPilot { diff --git a/sc/source/filter/xml/xmldpimp.hxx b/sc/source/filter/xml/xmldpimp.hxx index 874fe27654ba..10c1599e7b8a 100644 --- a/sc/source/filter/xml/xmldpimp.hxx +++ b/sc/source/filter/xml/xmldpimp.hxx @@ -40,6 +40,7 @@ #include "global.hxx" #include "dpobject.hxx" #include "dpsave.hxx" +#include "queryparam.hxx" class ScXMLImport; class ScDPSaveNumGroupDimension; diff --git a/sc/source/ui/dbgui/foptmgr.cxx b/sc/source/ui/dbgui/foptmgr.cxx index 603a9a3a5eea..007c24de3764 100644 --- a/sc/source/ui/dbgui/foptmgr.cxx +++ b/sc/source/ui/dbgui/foptmgr.cxx @@ -45,6 +45,7 @@ #include "dbcolect.hxx" #include "viewdata.hxx" #include "document.hxx" +#include "queryparam.hxx" #define _FOPTMGR_CXX #include "foptmgr.hxx" diff --git a/sc/source/ui/inc/pfiltdlg.hxx b/sc/source/ui/inc/pfiltdlg.hxx index 4009f06417dc..2896df74d818 100644 --- a/sc/source/ui/inc/pfiltdlg.hxx +++ b/sc/source/ui/inc/pfiltdlg.hxx @@ -53,8 +53,8 @@ #ifndef _COMBOBOX_HXX //autogen #include <vcl/combobox.hxx> #endif -#include "global.hxx" // -> ScQueryParam #include "address.hxx" +#include "queryparam.hxx" //------------------------------------------------------------------ diff --git a/sc/source/ui/inc/uiitems.hxx b/sc/source/ui/inc/uiitems.hxx index 868e772a2e68..2e56c5683c72 100644 --- a/sc/source/ui/inc/uiitems.hxx +++ b/sc/source/ui/inc/uiitems.hxx @@ -34,6 +34,7 @@ #include "scdllapi.h" #include "conditio.hxx" #include "sortparam.hxx" +#include "queryparam.hxx" #include "paramisc.hxx" #include <svtools/poolitem.hxx> diff --git a/sc/source/ui/inc/undodat.hxx b/sc/source/ui/inc/undodat.hxx index 3e92fc5fd5fa..40d9073e2e0a 100644 --- a/sc/source/ui/inc/undodat.hxx +++ b/sc/source/ui/inc/undodat.hxx @@ -36,6 +36,7 @@ #include "rangelst.hxx" // ScRangeListRef #include "markdata.hxx" #include "sortparam.hxx" +#include "queryparam.hxx" #include "pivot.hxx" class ScDocShell; diff --git a/sc/source/ui/undo/undobase.cxx b/sc/source/ui/undo/undobase.cxx index 200db8673cd2..09e8f452c1c6 100644 --- a/sc/source/ui/undo/undobase.cxx +++ b/sc/source/ui/undo/undobase.cxx @@ -45,6 +45,7 @@ #include "undodraw.hxx" #include "dbcolect.hxx" #include "attrib.hxx" +#include "queryparam.hxx" #include "globstr.hrc" // STATIC DATA ----------------------------------------------------------- diff --git a/sc/source/ui/view/gridwin4.cxx b/sc/source/ui/view/gridwin4.cxx index b90e5d3e802e..753c95973281 100644 --- a/sc/source/ui/view/gridwin4.cxx +++ b/sc/source/ui/view/gridwin4.cxx @@ -73,6 +73,7 @@ #include "editutil.hxx" #include "inputopt.hxx" #include "fillinfo.hxx" +#include "queryparam.hxx" #include "sc.hrc" #include <vcl/virdev.hxx> |