diff options
author | Vladimir Glazunov <vg@openoffice.org> | 2010-02-12 17:46:41 +0100 |
---|---|---|
committer | Vladimir Glazunov <vg@openoffice.org> | 2010-02-12 17:46:41 +0100 |
commit | 68bb4c0307a4297e5a7d935459eb2b8f4868cc3c (patch) | |
tree | f7f457717df963a13d58160cf91f3208a316bec2 /sc/source/core/data | |
parent | ad29ee75ae721392632cfd24c232e3e9ec80c4c8 (diff) | |
parent | bf7748b5b236cba3d47790224bd7db31d73f5665 (diff) |
CWS-TOOLING: integrate CWS kohei03
Diffstat (limited to 'sc/source/core/data')
-rw-r--r-- | sc/source/core/data/autonamecache.cxx | 1 | ||||
-rwxr-xr-x[-rw-r--r--] | sc/source/core/data/dociter.cxx | 467 | ||||
-rw-r--r-- | sc/source/core/data/document.cxx | 7 | ||||
-rw-r--r-- | sc/source/core/data/dpcachetable.cxx | 31 | ||||
-rw-r--r-- | sc/source/core/data/global2.cxx | 232 | ||||
-rw-r--r-- | sc/source/core/data/sortparam.cxx | 1 | ||||
-rw-r--r-- | sc/source/core/data/table3.cxx | 6 |
7 files changed, 452 insertions, 293 deletions
diff --git a/sc/source/core/data/autonamecache.cxx b/sc/source/core/data/autonamecache.cxx index ea41e3e4f..329e7f469 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 6f79316e0..fab5ad92d 100644..100755 --- a/sc/source/core/data/dociter.cxx +++ b/sc/source/core/data/dociter.cxx @@ -47,9 +47,23 @@ #include "docoptio.hxx" #include "cellform.hxx" +#include <vector> + +using ::rtl::math::approxEqual; +using ::std::vector; +using ::rtl::OUString; // STATIC DATA ----------------------------------------------------------- +namespace { + +void lcl_toUpper(OUString& rStr) +{ + rStr = ScGlobal::pCharClass->toUpper(rStr.trim(), 0, static_cast<USHORT>(rStr.getLength())); +} + +} + ScDocumentIterator::ScDocumentIterator( ScDocument* pDocument, SCTAB nStartTable, SCTAB nEndTable ) : pDoc( pDocument ), @@ -482,83 +496,121 @@ 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() ) +ScDBQueryDataIterator::DataAccess::DataAccess(const ScDBQueryDataIterator* pParent) : + mpParent(pParent) { - nCol = aParam.nCol1; - nRow = aParam.nRow1; +} + +ScDBQueryDataIterator::DataAccess::~DataAccess() +{ +} + +SCROW ScDBQueryDataIterator::GetRowByColEntryIndex(ScDocument& rDoc, SCTAB nTab, SCCOL nCol, SCSIZE nColRow) +{ + ScColumn* pCol = &rDoc.pTab[nTab]->aCol[nCol]; + return pCol->pItems[nColRow].nRow; +} + +ScBaseCell* ScDBQueryDataIterator::GetCellByColEntryIndex(ScDocument& rDoc, SCTAB nTab, SCCOL nCol, SCSIZE nColRow) +{ + ScColumn* pCol = &rDoc.pTab[nTab]->aCol[nCol]; + return pCol->pItems[nColRow].pCell; +} + +ScAttrArray* ScDBQueryDataIterator::GetAttrArrayByCol(ScDocument& rDoc, SCTAB nTab, SCCOL nCol) +{ + ScColumn* pCol = &rDoc.pTab[nTab]->aCol[nCol]; + return pCol->pAttrArray; +} + +bool ScDBQueryDataIterator::IsQueryValid(ScDocument& rDoc, const ScQueryParam& rParam, SCTAB nTab, SCROW nRow, ScBaseCell* pCell) +{ + return rDoc.pTab[nTab]->ValidQuery(nRow, rParam, NULL, pCell); +} + +SCSIZE ScDBQueryDataIterator::SearchColEntryIndex(ScDocument& rDoc, SCTAB nTab, SCROW nRow, SCCOL nCol) +{ + ScColumn* pCol = &rDoc.pTab[nTab]->aCol[nCol]; + SCSIZE nColRow; + pCol->Search(nRow, nColRow); + return nColRow; +} + +// ---------------------------------------------------------------------------- + +ScDBQueryDataIterator::DataAccessInternal::DataAccessInternal(const ScDBQueryDataIterator* pParent, ScDBQueryParamInternal* pParam, ScDocument* pDoc) : + DataAccess(pParent), + mpParam(pParam), + mpDoc(pDoc) +{ + nCol = mpParam->mnField; + 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) +ScDBQueryDataIterator::DataAccessInternal::~DataAccessInternal() { - ScColumn* pCol = &(pDoc->pTab[nTab])->aCol[nCol]; - SCCOLROW nFirstQueryField = aParam.GetEntry(0).nField; +} + +bool ScDBQueryDataIterator::DataAccessInternal::getCurrent(Value& rValue) +{ + SCCOLROW nFirstQueryField = mpParam->GetEntry(0).nField; for ( ;; ) { - if ( nRow > aParam.nRow2 ) + if (nRow > mpParam->nRow2) { - nRow = aParam.nRow1; - if (aParam.bHasHeader) - nRow++; - do - { - nCol++; - if ( nCol > aParam.nCol2 ) - { - // rValue = 0.0; // do not change caller's value! - rErr = 0; - return FALSE; // Ende und Aus - } - pCol = &(pDoc->pTab[nTab])->aCol[nCol]; - } while ( pCol->nCount == 0 ); - pCol->Search( nRow, nColRow ); + // Bottom of the range reached. Bail out. + rValue.mnError = 0; + return false; } - while ( (nColRow < pCol->nCount) && (pCol->pItems[nColRow].nRow < nRow) ) - nColRow++; + SCSIZE nCellCount = mpDoc->GetCellCount(nTab, nCol); + SCROW nThisRow = ScDBQueryDataIterator::GetRowByColEntryIndex(*mpDoc, nTab, nCol, nColRow); + while ( (nColRow < nCellCount) && (nThisRow < nRow) ) + nThisRow = ScDBQueryDataIterator::GetRowByColEntryIndex(*mpDoc, nTab, nCol, ++nColRow); - if ( nColRow < pCol->nCount && pCol->pItems[nColRow].nRow <= aParam.nRow2 ) + if ( nColRow < nCellCount && nThisRow <= mpParam->nRow2 ) { - nRow = pCol->pItems[nColRow].nRow; - ScBaseCell* pCell = pCol->pItems[nColRow].pCell; - if ( (pDoc->pTab[nTab])->ValidQuery( nRow, aParam, NULL, - (nCol == static_cast<SCCOL>(nFirstQueryField) ? pCell : NULL) ) ) + nRow = nThisRow; + ScBaseCell* pCell = NULL; + if (nCol == static_cast<SCCOL>(nFirstQueryField)) + pCell = ScDBQueryDataIterator::GetCellByColEntryIndex(*mpDoc, nTab, nCol, nColRow); + + if (ScDBQueryDataIterator::IsQueryValid(*mpDoc, *mpParam, nTab, nRow, pCell)) { switch (pCell->GetCellType()) { case CELLTYPE_VALUE: { - rValue = ((ScValueCell*)pCell)->GetValue(); + rValue.mfValue = ((ScValueCell*)pCell)->GetValue(); + rValue.mbIsNumber = true; if ( bCalcAsShown ) { + const ScAttrArray* pNewAttrArray = + ScDBQueryDataIterator::GetAttrArrayByCol(*mpDoc, nTab, nCol); lcl_IterGetNumberFormat( nNumFormat, pAttrArray, - nAttrEndRow, pCol->pAttrArray, nRow, pDoc ); - rValue = pDoc->RoundValueAsShown( rValue, nNumFormat ); + nAttrEndRow, pNewAttrArray, nRow, mpDoc ); + rValue.mfValue = mpDoc->RoundValueAsShown( rValue.mfValue, nNumFormat ); } nNumFmtType = NUMBERFORMAT_NUMBER; nNumFmtIndex = 0; - rErr = 0; + rValue.mnError = 0; return TRUE; // gefunden } // break; @@ -566,17 +618,31 @@ BOOL ScQueryValueIterator::GetThis(double& rValue, USHORT& rErr) { if (((ScFormulaCell*)pCell)->IsValue()) { - rValue = ((ScFormulaCell*)pCell)->GetValue(); - pDoc->GetNumberFormatInfo( nNumFmtType, + rValue.mfValue = ((ScFormulaCell*)pCell)->GetValue(); + rValue.mbIsNumber = true; + mpDoc->GetNumberFormatInfo( nNumFmtType, nNumFmtIndex, ScAddress( nCol, nRow, nTab ), pCell ); - rErr = ((ScFormulaCell*)pCell)->GetErrCode(); + rValue.mnError = ((ScFormulaCell*)pCell)->GetErrCode(); return TRUE; // gefunden } else nRow++; } break; + case CELLTYPE_STRING: + case CELLTYPE_EDIT: + if (mpParam->mbSkipString) + ++nRow; + else + { + rValue.maString = pCell->GetStringData(); + rValue.mfValue = 0.0; + rValue.mnError = 0; + rValue.mbIsNumber = false; + return true; + } + break; default: nRow++; break; @@ -586,30 +652,309 @@ BOOL ScQueryValueIterator::GetThis(double& rValue, USHORT& rErr) nRow++; } else - nRow = aParam.nRow2 + 1; // Naechste Spalte + nRow = mpParam->nRow2 + 1; // Naechste Spalte } -// return FALSE; +// statement unreachable +// return false; } -BOOL ScQueryValueIterator::GetFirst(double& rValue, USHORT& rErr) +bool ScDBQueryDataIterator::DataAccessInternal::getFirst(Value& rValue) { - nCol = aParam.nCol1; - nRow = aParam.nRow1; - if (aParam.bHasHeader) + if (mpParam->bHasHeader) nRow++; -// nColRow = 0; - ScColumn* pCol = &(pDoc->pTab[nTab])->aCol[nCol]; - pCol->Search( nRow, nColRow ); - return GetThis(rValue, rErr); + + nColRow = ScDBQueryDataIterator::SearchColEntryIndex(*mpDoc, nTab, nRow, nCol); + return getCurrent(rValue); } -BOOL ScQueryValueIterator::GetNext(double& rValue, USHORT& rErr) +bool ScDBQueryDataIterator::DataAccessInternal::getNext(Value& rValue) { ++nRow; - return GetThis(rValue, rErr); + return getCurrent(rValue); } -//------------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- + +ScDBQueryDataIterator::DataAccessMatrix::DataAccessMatrix(const ScDBQueryDataIterator* pParent, ScDBQueryParamMatrix* pParam) : + DataAccess(pParent), + mpParam(pParam) +{ + SCSIZE nC, nR; + mpParam->mpMatrix->GetDimensions(nC, nR); + mnRows = static_cast<SCROW>(nR); + mnCols = static_cast<SCCOL>(nC); +} + +ScDBQueryDataIterator::DataAccessMatrix::~DataAccessMatrix() +{ +} + +bool ScDBQueryDataIterator::DataAccessMatrix::getCurrent(Value& rValue) +{ + // Starting from row == mnCurRow, get the first row that satisfies all the + // query parameters. + for ( ;mnCurRow < mnRows; ++mnCurRow) + { + const ScMatrix& rMat = *mpParam->mpMatrix; + if (rMat.IsEmpty(mpParam->mnField, mnCurRow)) + // Don't take empty values into account. + continue; + + bool bIsStrVal = rMat.IsString(mpParam->mnField, mnCurRow); + if (bIsStrVal && mpParam->mbSkipString) + continue; + + if (isValidQuery(mnCurRow, rMat)) + { + rValue.maString = rMat.GetString(mpParam->mnField, mnCurRow); + rValue.mfValue = rMat.GetDouble(mpParam->mnField, mnCurRow); + rValue.mbIsNumber = !bIsStrVal; + rValue.mnError = 0; + return true; + } + } + return false; +} + +bool ScDBQueryDataIterator::DataAccessMatrix::getFirst(Value& rValue) +{ + mnCurRow = mpParam->bHasHeader ? 1 : 0; + return getCurrent(rValue); +} + +bool ScDBQueryDataIterator::DataAccessMatrix::getNext(Value& rValue) +{ + ++mnCurRow; + return getCurrent(rValue); +} + +namespace { + +bool lcl_isQueryByValue(const ScQueryEntry& rEntry, const ScMatrix& rMat, SCSIZE nCol, SCSIZE nRow) +{ + if (rEntry.bQueryByString) + return false; + + if (!rMat.IsValueOrEmpty(nCol, nRow)) + return false; + + return true; +} + +bool lcl_isQueryByString(const ScQueryEntry& rEntry, const ScMatrix& rMat, SCSIZE nCol, SCSIZE nRow) +{ + switch (rEntry.eOp) + { + case SC_EQUAL: + case SC_NOT_EQUAL: + case SC_CONTAINS: + case SC_DOES_NOT_CONTAIN: + case SC_BEGINS_WITH: + case SC_ENDS_WITH: + case SC_DOES_NOT_BEGIN_WITH: + case SC_DOES_NOT_END_WITH: + return true; + default: + ; + } + + if (rEntry.bQueryByString && rMat.IsString(nCol, nRow)) + return true; + + return false; +} + +} + +bool ScDBQueryDataIterator::DataAccessMatrix::isValidQuery(SCROW nRow, const ScMatrix& rMat) const +{ + SCSIZE nEntryCount = mpParam->GetEntryCount(); + vector<bool> aResults; + aResults.reserve(nEntryCount); + + const CollatorWrapper& rCollator = + mpParam->bCaseSens ? *ScGlobal::GetCaseCollator() : *ScGlobal::GetCollator(); + + for (SCSIZE i = 0; i < nEntryCount; ++i) + { + const ScQueryEntry& rEntry = mpParam->GetEntry(i); + if (!rEntry.bDoQuery) + continue; + + switch (rEntry.eOp) + { + case SC_EQUAL: + case SC_LESS: + case SC_GREATER: + case SC_LESS_EQUAL: + case SC_GREATER_EQUAL: + case SC_NOT_EQUAL: + break; + default: + // Only the above operators are supported. + continue; + } + + bool bValid = false; + + SCSIZE nField = static_cast<SCSIZE>(rEntry.nField); + if (lcl_isQueryByValue(rEntry, rMat, nField, nRow)) + { + // By value + double fMatVal = rMat.GetDouble(nField, nRow); + bool bEqual = approxEqual(fMatVal, rEntry.nVal); + switch (rEntry.eOp) + { + case SC_EQUAL: + bValid = bEqual; + break; + case SC_LESS: + bValid = (fMatVal < rEntry.nVal) && !bEqual; + break; + case SC_GREATER: + bValid = (fMatVal > rEntry.nVal) && !bEqual; + break; + case SC_LESS_EQUAL: + bValid = (fMatVal < rEntry.nVal) || bEqual; + break; + case SC_GREATER_EQUAL: + bValid = (fMatVal > rEntry.nVal) || bEqual; + break; + case SC_NOT_EQUAL: + bValid = !bEqual; + break; + default: + ; + } + } + else if (lcl_isQueryByString(rEntry, rMat, nField, nRow)) + { + // By string + do + { + if (!rEntry.pStr) + break; + + // Equality check first. + + OUString aMatStr = rMat.GetString(nField, nRow); + lcl_toUpper(aMatStr); + OUString aQueryStr = *rEntry.pStr; + lcl_toUpper(aQueryStr); + bool bDone = false; + switch (rEntry.eOp) + { + case SC_EQUAL: + bValid = aMatStr.equals(aQueryStr); + bDone = true; + break; + case SC_NOT_EQUAL: + bValid = !aMatStr.equals(aQueryStr); + bDone = true; + break; + default: + ; + } + + if (bDone) + break; + + // Unequality check using collator. + + sal_Int32 nCompare = rCollator.compareString(aMatStr, aQueryStr); + switch (rEntry.eOp) + { + case SC_LESS : + bValid = (nCompare < 0); + break; + case SC_GREATER : + bValid = (nCompare > 0); + break; + case SC_LESS_EQUAL : + bValid = (nCompare <= 0); + break; + case SC_GREATER_EQUAL : + bValid = (nCompare >= 0); + break; + default: + ; + } + } + while (false); + } + else if (mpParam->bMixedComparison) + { + // Not used at the moment. + } + + if (aResults.empty()) + // First query entry. + aResults.push_back(bValid); + else if (rEntry.eConnect == SC_AND) + { + // For AND op, tuck the result into the last result value. + size_t n = aResults.size(); + aResults[n-1] = aResults[n-1] && bValid; + } + else + // For OR op, store its own result. + aResults.push_back(bValid); + } + + // Row is valid as long as there is at least one result being true. + vector<bool>::const_iterator itr = aResults.begin(), itrEnd = aResults.end(); + for (; itr != itrEnd; ++itr) + if (*itr) + return true; + + return false; +} + +// ---------------------------------------------------------------------------- + +ScDBQueryDataIterator::Value::Value() : + mnError(0), mbIsNumber(true) +{ + ::rtl::math::setNan(&mfValue); +} + +// ---------------------------------------------------------------------------- + +ScDBQueryDataIterator::ScDBQueryDataIterator(ScDocument* pDocument, ScDBQueryParamBase* pParam) : + mpParam (pParam) +{ + switch (mpParam->GetType()) + { + case ScDBQueryParamBase::INTERNAL: + { + ScDBQueryParamInternal* p = static_cast<ScDBQueryParamInternal*>(pParam); + mpData.reset(new DataAccessInternal(this, p, pDocument)); + } + break; + case ScDBQueryParamBase::MATRIX: + { + ScDBQueryParamMatrix* p = static_cast<ScDBQueryParamMatrix*>(pParam); + mpData.reset(new DataAccessMatrix(this, p)); + } + } +} + +bool ScDBQueryDataIterator::GetThis(Value& rValue) +{ + return mpData->getCurrent(rValue); +} + +bool ScDBQueryDataIterator::GetFirst(Value& rValue) +{ + return mpData->getFirst(rValue); +} + +bool ScDBQueryDataIterator::GetNext(Value& rValue) +{ + return mpData->getNext(rValue); +} + +// ============================================================================ ScCellIterator::ScCellIterator( ScDocument* pDocument, SCCOL nSCol, SCROW nSRow, SCTAB nSTab, diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx index bf2ec7102..b78d11539 100644 --- a/sc/source/core/data/document.cxx +++ b/sc/source/core/data/document.cxx @@ -4703,6 +4703,13 @@ ULONG ScDocument::GetCellCount() const return nCellCount; } +SCSIZE ScDocument::GetCellCount(SCTAB nTab, SCCOL nCol) const +{ + if (!ValidTab(nTab) || !pTab[nTab]) + return 0; + + return pTab[nTab]->GetCellCount(nCol); +} ULONG ScDocument::GetCodeCount() const { diff --git a/sc/source/core/data/dpcachetable.cxx b/sc/source/core/data/dpcachetable.cxx index 015c6512d..e4fac9ee1 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> @@ -209,9 +210,39 @@ sal_Int32 ScDPCacheTable::getColSize() const return maTable.empty() ? 0 : maTable[0].size(); } +namespace { + +/** + * While the macro interpret level is incremented, the formula cells are + * (semi-)guaranteed to be interpreted. + */ +class MacroInterpretIncrementer +{ +public: + MacroInterpretIncrementer(ScDocument* pDoc) : + mpDoc(pDoc) + { + mpDoc->IncMacroInterpretLevel(); + } + ~MacroInterpretIncrementer() + { + mpDoc->DecMacroInterpretLevel(); + } +private: + ScDocument* mpDoc; +}; + +} + void ScDPCacheTable::fillTable(ScDocument* pDoc, const ScRange& rRange, const ScQueryParam& rQuery, BOOL* pSpecial, bool bIgnoreEmptyRows) { + // Make sure the formula cells within the data range are interpreted + // during this call, for this method may be called from the interpretation + // of GETPIVOTDATA, which disables nested formula interpretation without + // increasing the macro level. + MacroInterpretIncrementer aMacroInc(pDoc); + SCTAB nTab = rRange.aStart.Tab(); SCCOL nStartCol = rRange.aStart.Col(); SCROW nStartRow = rRange.aStart.Row(); diff --git a/sc/source/core/data/global2.cxx b/sc/source/core/data/global2.cxx index bf69367bf..4c2e2d3c0 100644 --- a/sc/source/core/data/global2.cxx +++ b/sc/source/core/data/global2.cxx @@ -243,238 +243,6 @@ utl::TextSearch* ScQueryEntry::GetSearchTextPtr( BOOL bCaseSens ) } //------------------------------------------------------------------------ - -ScQueryParam::ScQueryParam() -{ - nEntryCount = 0; - Clear(); -} - -//------------------------------------------------------------------------ - -ScQueryParam::ScQueryParam( const ScQueryParam& r ) : - nCol1(r.nCol1),nRow1(r.nRow1),nCol2(r.nCol2),nRow2(r.nRow2),nTab(r.nTab), - bHasHeader(r.bHasHeader), bByRow(r.bByRow), bInplace(r.bInplace), bCaseSens(r.bCaseSens), - bRegExp(r.bRegExp), bMixedComparison(r.bMixedComparison), - bDuplicate(r.bDuplicate), 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() -{ - delete[] pEntries; -} - -//------------------------------------------------------------------------ - -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::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 ScQueryParam::DeleteQuery"); - } -} - -//------------------------------------------------------------------------ - -void ScQueryParam::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 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"); - } -} - -//------------------------------------------------------------------------ - -void ScQueryParam::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; - } - } -} - -//------------------------------------------------------------------------ // struct ScSubTotalParam: ScSubTotalParam::ScSubTotalParam() diff --git a/sc/source/core/data/sortparam.cxx b/sc/source/core/data/sortparam.cxx index 9531c7175..dfab465d0 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 e5943d721..1525f0c62 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> @@ -1818,6 +1819,11 @@ BOOL ScTable::GetDataEntries(SCCOL nCol, SCROW nRow, TypedScStrCollection& rStri return aCol[nCol].GetDataEntries( nRow, rStrings, bLimit ); } +SCSIZE ScTable::GetCellCount(SCCOL nCol) const +{ + return aCol[nCol].GetCellCount(); +} + ULONG ScTable::GetCellCount() const { ULONG nCellCount = 0; |