Kaydet (Commit) 0637ca0a authored tarafından Kohei Yoshida's avatar Kohei Yoshida

Populate group dimensions directly to the cache.

This is to avoid populating them twice in case the same cache is
referenced by multiple pivot tables.
üst 593f6ac1
......@@ -52,13 +52,14 @@ class ScDPSaveGroupDimension;
class SC_DLLPUBLIC ScDPSaveGroupItem
{
rtl::OUString aGroupName; // name of group
::std::vector<rtl::OUString> aElements; // names of items in original dimension
std::vector<rtl::OUString> aElements; // names of items in original dimension
mutable std::vector<ScDPItemData> maItems; // items converted from the strings.
public:
ScDPSaveGroupItem( const rtl::OUString& rName );
~ScDPSaveGroupItem();
void AddToData( ScDPGroupDimension& rDataDim, SvNumberFormatter* pFormatter ) const;
void AddToData(ScDPGroupDimension& rDataDim) const;
void AddElement( const rtl::OUString& rName );
void AddElementsFromGroup( const ScDPSaveGroupItem& rGroup );
......@@ -74,6 +75,9 @@ public:
// remove this group's elements from their groups in rDimension
// (rDimension must be a different dimension from the one which contains this)
void RemoveElementsFromGroups( ScDPSaveGroupDimension& rDimension ) const;
void ConvertElementsToItems(SvNumberFormatter* pFormatter) const;
bool HasInGroup(const ScDPItemData& rItem) const;
};
typedef ::std::vector<ScDPSaveGroupItem> ScDPSaveGroupItemVec;
......@@ -87,7 +91,7 @@ class SC_DLLPUBLIC ScDPSaveGroupDimension
rtl::OUString aSourceDim; // always the real source from the original data
rtl::OUString aGroupDimName;
ScDPSaveGroupItemVec aGroups;
ScDPNumGroupInfo aDateInfo;
mutable ScDPNumGroupInfo aDateInfo;
sal_Int32 nDatePart;
public:
......@@ -96,7 +100,7 @@ public:
~ScDPSaveGroupDimension();
void AddToData( ScDPGroupTableData& rData ) const;
void AddToCache(ScDPCache& rCache) const;
void SetDateInfo( const ScDPNumGroupInfo& rInfo, sal_Int32 nPart );
void AddGroupItem( const ScDPSaveGroupItem& rItem );
......@@ -119,18 +123,21 @@ public:
ScDPSaveGroupItem* GetGroupAccByIndex( long nIndex );
void Rename( const rtl::OUString& rNewName );
private:
bool IsInGroup(const ScDPItemData& rItem) const;
};
/**
* Represents a group dimension that introduces a new hierarchy for an
* existing dimension. Unlike the ScDPSaveGroupDimension counterpart, it
* re-uses the source dimension.
* re-uses the source dimension name and ID.
*/
class SC_DLLPUBLIC ScDPSaveNumGroupDimension
{
rtl::OUString aDimensionName;
ScDPNumGroupInfo aGroupInfo;
ScDPNumGroupInfo aDateInfo;
mutable ScDPNumGroupInfo aGroupInfo;
mutable ScDPNumGroupInfo aDateInfo;
sal_Int32 nDatePart;
public:
......@@ -139,6 +146,7 @@ public:
~ScDPSaveNumGroupDimension();
void AddToData( ScDPGroupTableData& rData ) const;
void AddToCache(ScDPCache& rCache) const;
const rtl::OUString& GetDimensionName() const { return aDimensionName; }
const ScDPNumGroupInfo& GetInfo() const { return aGroupInfo; }
......
......@@ -60,9 +60,7 @@ public:
sal_Int32 GetDatePart() const { return nDatePart; }
const ScDPNumGroupInfo& GetNumInfo() const { return aNumInfo; }
void FillColumnEntries(
SCCOL nSourceDim, ScDPCache* pCahe , std::vector<SCROW>& rEntries,
const std::vector<SCROW>& rOriginal) const;
void FillColumnEntries(const ScDPCache* pCache, std::vector<SCROW>& rEntries) const;
};
typedef ::std::vector<ScDPItemData> ScDPItemDataVec;
......@@ -143,8 +141,7 @@ public:
const ScDPDateGroupHelper* GetDateHelper() const { return pDateHelper; }
const std::vector<SCROW>& GetNumEntries(
SCCOL nSourceDim, ScDPCache* pCache, const std::vector<SCROW>& rOriginal) const;
const std::vector<SCROW>& GetNumEntries(SCCOL nSourceDim, const ScDPCache* pCache) const;
void MakeDateHelper( const ScDPNumGroupInfo& rInfo, long nDim, sal_Int32 nPart );
......
......@@ -131,15 +131,16 @@ public:
SCROW GetIdByItemData(long nDim, const rtl::OUString& sItemData) const;
SCROW GetIdByItemData(long nDim, const ScDPItemData& rItem) const;
rtl::OUString GetFormattedString(long nDim, const ScDPItemData& rItem) const;
void AppendGroupField();
long AppendGroupField();
void ResetGroupItems(long nDim, const ScDPNumGroupInfo& rNumInfo);
SCROW SetGroupItem(long nDim, const ScDPItemData& rData);
const DataListType* GetGroupDimMemberValues(long nDim) const;
void GetGroupDimMemberIds(long nDim, std::vector<SCROW>& rIds) const;
void ClearGroupFields();
SCROW GetAdditionalItemID( const ScDPItemData& rData ) const;
SCCOL GetDimensionIndex(const rtl::OUString& sName) const;
sal_uLong GetNumType ( sal_uLong nFormat ) const;
sal_uLong GetNumberFormat( long nDim ) const;
bool IsDateDimension( long nDim ) const ;
SCROW GetDimMemberCount( SCCOL nDim ) const;
......@@ -151,12 +152,12 @@ public:
SCROW GetRowCount() const;
SCROW GetItemDataId( sal_uInt16 nDim, SCROW nRow, bool bRepeatIfEmpty ) const;
rtl::OUString GetDimensionName( sal_uInt16 nColumn ) const;
rtl::OUString GetDimensionName(long nDim) const;
bool IsRowEmpty( SCROW nRow ) const;
bool IsValid() const;
bool ValidQuery(SCROW nRow, const ScQueryParam& rQueryParam) const;
ScDocument* GetDoc() const;//ms-cache-core
ScDocument* GetDoc() const;
long GetColumnCount() const;
long GetGroupFieldCount() const;
......
......@@ -51,7 +51,12 @@ public:
static double getNumGroupStartValue(double fValue, const ScDPNumGroupInfo& rInfo);
static rtl::OUString getNumGroupName(
double fValue, const ScDPNumGroupInfo& rInfo, sal_Unicode cDecSep, SvNumberFormatter* pFormatter);
double fValue, const ScDPNumGroupInfo& rInfo, sal_Unicode cDecSep,
SvNumberFormatter* pFormatter);
static sal_Int32 getDatePartValue(
double fValue, const ScDPNumGroupInfo& rInfo, sal_Int32 nDatePart,
SvNumberFormatter* pFormatter);
};
#endif
......
This diff is collapsed.
......@@ -386,7 +386,7 @@ bool ScDPCache::InitFromDoc(ScDocument* pDoc, const ScRange& rRange)
for (size_t i = 0; i < static_cast<size_t>(mnColumnCount); ++i)
maFields.push_back(new Field);
maLabelNames.reserve(mnColumnCount);
maLabelNames.reserve(mnColumnCount+1);
for (sal_uInt16 nCol = nStartCol; nCol <= nEndCol; ++nCol)
{
......@@ -423,7 +423,7 @@ bool ScDPCache::InitFromDataBase (const Reference<sdbc::XRowSet>& xRowSet, const
// Get column titles and types.
maLabelNames.clear();
maLabelNames.reserve(mnColumnCount);
maLabelNames.reserve(mnColumnCount+1);
std::vector<sal_Int32> aColTypes(mnColumnCount);
......@@ -713,14 +713,14 @@ const ScDPCache::GroupItems* ScDPCache::GetGroupItems(long nDim) const
return NULL;
}
rtl::OUString ScDPCache::GetDimensionName( sal_uInt16 nColumn ) const
rtl::OUString ScDPCache::GetDimensionName(long nDim) const
{
OSL_ENSURE(nColumn < maLabelNames.size()-1 , "ScDPTableDataCache::GetDimensionName");
OSL_ENSURE(nDim < maLabelNames.size()-1 , "ScDPTableDataCache::GetDimensionName");
OSL_ENSURE(maLabelNames.size() == static_cast <sal_uInt16> (mnColumnCount+1), "ScDPTableDataCache::GetDimensionName");
if ( static_cast<size_t>(nColumn+1) < maLabelNames.size() )
if ( static_cast<size_t>(nDim+1) < maLabelNames.size() )
{
return maLabelNames[nColumn+1];
return maLabelNames[nDim+1];
}
else
return rtl::OUString();
......@@ -844,15 +844,6 @@ const ScDPCache::DataListType& ScDPCache::GetDimMemberValues(SCCOL nDim) const
return maFields[nDim].maItems;
}
sal_uLong ScDPCache::GetNumType(sal_uLong nFormat) const
{
SvNumberFormatter* pFormatter = mpDoc->GetFormatTable();
sal_uLong nType = NUMBERFORMAT_NUMBER;
if ( pFormatter )
nType = pFormatter->GetType( nFormat );
return nType;
}
sal_uLong ScDPCache::GetNumberFormat( long nDim ) const
{
if ( nDim >= mnColumnCount )
......@@ -895,7 +886,7 @@ SCCOL ScDPCache::GetDimensionIndex(const rtl::OUString& sName) const
for (size_t i = 1; i < maLabelNames.size(); ++i)
{
if (maLabelNames[i].equals(sName))
return (SCCOL)(i-1);
return static_cast<SCCOL>(i-1);
}
return -1;
}
......@@ -1055,10 +1046,10 @@ rtl::OUString ScDPCache::GetFormattedString(long nDim, const ScDPItemData& rItem
return rItem.GetString();
}
void ScDPCache::AppendGroupField()
long ScDPCache::AppendGroupField()
{
maGroupFields.push_back(new GroupItems);
fprintf(stdout, "ScDPCache::AppendGroupField: added; new count = %d\n", maGroupFields.size());
return static_cast<long>(maFields.size() + maGroupFields.size() - 1);
}
void ScDPCache::ResetGroupItems(long nDim, const ScDPNumGroupInfo& rNumInfo)
......@@ -1107,6 +1098,55 @@ SCROW ScDPCache::SetGroupItem(long nDim, const ScDPItemData& rData)
return -1;
}
const ScDPCache::DataListType* ScDPCache::GetGroupDimMemberValues(long nDim) const
{
if (nDim < 0)
return NULL;
long nSourceCount = static_cast<long>(maFields.size());
if (nDim < nSourceCount)
{
if (!maFields.at(nDim).mpGroup)
return NULL;
return &maFields[nDim].mpGroup->maItems;
}
nDim -= nSourceCount;
if (nDim < static_cast<long>(maGroupFields.size()))
return &maGroupFields.at(nDim).maItems;
return NULL;
}
void ScDPCache::GetGroupDimMemberIds(long nDim, std::vector<SCROW>& rIds) const
{
if (nDim < 0)
return;
long nSourceCount = static_cast<long>(maFields.size());
if (nDim < nSourceCount)
{
if (!maFields.at(nDim).mpGroup)
return;
size_t nOffset = maFields[nDim].maItems.size();
const DataListType& rGI = maFields[nDim].mpGroup->maItems;
for (size_t i = 0, n = rGI.size(); i < n; ++i)
rIds.push_back(static_cast<SCROW>(i + nOffset));
return;
}
nDim -= nSourceCount;
if (nDim < static_cast<long>(maGroupFields.size()))
{
const DataListType& rGI = maGroupFields.at(nDim).maItems;
for (size_t i = 0, n = rGI.size(); i < n; ++i)
rIds.push_back(static_cast<SCROW>(i));
}
}
namespace {
struct ClearGroupItems : std::unary_function<ScDPCache::Field, void>
......
......@@ -40,6 +40,8 @@
#include <com/sun/star/sheet/DataPilotFieldGroupBy.hpp>
#include <com/sun/star/i18n/CalendarDisplayIndex.hpp>
#define D_TIMEFACTOR 86400.0
using namespace com::sun::star;
namespace {
......@@ -290,4 +292,76 @@ rtl::OUString ScDPUtil::getNumGroupName(
return lcl_GetNumGroupName(fGroupStart, rInfo, cDecSep, pFormatter);
}
sal_Int32 ScDPUtil::getDatePartValue(
double fValue, const ScDPNumGroupInfo& rInfo, sal_Int32 nDatePart,
SvNumberFormatter* pFormatter)
{
// Start and end are inclusive
// (End date without a time value is included, with a time value it's not)
if (fValue < rInfo.mfStart && !rtl::math::approxEqual(fValue, rInfo.mfStart))
return ScDPItemData::DateFirst;
if (fValue > rInfo.mfEnd && !rtl::math::approxEqual(fValue, rInfo.mfEnd))
return ScDPItemData::DateLast;
sal_Int32 nResult = 0;
if (nDatePart == sheet::DataPilotFieldGroupBy::HOURS ||
nDatePart == sheet::DataPilotFieldGroupBy::MINUTES ||
nDatePart == sheet::DataPilotFieldGroupBy::SECONDS)
{
// handle time
// (as in the cell functions, ScInterpreter::ScGetHour etc.: seconds are rounded)
double fTime = fValue - rtl::math::approxFloor(fValue);
long nSeconds = (long)rtl::math::approxFloor(fTime*D_TIMEFACTOR+0.5);
switch (nDatePart)
{
case sheet::DataPilotFieldGroupBy::HOURS:
nResult = nSeconds / 3600;
break;
case sheet::DataPilotFieldGroupBy::MINUTES:
nResult = ( nSeconds % 3600 ) / 60;
break;
case sheet::DataPilotFieldGroupBy::SECONDS:
nResult = nSeconds % 60;
break;
}
}
else
{
Date aDate = *(pFormatter->GetNullDate());
aDate += (long)::rtl::math::approxFloor(fValue);
switch ( nDatePart )
{
case com::sun::star::sheet::DataPilotFieldGroupBy::YEARS:
nResult = aDate.GetYear();
break;
case com::sun::star::sheet::DataPilotFieldGroupBy::QUARTERS:
nResult = 1 + (aDate.GetMonth() - 1) / 3; // 1..4
break;
case com::sun::star::sheet::DataPilotFieldGroupBy::MONTHS:
nResult = aDate.GetMonth(); // 1..12
break;
case com::sun::star::sheet::DataPilotFieldGroupBy::DAYS:
{
Date aYearStart(1, 1, aDate.GetYear());
nResult = (aDate - aYearStart) + 1; // Jan 01 has value 1
if (nResult >= 60 && !aDate.IsLeapYear())
{
// days are counted from 1 to 366 - if not from a leap year, adjust
++nResult;
}
}
break;
default:
OSL_FAIL("invalid date part");
}
}
return nResult;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
......@@ -554,8 +554,7 @@ void XclExpPCField::InsertNumDateGroupItems( const ScDPObject& rDPObj, const ScD
if( nDatePart != 0 )
aTmpDim.MakeDateHelper( rNumInfo, mnFieldIdx, nDatePart );
const std::vector<SCROW>& aMemberIds = aTmpDim.GetNumEntries(
static_cast<SCCOL>(GetBaseFieldIndex()),
const_cast<ScDPCache*>(aDPData.GetCacheTable().getCache()), aOrignial);
static_cast<SCCOL>(GetBaseFieldIndex()), aDPData.GetCacheTable().getCache());
for ( size_t nIdx = 0 ; nIdx < aMemberIds.size(); nIdx++ )
{
const ScDPItemData* pData = aDPData.GetMemberById( static_cast< long >( GetBaseFieldIndex() ) , aMemberIds[ nIdx] );
......
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