Implemented the new multi-value filter API.

This commit is contained in:
Kohei Yoshida 2011-11-29 15:58:51 -05:00
parent 34493546d6
commit 0278ebc50e
2 changed files with 270 additions and 106 deletions

View file

@ -37,6 +37,8 @@
#include <com/sun/star/sheet/GeneralFunction.hpp>
#include <com/sun/star/sheet/XCellRangeReferrer.hpp>
#include <com/sun/star/sheet/XSheetFilterDescriptor.hpp>
#include <com/sun/star/sheet/XSheetFilterDescriptor2.hpp>
#include <com/sun/star/sheet/XSheetFilterDescriptor3.hpp>
#include <com/sun/star/sheet/XConsolidationDescriptor.hpp>
#include <com/sun/star/sheet/XDatabaseRanges.hpp>
#include <com/sun/star/sheet/XDatabaseRange.hpp>
@ -50,7 +52,6 @@
#include <com/sun/star/lang/XUnoTunnel.hpp>
#include <com/sun/star/container/XNamed.hpp>
#include <com/sun/star/util/XRefreshable.hpp>
#include <com/sun/star/sheet/XSheetFilterDescriptor2.hpp>
#include <cppuhelper/implbase2.hxx>
#include <cppuhelper/implbase3.hxx>
#include <cppuhelper/implbase4.hxx>
@ -342,9 +343,10 @@ public:
// to uno, all three look the same
class ScFilterDescriptorBase : public cppu::WeakImplHelper4<
class ScFilterDescriptorBase : public cppu::WeakImplHelper5<
com::sun::star::sheet::XSheetFilterDescriptor,
com::sun::star::sheet::XSheetFilterDescriptor2,
com::sun::star::sheet::XSheetFilterDescriptor3,
com::sun::star::beans::XPropertySet,
com::sun::star::lang::XServiceInfo >,
public SfxListener
@ -354,10 +356,6 @@ private:
ScDocShell* pDocSh;
public:
static void fillQueryParam(
ScQueryParam& rParam, ScDocument* pDoc,
const ::com::sun::star::uno::Sequence< ::com::sun::star::sheet::TableFilterField2>& aFilterFields);
ScFilterDescriptorBase(ScDocShell* pDocShell);
virtual ~ScFilterDescriptorBase();
@ -382,6 +380,13 @@ public:
::com::sun::star::sheet::TableFilterField2 >& aFilterFields )
throw(::com::sun::star::uno::RuntimeException);
// XSheetFilterDescriptor3
virtual ::com::sun::star::uno::Sequence< ::com::sun::star::sheet::TableFilterField3 > SAL_CALL
getFilterFields3() throw(::com::sun::star::uno::RuntimeException);
virtual void SAL_CALL setFilterFields3( const ::com::sun::star::uno::Sequence<
::com::sun::star::sheet::TableFilterField3 >& aFilterFields )
throw(::com::sun::star::uno::RuntimeException);
// XPropertySet
virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo >
SAL_CALL getPropertySetInfo()

View file

@ -1058,67 +1058,6 @@ void SAL_CALL ScConsolidationDescriptor::setInsertLinks( sal_Bool bInsertLinks )
aParam.bReferenceData = bInsertLinks;
}
//------------------------------------------------------------------------
void ScFilterDescriptorBase::fillQueryParam(
ScQueryParam& rParam, ScDocument* pDoc,
const uno::Sequence<sheet::TableFilterField2>& aFilterFields)
{
SCSIZE nCount = static_cast<SCSIZE>(aFilterFields.getLength());
rParam.Resize( nCount );
const sheet::TableFilterField2* pAry = aFilterFields.getConstArray();
SCSIZE i;
for (i=0; i<nCount; i++)
{
ScQueryEntry& rEntry = rParam.GetEntry(i);
ScQueryEntry::Item& rItem = rEntry.GetQueryItem();
rEntry.bDoQuery = true;
rEntry.eConnect = (pAry[i].Connection == sheet::FilterConnection_AND) ? SC_AND : SC_OR;
rEntry.nField = pAry[i].Field;
rItem.meType = pAry[i].IsNumeric ? ScQueryEntry::ByValue : ScQueryEntry::ByString;
rItem.mfVal = pAry[i].NumericValue;
rItem.maString = pAry[i].StringValue;
if (rItem.meType == ScQueryEntry::ByValue && pDoc)
pDoc->GetFormatTable()->GetInputLineString(rItem.mfVal, 0, rItem.maString);
switch (pAry[i].Operator) // FilterOperator
{
case sheet::FilterOperator2::EQUAL: rEntry.eOp = SC_EQUAL; break;
case sheet::FilterOperator2::LESS: rEntry.eOp = SC_LESS; break;
case sheet::FilterOperator2::GREATER: rEntry.eOp = SC_GREATER; break;
case sheet::FilterOperator2::LESS_EQUAL: rEntry.eOp = SC_LESS_EQUAL; break;
case sheet::FilterOperator2::GREATER_EQUAL: rEntry.eOp = SC_GREATER_EQUAL; break;
case sheet::FilterOperator2::NOT_EQUAL: rEntry.eOp = SC_NOT_EQUAL; break;
case sheet::FilterOperator2::TOP_VALUES: rEntry.eOp = SC_TOPVAL; break;
case sheet::FilterOperator2::BOTTOM_VALUES: rEntry.eOp = SC_BOTVAL; break;
case sheet::FilterOperator2::TOP_PERCENT: rEntry.eOp = SC_TOPPERC; break;
case sheet::FilterOperator2::BOTTOM_PERCENT: rEntry.eOp = SC_BOTPERC; break;
case sheet::FilterOperator2::CONTAINS: rEntry.eOp = SC_CONTAINS; break;
case sheet::FilterOperator2::DOES_NOT_CONTAIN: rEntry.eOp = SC_DOES_NOT_CONTAIN; break;
case sheet::FilterOperator2::BEGINS_WITH: rEntry.eOp = SC_BEGINS_WITH; break;
case sheet::FilterOperator2::DOES_NOT_BEGIN_WITH: rEntry.eOp = SC_DOES_NOT_BEGIN_WITH;break;
case sheet::FilterOperator2::ENDS_WITH: rEntry.eOp = SC_ENDS_WITH; break;
case sheet::FilterOperator2::DOES_NOT_END_WITH: rEntry.eOp = SC_DOES_NOT_END_WITH; break;
case sheet::FilterOperator2::EMPTY:
rEntry.SetQueryByEmpty();
break;
case sheet::FilterOperator2::NOT_EMPTY:
rEntry.SetQueryByNonEmpty();
break;
default:
OSL_FAIL("Falscher Query-enum");
rEntry.eOp = SC_EQUAL;
}
}
SCSIZE nParamCount = rParam.GetEntryCount(); // Param wird nicht unter 8 resized
for (i=nCount; i<nParamCount; i++)
rParam.GetEntry(i).bDoQuery = false; // ueberzaehlige Felder zuruecksetzen
}
ScFilterDescriptorBase::ScFilterDescriptorBase(ScDocShell* pDocShell) :
aPropSet( lcl_GetFilterPropertyMap() ),
pDocSh(pDocShell)
@ -1210,6 +1149,172 @@ uno::Sequence<sheet::TableFilterField> SAL_CALL ScFilterDescriptorBase::getFilte
return aSeq;
}
namespace {
template<typename T>
void convertQueryEntryToUno(const ScQueryEntry& rEntry, T& rField)
{
rField.Connection = (rEntry.eConnect == SC_AND) ? sheet::FilterConnection_AND : sheet::FilterConnection_OR;
rField.Field = rEntry.nField;
switch (rEntry.eOp) // ScQueryOp
{
case SC_EQUAL: rField.Operator = sheet::FilterOperator2::EQUAL; break;
case SC_LESS: rField.Operator = sheet::FilterOperator2::LESS; break;
case SC_GREATER: rField.Operator = sheet::FilterOperator2::GREATER; break;
case SC_LESS_EQUAL: rField.Operator = sheet::FilterOperator2::LESS_EQUAL; break;
case SC_GREATER_EQUAL: rField.Operator = sheet::FilterOperator2::GREATER_EQUAL; break;
case SC_NOT_EQUAL: rField.Operator = sheet::FilterOperator2::NOT_EQUAL; break;
case SC_TOPVAL: rField.Operator = sheet::FilterOperator2::TOP_VALUES; break;
case SC_BOTVAL: rField.Operator = sheet::FilterOperator2::BOTTOM_VALUES; break;
case SC_TOPPERC: rField.Operator = sheet::FilterOperator2::TOP_PERCENT; break;
case SC_BOTPERC: rField.Operator = sheet::FilterOperator2::BOTTOM_PERCENT; break;
case SC_CONTAINS: rField.Operator = sheet::FilterOperator2::CONTAINS; break;
case SC_DOES_NOT_CONTAIN: rField.Operator = sheet::FilterOperator2::DOES_NOT_CONTAIN; break;
case SC_BEGINS_WITH: rField.Operator = sheet::FilterOperator2::BEGINS_WITH; break;
case SC_DOES_NOT_BEGIN_WITH: rField.Operator = sheet::FilterOperator2::DOES_NOT_BEGIN_WITH; break;
case SC_ENDS_WITH: rField.Operator = sheet::FilterOperator2::ENDS_WITH; break;
case SC_DOES_NOT_END_WITH: rField.Operator = sheet::FilterOperator2::DOES_NOT_END_WITH; break;
default:
OSL_FAIL("Unknown filter operator value.");
rField.Operator = sheet::FilterOperator2::EMPTY;
}
}
void fillQueryParam(
ScQueryParam& rParam, ScDocument* pDoc,
const uno::Sequence<sheet::TableFilterField2>& aFilterFields)
{
size_t nCount = static_cast<size_t>(aFilterFields.getLength());
rParam.Resize(nCount);
const sheet::TableFilterField2* pAry = aFilterFields.getConstArray();
for (size_t i = 0; i < nCount; ++i)
{
ScQueryEntry& rEntry = rParam.GetEntry(i);
rEntry.bDoQuery = true;
rEntry.eConnect = (pAry[i].Connection == sheet::FilterConnection_AND) ? SC_AND : SC_OR;
rEntry.nField = pAry[i].Field;
switch (pAry[i].Operator) // FilterOperator
{
case sheet::FilterOperator2::EQUAL: rEntry.eOp = SC_EQUAL; break;
case sheet::FilterOperator2::LESS: rEntry.eOp = SC_LESS; break;
case sheet::FilterOperator2::GREATER: rEntry.eOp = SC_GREATER; break;
case sheet::FilterOperator2::LESS_EQUAL: rEntry.eOp = SC_LESS_EQUAL; break;
case sheet::FilterOperator2::GREATER_EQUAL: rEntry.eOp = SC_GREATER_EQUAL; break;
case sheet::FilterOperator2::NOT_EQUAL: rEntry.eOp = SC_NOT_EQUAL; break;
case sheet::FilterOperator2::TOP_VALUES: rEntry.eOp = SC_TOPVAL; break;
case sheet::FilterOperator2::BOTTOM_VALUES: rEntry.eOp = SC_BOTVAL; break;
case sheet::FilterOperator2::TOP_PERCENT: rEntry.eOp = SC_TOPPERC; break;
case sheet::FilterOperator2::BOTTOM_PERCENT: rEntry.eOp = SC_BOTPERC; break;
case sheet::FilterOperator2::CONTAINS: rEntry.eOp = SC_CONTAINS; break;
case sheet::FilterOperator2::DOES_NOT_CONTAIN: rEntry.eOp = SC_DOES_NOT_CONTAIN; break;
case sheet::FilterOperator2::BEGINS_WITH: rEntry.eOp = SC_BEGINS_WITH; break;
case sheet::FilterOperator2::DOES_NOT_BEGIN_WITH: rEntry.eOp = SC_DOES_NOT_BEGIN_WITH;break;
case sheet::FilterOperator2::ENDS_WITH: rEntry.eOp = SC_ENDS_WITH; break;
case sheet::FilterOperator2::DOES_NOT_END_WITH: rEntry.eOp = SC_DOES_NOT_END_WITH; break;
case sheet::FilterOperator2::EMPTY:
rEntry.SetQueryByEmpty();
break;
case sheet::FilterOperator2::NOT_EMPTY:
rEntry.SetQueryByNonEmpty();
break;
default:
OSL_FAIL("Falscher Query-enum");
rEntry.eOp = SC_EQUAL;
}
if (pAry[i].Operator != sheet::FilterOperator2::EMPTY && pAry[i].Operator != sheet::FilterOperator2::NOT_EMPTY)
{
ScQueryEntry::Item& rItem = rEntry.GetQueryItem();
rItem.meType = pAry[i].IsNumeric ? ScQueryEntry::ByValue : ScQueryEntry::ByString;
rItem.mfVal = pAry[i].NumericValue;
rItem.maString = pAry[i].StringValue;
if (rItem.meType == ScQueryEntry::ByValue && pDoc)
pDoc->GetFormatTable()->GetInputLineString(rItem.mfVal, 0, rItem.maString);
}
}
size_t nParamCount = rParam.GetEntryCount(); // Param wird nicht unter 8 resized
for (size_t i = nCount; i < nParamCount; ++i)
rParam.GetEntry(i).bDoQuery = false; // ueberzaehlige Felder zuruecksetzen
}
void fillQueryParam(
ScQueryParam& rParam, ScDocument* pDoc,
const uno::Sequence<sheet::TableFilterField3>& aFilterFields)
{
size_t nCount = static_cast<size_t>(aFilterFields.getLength());
rParam.Resize(nCount);
const sheet::TableFilterField3* pAry = aFilterFields.getConstArray();
for (size_t i = 0; i < nCount; ++i)
{
ScQueryEntry& rEntry = rParam.GetEntry(i);
rEntry.bDoQuery = true;
rEntry.eConnect = (pAry[i].Connection == sheet::FilterConnection_AND) ? SC_AND : SC_OR;
rEntry.nField = pAry[i].Field;
switch (pAry[i].Operator) // FilterOperator
{
case sheet::FilterOperator2::EQUAL: rEntry.eOp = SC_EQUAL; break;
case sheet::FilterOperator2::LESS: rEntry.eOp = SC_LESS; break;
case sheet::FilterOperator2::GREATER: rEntry.eOp = SC_GREATER; break;
case sheet::FilterOperator2::LESS_EQUAL: rEntry.eOp = SC_LESS_EQUAL; break;
case sheet::FilterOperator2::GREATER_EQUAL: rEntry.eOp = SC_GREATER_EQUAL; break;
case sheet::FilterOperator2::NOT_EQUAL: rEntry.eOp = SC_NOT_EQUAL; break;
case sheet::FilterOperator2::TOP_VALUES: rEntry.eOp = SC_TOPVAL; break;
case sheet::FilterOperator2::BOTTOM_VALUES: rEntry.eOp = SC_BOTVAL; break;
case sheet::FilterOperator2::TOP_PERCENT: rEntry.eOp = SC_TOPPERC; break;
case sheet::FilterOperator2::BOTTOM_PERCENT: rEntry.eOp = SC_BOTPERC; break;
case sheet::FilterOperator2::CONTAINS: rEntry.eOp = SC_CONTAINS; break;
case sheet::FilterOperator2::DOES_NOT_CONTAIN: rEntry.eOp = SC_DOES_NOT_CONTAIN; break;
case sheet::FilterOperator2::BEGINS_WITH: rEntry.eOp = SC_BEGINS_WITH; break;
case sheet::FilterOperator2::DOES_NOT_BEGIN_WITH: rEntry.eOp = SC_DOES_NOT_BEGIN_WITH;break;
case sheet::FilterOperator2::ENDS_WITH: rEntry.eOp = SC_ENDS_WITH; break;
case sheet::FilterOperator2::DOES_NOT_END_WITH: rEntry.eOp = SC_DOES_NOT_END_WITH; break;
case sheet::FilterOperator2::EMPTY:
rEntry.SetQueryByEmpty();
break;
case sheet::FilterOperator2::NOT_EMPTY:
rEntry.SetQueryByNonEmpty();
break;
default:
OSL_FAIL("Unknown filter operator type.");
rEntry.eOp = SC_EQUAL;
}
if (pAry[i].Operator != sheet::FilterOperator2::EMPTY && pAry[i].Operator != sheet::FilterOperator2::NOT_EMPTY)
{
ScQueryEntry::QueryItemsType& rItems = rEntry.GetQueryItems();
rItems.clear();
const uno::Sequence<sheet::FilterFieldValue>& rVals = pAry[i].Values;
for (sal_Int32 j = 0, n = rVals.getLength(); j < n; ++j)
{
ScQueryEntry::Item aItem;
aItem.meType = rVals[j].IsNumeric ? ScQueryEntry::ByValue : ScQueryEntry::ByString;
aItem.mfVal = rVals[j].NumericValue;
aItem.maString = rVals[j].StringValue;
if (aItem.meType == ScQueryEntry::ByValue && pDoc)
pDoc->GetFormatTable()->GetInputLineString(aItem.mfVal, 0, aItem.maString);
rItems.push_back(aItem);
}
}
}
size_t nParamCount = rParam.GetEntryCount(); // Param wird nicht unter 8 resized
for (size_t i = nCount; i < nParamCount; ++i)
rParam.GetEntry(i).bDoQuery = false; // ueberzaehlige Felder zuruecksetzen
}
}
uno::Sequence<sheet::TableFilterField2> SAL_CALL ScFilterDescriptorBase::getFilterFields2()
throw(uno::RuntimeException)
{
@ -1229,50 +1334,93 @@ throw(uno::RuntimeException)
for (SCSIZE i=0; i<nCount; i++)
{
const ScQueryEntry& rEntry = aParam.GetEntry(i);
const ScQueryEntry::Item& rItem = rEntry.GetQueryItem();
convertQueryEntryToUno(rEntry, aField);
aField.Connection = (rEntry.eConnect == SC_AND) ? sheet::FilterConnection_AND : sheet::FilterConnection_OR;
aField.Field = rEntry.nField;
aField.IsNumeric = !rItem.meType != ScQueryEntry::ByString;
aField.StringValue = rItem.maString;
aField.NumericValue = rItem.mfVal;
switch (rEntry.eOp) // ScQueryOp
bool bByEmpty = false;
if (aField.Operator == sheet::FilterOperator2::EQUAL)
{
case SC_EQUAL:
if (rEntry.IsQueryByEmpty())
{
aField.Operator = sheet::FilterOperator2::EQUAL;
if (rEntry.IsQueryByEmpty())
{
aField.Operator = sheet::FilterOperator2::EMPTY;
aField.NumericValue = 0;
}
else if (rEntry.IsQueryByNonEmpty())
{
aField.Operator = sheet::FilterOperator2::NOT_EMPTY;
aField.NumericValue = 0;
}
aField.Operator = sheet::FilterOperator2::EMPTY;
aField.NumericValue = 0;
bByEmpty = true;
}
else if (rEntry.IsQueryByNonEmpty())
{
aField.Operator = sheet::FilterOperator2::NOT_EMPTY;
aField.NumericValue = 0;
bByEmpty = true;
}
break;
case SC_LESS: aField.Operator = sheet::FilterOperator2::LESS; break;
case SC_GREATER: aField.Operator = sheet::FilterOperator2::GREATER; break;
case SC_LESS_EQUAL: aField.Operator = sheet::FilterOperator2::LESS_EQUAL; break;
case SC_GREATER_EQUAL: aField.Operator = sheet::FilterOperator2::GREATER_EQUAL; break;
case SC_NOT_EQUAL: aField.Operator = sheet::FilterOperator2::NOT_EQUAL; break;
case SC_TOPVAL: aField.Operator = sheet::FilterOperator2::TOP_VALUES; break;
case SC_BOTVAL: aField.Operator = sheet::FilterOperator2::BOTTOM_VALUES; break;
case SC_TOPPERC: aField.Operator = sheet::FilterOperator2::TOP_PERCENT; break;
case SC_BOTPERC: aField.Operator = sheet::FilterOperator2::BOTTOM_PERCENT; break;
case SC_CONTAINS: aField.Operator = sheet::FilterOperator2::CONTAINS; break;
case SC_DOES_NOT_CONTAIN: aField.Operator = sheet::FilterOperator2::DOES_NOT_CONTAIN; break;
case SC_BEGINS_WITH: aField.Operator = sheet::FilterOperator2::BEGINS_WITH; break;
case SC_DOES_NOT_BEGIN_WITH: aField.Operator = sheet::FilterOperator2::DOES_NOT_BEGIN_WITH; break;
case SC_ENDS_WITH: aField.Operator = sheet::FilterOperator2::ENDS_WITH; break;
case SC_DOES_NOT_END_WITH: aField.Operator = sheet::FilterOperator2::DOES_NOT_END_WITH; break;
default:
OSL_FAIL("Falscher Filter-enum");
aField.Operator = sheet::FilterOperator2::EMPTY;
}
if (!bByEmpty)
{
const ScQueryEntry::Item& rItem = rEntry.GetQueryItem();
aField.IsNumeric = !rItem.meType != ScQueryEntry::ByString;
aField.StringValue = rItem.maString;
aField.NumericValue = rItem.mfVal;
}
pAry[i] = aField;
}
return aSeq;
}
uno::Sequence<sheet::TableFilterField3> SAL_CALL ScFilterDescriptorBase::getFilterFields3()
throw(uno::RuntimeException)
{
SolarMutexGuard aGuard;
ScQueryParam aParam;
GetData(aParam);
SCSIZE nEntries = aParam.GetEntryCount(); // allozierte Eintraege im Param
SCSIZE nCount = 0; // aktive
while ( nCount < nEntries &&
aParam.GetEntry(nCount).bDoQuery )
++nCount;
sheet::TableFilterField3 aField;
uno::Sequence<sheet::TableFilterField3> aSeq(static_cast<sal_Int32>(nCount));
sheet::TableFilterField3* pAry = aSeq.getArray();
for (SCSIZE i = 0; i < nCount; ++i)
{
const ScQueryEntry& rEntry = aParam.GetEntry(i);
convertQueryEntryToUno(rEntry, aField);
bool bByEmpty = false;
if (aField.Operator == sheet::FilterOperator2::EQUAL)
{
if (rEntry.IsQueryByEmpty())
{
aField.Operator = sheet::FilterOperator2::EMPTY;
aField.Values.realloc(1);
aField.Values[0].NumericValue = 0;
bByEmpty = true;
}
else if (rEntry.IsQueryByNonEmpty())
{
aField.Operator = sheet::FilterOperator2::NOT_EMPTY;
aField.Values.realloc(1);
aField.Values[0].NumericValue = 0;
bByEmpty = true;
}
}
if (!bByEmpty)
{
const ScQueryEntry::QueryItemsType& rItems = rEntry.GetQueryItems();
size_t nItemCount = rItems.size();
aField.Values.realloc(nItemCount);
ScQueryEntry::QueryItemsType::const_iterator itr = rItems.begin(), itrEnd = rItems.end();
for (size_t j = 0; itr != itrEnd; ++itr, ++j)
{
aField.Values[j].IsNumeric = itr->meType != ScQueryEntry::ByString;
aField.Values[j].StringValue = itr->maString;
aField.Values[j].NumericValue = itr->mfVal;
}
}
pAry[i] = aField;
}
return aSeq;
@ -1347,6 +1495,17 @@ void SAL_CALL ScFilterDescriptorBase::setFilterFields2(
PutData(aParam);
}
void SAL_CALL ScFilterDescriptorBase::setFilterFields3(
const uno::Sequence<sheet::TableFilterField3>& aFilterFields )
throw(uno::RuntimeException)
{
SolarMutexGuard aGuard;
ScQueryParam aParam;
GetData(aParam);
fillQueryParam(aParam, pDocSh->GetDocument(), aFilterFields);
PutData(aParam);
}
// Rest sind Properties
// XPropertySet