summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKohei Yoshida <kohei.yoshida@suse.com>2012-03-02 16:52:14 -0500
committerKohei Yoshida <kohei.yoshida@gmail.com>2012-03-09 11:13:28 -0500
commit246521c9578e3cb66e610850716ba72f1e9981bc (patch)
tree8ce6cba13a105c6732f6e3284577e31ee809dc63
parent98b4beebce3720c55ff3302a43d482db8adbc6fe (diff)
Massive rework to reduce the size of ScDPItemData.
Currently lots of things are broken.
-rw-r--r--sc/inc/dpdimsave.hxx13
-rw-r--r--sc/inc/dpgroup.hxx9
-rw-r--r--sc/inc/dpitemdata.hxx74
-rw-r--r--sc/inc/dptablecache.hxx25
-rw-r--r--sc/inc/dptabres.hxx2
-rw-r--r--sc/inc/dputil.hxx5
-rw-r--r--sc/source/core/data/dpcachetable.cxx2
-rw-r--r--sc/source/core/data/dpdimsave.cxx49
-rw-r--r--sc/source/core/data/dpgroup.cxx216
-rw-r--r--sc/source/core/data/dpitemdata.cxx213
-rw-r--r--sc/source/core/data/dptabdat.cxx58
-rw-r--r--sc/source/core/data/dptablecache.cxx230
-rw-r--r--sc/source/core/data/dptabres.cxx188
-rw-r--r--sc/source/core/data/dptabsrc.cxx12
-rw-r--r--sc/source/core/data/dputil.cxx69
-rw-r--r--sc/source/filter/excel/xepivot.cxx2
16 files changed, 830 insertions, 337 deletions
diff --git a/sc/inc/dpdimsave.hxx b/sc/inc/dpdimsave.hxx
index 847568ab173a..ea280a1b50fd 100644
--- a/sc/inc/dpdimsave.hxx
+++ b/sc/inc/dpdimsave.hxx
@@ -77,6 +77,10 @@ public:
typedef ::std::vector<ScDPSaveGroupItem> ScDPSaveGroupItemVec;
+/**
+ * Represents a new group dimension whose dimension ID is higher than the
+ * highest source dimension ID.
+ */
class SC_DLLPUBLIC ScDPSaveGroupDimension
{
rtl::OUString aSourceDim; // always the real source from the original data
@@ -116,6 +120,11 @@ public:
void Rename( const rtl::OUString& rNewName );
};
+/**
+ * Represents a group dimension that introduces a new hierarchy for an
+ * existing dimension. Unlike the ScDPSaveGroupDimension counterpart, it
+ * re-uses the source dimension.
+ */
class SC_DLLPUBLIC ScDPSaveNumGroupDimension
{
rtl::OUString aDimensionName;
@@ -140,6 +149,10 @@ public:
void SetDateInfo( const ScDPNumGroupInfo& rInfo, sal_Int32 nPart );
};
+/**
+ * This class has to do with handling exclusively grouped dimensions? TODO:
+ * Find out what this class does and document it here.
+ */
class SC_DLLPUBLIC ScDPDimensionSaveData
{
public:
diff --git a/sc/inc/dpgroup.hxx b/sc/inc/dpgroup.hxx
index f6be836c8567..76a3fcdd65c4 100644
--- a/sc/inc/dpgroup.hxx
+++ b/sc/inc/dpgroup.hxx
@@ -61,16 +61,19 @@ class ScDPDateGroupHelper
{
ScDPNumGroupInfo aNumInfo; // only start and end (incl. auto flags) are used
sal_Int32 nDatePart; // single part
+ long mnGroupDim;
public:
- ScDPDateGroupHelper( const ScDPNumGroupInfo& rInfo, sal_Int32 nPart );
+ ScDPDateGroupHelper( const ScDPNumGroupInfo& rInfo, long nDim, sal_Int32 nPart );
~ScDPDateGroupHelper();
+ void SetGroupDim(long nDim);
+
sal_Int32 GetDatePart() const { return nDatePart; }
const ScDPNumGroupInfo& GetNumInfo() const { return aNumInfo; }
void FillColumnEntries(
- SCCOL nSourceDim, const ScDPCache* pCahe , std::vector<SCROW>& rEntries,
+ SCCOL nSourceDim, ScDPCache* pCahe , std::vector<SCROW>& rEntries,
const std::vector<SCROW>& rOriginal) const;
};
@@ -160,7 +163,7 @@ public:
SCCOL nSourceDim, const ScDPCache* pCache,
const std::vector< SCROW >& rOriginal) const;
- void MakeDateHelper( const ScDPNumGroupInfo& rInfo, sal_Int32 nPart );
+ void MakeDateHelper( const ScDPNumGroupInfo& rInfo, long nDim, sal_Int32 nPart );
void DisposeData();
};
diff --git a/sc/inc/dpitemdata.hxx b/sc/inc/dpitemdata.hxx
index 7b26674e400e..ec95038b53af 100644
--- a/sc/inc/dpitemdata.hxx
+++ b/sc/inc/dpitemdata.hxx
@@ -45,69 +45,55 @@ class ScDocument;
class SC_DLLPUBLIC ScDPItemData
{
friend class ScDPCache;
+
public:
- enum {
- MK_VAL = 0x01,
- MK_DATA = 0x02,
- MK_ERR = 0x04,
- MK_DATE = 0x08
- };
+ enum Type { String, Value, Error, Empty, GroupValue };
- static bool isDate( sal_uLong nNumType );
+ struct GroupValueAttr
+ {
+ sal_Int32 mnGroupType;
+ sal_Int32 mnValue;
+ };
private:
- rtl::OUString maString;
- double mfValue;
- sal_uInt8 mbFlag;
+
+ union {
+ rtl::OUString* mpString;
+ GroupValueAttr maGroupValue;
+ double mfValue;
+ };
+
+ Type meType;
public:
+ // case insensitive equality
+ static sal_Int32 Compare(const ScDPItemData& rA, const ScDPItemData& rB);
+
ScDPItemData();
- ScDPItemData(const rtl::OUString& rS, double fV, sal_uInt8 bF);
- ScDPItemData(const rtl::OUString& rS, double fV = 0.0, bool bHV = false, bool bData = true);
+ ScDPItemData(const rtl::OUString& rStr);
+ ScDPItemData(double fVal);
+ ScDPItemData(sal_Int32 nGroupType, sal_Int32 nValue);
+ ~ScDPItemData();
- void Set(const rtl::OUString& rS, double fVal, sal_uInt8 nFlag);
void SetString(const rtl::OUString& rS);
+ void SetValue(double fVal);
+ void SetGroupValue(sal_Int32 nGroupType, sal_Int32 nValue);
void SetErrorString(const rtl::OUString& rS);
bool IsCaseInsEqual(const ScDPItemData& r) const;
size_t Hash() const;
// exact equality
- bool operator==( const ScDPItemData& r ) const;
- // case insensitive equality
- static sal_Int32 Compare( const ScDPItemData& rA, const ScDPItemData& rB );
+ bool operator==(const ScDPItemData& r) const;
-public:
- bool IsHasData() const ;
- bool IsHasErr() const ;
+ bool IsEmpty() const;
bool IsValue() const;
- const rtl::OUString& GetString() const;
- double GetValue() const ;
+ rtl::OUString GetString() const;
+ double GetValue() const;
+ GroupValueAttr GetGroupValue() const;
bool HasStringData() const ;
- sal_uInt8 GetType() const;
-};
-
-class SC_DLLPUBLIC ScDPItemDataPool
-{
-public:
- ScDPItemDataPool();
- ScDPItemDataPool(const ScDPItemDataPool& r);
-
- virtual ~ScDPItemDataPool();
- virtual const ScDPItemData* getData( sal_Int32 nId );
- virtual sal_Int32 getDataId( const ScDPItemData& aData );
- virtual sal_Int32 insertData( const ScDPItemData& aData );
-protected:
- struct DataHashFunc : public std::unary_function< const ScDPItemData &, size_t >
- {
- size_t operator() (const ScDPItemData &rData) const { return rData.Hash(); }
- };
-
- typedef ::boost::unordered_multimap< ScDPItemData, sal_Int32, DataHashFunc > DataHash;
-
- ::std::vector< ScDPItemData > maItems;
- DataHash maItemIds;
+ sal_uInt8 GetCellType() const;
};
#endif
diff --git a/sc/inc/dptablecache.hxx b/sc/inc/dptablecache.hxx
index 2a61b94b4f79..dac253768320 100644
--- a/sc/inc/dptablecache.hxx
+++ b/sc/inc/dptablecache.hxx
@@ -70,8 +70,18 @@ private:
*/
mutable ObjectSetType maRefObjects;
+ struct GroupItems : boost::noncopyable
+ {
+ DataListType maItems;
+ };
+
struct Field : boost::noncopyable
{
+ /**
+ * Optional items for grouped field.
+ */
+ boost::scoped_ptr<GroupItems> mpGroup;
+
DataListType maItems; /// Unique values in the field.
/**
@@ -97,14 +107,20 @@ private:
Field();
};
+ struct GroupField : boost::noncopyable
+ {
+ DataListType maItems; /// Unique values in the field.
+ };
+
typedef boost::ptr_vector<Field> FieldsType;
+ typedef boost::ptr_vector<GroupField> GroupFieldsType;
+
FieldsType maFields;
+ GroupFieldsType maGroupFields;
LabelsType maLabelNames; // Stores dimension names.
std::vector<bool> mbEmptyRow; // Keeps track of empty rows.
- boost::scoped_ptr<ScDPItemDataPool> mpAdditionalData;
-
bool mbDisposing;
public:
@@ -115,6 +131,10 @@ public:
SCROW GetIdByItemData(long nDim, const rtl::OUString& sItemData) const;
SCROW GetIdByItemData(long nDim, const ScDPItemData& rData) const;
+ void AppendGroupField();
+ void ResetGroupItems(long nDim);
+ SCROW SetGroupItem(long nDim, const ScDPItemData& rData);
+
SCROW GetAdditionalItemID( const ScDPItemData& rData ) const;
SCCOL GetDimensionIndex(const rtl::OUString& sName) const;
@@ -137,6 +157,7 @@ public:
ScDocument* GetDoc() const;//ms-cache-core
long GetColumnCount() const;
+ long GetGroupFieldCount() const;
const ScDPItemData* GetItemDataById( long nDim, SCROW nId ) const;
diff --git a/sc/inc/dptabres.hxx b/sc/inc/dptabres.hxx
index 80e77cca99c7..bfdef7ff4411 100644
--- a/sc/inc/dptabres.hxx
+++ b/sc/inc/dptabres.hxx
@@ -506,7 +506,7 @@ public:
typedef std::vector<ScDPResultMember*> MemberArray;
typedef std::map<SCROW, ScDPResultMember*> MemberHash;
private:
- const ScDPResultData* pResultData;
+ const ScDPResultData* pResultData;
MemberArray maMemberArray;
MemberHash maMemberHash;
sal_Bool bInitialized;
diff --git a/sc/inc/dputil.hxx b/sc/inc/dputil.hxx
index cf574c1e056e..0dfab31ee8aa 100644
--- a/sc/inc/dputil.hxx
+++ b/sc/inc/dputil.hxx
@@ -32,6 +32,8 @@
#include "rtl/ustring.hxx"
#include "scdllapi.h"
+class SvNumberFormatter;
+
class ScDPUtil
{
public:
@@ -40,6 +42,9 @@ public:
SC_DLLPUBLIC static rtl::OUString getSourceDimensionName(const rtl::OUString& rName);
static rtl::OUString createDuplicateDimensionName(const rtl::OUString& rOriginal, size_t nDupCount);
+
+ static rtl::OUString getDateGroupName(
+ sal_Int32 nDatePart, sal_Int32 nValue, SvNumberFormatter* pFormatter);
};
#endif
diff --git a/sc/source/core/data/dpcachetable.cxx b/sc/source/core/data/dpcachetable.cxx
index 7db3ceb7101f..d751e39bc3a8 100644
--- a/sc/source/core/data/dpcachetable.cxx
+++ b/sc/source/core/data/dpcachetable.cxx
@@ -327,7 +327,7 @@ void ScDPCacheTable::getValue( ScDPValueData& rVal, SCCOL nCol, SCROW nRow, boo
if (pData)
{
rVal.fValue = pData->IsValue() ? pData->GetValue() : 0.0;
- rVal.nType = pData->GetType();
+ rVal.nType = pData->GetCellType();
}
else
rVal.Set(0.0, SC_VALTYPE_EMPTY);
diff --git a/sc/source/core/data/dpdimsave.cxx b/sc/source/core/data/dpdimsave.cxx
index 362943d06a63..8bcb37e92323 100644
--- a/sc/source/core/data/dpdimsave.cxx
+++ b/sc/source/core/data/dpdimsave.cxx
@@ -38,6 +38,48 @@
#include <rtl/math.hxx>
#include <algorithm>
+#include <stdio.h>
+#include <string>
+#include <sys/time.h>
+
+namespace {
+
+class stack_printer
+{
+public:
+ explicit stack_printer(const char* msg) :
+ msMsg(msg)
+ {
+ fprintf(stdout, "%s: --begin\n", msMsg.c_str());
+ mfStartTime = getTime();
+ }
+
+ ~stack_printer()
+ {
+ double fEndTime = getTime();
+ fprintf(stdout, "%s: --end (duration: %g sec)\n", msMsg.c_str(), (fEndTime-mfStartTime));
+ }
+
+ void printTime(int line) const
+ {
+ double fEndTime = getTime();
+ fprintf(stdout, "%s: --(%d) (duration: %g sec)\n", msMsg.c_str(), line, (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;
+};
+
+}
+
// ============================================================================
ScDPSaveGroupItem::ScDPSaveGroupItem( const rtl::OUString& rName ) :
@@ -110,7 +152,7 @@ void ScDPSaveGroupItem::AddToData( ScDPGroupDimension& rDataDim, SvNumberFormatt
sal_uInt32 nFormat = 0; //! ...
double fValue;
if ( pFormatter->IsNumberFormat( *aIter, nFormat, fValue ) )
- aData = ScDPItemData( *aIter, fValue, sal_True );
+ aData.SetValue(fValue);
else
aData.SetString( *aIter );
@@ -309,12 +351,15 @@ ScDPSaveNumGroupDimension::~ScDPSaveNumGroupDimension()
void ScDPSaveNumGroupDimension::AddToData( ScDPGroupTableData& rData ) const
{
+ stack_printer __stack_printer__("ScDPSaveNumGroupDimension::AddToData");
+ fprintf(stdout, "ScDPSaveNumGroupDimension::AddToData: dim name = '%s'\n",
+ rtl::OUStringToOString(aDimensionName, RTL_TEXTENCODING_UTF8).getStr());
long nSource = rData.GetDimensionIndex( aDimensionName );
if ( nSource >= 0 )
{
ScDPNumGroupDimension aDim( aGroupInfo ); // aGroupInfo: value grouping
if ( nDatePart )
- aDim.MakeDateHelper( aDateInfo, nDatePart ); // date grouping
+ aDim.MakeDateHelper( aDateInfo, nSource, nDatePart ); // date grouping
rData.SetNumGroupDimension( nSource, aDim );
}
diff --git a/sc/source/core/data/dpgroup.cxx b/sc/source/core/data/dpgroup.cxx
index 3dc3e506252f..e3024b0229fb 100644
--- a/sc/source/core/data/dpgroup.cxx
+++ b/sc/source/core/data/dpgroup.cxx
@@ -31,13 +31,8 @@
// INCLUDE ---------------------------------------------------------------
-#include <com/sun/star/i18n/CalendarDisplayIndex.hpp>
-
-#include <rtl/math.hxx>
-#include <unotools/localedatawrapper.hxx>
-#include <svl/zforlist.hxx>
-
#include "dpgroup.hxx"
+
#include "global.hxx"
#include "document.hxx"
#include "dpcachetable.hxx"
@@ -45,9 +40,13 @@
#include "dptabres.hxx"
#include "dpobject.hxx"
#include "dpglobal.hxx"
+#include "dputil.hxx"
+
+#include <rtl/math.hxx>
#include <com/sun/star/sheet/DataPilotFieldGroupBy.hpp>
#include <com/sun/star/sheet/DataPilotFieldFilter.hpp>
+#include <com/sun/star/i18n/CalendarDisplayIndex.hpp>
#include <vector>
#include <boost/unordered_map.hpp>
@@ -65,6 +64,48 @@ using ::rtl::OUStringHash;
using ::std::vector;
using ::boost::shared_ptr;
+#include <stdio.h>
+#include <string>
+#include <sys/time.h>
+
+namespace {
+
+class stack_printer
+{
+public:
+ explicit stack_printer(const char* msg) :
+ msMsg(msg)
+ {
+ fprintf(stdout, "%s: --begin\n", msMsg.c_str());
+ mfStartTime = getTime();
+ }
+
+ ~stack_printer()
+ {
+ double fEndTime = getTime();
+ fprintf(stdout, "%s: --end (duration: %g sec)\n", msMsg.c_str(), (fEndTime-mfStartTime));
+ }
+
+ void printTime(int line) const
+ {
+ double fEndTime = getTime();
+ fprintf(stdout, "%s: --(%d) (duration: %g sec)\n", msMsg.c_str(), line, (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;
+};
+
+}
+
#define D_TIMEFACTOR 86400.0
const sal_uInt16 SC_DP_LEAPYEAR = 1648; // arbitrary leap year for date calculations
@@ -143,7 +184,7 @@ SCROW lcl_InsertValue<true>(SCCOL nSourceDim, const ScDPCache* pCache, std::vect
template<bool bUpdateData>
void lcl_InsertValue ( SCCOL nSourceDim, const ScDPCache* pCache, std::vector< SCROW >& vIdx, const String& rString, const double& fValue )
{
- lcl_InsertValue<bUpdateData>( nSourceDim, pCache, vIdx, ScDPItemData( rString, fValue, sal_True ) );
+ lcl_InsertValue<bUpdateData>(nSourceDim, pCache, vIdx, ScDPItemData(fValue));
}
void lcl_AppendDateStr( rtl::OUStringBuffer& rBuffer, double fValue, SvNumberFormatter* pFormatter )
@@ -395,9 +436,11 @@ bool ScDPGroupDateFilter::match( const ScDPItemData & rCellData ) const
}
// -----------------------------------------------------------------------
-ScDPDateGroupHelper::ScDPDateGroupHelper( const ScDPNumGroupInfo& rInfo, sal_Int32 nPart ) :
+ScDPDateGroupHelper::ScDPDateGroupHelper(
+ const ScDPNumGroupInfo& rInfo, long nDim, sal_Int32 nPart ) :
aNumInfo( rInfo ),
- nDatePart( nPart )
+ nDatePart( nPart ),
+ mnGroupDim(nDim)
{
}
@@ -405,58 +448,6 @@ ScDPDateGroupHelper::~ScDPDateGroupHelper()
{
}
-String lcl_GetTwoDigitString( sal_Int32 nValue )
-{
- String aRet = String::CreateFromInt32( nValue );
- if ( aRet.Len() < 2 )
- aRet.Insert( (sal_Unicode)'0', 0 );
- return aRet;
-}
-
-String lcl_GetDateGroupName( sal_Int32 nDatePart, sal_Int32 nValue, SvNumberFormatter* pFormatter )
-{
- String aRet;
- switch ( nDatePart )
- {
- case com::sun::star::sheet::DataPilotFieldGroupBy::YEARS:
- aRet = String::CreateFromInt32( nValue );
- break;
- case com::sun::star::sheet::DataPilotFieldGroupBy::QUARTERS:
- aRet = ScGlobal::pLocaleData->getQuarterAbbreviation( (sal_Int16)(nValue - 1) ); // nValue is 1-based
- break;
- case com::sun::star::sheet::DataPilotFieldGroupBy::MONTHS:
- //! cache getMonths() result?
- aRet = ScGlobal::GetCalendar()->getDisplayName(
- ::com::sun::star::i18n::CalendarDisplayIndex::MONTH,
- sal_Int16(nValue-1), 0 ); // 0-based, get short name
- break;
- case com::sun::star::sheet::DataPilotFieldGroupBy::DAYS:
- {
- Date aDate( 1, 1, SC_DP_LEAPYEAR );
- aDate += ( nValue - 1 ); // nValue is 1-based
- Date aNullDate = *(pFormatter->GetNullDate());
- long nDays = aDate - aNullDate;
-
- sal_uLong nFormat = pFormatter->GetFormatIndex( NF_DATE_SYS_DDMMM, ScGlobal::eLnge );
- Color* pColor;
- pFormatter->GetOutputString( nDays, nFormat, aRet, &pColor );
- }
- break;
- case com::sun::star::sheet::DataPilotFieldGroupBy::HOURS:
- //! allow am/pm format?
- aRet = lcl_GetTwoDigitString( nValue );
- break;
- case com::sun::star::sheet::DataPilotFieldGroupBy::MINUTES:
- case com::sun::star::sheet::DataPilotFieldGroupBy::SECONDS:
- aRet = ScGlobal::pLocaleData->getTimeSep();
- aRet.Append( lcl_GetTwoDigitString( nValue ) );
- break;
- default:
- OSL_FAIL("invalid date part");
- }
- return aRet;
-}
-
sal_Int32 lcl_GetDatePartValue( double fValue, sal_Int32 nDatePart, SvNumberFormatter* pFormatter,
const ScDPNumGroupInfo* pNumInfo )
{
@@ -595,9 +586,15 @@ String lcl_GetSpecialDateName( double fValue, bool bFirst, SvNumberFormatter* pF
return aBuffer.makeStringAndClear();
}
+void ScDPDateGroupHelper::SetGroupDim(long nDim)
+{
+ mnGroupDim = nDim;
+}
+
void ScDPDateGroupHelper::FillColumnEntries(
- SCCOL nSourceDim, const ScDPCache* pCache, std::vector<SCROW>& rEntries, const std::vector<SCROW>& rOriginal) const
+ SCCOL nSourceDim, ScDPCache* pCache, std::vector<SCROW>& rEntries, const std::vector<SCROW>& rOriginal) const
{
+ stack_printer __stack_printer__("ScDPDateGroupHelper::FillColumnEntries");
// auto min/max is only used for "Years" part, but the loop is always needed
double fSourceMin = 0.0;
double fSourceMax = 0.0;
@@ -659,18 +656,35 @@ void ScDPDateGroupHelper::FillColumnEntries(
OSL_FAIL("invalid date part");
}
+ pCache->ResetGroupItems(mnGroupDim);
+
+ fprintf(stdout, "ScDPDateGroupHelper::FillColumnEntries: source dim = %d group dim = %d\n",
+ nSourceDim, mnGroupDim);
for ( sal_Int32 nValue = nStart; nValue <= nEnd; nValue++ )
{
- String aName = lcl_GetDateGroupName( nDatePart, nValue, pFormatter );
- lcl_InsertValue<false>( nSourceDim, pCache, rEntries, aName, nValue );
+ rtl::OUString aName = ScDPUtil::getDateGroupName( nDatePart, nValue, pFormatter );
+ fprintf(stdout, "ScDPDateGroupHelper::FillColumnEntries: name = '%s'\n",
+ rtl::OUStringToOString(aName, RTL_TEXTENCODING_UTF8).getStr());
+ SCROW nId = pCache->SetGroupItem(mnGroupDim, ScDPItemData(aName));
+ rEntries.push_back(nId);
}
// add first/last entry (min/max)
- String aFirstName = lcl_GetSpecialDateName( aNumInfo.mfStart, true, pFormatter );
- lcl_InsertValue<true>( nSourceDim, pCache, rEntries, aFirstName, SC_DP_DATE_FIRST );
+ rtl::OUString aFirstName = lcl_GetSpecialDateName( aNumInfo.mfStart, true, pFormatter );
+ fprintf(stdout, "ScDPDateGroupHelper::FillColumnEntries: first = '%s'\n",
+ rtl::OUStringToOString(aFirstName, RTL_TEXTENCODING_UTF8).getStr());
+ SCROW nId = pCache->SetGroupItem(mnGroupDim, ScDPItemData(aFirstName));
+ rEntries.push_back(nId);
+
+ rtl::OUString aLastName = lcl_GetSpecialDateName( aNumInfo.mfEnd, false, pFormatter );
+ fprintf(stdout, "ScDPDateGroupHelper::FillColumnEntries: last = '%s'\n",
+ rtl::OUStringToOString(aLastName, RTL_TEXTENCODING_UTF8).getStr());
+ nId = pCache->SetGroupItem(mnGroupDim, ScDPItemData(aLastName));
+ rEntries.push_back(nId);
- String aLastName = lcl_GetSpecialDateName( aNumInfo.mfEnd, false, pFormatter );
- lcl_InsertValue<true>( nSourceDim, pCache, rEntries, aLastName, SC_DP_DATE_LAST );
+ std::vector<SCROW>::const_iterator it = rEntries.begin(), itEnd = rEntries.end();
+ for (; it != itEnd; ++it)
+ fprintf(stdout, "ScDPDateGroupHelper::FillColumnEntries: id = %d\n", *it);
}
// -----------------------------------------------------------------------
@@ -760,7 +774,7 @@ ScDPGroupDimension& ScDPGroupDimension::operator=( const ScDPGroupDimension& rOt
void ScDPGroupDimension::MakeDateHelper( const ScDPNumGroupInfo& rInfo, sal_Int32 nPart )
{
delete pDateHelper;
- pDateHelper = new ScDPDateGroupHelper( rInfo, nPart );
+ pDateHelper = new ScDPDateGroupHelper(rInfo, nGroupDim, nPart);
}
void ScDPGroupDimension::AddItem( const ScDPGroupItem& rItem )
@@ -771,6 +785,8 @@ void ScDPGroupDimension::AddItem( const ScDPGroupItem& rItem )
void ScDPGroupDimension::SetGroupDim( long nDim )
{
nGroupDim = nDim;
+ if (pDateHelper)
+ pDateHelper->SetGroupDim(nDim);
}
const std::vector< SCROW >& ScDPGroupDimension::GetColumnEntries( const ScDPCacheTable& rCacheTable, const std::vector< SCROW >& rOriginal ) const
{
@@ -778,7 +794,8 @@ const std::vector< SCROW >& ScDPGroupDimension::GetColumnEntries( const ScDPCac
{
if ( pDateHelper )
{
- pDateHelper->FillColumnEntries( (SCCOL)GetSourceDim(), rCacheTable.getCache(), maMemberEntries, rOriginal );
+ pDateHelper->FillColumnEntries(
+ GetSourceDim(), const_cast<ScDPCache*>(rCacheTable.getCache()), maMemberEntries, rOriginal);
}
else
{
@@ -888,10 +905,10 @@ ScDPNumGroupDimension::~ScDPNumGroupDimension()
delete pDateHelper;
}
-void ScDPNumGroupDimension::MakeDateHelper( const ScDPNumGroupInfo& rInfo, sal_Int32 nPart )
+void ScDPNumGroupDimension::MakeDateHelper( const ScDPNumGroupInfo& rInfo, long nDim, sal_Int32 nPart )
{
delete pDateHelper;
- pDateHelper = new ScDPDateGroupHelper( rInfo, nPart );
+ pDateHelper = new ScDPDateGroupHelper(rInfo, nDim, nPart);
aGroupInfo.mbEnable = sal_True; //! or query both?
}
@@ -904,7 +921,8 @@ const std::vector<SCROW>& ScDPNumGroupDimension::GetNumEntries(
SvNumberFormatter* pFormatter = pCache->GetDoc()->GetFormatTable();
if ( pDateHelper )
- pDateHelper->FillColumnEntries( nSourceDim, pCache, maMemberEntries,rOriginal );
+ pDateHelper->FillColumnEntries(
+ nSourceDim, const_cast<ScDPCache*>(pCache), maMemberEntries, rOriginal);
else
{
// Copy textual entries.
@@ -998,6 +1016,8 @@ const std::vector<SCROW>& ScDPNumGroupDimension::GetNumEntries(
String aLastName = lcl_GetSpecialNumGroupName( aGroupInfo.mfEnd, false, cDecSeparator, aGroupInfo.mbDateValues, pFormatter );
lcl_InsertValue<true>( nSourceDim, pCache, maMemberEntries, aLastName, aGroupInfo.mfEnd + aGroupInfo.mfStep );
+
+ fprintf(stdout, "ScDPNumGroupDimension::GetNumEntries: FIXME\n");
}
}
return maMemberEntries;
@@ -1025,7 +1045,11 @@ void ScDPGroupTableData::AddGroupDimension( const ScDPGroupDimension& rGroup )
ScDPGroupDimension aNewGroup( rGroup );
aNewGroup.SetGroupDim( GetColumnCount() ); // new dimension will be at the end
aGroups.push_back( aNewGroup );
- aGroupNames.insert( OUString(aNewGroup.GetName()) );
+ aGroupNames.insert(aNewGroup.GetName());
+ ScDPCache* pCache = const_cast<ScDPCache*>(GetCacheTable().getCache());
+ pCache->AppendGroupField();
+ fprintf(stdout, "ScDPGroupTableData::AddGroupDimension: name = '%s' group count = %d\n",
+ rtl::OUStringToOString(aNewGroup.GetName(), RTL_TEXTENCODING_UTF8).getStr(), aGroups.size());
}
void ScDPGroupTableData::SetNumGroupDimension( long nIndex, const ScDPNumGroupDimension& rGroup )
@@ -1099,6 +1123,8 @@ const std::vector< SCROW >& ScDPGroupTableData::GetColumnEntries( long nColumn
const ScDPItemData* ScDPGroupTableData::GetMemberById( long nDim, long nId )
{
+// stack_printer __stack_printer__("ScDPGroupTableData::GetMemberById");
+// fprintf(stdout, "ScDPGroupTableData::GetMemberById: dim = %d id = %d\n", nDim, nId);
if ( nDim >= nSourceCount )
{
if ( getIsDataLayoutDimension( nDim) )
@@ -1263,9 +1289,13 @@ void ScDPGroupTableData::ModifyFilterCriteria(vector<ScDPCacheTable::Criterion>&
for (size_t i = 0; i < nGroupItemCount; ++i)
{
const ScDPGroupItem* pGrpItem = pGrpDim->GetGroupByIndex(i);
- ScDPItemData aName( pFilter->getMatchString(),pFilter->getMatchValue(),pFilter->hasValue()) ;
+ ScDPItemData aName;
+ if (pFilter->hasValue())
+ aName.SetValue(pFilter->getMatchValue());
+ else
+ aName.SetString(pFilter->getMatchString());
- if (!pGrpItem || !pGrpItem->GetName().IsCaseInsEqual(aName))
+ if (!pGrpItem || !pGrpItem->GetName().IsCaseInsEqual(aName))
continue;
ScDPCacheTable::Criterion aCri;
@@ -1329,8 +1359,9 @@ const ScDPCacheTable& ScDPGroupTableData::GetCacheTable() const
return pSourceData->GetCacheTable();
}
-void ScDPGroupTableData::FillGroupValues( /*ScDPItemData* pItemData*/ SCROW* pItemDataIndex, long nCount, const long* pDims )
+void ScDPGroupTableData::FillGroupValues(SCROW* pItemDataIndex, long nCount, const long* pDims)
{
+ stack_printer __stack_printer__("ScDPGroupTableData::FillGroupValues");
long nGroupedColumns = aGroups.size();
const ScDPCache* pCache = GetCacheTable().getCache();
@@ -1360,6 +1391,7 @@ void ScDPGroupTableData::FillGroupValues( /*ScDPItemData* pItemData*/ SCROW* pIt
const ScDPItemData* pData = pCache->GetItemDataById( (SCCOL)nSourceDim, pItemDataIndex[nDim]);
if ( pData ->IsValue() )
{
+ // TODO: This needs fixing.
ScDPNumGroupInfo aNumInfo;
bool bHasNonInteger = false;
sal_Unicode cDecSeparator = 0;
@@ -1367,8 +1399,8 @@ void ScDPGroupTableData::FillGroupValues( /*ScDPItemData* pItemData*/ SCROW* pIt
double fGroupValue;
String aGroupName = lcl_GetNumGroupForValue( pData->GetValue(),
aNumInfo, bHasNonInteger, cDecSeparator, fGroupValue, pDoc );
- ScDPItemData aItemData ( aGroupName, fGroupValue, sal_True ) ;
- pItemDataIndex[nDim] = pCache->GetAdditionalItemID( aItemData );
+ ScDPItemData aItemData(aGroupName);
+ pItemDataIndex[nDim] = pCache->GetAdditionalItemID(aItemData);
}
// else (textual) keep original value
}
@@ -1377,14 +1409,26 @@ void ScDPGroupTableData::FillGroupValues( /*ScDPItemData* pItemData*/ SCROW* pIt
if ( pDateHelper )
{
const ScDPItemData* pData = GetCacheTable().getCache()->GetItemDataById( (SCCOL)nSourceDim, pItemDataIndex[nDim]);
- if ( pData ->IsValue() )
+ if ( pData ->IsValue() )
{
+ SvNumberFormatter* pFormatter = pDoc->GetFormatTable();
sal_Int32 nPartValue = lcl_GetDatePartValue(
- pData->GetValue(), pDateHelper->GetDatePart(), pDoc->GetFormatTable(),
+ pData->GetValue(), pDateHelper->GetDatePart(), pFormatter,
&pDateHelper->GetNumInfo() );
- sal_uInt8 nFlag = ScDPItemData::MK_DATA | ScDPItemData::MK_VAL;
- ScDPItemData aItemData(rtl::OUString(), static_cast<double>(nPartValue), nFlag);
- pItemDataIndex[nDim] = GetCacheTable().getCache()->GetAdditionalItemID( aItemData );
+ rtl::OUString aName = ScDPUtil::getDateGroupName(pDateHelper->GetDatePart(), nPartValue, pFormatter);
+ fprintf(stdout, "ScDPGroupTableData::FillGroupValues: column = %d source dim = %d group by = %d value = %d name = '%s'\n",
+ nColumn, nSourceDim,
+ pDateHelper->GetDatePart(), nPartValue,
+ rtl::OUStringToOString(aName, RTL_TEXTENCODING_UTF8).getStr());
+ ScDPItemData aItem(pDateHelper->GetDatePart(), nPartValue);
+ pItemDataIndex[nDim] = GetCacheTable().getCache()->GetIdByItemData(nColumn, aItem);
+ const ScDPItemData* pTest = GetCacheTable().getCache()->GetItemDataById(nColumn, pItemDataIndex[nDim]);
+ fprintf(stdout, "ScDPGroupTableData::FillGroupValues: id = %d\n", pItemDataIndex[nDim]);
+ if (pTest)
+ fprintf(stdout, "ScDPGroupTableData::FillGroupValues: test str = '%s'\n", rtl::OUStringToOString(pTest->GetString(), RTL_TEXTENCODING_UTF8).getStr());
+// sal_uInt8 nFlag = ScDPItemData::MK_DATA | ScDPItemData::MK_VAL;
+// ScDPItemData aItemData(rtl::OUString(), static_cast<double>(nPartValue), nFlag);
+// pItemDataIndex[nDim] = GetCacheTable().getCache()->GetAdditionalItemID( aItemData );
}
}
}
@@ -1437,6 +1481,10 @@ sal_Bool ScDPGroupTableData::IsNumOrDateGroup(long nDimension) const
sal_Bool ScDPGroupTableData::IsInGroup( const ScDPItemData& rGroupData, long nGroupIndex,
const ScDPItemData& rBaseData, long nBaseIndex ) const
{
+ stack_printer __stack_printer__("ScDPGroupTableData::IsInGroup");
+ fprintf(stdout, "ScDPGroupTableData::IsInGroup: group = '%s' base = '%s' group id = %d base id = %d\n",
+ rtl::OUStringToOString(rGroupData.GetString(), RTL_TEXTENCODING_UTF8).getStr(),
+ rtl::OUStringToOString(rBaseData.GetString(), RTL_TEXTENCODING_UTF8).getStr(), nGroupIndex, nBaseIndex);
for ( ScDPGroupDimensionVec::const_iterator aIter(aGroups.begin()); aIter != aGroups.end(); aIter++ )
{
const ScDPGroupDimension& rDim = *aIter;
diff --git a/sc/source/core/data/dpitemdata.cxx b/sc/source/core/data/dpitemdata.cxx
index 1b7368bf82e6..579f98521ab2 100644
--- a/sc/source/core/data/dpitemdata.cxx
+++ b/sc/source/core/data/dpitemdata.cxx
@@ -34,99 +34,117 @@
#include "globstr.hrc"
#include "dptabdat.hxx"
-bool ScDPItemData::isDate( sal_uLong nNumType )
+sal_Int32 ScDPItemData::Compare(const ScDPItemData& rA, const ScDPItemData& rB)
{
- return ((nNumType & NUMBERFORMAT_DATE) != 0) ? 1 : 0;
+ if ( rA.IsValue() )
+ {
+ if ( rB.IsValue() )
+ return rA.mfValue < rB.mfValue ? -1 : 1;
+ else
+ return -1; // values first
+ }
+ else if ( rB.IsValue() )
+ return 1; // values first
+ else
+ return ScGlobal::GetCollator()->compareString(rA.GetString(), rB.GetString());
}
ScDPItemData::ScDPItemData() :
- mfValue(0.0), mbFlag(0) {}
+ mfValue(0.0), meType(Empty) {}
+
+ScDPItemData::ScDPItemData(const rtl::OUString& rStr) :
+ mpString(new rtl::OUString(rStr)), meType(String) {}
-ScDPItemData::ScDPItemData(const rtl::OUString & rS, double fV, sal_uInt8 bF) :
- maString(rS), mfValue(fV), mbFlag(bF) {}
+ScDPItemData::ScDPItemData(double fVal) :
+ mfValue(fVal), meType(Value) {}
-ScDPItemData::ScDPItemData(const rtl::OUString& rS, double fV, bool bHV, bool bData) :
- maString(rS), mfValue(fV),
- mbFlag( (MK_VAL*!!bHV) | (MK_DATA*!!bData) | (MK_ERR*!!false) )
+ScDPItemData::ScDPItemData(sal_Int32 nGroupType, sal_Int32 nValue) :
+ meType(GroupValue)
{
+ maGroupValue.mnGroupType = nGroupType;
+ maGroupValue.mnValue = nValue;
}
-void ScDPItemData::Set(const rtl::OUString& rS, double fVal, sal_uInt8 nFlag)
+ScDPItemData::~ScDPItemData()
{
- maString = rS;
- mfValue = fVal;
- mbFlag = nFlag;
+ if (meType == String)
+ delete mpString;
}
void ScDPItemData::SetString(const rtl::OUString& rS)
{
- maString = rS;
- mbFlag &= ~(MK_VAL|MK_DATE);
- mbFlag |= MK_DATA;
+ if (meType == String)
+ delete mpString;
+ mpString = new rtl::OUString(rS);
+ meType = String;
+}
+
+void ScDPItemData::SetValue(double fVal)
+{
+ if (meType == String)
+ delete mpString;
+ mfValue = fVal;
+ meType = Value;
+}
+
+void ScDPItemData::SetGroupValue(sal_Int32 nGroupType, sal_Int32 nValue)
+{
+ if (meType == String)
+ delete mpString;
+
+ maGroupValue.mnGroupType = nGroupType;
+ maGroupValue.mnValue = nValue;
+ meType = GroupValue;
}
void ScDPItemData::SetErrorString(const rtl::OUString& rS)
{
SetString(rS);
- mbFlag |= MK_ERR;
}
-bool ScDPItemData::IsCaseInsEqual( const ScDPItemData& r ) const
+bool ScDPItemData::IsCaseInsEqual(const ScDPItemData& r) const
{
- //! pass Transliteration?
- //! inline?
- return IsValue() ? ( r.IsValue() && rtl::math::approxEqual( mfValue, r.mfValue ) ) :
- ( !r.IsValue() &&
- ScGlobal::GetpTransliteration()->isEqual( maString, r.maString ) );
+ if (meType != r.meType)
+ return false;
+
+ if (meType == Value)
+ return rtl::math::approxEqual(mfValue, r.mfValue);
+
+ return ScGlobal::GetpTransliteration()->isEqual(GetString(), r.GetString());
}
size_t ScDPItemData::Hash() const
{
- if ( IsValue() )
- return (size_t) rtl::math::approxFloor( mfValue );
- else
- // If we do unicode safe case insensitive hash we can drop
- // ScDPItemData::operator== and use ::IsCasInsEqual
- return rtl_ustr_hashCode_WithLength(maString.getStr(), maString.getLength());
+ if (meType == Value)
+ return static_cast<size_t>(rtl::math::approxFloor(mfValue));
+
+ // If we do unicode safe case insensitive hash we can drop
+ // ScDPItemData::operator== and use ::IsCasInsEqual
+ rtl::OUString aStr = GetString();
+ return rtl_ustr_hashCode_WithLength(aStr.getStr(), aStr.getLength());
}
-bool ScDPItemData::operator==( const ScDPItemData& r ) const
+bool ScDPItemData::operator== (const ScDPItemData& r) const
{
- if ( IsValue() )
- {
- if ( r.IsValue() )
- return rtl::math::approxEqual( mfValue, r.mfValue );
- else
- return false;
- }
- else if ( r.IsValue() )
+ if (meType != r.meType)
return false;
- else
- // need exact equality until we have a safe case insensitive string hash
- return maString == r.maString;
-}
-sal_Int32 ScDPItemData::Compare( const ScDPItemData& rA,
- const ScDPItemData& rB )
-{
- if ( rA.IsValue() )
- {
- if ( rB.IsValue() )
- return rA.mfValue < rB.mfValue ? -1 : 1;
- else
- return -1; // values first
- }
- else if ( rB.IsValue() )
- return 1; // values first
- else
- return ScGlobal::GetCollator()->compareString( rA.maString, rB.maString );
+ if (meType == Value)
+ return (r.meType == Value) ? rtl::math::approxEqual(mfValue, r.mfValue) : false;
+
+ if (meType == GroupValue)
+ return maGroupValue.mnGroupType == r.maGroupValue.mnGroupType &&
+ maGroupValue.mnValue == r.maGroupValue.mnValue;
+
+ // need exact equality until we have a safe case insensitive string hash
+ return GetString() == r.GetString();
}
-sal_uInt8 ScDPItemData::GetType() const
+sal_uInt8 ScDPItemData::GetCellType() const
{
- if ( IsHasErr() )
+ if (meType == Error)
return SC_VALTYPE_ERROR;
- else if ( !IsHasData() )
+ else if (meType == Empty)
return SC_VALTYPE_EMPTY;
else if ( IsValue())
return SC_VALTYPE_VALUE;
@@ -134,83 +152,50 @@ sal_uInt8 ScDPItemData::GetType() const
return SC_VALTYPE_STRING;
}
-bool ScDPItemData::IsHasData() const
+bool ScDPItemData::IsEmpty() const
{
- return !!(mbFlag&MK_DATA);
-}
-
-bool ScDPItemData::IsHasErr() const
-{
- return !!(mbFlag&MK_ERR);
+ return meType == Empty;
}
bool ScDPItemData::IsValue() const
{
- return !!(mbFlag&MK_VAL);
-}
-
-const rtl::OUString& ScDPItemData::GetString() const
-{
- return maString;
-}
-
-double ScDPItemData::GetValue() const
-{
- return mfValue;
+ return meType == Value || meType == GroupValue;
}
-bool ScDPItemData::HasStringData() const
+rtl::OUString ScDPItemData::GetString() const
{
- return IsHasData()&&!IsHasErr()&&!IsValue();
-}
+ if (meType == String)
+ return *mpString;
-ScDPItemDataPool::ScDPItemDataPool()
-{
+ // TODO: Generate appropriate string.
+ return rtl::OUString();
}
-ScDPItemDataPool::ScDPItemDataPool(const ScDPItemDataPool& r):
- maItems(r.maItems),
- maItemIds(r.maItemIds)
-{
-}
-
-ScDPItemDataPool::~ScDPItemDataPool()
+double ScDPItemData::GetValue() const
{
-}
+ if (meType == Value)
+ return mfValue;
+ if (meType == GroupValue)
+ return maGroupValue.mnValue;
-const ScDPItemData* ScDPItemDataPool::getData( sal_Int32 nId )
-{
- if ( nId >= static_cast<sal_Int32>(maItems.size()) )
- return NULL;
- else
- return &(maItems[nId]);
+ return 0.0;
}
-sal_Int32 ScDPItemDataPool::getDataId( const ScDPItemData& aData )
+ScDPItemData::GroupValueAttr ScDPItemData::GetGroupValue() const
{
- DataHash::const_iterator itr = maItemIds.find( aData),
- itrEnd = maItemIds.end();
- if ( itr == itrEnd )
- // not exist
- return -1;
-
- else //exist
- return itr->second;
+ if (meType == GroupValue)
+ return maGroupValue;
+ GroupValueAttr aGV;
+ aGV.mnGroupType = -1;
+ aGV.mnValue = -1;
+ return aGV;
}
-sal_Int32 ScDPItemDataPool::insertData( const ScDPItemData& aData )
+bool ScDPItemData::HasStringData() const
{
- sal_Int32 nResult = getDataId( aData );
-
- if( nResult < 0 )
- {
- maItemIds.insert( DataHash::value_type( aData, nResult = maItems.size() ) );
- maItems.push_back( aData );
- }
-
- return nResult;
+ return meType == String;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/data/dptabdat.cxx b/sc/source/core/data/dptabdat.cxx
index dc76211608f9..4993207fc182 100644
--- a/sc/source/core/data/dptabdat.cxx
+++ b/sc/source/core/data/dptabdat.cxx
@@ -50,6 +50,49 @@ using namespace ::com::sun::star;
using ::com::sun::star::uno::Sequence;
using ::com::sun::star::uno::Any;
using ::std::vector;
+
+#include <stdio.h>
+#include <string>
+#include <sys/time.h>
+
+namespace {
+
+class stack_printer
+{
+public:
+ explicit stack_printer(const char* msg) :
+ msMsg(msg)
+ {
+ fprintf(stdout, "%s: --begin\n", msMsg.c_str());
+ mfStartTime = getTime();
+ }
+
+ ~stack_printer()
+ {
+ double fEndTime = getTime();
+ fprintf(stdout, "%s: --end (duration: %g sec)\n", msMsg.c_str(), (fEndTime-mfStartTime));
+ }
+
+ void printTime(int line) const
+ {
+ double fEndTime = getTime();
+ fprintf(stdout, "%s: --(%d) (duration: %g sec)\n", msMsg.c_str(), line, (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;
+};
+
+}
+
// ---------------------------------------------------------------------------
ScDPTableData::CalcInfo::CalcInfo() :
@@ -184,18 +227,19 @@ void ScDPTableData::FillRowDataFromCacheTable(sal_Int32 nRow, const ScDPCacheTab
void ScDPTableData::ProcessRowData(CalcInfo& rInfo, CalcRowData& rData, bool bAutoShow)
{
+ stack_printer __stack_printer__("ScDPTableData::ProcessRowData");
if (!bAutoShow)
{
- LateInitParams aColParams( rInfo.aColDims, rInfo.aColLevels, false );
- LateInitParams aRowParams ( rInfo.aRowDims, rInfo.aRowLevels, sal_True );
+ LateInitParams aColParams(rInfo.aColDims, rInfo.aColLevels, false);
+ LateInitParams aRowParams(rInfo.aRowDims, rInfo.aRowLevels, true);
// root always init child
- aColParams.SetInitChild( sal_True );
+ aColParams.SetInitChild(true);
aColParams.SetInitAllChildren( false);
- aRowParams.SetInitChild( sal_True );
+ aRowParams.SetInitChild(true);
aRowParams.SetInitAllChildren( false);
- rInfo.pColRoot->LateInitFrom( aColParams, rData.aColData,0, *rInfo.pInitState);
- rInfo.pRowRoot->LateInitFrom( aRowParams, rData.aRowData, 0, *rInfo.pInitState);
+ rInfo.pColRoot->LateInitFrom(aColParams, rData.aColData, 0, *rInfo.pInitState);
+ rInfo.pRowRoot->LateInitFrom(aRowParams, rData.aRowData, 0, *rInfo.pInitState);
}
if ( ( !rInfo.pColRoot->GetChildDimension() || rInfo.pColRoot->GetChildDimension()->IsValidEntry(rData.aColData) ) &&
@@ -204,7 +248,7 @@ void ScDPTableData::ProcessRowData(CalcInfo& rInfo, CalcRowData& rData, bool bAu
//! single process method with ColMembers, RowMembers and data !!!
if (rInfo.pColRoot->GetChildDimension())
{
- vector</*ScDPItemData*/ SCROW > aEmptyData;
+ vector<SCROW> aEmptyData;
rInfo.pColRoot->GetChildDimension()->ProcessData(rData.aColData, NULL, aEmptyData, rData.aValues);
}
diff --git a/sc/source/core/data/dptablecache.cxx b/sc/source/core/data/dptablecache.cxx
index f4504e9063b1..372ca929f5fd 100644
--- a/sc/source/core/data/dptablecache.cxx
+++ b/sc/source/core/data/dptablecache.cxx
@@ -60,6 +60,48 @@ using ::com::sun::star::uno::UNO_QUERY_THROW;
using ::std::vector;
using ::std::auto_ptr;
+#include <stdio.h>
+#include <string>
+#include <sys/time.h>
+
+namespace {
+
+class stack_printer
+{
+public:
+ explicit stack_printer(const char* msg) :
+ msMsg(msg)
+ {
+ fprintf(stdout, "%s: --begin\n", msMsg.c_str());
+ mfStartTime = getTime();
+ }
+
+ ~stack_printer()
+ {
+ double fEndTime = getTime();
+ fprintf(stdout, "%s: --end (duration: %g sec)\n", msMsg.c_str(), (fEndTime-mfStartTime));
+ }
+
+ void printTime(int line) const
+ {
+ double fEndTime = getTime();
+ fprintf(stdout, "%s: --(%d) (duration: %g sec)\n", msMsg.c_str(), line, (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;
+};
+
+}
+
namespace {
/**
@@ -106,7 +148,6 @@ ScDPItemData* lcl_GetItemValue(
rNumType = NUMBERFORMAT_NUMBER;
try
{
- String rStr = xRow->getString(nCol);
double fValue = 0.0;
switch (nType)
{
@@ -115,7 +156,7 @@ ScDPItemData* lcl_GetItemValue(
{
rNumType = NUMBERFORMAT_LOGICAL;
fValue = xRow->getBoolean(nCol) ? 1 : 0;
- return new ScDPItemData(rStr, fValue, true);
+ return new ScDPItemData(fValue);
}
case sdbc::DataType::TINYINT:
case sdbc::DataType::SMALLINT:
@@ -129,7 +170,7 @@ ScDPItemData* lcl_GetItemValue(
{
//! do the conversion here?
fValue = xRow->getDouble(nCol);
- return new ScDPItemData(rStr, fValue, true);
+ return new ScDPItemData(fValue);
}
case sdbc::DataType::DATE:
{
@@ -137,7 +178,7 @@ ScDPItemData* lcl_GetItemValue(
util::Date aDate = xRow->getDate(nCol);
fValue = Date(aDate.Day, aDate.Month, aDate.Year) - rNullDate;
- return new ScDPItemData(rStr, fValue, true);
+ return new ScDPItemData(fValue);
}
case sdbc::DataType::TIME:
{
@@ -146,7 +187,7 @@ ScDPItemData* lcl_GetItemValue(
util::Time aTime = xRow->getTime(nCol);
fValue = ( aTime.Hours * 3600 + aTime.Minutes * 60 +
aTime.Seconds + aTime.HundredthSeconds / 100.0 ) / D_TIMEFACTOR;
- return new ScDPItemData(rStr,fValue, true);
+ return new ScDPItemData(fValue);
}
case sdbc::DataType::TIMESTAMP:
{
@@ -156,7 +197,7 @@ ScDPItemData* lcl_GetItemValue(
fValue = ( Date( aStamp.Day, aStamp.Month, aStamp.Year ) - rNullDate ) +
( aStamp.Hours * 3600 + aStamp.Minutes * 60 +
aStamp.Seconds + aStamp.HundredthSeconds / 100.0 ) / D_TIMEFACTOR;
- return new ScDPItemData(rStr,fValue, true);
+ return new ScDPItemData(fValue);
}
case sdbc::DataType::CHAR:
case sdbc::DataType::VARCHAR:
@@ -166,7 +207,7 @@ ScDPItemData* lcl_GetItemValue(
case sdbc::DataType::VARBINARY:
case sdbc::DataType::LONGVARBINARY:
default:
- return new ScDPItemData(rStr);
+ return new ScDPItemData(xRow->getString(nCol));
}
}
catch (uno::Exception&)
@@ -225,7 +266,6 @@ ScDPCache::Field::Field() {}
ScDPCache::ScDPCache(ScDocument* pDoc) :
mpDoc( pDoc ),
mnColumnCount ( 0 ),
- mpAdditionalData(new ScDPItemDataPool),
mbDisposing(false)
{
}
@@ -310,18 +350,8 @@ void initFromCell(ScDocument* pDoc, SCCOL nCol, SCROW nRow, SCTAB nTab, ScDPItem
else if (pDoc->HasValueData(nCol, nRow, nTab))
{
double fVal = pDoc->GetValue(aPos);
- sal_uLong nFormatType = NUMBERFORMAT_NUMBER;
rNumFormat = pDoc->GetNumberFormat(aPos);
- sal_uInt8 nFlag = ScDPItemData::MK_VAL | ScDPItemData::MK_DATA;
-
- SvNumberFormatter* pFormatter = pDoc->GetFormatTable();
- if (pFormatter)
- nFormatType = pFormatter->GetType(rNumFormat);
-
- if (ScDPItemData::isDate(nFormatType))
- nFlag |= ScDPItemData::MK_DATE;
-
- rData.Set(aDocStr, fVal, nFlag);
+ rData.SetValue(fVal);
}
else if (pDoc->HasData(nCol, nRow, nTab))
{
@@ -464,11 +494,11 @@ bool ScDPCache::ValidQuery( SCROW nRow, const ScQueryParam &rParam) const
if (rEntry.GetQueryItem().meType == ScQueryEntry::ByEmpty)
{
if (rEntry.IsQueryByEmpty())
- bOk = !pCellData->IsHasData();
+ bOk = pCellData->IsEmpty();
else
{
OSL_ASSERT(rEntry.IsQueryByNonEmpty());
- bOk = pCellData->IsHasData();
+ bOk = !pCellData->IsEmpty();
}
}
else if (rEntry.GetQueryItem().meType != ScQueryEntry::ByString && pCellData->IsValue())
@@ -656,7 +686,7 @@ bool ScDPCache::AddData(long nDim, ScDPItemData* pData, sal_uLong nNumFormat)
while ( mbEmptyRow.size() <= nCurRow )
mbEmptyRow.push_back( true );
- if ( pData->IsHasData() )
+ if (!pData->IsEmpty())
mbEmptyRow[ nCurRow ] = false;
return true;
@@ -729,7 +759,7 @@ SCROW ScDPCache::GetItemDataId(sal_uInt16 nDim, SCROW nRow, bool bRepeatIfEmpty)
const Field& rField = maFields[nDim];
if (bRepeatIfEmpty)
{
- while (nRow > 0 && !rField.maItems[rField.maData[nRow]].IsHasData())
+ while (nRow > 0 && rField.maItems[rField.maData[nRow]].IsEmpty())
--nRow;
}
@@ -738,14 +768,61 @@ SCROW ScDPCache::GetItemDataId(sal_uInt16 nDim, SCROW nRow, bool bRepeatIfEmpty)
const ScDPItemData* ScDPCache::GetItemDataById(long nDim, SCROW nId) const
{
- if ( nId >= GetRowCount() )
- return mpAdditionalData->getData(nId - GetRowCount());
+// stack_printer __stack_printer__("ScDPCache::GetItemDataById");
+// fprintf(stdout, "ScDPCache::GetItemDataById: dim = %d id = %d\n", nDim, nId);
+ if (nDim < 0)
+ {
+ fprintf(stdout, "ScDPCache::GetItemDataById: fail (%d)\n", __LINE__);
+ return NULL;
+ }
- const Field& rField = maFields[nDim];
- if (static_cast<size_t>(nId) >= rField.maItems.size() || nDim >= mnColumnCount || nId < 0)
+ long nSourceCount = static_cast<long>(maFields.size());
+ if (nDim < nSourceCount)
+ {
+ // source field.
+ const Field& rField = maFields[nDim];
+ if (nId < rField.maItems.size())
+ {
+// fprintf(stdout, "ScDPCache::GetItemDataById: s = '%s' (source)\n",
+// rtl::OUStringToOString(rField.maItems[nId].GetString(), RTL_TEXTENCODING_UTF8).getStr());
+ return &rField.maItems[nId];
+ }
+
+ if (!rField.mpGroup)
+ {
+ fprintf(stdout, "ScDPCache::GetItemDataById: fail (%d)\n", __LINE__);
+ return NULL;
+ }
+
+ nId -= rField.maItems.size();
+ const DataListType& rGI = rField.mpGroup->maItems;
+ if (nId >= rGI.size())
+ {
+ fprintf(stdout, "ScDPCache::GetItemDataById: fail (%d)\n", __LINE__);
+ return NULL;
+ }
+// fprintf(stdout, "ScDPCache::GetItemDataById: s = '%s' (grouped source field)\n",
+// rtl::OUStringToOString(rGI[nId].GetString(), RTL_TEXTENCODING_UTF8).getStr());
+ return &rGI[nId];
+ }
+
+ // Try group fields.
+ nDim -= nSourceCount;
+ if (nDim >= maGroupFields.size())
+ {
+ fprintf(stdout, "ScDPCache::GetItemDataById: fail (%d)\n", __LINE__);
return NULL;
- else
- return &rField.maItems[nId];
+ }
+
+ const DataListType& rGI = maGroupFields[nDim].maItems;
+ if (nId >= rGI.size())
+ {
+ fprintf(stdout, "ScDPCache::GetItemDataById: fail (%d)\n", __LINE__);
+ return NULL;
+ }
+// fprintf(stdout, "ScDPCache::GetItemDataById: s = '%s' (group field)\n",
+// rtl::OUStringToOString(rGI[nId].GetString(), RTL_TEXTENCODING_UTF8).getStr());
+ return &rGI[nId];
}
SCROW ScDPCache::GetRowCount() const
@@ -841,23 +918,56 @@ const ScDPCache::ObjectSetType& ScDPCache::GetAllReferences() const
SCROW ScDPCache::GetIdByItemData(long nDim, const rtl::OUString& sItemData) const
{
- if ( nDim < mnColumnCount && nDim >=0 )
+// stack_printer __stack_printer__("ScDPCache::GetIdByItemData");
+// fprintf(stdout, "ScDPCache::GetIdByItemData: dim = %ld s = '%s'\n",
+// nDim, rtl::OUStringToOString(sItemData, RTL_TEXTENCODING_UTF8).getStr());
+ if (nDim < 0)
+ return -1;
+
+ if (nDim < mnColumnCount)
{
+ // source field.
const DataListType& rItems = maFields[nDim].maItems;
for (size_t i = 0, n = rItems.size(); i < n; ++i)
{
+// fprintf(stdout, "ScDPCache::GetIdByItemData: source item = '%s'\n", rtl::OUStringToOString(rItems[i].GetString(), RTL_TEXTENCODING_UTF8).getStr());
if (rItems[i].GetString() == sItemData)
return i;
}
+
+ if (!maFields[nDim].mpGroup)
+ return -1;
+
+ // grouped source field.
+ const DataListType& rGI = maFields[nDim].mpGroup->maItems;
+ for (size_t i = 0, n = rGI.size(); i < n; ++i)
+ {
+// fprintf(stdout, "ScDPCache::GetIdByItemData: grouped source item = '%s'\n", rtl::OUStringToOString(rGI[i].GetString(), RTL_TEXTENCODING_UTF8).getStr());
+ if (rGI[i].GetString() == sItemData)
+ return rItems.size() + i;
+ }
+ return -1;
}
- ScDPItemData rData ( sItemData );
- return GetRowCount() + mpAdditionalData->getDataId(rData);
+ // group field.
+ nDim -= mnColumnCount;
+ if (nDim < maGroupFields.size())
+ {
+ const DataListType& rGI = maGroupFields[nDim].maItems;
+ for (size_t i = 0, n = rGI.size(); i < n; ++i)
+ {
+// fprintf(stdout, "ScDPCache::GetIdByItemData: grouped item = '%s'\n", rtl::OUStringToOString(rGI[i].GetString(), RTL_TEXTENCODING_UTF8).getStr());
+ if (rGI[i].GetString() == sItemData)
+ return i;
+ }
+ }
+ return -1;
}
SCROW ScDPCache::GetIdByItemData(long nDim, const ScDPItemData& rData) const
{
+ fprintf(stdout, "ScDPCache::GetIdByItemData: FIXME\n");
if ( nDim < mnColumnCount && nDim >=0 )
{
const DataListType& rItems = maFields[nDim].maItems;
@@ -867,12 +977,57 @@ SCROW ScDPCache::GetIdByItemData(long nDim, const ScDPItemData& rData) const
return i;
}
}
- return GetRowCount() + mpAdditionalData->getDataId(rData);
+ return -1;
}
-SCROW ScDPCache::GetAdditionalItemID( const ScDPItemData& rData ) const
+void ScDPCache::AppendGroupField()
{
- return GetRowCount() + mpAdditionalData->insertData(rData);
+ maGroupFields.push_back(new GroupField);
+}
+
+void ScDPCache::ResetGroupItems(long nDim)
+{
+ if (nDim < 0)
+ return;
+
+ long nSourceCount = static_cast<long>(maFields.size());
+ if (nDim < nSourceCount)
+ {
+ maFields.at(nDim).mpGroup.reset(new GroupItems);
+ return;
+ }
+
+ nDim -= nSourceCount;
+ if (nDim < static_cast<long>(maGroupFields.size()))
+ maGroupFields[nDim].maItems.clear();
+}
+
+SCROW ScDPCache::SetGroupItem(long nDim, const ScDPItemData& rData)
+{
+ long nSourceCount = static_cast<long>(maFields.size());
+ if (nDim < nSourceCount)
+ {
+ GroupItems& rGI = *maFields.at(nDim).mpGroup;
+ rGI.maItems.push_back(new ScDPItemData(rData));
+ SCROW nId = maFields[nDim].maItems.size() + rGI.maItems.size() - 1;
+ return nId;
+ }
+
+ nDim -= nSourceCount;
+ if (nDim < static_cast<long>(maGroupFields.size()))
+ {
+ DataListType& rItems = maGroupFields.at(nDim).maItems;
+ rItems.push_back(new ScDPItemData(rData));
+ return rItems.size()-1;
+ }
+
+ return -1;
+}
+
+SCROW ScDPCache::GetAdditionalItemID(const ScDPItemData&) const
+{
+ fprintf(stdout, "ScDPCache::GetAdditionalItemID: FIXME\n");
+ return -1;
}
@@ -907,4 +1062,9 @@ long ScDPCache::GetColumnCount() const
return mnColumnCount;
}
+long ScDPCache::GetGroupFieldCount() const
+{
+ return maGroupFields.size();
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/data/dptabres.cxx b/sc/source/core/data/dptabres.cxx
index 421c17d6647c..7a59b0ea4fef 100644
--- a/sc/source/core/data/dptabres.cxx
+++ b/sc/source/core/data/dptabres.cxx
@@ -68,6 +68,48 @@ using ::std::pair;
using ::com::sun::star::uno::Sequence;
using ::rtl::OUString;
+#include <stdio.h>
+#include <string>
+#include <sys/time.h>
+
+namespace {
+
+class stack_printer
+{
+public:
+ explicit stack_printer(const char* msg) :
+ msMsg(msg)
+ {
+ fprintf(stdout, "%s: --begin\n", msMsg.c_str());
+ mfStartTime = getTime();
+ }
+
+ ~stack_printer()
+ {
+ double fEndTime = getTime();
+ fprintf(stdout, "%s: --end (duration: %g sec)\n", msMsg.c_str(), (fEndTime-mfStartTime));
+ }
+
+ void printTime(int line) const
+ {
+ double fEndTime = getTime();
+ fprintf(stdout, "%s: --(%d) (duration: %g sec)\n", msMsg.c_str(), line, (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;
+};
+
+}
+
// -----------------------------------------------------------------------
static sal_uInt16 nFuncStrIds[12] = // passend zum enum ScSubTotalFunc
@@ -932,6 +974,7 @@ bool ScDPResultData::IsInGroup( const ScDPItemData& rGroupData, long nGroupIndex
bool ScDPResultData::IsInGroup( SCROW nGroupDataId, long nGroupIndex,
const ScDPItemData& rBaseData, long nBaseIndex ) const
{
+ fprintf(stdout, "ScDPResultData::IsInGroup: dim = %d id = %d\n", nGroupIndex, nGroupDataId);
const ScDPItemData* pGroupData = pSource->GetItemDataById( nGroupIndex , nGroupDataId);
if ( pGroupData )
return pSource->GetData()->IsInGroup( *pGroupData, nGroupIndex, rBaseData , nBaseIndex );
@@ -1112,9 +1155,8 @@ void ScDPResultMember::InitFrom( const vector<ScDPDimension*>& ppDim, const vect
}
}
-void ScDPResultMember::LateInitFrom( LateInitParams& rParams/*const vector<ScDPDimension*>& ppDim, const vector<ScDPLevel*>& ppLev*/,
- const vector< SCROW >& pItemData, size_t nPos,
- ScDPInitState& rInitState )
+void ScDPResultMember::LateInitFrom(
+ LateInitParams& rParams, const vector<SCROW>& pItemData, size_t nPos, ScDPInitState& rInitState)
{
// without LateInit, everything has already been initialized
if ( !pResultData->IsLateInit() )
@@ -1226,10 +1268,23 @@ long ScDPResultMember::GetSize(long nMeasure) const
sal_Bool ScDPResultMember::IsVisible() const
{
+// fprintf(stdout, "ScDPResultMember::IsVisible: initialized = %d valid = %d has elements = %d\n",
+// bInitialized, IsValid(), bHasElements);
+
+ if (!bInitialized)
+ return false;
+
+ if (!IsValid())
+ return false;
+
+ if (bHasElements)
+ return true;
+
// not initialized -> shouldn't be there at all
// (allocated only to preserve ordering)
- const ScDPLevel* pParentLevel = GetParentLevel();
- return ( bHasElements || ( pParentLevel && pParentLevel->getShowEmpty() ) ) && IsValid() && bInitialized;
+ const ScDPLevel* pParentLevel = GetParentLevel();
+
+ return (pParentLevel && pParentLevel->getShowEmpty());
}
sal_Bool ScDPResultMember::IsValid() const
@@ -1356,6 +1411,7 @@ void ScDPResultMember::FillMemberResults( uno::Sequence<sheet::MemberResult>* pS
const String* pMemberName,
const String* pMemberCaption )
{
+// stack_printer __stack_printer__("ScDPResultMember::FillMemberResults");
// IsVisible() test is in ScDPResultDimension::FillMemberResults
// (not on data layout dimension)
@@ -1370,7 +1426,9 @@ void ScDPResultMember::FillMemberResults( uno::Sequence<sheet::MemberResult>* pS
sal_Bool bIsNumeric = false;
String aName;
if ( pMemberName ) // if pMemberName != NULL, use instead of real member name
+ {
aName = *pMemberName;
+ }
else
{
ScDPItemData aItemData;
@@ -1378,6 +1436,10 @@ void ScDPResultMember::FillMemberResults( uno::Sequence<sheet::MemberResult>* pS
aName = aItemData.GetString();
bIsNumeric = aItemData.IsValue();
}
+
+ fprintf(stdout, "ScDPResultMember::FillMemberResults: name = '%s' numeric = %d\n",
+ rtl::OUStringToOString(aName, RTL_TEXTENCODING_UTF8).getStr(), bIsNumeric);
+
const ScDPDimension* pParentDim = GetParentDim();
if ( bIsNumeric && pParentDim && pResultData->IsNumOrDateGroup( pParentDim->GetDimension() ) )
{
@@ -2666,32 +2728,44 @@ ScDPGroupCompare::ScDPGroupCompare( const ScDPResultData* pData, const ScDPInitS
sal_Bool ScDPGroupCompare::TestIncluded( const ScDPMember& rMember )
{
- sal_Bool bInclude = sal_True;
+ stack_printer __stack_printer__("ScDPGroupCompare::TestIncluded");
+ fprintf(stdout, "ScDPGroupCompare::TestIncluded: dim source = %d group base = %d, base data id = %d\n",
+ nDimSource, nGroupBase, nBaseDataId);
+ bool bInclude = true;
if ( nBaseDataId >=0 )
{
+ fprintf(stdout, "ScDPGroupCompare::TestIncluded: case 1 (this should not happen)\n");
ScDPItemData aMemberData;
rMember.FillItemData( aMemberData );
bInclude = pResultData->IsInGroup( aMemberData, nDimSource, nBaseDataId, nGroupBase );
}
else if ( bIsBase )
{
+ fprintf(stdout, "ScDPGroupCompare::TestIncluded: case 2 (source dim)\n");
// need to check all previous groups
//! get array of groups (or indexes) before loop?
ScDPItemData aMemberData;
rMember.FillItemData( aMemberData );
+ fprintf(stdout, "ScDPGroupCompare::TestIncluded: s = '%s'\n", rtl::OUStringToOString(aMemberData.GetString(), RTL_TEXTENCODING_UTF8).getStr());
long nInitCount = rInitState.GetCount();
const long* pInitSource = rInitState.GetSource();
- /*const ScDPItemData* pInitNames = rInitState.GetNames();*/
const SCROW* pInitNames = rInitState.GetNameIds();
+ for (long nInitPos=0; nInitPos<nInitCount; nInitPos++)
+ {
+ fprintf(stdout, "ScDPGroupCompare::TestIncluded: source = %d name id = %d\n", pInitSource[nInitPos], pInitNames[nInitPos]);
+ }
for (long nInitPos=0; nInitPos<nInitCount && bInclude; nInitPos++)
+ {
if ( pResultData->GetGroupBase( pInitSource[nInitPos] ) == nDimSource )
{
bInclude = pResultData->IsInGroup( pInitNames[nInitPos], pInitSource[nInitPos],
aMemberData, nDimSource );
}
+ }
}
else if ( nGroupBase >= 0 )
{
+ fprintf(stdout, "ScDPGroupCompare::TestIncluded: case 3 (group dim?)\n");
// base isn't used in preceding fields
// -> look for other groups using the same base
@@ -2738,11 +2812,23 @@ ScDPResultDimension::~ScDPResultDimension()
ScDPResultMember *ScDPResultDimension::FindMember( SCROW iData ) const
{
+// stack_printer __stack_printer__("ScDPResultDimension::FindMember");
+// fprintf(stdout, "ScDPResultDimension::FindMember: iData = %d\n", iData);
if( bIsDataLayout )
return maMemberArray[0];
+// fprintf(stdout, "ScDPResultDimension::FindMember: hash size = %d\n", maMemberHash.size());
+// {
+// MemberHash::const_iterator i = maMemberHash.begin(), ie = maMemberHash.end();
+// for (; i != ie; ++i)
+// {
+// printf("%d ", i->first);
+// }
+// printf("\n");
+// }
MemberHash::const_iterator aRes = maMemberHash.find( iData );
if( aRes != maMemberHash.end()) {
+// fprintf(stdout, "ScDPResultDimension::FindMember: in hash\n");
if ( aRes->second->IsNamedItem( iData ) )
return aRes->second;
OSL_FAIL("problem! hash result is not the same as IsNamedItem");
@@ -2750,13 +2836,19 @@ ScDPResultMember *ScDPResultDimension::FindMember( SCROW iData ) const
unsigned int i;
unsigned int nCount = maMemberArray.size();
+// fprintf(stdout, "ScDPResultDimension::FindMember: member size = %d\n", nCount);
ScDPResultMember* pResultMember;
for( i = 0; i < nCount ; i++ )
{
pResultMember = maMemberArray[i];
+// fprintf(stdout, "ScDPResultDimension::FindMember: pResultMember = %p\n", pResultMember);
if ( pResultMember->IsNamedItem( iData ) )
+ {
+// fprintf(stdout, "ScDPResultDimension::FindMember: not in hash but found it.\n");
return pResultMember;
+ }
}
+// fprintf(stdout, "ScDPResultDimension::FindMember: total fail\n");
return NULL;
}
@@ -2827,9 +2919,8 @@ void ScDPResultDimension::InitFrom( const vector<ScDPDimension*>& ppDim, const v
bInitialized = sal_True;
}
-void ScDPResultDimension::LateInitFrom( LateInitParams& rParams/* const vector<ScDPDimension*>& ppDim, const vector<ScDPLevel*>& ppLev*/,
- const vector<SCROW>& pItemData, size_t nPos,
- ScDPInitState& rInitState )
+void ScDPResultDimension::LateInitFrom(
+ LateInitParams& rParams, const vector<SCROW>& pItemData, size_t nPos, ScDPInitState& rInitState)
{
if ( rParams.IsEnd( nPos ) )
return;
@@ -2923,7 +3014,7 @@ void ScDPResultDimension::LateInitFrom( LateInitParams& rParams/* const vector<S
if ( pResultMember->IsNamedItem( rThisData ) )
bAllChildren = false;
else
- bAllChildren = sal_True;
+ bAllChildren = true;
}
rParams.SetInitAllChildren( bAllChildren );
rInitState.AddMember( nDimSource, pResultMember->GetDataId() );
@@ -2965,13 +3056,18 @@ long ScDPResultDimension::GetSize(long nMeasure) const
}
return nTotal;
}
-
+//#include <iostream>
bool ScDPResultDimension::IsValidEntry( const vector< SCROW >& aMembers ) const
{
+// stack_printer __stack_printer__("ScDPResultDimension::IsValidEntry");
+// fprintf(stdout, "ScDPResultDimension::IsValidEntry: dim name = '%s'\n", rtl::OUStringToOString(aDimensionName, RTL_TEXTENCODING_UTF8).getStr());
if (aMembers.empty())
return false;
+// std::copy(aMembers.begin(),aMembers.end(), std::ostream_iterator<SCROW>(std::cout, " "));std::cout << std::endl;
+
const ScDPResultMember* pMember = FindMember( aMembers[0] );
+// fprintf(stdout, "ScDPResultDimension::IsValidEntry: pMember = %p id = %d\n", pMember, aMembers[0]);
if ( NULL != pMember )
return pMember->IsValidEntry( aMembers );
#if OSL_DEBUG_LEVEL > 1
@@ -3027,7 +3123,12 @@ void ScDPResultDimension::FillMemberResults( uno::Sequence<sheet::MemberResult>*
maMemberArray[0]->FillMemberResults( pSequences, nPos, nSorted, false, &aMbrName, &aMbrCapt );
}
else if ( pMember->IsVisible() )
+ {
+ fprintf(stdout, "ScDPResultDimension::FillMemberResults: member visible\n");
pMember->FillMemberResults( pSequences, nPos, nMeasure, false, NULL, NULL );
+ }
+ else
+ fprintf(stdout, "ScDPResultDimension::FillMemberResults: member not visible\n");
// nPos is modified
}
}
@@ -3916,6 +4017,7 @@ SCROW ScDPResultMember::GetDataId( ) const
ScDPResultMember* ScDPResultDimension::AddMember(const ScDPParentDimData &aData )
{
+ fprintf(stdout, "ScDPResultDimension::AddMember: dim name = '%s'\n", rtl::OUStringToOString(aDimensionName, RTL_TEXTENCODING_UTF8).getStr());
ScDPResultMember* pMember = new ScDPResultMember( pResultData, aData, false );
SCROW nDataIndex = pMember->GetDataId();
maMemberArray.push_back( pMember );
@@ -3927,9 +4029,11 @@ ScDPResultMember* ScDPResultDimension::AddMember(const ScDPParentDimData &aData
ScDPResultMember* ScDPResultDimension::InsertMember(ScDPParentDimData *pMemberData)
{
+ fprintf(stdout, "ScDPResultDimension::InsertMember: dim name = '%s'\n", rtl::OUStringToOString(aDimensionName, RTL_TEXTENCODING_UTF8).getStr());
SCROW nInsert = 0;
if ( !lcl_SearchMember( maMemberArray, pMemberData->mnOrder , nInsert ) )
- { //Member not exist
+ {
+ fprintf(stdout, "ScDPResultDimension::InsertMember: member doesn't exist\n");
ScDPResultMember* pNew = new ScDPResultMember( pResultData, *pMemberData, false );
maMemberArray.insert( maMemberArray.begin()+nInsert, pNew );
@@ -3938,13 +4042,14 @@ ScDPResultMember* ScDPResultDimension::InsertMember(ScDPParentDimData *pMemberDa
maMemberHash.insert( std::pair< SCROW, ScDPResultMember *>( nDataIndex, pNew ) );
return pNew;
}
+ else
+ fprintf(stdout, "ScDPResultDimension::InsertMember: member exists. no insert.\n");
return maMemberArray[ nInsert ];
}
-void ScDPResultDimension:: InitWithMembers( LateInitParams& rParams,
- const ::std::vector< SCROW >& pItemData,
- size_t nPos,
- ScDPInitState& rInitState )
+void ScDPResultDimension::InitWithMembers(
+ LateInitParams& rParams, const std::vector<SCROW>& pItemData, size_t nPos,
+ ScDPInitState& rInitState)
{
if ( rParams.IsEnd( nPos ) )
return;
@@ -3954,6 +4059,7 @@ void ScDPResultDimension:: InitWithMembers( LateInitParams& rParams,
if (pThisDim && pThisLevel)
{
+ stack_printer __stack_printer__("ScDPResultDimension::InitWithMembers");
long nDimSource = pThisDim->GetDimension(); //! check GetSourceDim?
// create all members at the first call (preserve order)
@@ -3968,7 +4074,11 @@ void ScDPResultDimension:: InitWithMembers( LateInitParams& rParams,
if ( pResultMember == NULL )
{ //only insert found item
+ fprintf(stdout, "ScDPResultDimension::InitWithMembers: insert (dim name = '%s'; id = %d)\n",
+ rtl::OUStringToOString(aDimensionName, RTL_TEXTENCODING_UTF8).getStr(), nDataID);
ScDPParentDimData* pMemberData = pMembers->FindMember( nDataID );
+ fprintf(stdout, "ScDPResultDimension::InitWithMembers: included = %d\n",
+ aCompare.IsIncluded(*pMemberData->mpMemberDesc));
if ( pMemberData && aCompare.IsIncluded( *( pMemberData->mpMemberDesc ) ) )
pResultMember = InsertMember( pMemberData );
}
@@ -4027,36 +4137,36 @@ sal_Bool LateInitParams::IsEnd( size_t nPos ) const
void ScDPResultDimension::CheckShowEmpty( sal_Bool bShow )
{
- long nCount = maMemberArray.size();
+ long nCount = maMemberArray.size();
- ScDPResultMember* pMember = NULL;
- for (long i=0; i<nCount; i++)
- {
- pMember = maMemberArray.at(i);
- pMember->CheckShowEmpty( bShow );
- }
+ ScDPResultMember* pMember = NULL;
+ for (long i=0; i<nCount; i++)
+ {
+ pMember = maMemberArray.at(i);
+ pMember->CheckShowEmpty(bShow);
+ }
}
void ScDPResultMember::CheckShowEmpty( sal_Bool bShow )
{
- if ( bHasElements )
- {
- ScDPResultDimension* pChildDim = GetChildDimension();
- if (pChildDim )
- pChildDim->CheckShowEmpty();
- }
- else if ( IsValid() && bInitialized )
+ if (bHasElements)
+ {
+ ScDPResultDimension* pChildDim = GetChildDimension();
+ if (pChildDim)
+ pChildDim->CheckShowEmpty();
+ }
+ else if (IsValid() && bInitialized)
+ {
+ bShow = bShow || (GetParentLevel() && GetParentLevel()->getShowEmpty());
+ if (bShow)
{
- bShow = bShow || ( GetParentLevel() && GetParentLevel()->getShowEmpty() );
- if ( bShow )
- {
- SetHasElements();
- ScDPResultDimension* pChildDim = GetChildDimension();
- if (pChildDim )
- pChildDim->CheckShowEmpty( sal_True );
- }
+ SetHasElements();
+ ScDPResultDimension* pChildDim = GetChildDimension();
+ if (pChildDim)
+ pChildDim->CheckShowEmpty(true);
}
+ }
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/data/dptabsrc.cxx b/sc/source/core/data/dptabsrc.cxx
index 24dc55f4cfa0..e37654169919 100644
--- a/sc/source/core/data/dptabsrc.cxx
+++ b/sc/source/core/data/dptabsrc.cxx
@@ -1022,6 +1022,7 @@ void ScDPSource::FillLevelList( sal_uInt16 nOrientation, std::vector<ScDPLevel*>
for (long nLev=0; nLev<nLevCount; nLev++)
{
ScDPLevel* pLevel = pLevels->getByIndex(nLev);
+// fprintf(stdout, "ScDPSource::FillLevelList: level name = '%s'\n", rtl::OUStringToOString(pLevel->getName(), RTL_TEXTENCODING_UTF8).getStr());
rList.push_back(pLevel);
}
}
@@ -1473,7 +1474,7 @@ const ScDPItemData& ScDPDimension::GetSelectedData()
}
if ( !pSelectedData )
- pSelectedData = new ScDPItemData( aSelectedPage, 0.0, false ); // default - name only
+ pSelectedData = new ScDPItemData(aSelectedPage); // default - name only
}
return *pSelectedData;
@@ -2524,7 +2525,8 @@ ScDPMember* ScDPMembers::getByIndex(long nIndex) const
if (aName.isEmpty())
aName = rtl::OUString::valueOf(nVal);
- ScDPItemData aData(aName, nVal, true, 0);
+ // TODO: This needs fixing.
+ ScDPItemData aData(nVal);
pNew = new ScDPMember(
pSource, nDim, nHier, nLev, pSource->GetCache()->GetAdditionalItemID(aData));
}
@@ -2570,10 +2572,11 @@ ScDPMember::~ScDPMember()
bool ScDPMember::IsNamedItem(SCROW nIndex) const
{
long nSrcDim = pSource->GetSourceDim( nDim );
+ fprintf(stdout, "ScDPMember::IsNamedItem: dim = %d src dim = %d\n", nDim, nSrcDim);
if ( nHier != SC_DAPI_HIERARCHY_FLAT && pSource->IsDateDimension( nSrcDim ) )
{
- const ScDPItemData* pData = pSource->GetCache()->GetItemDataById( (SCCOL) nSrcDim, nIndex );
- if ( pData->IsValue() )
+ const ScDPItemData* pData = pSource->GetCache()->GetItemDataById(nDim, nIndex);
+ if (pData->IsValue())
{
long nComp = pSource->GetData()->GetDatePart(
(long)::rtl::math::approxFloor( pData->GetValue() ),
@@ -2583,6 +2586,7 @@ bool ScDPMember::IsNamedItem(SCROW nIndex) const
}
}
+ fprintf(stdout, "ScDPMember::IsNamedItem: result = %d\n", nIndex == mnDataId);
return nIndex == mnDataId;
}
diff --git a/sc/source/core/data/dputil.cxx b/sc/source/core/data/dputil.cxx
index 65a1ee51d297..94e022359807 100644
--- a/sc/source/core/data/dputil.cxx
+++ b/sc/source/core/data/dputil.cxx
@@ -27,8 +27,31 @@
*/
#include "dputil.hxx"
+#include "global.hxx"
#include "comphelper/string.hxx"
+#include "unotools/localedatawrapper.hxx"
+#include "unotools/calendarwrapper.hxx"
+#include "svl/zforlist.hxx"
+
+#include <com/sun/star/sheet/DataPilotFieldGroupBy.hpp>
+#include <com/sun/star/i18n/CalendarDisplayIndex.hpp>
+
+using namespace com::sun::star;
+
+namespace {
+
+const sal_uInt16 SC_DP_LEAPYEAR = 1648; // arbitrary leap year for date calculations
+
+String getTwoDigitString( sal_Int32 nValue )
+{
+ String aRet = String::CreateFromInt32( nValue );
+ if ( aRet.Len() < 2 )
+ aRet.Insert( (sal_Unicode)'0', 0 );
+ return aRet;
+}
+
+}
bool ScDPUtil::isDuplicateDimension(const rtl::OUString& rName)
{
@@ -56,4 +79,50 @@ rtl::OUString ScDPUtil::createDuplicateDimensionName(const rtl::OUString& rOrigi
return aBuf.makeStringAndClear();
}
+rtl::OUString ScDPUtil::getDateGroupName(
+ sal_Int32 nDatePart, sal_Int32 nValue, SvNumberFormatter* pFormatter)
+{
+ switch ( nDatePart )
+ {
+ case sheet::DataPilotFieldGroupBy::YEARS:
+ return rtl::OUString::valueOf(nValue);
+ case sheet::DataPilotFieldGroupBy::QUARTERS:
+ return ScGlobal::pLocaleData->getQuarterAbbreviation(sal_Int16(nValue-1)); // nValue is 1-based
+ case com::sun::star::sheet::DataPilotFieldGroupBy::MONTHS:
+ return ScGlobal::GetCalendar()->getDisplayName(
+ i18n::CalendarDisplayIndex::MONTH, sal_Int16(nValue-1), 0); // 0-based, get short name
+ case sheet::DataPilotFieldGroupBy::DAYS:
+ {
+ Date aDate(1, 1, SC_DP_LEAPYEAR);
+ aDate += (nValue - 1); // nValue is 1-based
+ Date aNullDate = *pFormatter->GetNullDate();
+ long nDays = aDate - aNullDate;
+
+ sal_uLong nFormat = pFormatter->GetFormatIndex(NF_DATE_SYS_DDMMM, ScGlobal::eLnge);
+ Color* pColor;
+ String aStr;
+ pFormatter->GetOutputString(nDays, nFormat, aStr, &pColor);
+ return aStr;
+ }
+ case sheet::DataPilotFieldGroupBy::HOURS:
+ {
+ //! allow am/pm format?
+ return getTwoDigitString(nValue);
+ }
+ break;
+ case sheet::DataPilotFieldGroupBy::MINUTES:
+ case sheet::DataPilotFieldGroupBy::SECONDS:
+ {
+ rtl::OUStringBuffer aBuf(ScGlobal::pLocaleData->getTimeSep());
+ aBuf.append(getTwoDigitString(nValue));
+ return aBuf.makeStringAndClear();
+ }
+ break;
+ default:
+ OSL_FAIL("invalid date part");
+ }
+
+ return rtl::OUString();
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/excel/xepivot.cxx b/sc/source/filter/excel/xepivot.cxx
index 234ecc065d50..3a07b0e2d1a3 100644
--- a/sc/source/filter/excel/xepivot.cxx
+++ b/sc/source/filter/excel/xepivot.cxx
@@ -547,7 +547,7 @@ void XclExpPCField::InsertNumDateGroupItems( const ScDPObject& rDPObj, const ScD
// get the string collection with generated grouping elements
ScDPNumGroupDimension aTmpDim( rNumInfo );
if( nDatePart != 0 )
- aTmpDim.MakeDateHelper( rNumInfo, nDatePart );
+ aTmpDim.MakeDateHelper( rNumInfo, mnFieldIdx, nDatePart );
const std::vector<SCROW>& aMemberIds = aTmpDim.GetNumEntries(
static_cast<SCCOL>( GetBaseFieldIndex() ), aDPData.GetCacheTable().getCache(), aOrignial);
for ( size_t nIdx = 0 ; nIdx < aMemberIds.size(); nIdx++ )