Kaydet (Commit) 85f580ac authored tarafından Kohei Yoshida's avatar Kohei Yoshida

Get double-click drill-down of pivot data to work again.

üst 53f661b3
......@@ -32,6 +32,7 @@
#include "sal/types.h"
#include "osl/mutex.hxx"
#include "global.hxx"
#include "dpitemdata.hxx"
#include <vector>
#include <boost/unordered_set.hpp>
......@@ -68,12 +69,10 @@ public:
/** individual filter item used in SingleFilter and GroupFilter. */
struct FilterItem
{
rtl::OUString maString;
double mfValue;
bool mbHasValue;
ScDPItemData maItem;
FilterItem();
bool match( const ScDPItemData& rCellData ) const;
bool match(const ScDPItemData& rCellData) const;
};
/** interface class used for filtering of rows. */
......@@ -90,19 +89,17 @@ public:
class SingleFilter : public FilterBase
{
public:
explicit SingleFilter(const rtl::OUString& aString, double fValue, bool bHasValue);
explicit SingleFilter(const ScDPItemData &rItem);
virtual ~SingleFilter() {}
virtual bool match(const ScDPItemData& rCellData) const;
const rtl::OUString& getMatchString() const;
double getMatchValue() const;
bool hasValue() const;
const ScDPItemData& getMatchValue() const;
private:
explicit SingleFilter();
FilterItem maItem;
ScDPItemData maItem;
};
/** multi-item (group) filter. */
......@@ -111,12 +108,12 @@ public:
public:
GroupFilter();
virtual ~GroupFilter() {}
virtual bool match( const ScDPItemData& rCellData ) const;
void addMatchItem(const rtl::OUString& rStr, double fVal, bool bHasValue);
virtual bool match(const ScDPItemData& rCellData) const;
void addMatchItem(const ScDPItemData& rItem);
size_t getMatchItemCount() const;
private:
::std::vector<FilterItem> maItems;
::std::vector<ScDPItemData> maItems;
};
/** single filtering criterion. */
......
......@@ -84,74 +84,47 @@ ScDPCacheTable::RowFlag::RowFlag() :
{
}
ScDPCacheTable::FilterItem::FilterItem() :
mfValue(0.0),
mbHasValue(false)
{
}
ScDPCacheTable::FilterItem::FilterItem() {}
bool ScDPCacheTable::FilterItem::match( const ScDPItemData& rCellData ) const
bool ScDPCacheTable::FilterItem::match(const ScDPItemData& rCellData) const
{
if (!rCellData.GetString().equals(maString) &&
(!rCellData.IsValue()|| rCellData.GetValue()!= mfValue))
return false;
return true;
return rCellData == maItem;
}
// ----------------------------------------------------------------------------
ScDPCacheTable::SingleFilter::SingleFilter(const rtl::OUString& aString, double fValue, bool bHasValue)
{
maItem.maString = aString;
maItem.mfValue = fValue;
maItem.mbHasValue = bHasValue;
}
bool ScDPCacheTable::SingleFilter::match( const ScDPItemData& rCellData ) const
{
return maItem.match(rCellData);
}
ScDPCacheTable::SingleFilter::SingleFilter(const ScDPItemData& rItem) :
maItem(rItem) {}
const rtl::OUString& ScDPCacheTable::SingleFilter::getMatchString() const
bool ScDPCacheTable::SingleFilter::match(const ScDPItemData& rCellData) const
{
return maItem.maString;
return maItem == rCellData;
}
double ScDPCacheTable::SingleFilter::getMatchValue() const
const ScDPItemData& ScDPCacheTable::SingleFilter::getMatchValue() const
{
return maItem.mfValue;
return maItem;
}
bool ScDPCacheTable::SingleFilter::hasValue() const
{
return maItem.mbHasValue;
}
// ----------------------------------------------------------------------------
ScDPCacheTable::GroupFilter::GroupFilter()
{
}
bool ScDPCacheTable::GroupFilter::match( const ScDPItemData& rCellData ) const
bool ScDPCacheTable::GroupFilter::match(const ScDPItemData& rCellData) const
{
vector<FilterItem>::const_iterator itrEnd = maItems.end();
for (vector<FilterItem>::const_iterator itr = maItems.begin(); itr != itrEnd; ++itr)
{
bool bMatch = itr->match( rCellData);
if (bMatch)
return true;
}
return false;
vector<ScDPItemData>::const_iterator it = maItems.begin(), itEnd = maItems.end();
for (; it != itEnd; ++it)
{
bool bMatch = *it == rCellData;
if (bMatch)
return true;
}
return false;
}
void ScDPCacheTable::GroupFilter::addMatchItem(const rtl::OUString& rStr, double fVal, bool bHasValue)
void ScDPCacheTable::GroupFilter::addMatchItem(const ScDPItemData& rItem)
{
FilterItem aItem;
aItem.maString = rStr;
aItem.mfValue = fVal;
aItem.mbHasValue = bHasValue;
maItems.push_back(aItem);
maItems.push_back(rItem);
}
size_t ScDPCacheTable::GroupFilter::getMatchItemCount() const
......
......@@ -81,28 +81,26 @@ class ScDPGroupDateFilter : public ScDPCacheTable::FilterBase
{
public:
virtual ~ScDPGroupDateFilter() {}
ScDPGroupDateFilter(double fMatchValue, sal_Int32 nDatePart,
const Date* pNullDate, const ScDPNumGroupInfo* pNumInfo);
ScDPGroupDateFilter(
const ScDPItemData& rValue, const Date& rNullDate, const ScDPNumGroupInfo& rNumInfo);
virtual bool match(const ScDPItemData & rCellData) const;
private:
ScDPGroupDateFilter(); // disabled
const Date* mpNullDate;
const ScDPNumGroupInfo* mpNumInfo;
double mfMatchValue;
sal_Int32 mnDatePart;
ScDPItemData maValue;
const Date maNullDate;
const ScDPNumGroupInfo maNumInfo;
};
// ----------------------------------------------------------------------------
ScDPGroupDateFilter::ScDPGroupDateFilter(double fMatchValue, sal_Int32 nDatePart,
const Date* pNullDate, const ScDPNumGroupInfo* pNumInfo) :
mpNullDate(pNullDate),
mpNumInfo(pNumInfo),
mfMatchValue(fMatchValue),
mnDatePart(nDatePart)
ScDPGroupDateFilter::ScDPGroupDateFilter(
const ScDPItemData& rItem, const Date& rNullDate, const ScDPNumGroupInfo& rNumInfo) :
maValue(rItem),
maNullDate(rNullDate),
maNumInfo(rNumInfo)
{
}
......@@ -115,20 +113,28 @@ bool ScDPGroupDateFilter::match( const ScDPItemData & rCellData ) const
if ( !rCellData.IsValue() )
return false;
if (!mpNumInfo)
if (maValue.GetType() != ScDPItemData::GroupValue)
return false;
sal_Int32 nGroupType = maValue.GetGroupValue().mnGroupType;
sal_Int32 nValue = maValue.GetGroupValue().mnValue;
// Start and end dates are inclusive. (An end date without a time value
// is included, while an end date with a time value is not.)
if ( rCellData.GetValue() < mpNumInfo->mfStart && !approxEqual(rCellData.GetValue(), mpNumInfo->mfStart) )
return static_cast<sal_Int32>(mfMatchValue) == ScDPItemData::DateFirst;
if ( rCellData.GetValue() < maNumInfo.mfStart && !approxEqual(rCellData.GetValue(), maNumInfo.mfStart) )
{
return nValue == ScDPItemData::DateFirst;
}
if ( rCellData.GetValue() > maNumInfo.mfEnd && !approxEqual(rCellData.GetValue(), maNumInfo.mfEnd) )
{
return nValue == ScDPItemData::DateLast;
}
if ( rCellData.GetValue() > mpNumInfo->mfEnd && !approxEqual(rCellData.GetValue(), mpNumInfo->mfEnd) )
return static_cast<sal_Int32>(mfMatchValue) == ScDPItemData::DateLast;
if (mnDatePart == DataPilotFieldGroupBy::HOURS || mnDatePart == DataPilotFieldGroupBy::MINUTES ||
mnDatePart == DataPilotFieldGroupBy::SECONDS)
if (nGroupType == DataPilotFieldGroupBy::HOURS || nGroupType == DataPilotFieldGroupBy::MINUTES ||
nGroupType == DataPilotFieldGroupBy::SECONDS)
{
// handle time
// (as in the cell functions, ScInterpreter::ScGetHour etc.: seconds are rounded)
......@@ -136,25 +142,22 @@ bool ScDPGroupDateFilter::match( const ScDPItemData & rCellData ) const
double time = rCellData.GetValue() - approxFloor(rCellData.GetValue());
long seconds = static_cast<long>(approxFloor(time*D_TIMEFACTOR + 0.5));
switch (mnDatePart)
switch (nGroupType)
{
case DataPilotFieldGroupBy::HOURS:
{
sal_Int32 hrs = seconds / 3600;
sal_Int32 matchHrs = static_cast<sal_Int32>(mfMatchValue);
return hrs == matchHrs;
return hrs == nValue;
}
case DataPilotFieldGroupBy::MINUTES:
{
sal_Int32 minutes = (seconds % 3600) / 60;
sal_Int32 matchMinutes = static_cast<sal_Int32>(mfMatchValue);
return minutes == matchMinutes;
return minutes == nValue;
}
case DataPilotFieldGroupBy::SECONDS:
{
sal_Int32 sec = seconds % 60;
sal_Int32 matchSec = static_cast<sal_Int32>(mfMatchValue);
return sec == matchSec;
return sec == nValue;
}
default:
OSL_FAIL("invalid time part");
......@@ -162,26 +165,23 @@ bool ScDPGroupDateFilter::match( const ScDPItemData & rCellData ) const
return false;
}
Date date = *mpNullDate + static_cast<long>(approxFloor(rCellData.GetValue()));
switch (mnDatePart)
Date date = maNullDate + static_cast<long>(approxFloor(rCellData.GetValue()));
switch (nGroupType)
{
case DataPilotFieldGroupBy::YEARS:
{
sal_Int32 year = static_cast<sal_Int32>(date.GetYear());
sal_Int32 matchYear = static_cast<sal_Int32>(mfMatchValue);
return year == matchYear;
return year == nValue;
}
case DataPilotFieldGroupBy::QUARTERS:
{
sal_Int32 qtr = 1 + (static_cast<sal_Int32>(date.GetMonth()) - 1) / 3;
sal_Int32 matchQtr = static_cast<sal_Int32>(mfMatchValue);
return qtr == matchQtr;
return qtr == nValue;
}
case DataPilotFieldGroupBy::MONTHS:
{
sal_Int32 month = static_cast<sal_Int32>(date.GetMonth());
sal_Int32 matchMonth = static_cast<sal_Int32>(mfMatchValue);
return month == matchMonth;
return month == nValue;
}
case DataPilotFieldGroupBy::DAYS:
{
......@@ -192,8 +192,7 @@ bool ScDPGroupDateFilter::match( const ScDPItemData & rCellData ) const
// This is not a leap year. Adjust the value accordingly.
++days;
}
sal_Int32 matchDays = static_cast<sal_Int32>(mfMatchValue);
return days == matchDays;
return days == nValue;
}
default:
OSL_FAIL("invalid date part");
......@@ -313,7 +312,7 @@ void ScDPGroupItem::FillGroupFilter( ScDPCacheTable::GroupFilter& rFilter ) cons
{
ScDPItemDataVec::const_iterator itrEnd = aElements.end();
for (ScDPItemDataVec::const_iterator itr = aElements.begin(); itr != itrEnd; ++itr)
rFilter.addMatchItem(itr->GetString(), itr->GetValue(), itr->IsValue());
rFilter.addMatchItem(*itr);
}
// -----------------------------------------------------------------------
......@@ -693,9 +692,9 @@ void ScDPGroupTableData::ModifyFilterCriteria(vector<ScDPCacheTable::Criterion>&
ScDPCacheTable::Criterion aCri;
aCri.mnFieldIndex = itr->mnFieldIndex;
aCri.mpFilter.reset(new ScDPGroupDateFilter(
pFilter->getMatchValue(), pDateHelper->GetDatePart(),
pDoc->GetFormatTable()->GetNullDate(), &pDateHelper->GetNumInfo()));
aCri.mpFilter.reset(
new ScDPGroupDateFilter(
pFilter->getMatchValue(), *pDoc->GetFormatTable()->GetNullDate(), pDateHelper->GetNumInfo()));
aNewCriteria.push_back(aCri);
}
......@@ -718,9 +717,9 @@ void ScDPGroupTableData::ModifyFilterCriteria(vector<ScDPCacheTable::Criterion>&
// external number group
ScDPCacheTable::Criterion aCri;
aCri.mnFieldIndex = nSrcDim; // use the source dimension, not the group dimension.
aCri.mpFilter.reset(new ScDPGroupDateFilter(
pFilter->getMatchValue(), pDateHelper->GetDatePart(),
pDoc->GetFormatTable()->GetNullDate(), &pDateHelper->GetNumInfo()));
aCri.mpFilter.reset(
new ScDPGroupDateFilter(
pFilter->getMatchValue(), *pDoc->GetFormatTable()->GetNullDate(), pDateHelper->GetNumInfo()));
aNewCriteria.push_back(aCri);
}
......@@ -733,11 +732,7 @@ void ScDPGroupTableData::ModifyFilterCriteria(vector<ScDPCacheTable::Criterion>&
for (size_t i = 0; i < nGroupItemCount; ++i)
{
const ScDPGroupItem* pGrpItem = pGrpDim->GetGroupByIndex(i);
ScDPItemData aName;
if (pFilter->hasValue())
aName.SetValue(pFilter->getMatchValue());
else
aName.SetString(pFilter->getMatchString());
ScDPItemData aName = pFilter->getMatchValue();
if (!pGrpItem || !pGrpItem->GetName().IsCaseInsEqual(aName))
continue;
......
......@@ -3908,7 +3908,7 @@ void ScDPResultVisibilityData::fillFieldFilters(vector<ScDPCacheTable::Criterion
itrMem != itrMemEnd; ++itrMem)
{
const ScDPItemData& rMemItem = *itrMem;
pGrpFilter->addMatchItem(rMemItem.GetString(), rMemItem.GetValue(), rMemItem.IsValue());
pGrpFilter->addMatchItem(rMemItem);
}
ScDPDimension* pDim = pDims->getByIndex(nDimIndex);
......
......@@ -459,7 +459,7 @@ Sequence< Sequence<Any> > SAL_CALL ScDPSource::getDrillDownData(const Sequence<s
aFilterCriteria.push_back( ScDPCacheTable::Criterion() );
aFilterCriteria.back().mnFieldIndex = nCol;
aFilterCriteria.back().mpFilter.reset(
new ScDPCacheTable::SingleFilter(aItem.GetString(), aItem.GetValue(), aItem.IsValue()));
new ScDPCacheTable::SingleFilter(aItem));
}
}
}
......@@ -724,7 +724,7 @@ void ScDPSource::FilterCacheTableByPageDimensions()
{
ScDPItemData aData;
pMem->FillItemData(aData);
pGrpFilter->addMatchItem(aData.GetString(), aData.GetValue(), aData.IsValue());
pGrpFilter->addMatchItem(aData);
}
}
if (pGrpFilter->getMatchItemCount() < static_cast<size_t>(nMemCount))
......@@ -738,8 +738,7 @@ void ScDPSource::FilterCacheTableByPageDimensions()
aCriteria.push_back(ScDPCacheTable::Criterion());
ScDPCacheTable::Criterion& r = aCriteria.back();
r.mnFieldIndex = static_cast<sal_Int32>(nField);
r.mpFilter.reset(
new ScDPCacheTable::SingleFilter(rData.GetString()/*rSharedString, nStrId*/, rData.GetValue(), rData.IsValue()));
r.mpFilter.reset(new ScDPCacheTable::SingleFilter(rData));
}
if (!aCriteria.empty())
{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment