summaryrefslogtreecommitdiff
path: root/sc
diff options
context:
space:
mode:
authorKohei Yoshida <kohei@openoffice.org>2009-06-19 02:29:09 +0000
committerKohei Yoshida <kohei@openoffice.org>2009-06-19 02:29:09 +0000
commit621ea5f0e56231a7d5063e6d12cce8aab55af37c (patch)
treeff8c9a18e1c4d4a9a4d79209f37f01e3e3785c1f /sc
parentacd89bd93d510281d1e46ca1617ff8545d0e981b (diff)
#i22029# #i81335# applied & adjusted the patch from ooo-build.
This enables changing the names of fields, field members and grand total names.
Diffstat (limited to 'sc')
-rw-r--r--sc/inc/dpgroup.hxx5
-rw-r--r--sc/inc/dpobject.hxx16
-rw-r--r--sc/inc/dpsave.hxx62
-rw-r--r--sc/inc/dptabres.hxx5
-rw-r--r--sc/inc/dptabsrc.hxx17
-rw-r--r--sc/inc/unonames.hxx3
-rw-r--r--sc/source/core/data/dpgroup.cxx4
-rw-r--r--sc/source/core/data/dpobject.cxx126
-rw-r--r--sc/source/core/data/dpoutput.cxx41
-rw-r--r--sc/source/core/data/dpsave.cxx233
-rw-r--r--sc/source/core/data/dptabres.cxx86
-rw-r--r--sc/source/core/data/dptabsrc.cxx121
-rw-r--r--sc/source/filter/excel/read.cxx3
-rw-r--r--sc/source/filter/excel/xepivot.cxx111
-rw-r--r--sc/source/filter/excel/xestring.cxx4
-rw-r--r--sc/source/filter/excel/xipivot.cxx124
-rw-r--r--sc/source/filter/excel/xlpivot.cxx125
-rw-r--r--sc/source/filter/inc/xepivot.hxx6
-rw-r--r--sc/source/filter/inc/xestring.hxx1
-rw-r--r--sc/source/filter/inc/xipivot.hxx9
-rw-r--r--sc/source/filter/inc/xlpivot.hxx15
-rw-r--r--sc/source/filter/inc/xlstring.hxx1
-rw-r--r--sc/source/ui/dbgui/pvfundlg.cxx22
-rw-r--r--sc/source/ui/dbgui/pvlaydlg.cxx41
-rw-r--r--sc/source/ui/inc/pvfundlg.hxx11
-rw-r--r--sc/source/ui/unoobj/dapiuno.cxx11
-rw-r--r--sc/source/ui/view/dbfunc3.cxx337
27 files changed, 1219 insertions, 321 deletions
diff --git a/sc/inc/dpgroup.hxx b/sc/inc/dpgroup.hxx
index 99dac0e517db..cb933f4d2a98 100644
--- a/sc/inc/dpgroup.hxx
+++ b/sc/inc/dpgroup.hxx
@@ -33,6 +33,7 @@
#include <vector>
#include <hash_set>
+#include <boost/shared_ptr.hpp>
#include "dptabdat.hxx"
#include "scdllapi.h"
@@ -182,7 +183,7 @@ class ScDPGroupTableData : public ScDPTableData
{
typedef ::std::hash_set< ::rtl::OUString, ::rtl::OUStringHash, ::std::equal_to< ::rtl::OUString > > StringHashSet;
- ScDPTableData* pSourceData;
+ ::boost::shared_ptr<ScDPTableData> pSourceData;
long nSourceCount;
ScDPGroupDimensionVec aGroups;
ScDPNumGroupDimension* pNumGroups; // array[nSourceCount]
@@ -200,7 +201,7 @@ class ScDPGroupTableData : public ScDPTableData
public:
// takes ownership of pSource
- ScDPGroupTableData( ScDPTableData* pSource, ScDocument* pDocument );
+ ScDPGroupTableData( const ::boost::shared_ptr<ScDPTableData>& pSource, ScDocument* pDocument );
virtual ~ScDPGroupTableData();
void AddGroupDimension( const ScDPGroupDimension& rGroup );
diff --git a/sc/inc/dpobject.hxx b/sc/inc/dpobject.hxx
index 1c50c773b4df..f90277769cba 100644
--- a/sc/inc/dpobject.hxx
+++ b/sc/inc/dpobject.hxx
@@ -38,6 +38,8 @@
#include "dpoutput.hxx"
#include <com/sun/star/sheet/XDimensionsSupplier.hpp>
+#include <boost/shared_ptr.hpp>
+
//------------------------------------------------------------------
namespace com { namespace sun { namespace star { namespace sheet {
@@ -66,6 +68,7 @@ class ScStrCollection;
class TypedScStrCollection;
struct PivotField;
class ScDPCacheTable;
+class ScDPTableData;
struct ScDPServiceDesc
{
@@ -101,6 +104,7 @@ private:
ScSheetSourceDesc* pSheetDesc; // for sheet data
ScImportSourceDesc* pImpDesc; // for database data
ScDPServiceDesc* pServDesc; // for external service
+ ::boost::shared_ptr<ScDPTableData> mpTableData;
// cached data
com::sun::star::uno::Reference<com::sun::star::sheet::XDimensionsSupplier> xSource;
ScDPOutput* pOutput;
@@ -112,6 +116,7 @@ private:
bool mbHeaderLayout; // TRUE : grid, FALSE : standard
+ SC_DLLPRIVATE ScDPTableData* GetTableData();
SC_DLLPRIVATE void CreateObjects();
SC_DLLPRIVATE void CreateOutput();
@@ -166,7 +171,14 @@ public:
void SetTag(const String& rNew);
const String& GetTag() const { return aTableTag; }
- BOOL IsDimNameInUse( const String& rName ) const;
+ /**
+ * Data description cell displays the description of a data dimension if
+ * and only if there is only one data dimension. It's usually located at
+ * the upper-left corner of the table output.
+ */
+ bool IsDataDescriptionCell(const ScAddress& rPos);
+
+ bool IsDimNameInUse(const ::rtl::OUString& rName) const;
String GetDimName( long nDim, BOOL& rIsDataLayout );
BOOL IsDuplicated( long nDim );
long GetDimCount();
@@ -230,6 +242,8 @@ public:
// (button attribute must be present)
void RefreshAfterLoad();
+ void BuildAllDimensionMembers();
+
static BOOL HasRegisteredSources();
static com::sun::star::uno::Sequence<rtl::OUString> GetRegisteredSources();
static com::sun::star::uno::Reference<com::sun::star::sheet::XDimensionsSupplier>
diff --git a/sc/inc/dpsave.hxx b/sc/inc/dpsave.hxx
index 44689bcf0772..9d680dfa3856 100644
--- a/sc/inc/dpsave.hxx
+++ b/sc/inc/dpsave.hxx
@@ -34,9 +34,11 @@
#include <tools/string.hxx>
#include <tools/list.hxx>
#include <com/sun/star/sheet/XDimensionsSupplier.hpp>
+#include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
#include "scdllapi.h"
#include <hash_map>
#include <list>
+#include <memory>
namespace com { namespace sun { namespace star { namespace sheet {
struct DataPilotFieldReference;
@@ -46,6 +48,7 @@ namespace com { namespace sun { namespace star { namespace sheet {
} } } }
class ScDPDimensionSaveData;
+class ScDPTableData;
// --------------------------------------------------------------------
//
@@ -57,6 +60,7 @@ class ScDPSaveMember
{
private:
String aName;
+ ::std::auto_ptr<rtl::OUString> mpLayoutName; // custom name to be displayed in the table.
USHORT nVisibleMode;
USHORT nShowDetailsMode;
@@ -77,18 +81,23 @@ public:
void SetName( const String& rNew ); // used if the source member was renamed (groups)
+ SC_DLLPUBLIC void SetLayoutName( const ::rtl::OUString& rName );
+ SC_DLLPUBLIC const ::rtl::OUString* GetLayoutName() const;
+ void RemoveLayoutName();
+
void WriteToSource( const com::sun::star::uno::Reference<
com::sun::star::uno::XInterface>& xMember,
sal_Int32 nPosition );
};
-class ScDPSaveDimension
+class SC_DLLPUBLIC ScDPSaveDimension
{
private:
String aName;
- String* pLayoutName; // alternative name for layout, not used (yet)
String* pSelectedPage;
+ ::std::auto_ptr<rtl::OUString> mpLayoutName;
+ ::std::auto_ptr<rtl::OUString> mpSubtotalName;
BOOL bIsDataLayout;
BOOL bDupFlag;
USHORT nOrientation;
@@ -127,39 +136,44 @@ public:
void SetName( const String& rNew ); // used if the source dim was renamed (groups)
- SC_DLLPUBLIC void SetOrientation(USHORT nNew);
+ void SetOrientation(USHORT nNew);
void SetSubTotals(BOOL bSet); // to be removed!
- SC_DLLPUBLIC void SetSubTotals(long nCount, const USHORT* pFuncs);
+ void SetSubTotals(long nCount, const USHORT* pFuncs);
long GetSubTotalsCount() const { return nSubTotalCount; }
USHORT GetSubTotalFunc(long nIndex) const { return pSubTotalFuncs[nIndex]; }
- SC_DLLPUBLIC void SetShowEmpty(BOOL bSet);
+ void SetShowEmpty(BOOL bSet);
BOOL GetShowEmpty() const { return BOOL(nShowEmptyMode); }
- SC_DLLPUBLIC void SetFunction(USHORT nNew); // enum GeneralFunction
+ void SetFunction(USHORT nNew); // enum GeneralFunction
USHORT GetFunction() const { return nFunction; }
void SetUsedHierarchy(long nNew);
long GetUsedHierarchy() const { return nUsedHierarchy; }
- SC_DLLPUBLIC void SetLayoutName(const String* pName);
- SC_DLLPUBLIC const String& GetLayoutName() const;
- SC_DLLPUBLIC BOOL HasLayoutName() const;
+
+ void SetLayoutName(const ::rtl::OUString& rName);
+ const ::rtl::OUString* GetLayoutName() const;
+ void RemoveLayoutName();
+ void SetSubtotalName(const ::rtl::OUString& rName);
+ const ::rtl::OUString* GetSubtotalName() const;
+
+ bool IsMemberNameInUse(const ::rtl::OUString& rName) const;
const ::com::sun::star::sheet::DataPilotFieldReference* GetReferenceValue() const { return pReferenceValue; }
- SC_DLLPUBLIC void SetReferenceValue(const ::com::sun::star::sheet::DataPilotFieldReference* pNew);
+ void SetReferenceValue(const ::com::sun::star::sheet::DataPilotFieldReference* pNew);
const ::com::sun::star::sheet::DataPilotFieldSortInfo* GetSortInfo() const { return pSortInfo; }
- SC_DLLPUBLIC void SetSortInfo(const ::com::sun::star::sheet::DataPilotFieldSortInfo* pNew);
+ void SetSortInfo(const ::com::sun::star::sheet::DataPilotFieldSortInfo* pNew);
const ::com::sun::star::sheet::DataPilotFieldAutoShowInfo* GetAutoShowInfo() const { return pAutoShowInfo; }
- SC_DLLPUBLIC void SetAutoShowInfo(const ::com::sun::star::sheet::DataPilotFieldAutoShowInfo* pNew);
+ void SetAutoShowInfo(const ::com::sun::star::sheet::DataPilotFieldAutoShowInfo* pNew);
const ::com::sun::star::sheet::DataPilotFieldLayoutInfo* GetLayoutInfo() const { return pLayoutInfo; }
- SC_DLLPUBLIC void SetLayoutInfo(const ::com::sun::star::sheet::DataPilotFieldLayoutInfo* pNew);
+ void SetLayoutInfo(const ::com::sun::star::sheet::DataPilotFieldLayoutInfo* pNew);
- SC_DLLPUBLIC void SetCurrentPage( const String* pPage ); // NULL = no selection (all)
- SC_DLLPUBLIC BOOL HasCurrentPage() const;
- SC_DLLPUBLIC const String& GetCurrentPage() const;
+ void SetCurrentPage( const String* pPage ); // NULL = no selection (all)
+ BOOL HasCurrentPage() const;
+ const String& GetCurrentPage() const;
USHORT GetOrientation() const { return nOrientation; }
ScDPSaveMember* GetExistingMemberByName(const String& rName);
- SC_DLLPUBLIC ScDPSaveMember* GetMemberByName(const String& rName);
+ ScDPSaveMember* GetMemberByName(const String& rName);
void SetMemberPosition( const String& rName, sal_Int32 nNewPos );
@@ -180,6 +194,12 @@ private:
BOOL bFilterButton; // not passed to DataPilotSource
BOOL bDrillDown; // not passed to DataPilotSource
+ /** if true, all dimensions already have all of their member instances
+ * created. */
+ bool mbDimensionMembersBuilt;
+
+ ::std::auto_ptr<rtl::OUString> mpGrandTotalName;
+
public:
SC_DLLPUBLIC ScDPSaveData();
ScDPSaveData(const ScDPSaveData& r);
@@ -189,21 +209,26 @@ public:
BOOL operator== ( const ScDPSaveData& r ) const;
+ SC_DLLPUBLIC void SetGrandTotalName(const ::rtl::OUString& rName);
+ SC_DLLPUBLIC const ::rtl::OUString* GetGrandTotalName() const;
+
const List& GetDimensions() const { return aDimList; }
void AddDimension(ScDPSaveDimension* pDim) { aDimList.Insert(pDim, LIST_APPEND); }
ScDPSaveDimension* GetDimensionByName(const String& rName);
SC_DLLPUBLIC ScDPSaveDimension* GetDataLayoutDimension();
+ SC_DLLPUBLIC ScDPSaveDimension* GetExistingDataLayoutDimension() const;
ScDPSaveDimension* DuplicateDimension(const String& rName);
SC_DLLPUBLIC ScDPSaveDimension& DuplicateDimension(const ScDPSaveDimension& rDim);
- SC_DLLPUBLIC ScDPSaveDimension* GetExistingDimensionByName(const String& rName);
+ SC_DLLPUBLIC ScDPSaveDimension* GetExistingDimensionByName(const String& rName) const;
SC_DLLPUBLIC ScDPSaveDimension* GetNewDimensionByName(const String& rName);
void RemoveDimensionByName(const String& rName);
ScDPSaveDimension* GetInnermostDimension(USHORT nOrientation);
+ ScDPSaveDimension* GetFirstDimension(::com::sun::star::sheet::DataPilotFieldOrientation eOrientation);
long GetDataDimensionCount() const;
@@ -230,6 +255,7 @@ public:
const ScDPDimensionSaveData* GetExistingDimensionData() const { return pDimensionData; }
SC_DLLPUBLIC ScDPDimensionSaveData* GetDimensionData(); // create if not there
void SetDimensionData( const ScDPDimensionSaveData* pNew ); // copied
+ void BuildAllDimensionMembers(ScDPTableData* pData);
};
diff --git a/sc/inc/dptabres.hxx b/sc/inc/dptabres.hxx
index 6dfb782b2313..670c5eb566a4 100644
--- a/sc/inc/dptabres.hxx
+++ b/sc/inc/dptabres.hxx
@@ -41,6 +41,7 @@
#include <hash_map>
#include <hash_set>
#include <vector>
+#include <memory>
namespace com { namespace sun { namespace star { namespace sheet {
struct DataPilotFieldReference;
@@ -262,7 +263,7 @@ public:
long GetMeasureCount() const { return nMeasCount; }
ScSubTotalFunc GetMeasureFunction(long nMeasure) const;
- String GetMeasureString(long nMeasure, BOOL bForce, ScSubTotalFunc eForceFunc) const;
+ String GetMeasureString(long nMeasure, BOOL bForce, ScSubTotalFunc eForceFunc, bool& rbTotalResult) const;
String GetMeasureDimensionName(long nMeasure) const;
const ::com::sun::star::sheet::DataPilotFieldReference& GetMeasureRefVal(long nMeasure) const;
USHORT GetMeasureRefOrient(long nMeasure) const;
@@ -284,6 +285,8 @@ public:
const ScDPItemData& rBaseData, long nBaseIndex ) const;
BOOL HasCommonElement( const ScDPItemData& rFirstData, long nFirstIndex,
const ScDPItemData& rSecondData, long nSecondIndex ) const;
+
+ const ScDPSource* GetSource() const;
};
diff --git a/sc/inc/dptabsrc.hxx b/sc/inc/dptabsrc.hxx
index 59996d08b8aa..5538959b2dfc 100644
--- a/sc/inc/dptabsrc.hxx
+++ b/sc/inc/dptabsrc.hxx
@@ -33,6 +33,7 @@
#include <vector>
#include <hash_map>
+#include <memory>
#include <tools/string.hxx>
#include <tools/list.hxx>
#include "global.hxx" // enum ScSubTotalFunc
@@ -108,7 +109,7 @@ class ScDPSource : public cppu::WeakImplHelper6<
com::sun::star::lang::XServiceInfo >
{
private:
- ScDPTableData* pData; // data source
+ ScDPTableData* pData; // data source (ScDPObject manages its life time)
ScDPDimensions* pDimensions; // api objects
// settings:
long nColDims[SC_DAPI_MAXFIELDS];
@@ -136,6 +137,8 @@ private:
List aRowLevelList;
BOOL bResultOverflow;
+ ::std::auto_ptr<rtl::OUString> mpGrandTotalName;
+
void CreateRes_Impl();
void FillMemberResults();
void FillLevelList( USHORT nOrientation, List& rList );
@@ -162,11 +165,15 @@ public:
ScDPTableData* GetData() { return pData; }
const ScDPTableData* GetData() const { return pData; }
+ void SetGrandTotalName(const ::rtl::OUString& rName);
+ const ::rtl::OUString* GetGrandTotalName() const;
+
USHORT GetOrientation(long nColumn);
void SetOrientation(long nColumn, USHORT nNew);
long GetPosition(long nColumn);
long GetDataDimensionCount();
+ ScDPDimension* GetDataDimension(long nIndex);
String GetDataDimName(long nIndex);
BOOL IsDataLayoutDimension(long nDim);
USHORT GetDataLayoutOrientation();
@@ -333,6 +340,8 @@ private:
long nUsedHier;
USHORT nFunction; // enum GeneralFunction
String aName; // if empty, take from source
+ ::std::auto_ptr<rtl::OUString> mpLayoutName;
+ ::std::auto_ptr<rtl::OUString> mpSubtotalName;
long nSourceDim; // >=0 if dup'ed
::com::sun::star::sheet::DataPilotFieldReference
aReferenceValue; // settings for "show data as" / "displayed value"
@@ -350,6 +359,9 @@ public:
ScDPDimension* CreateCloneObject();
ScDPHierarchies* GetHierarchiesObject();
+ SC_DLLPUBLIC const ::rtl::OUString* GetLayoutName() const;
+ const ::rtl::OUString* GetSubtotalName() const;
+
// XNamed
virtual ::rtl::OUString SAL_CALL getName() throw(::com::sun::star::uno::RuntimeException);
virtual void SAL_CALL setName( const ::rtl::OUString& aName )
@@ -736,7 +748,7 @@ private:
long nLev;
ScDPItemData maData;
-// String aCaption; // visible name (changeable by user)
+ ::std::auto_ptr<rtl::OUString> mpLayoutName;
sal_Int32 nPosition; // manual sorting
BOOL bVisible;
@@ -750,6 +762,7 @@ public:
BOOL IsNamedItem( const ScDPItemData& r ) const;
String GetNameStr() const;
void FillItemData( ScDPItemData& rData ) const;
+ SC_DLLPUBLIC const ::rtl::OUString* GetLayoutName() const;
sal_Int32 Compare( const ScDPMember& rOther ) const; // visible order
diff --git a/sc/inc/unonames.hxx b/sc/inc/unonames.hxx
index 367e7d7cfe35..bfc5aa9de831 100644
--- a/sc/inc/unonames.hxx
+++ b/sc/inc/unonames.hxx
@@ -558,6 +558,9 @@
#define SC_UNO_ROWFIELDCOUNT "RowFieldCount"
#define SC_UNO_COLUMNFIELDCOUNT "ColumnFieldCount"
#define SC_UNO_DATAFIELDCOUNT "DataFieldCount"
+#define SC_UNO_LAYOUTNAME "LayoutName"
+#define SC_UNO_FIELD_SUBTOTALNAME "FieldSubtotalName"
+#define SC_UNO_GRANDTOTAL_NAME "GrandTotalName"
// (preliminary:)
#define SC_UNO_REFVALUE "ReferenceValue"
diff --git a/sc/source/core/data/dpgroup.cxx b/sc/source/core/data/dpgroup.cxx
index a92d1681ec0e..037a232bbd2a 100644
--- a/sc/source/core/data/dpgroup.cxx
+++ b/sc/source/core/data/dpgroup.cxx
@@ -70,6 +70,7 @@ using ::rtl::OUStringHash;
using ::std::vector;
using ::std::hash_set;
using ::std::hash_map;
+using ::boost::shared_ptr;
#define D_TIMEFACTOR 86400.0
@@ -977,7 +978,7 @@ String lcl_GetNumGroupForValue( double fValue, const ScDPNumGroupInfo& rInfo, bo
return lcl_GetNumGroupName( fGroupStart, rInfo, bHasNonInteger, cDecSeparator, pFormatter );
}
-ScDPGroupTableData::ScDPGroupTableData( ScDPTableData* pSource, ScDocument* pDocument ) :
+ScDPGroupTableData::ScDPGroupTableData( const shared_ptr<ScDPTableData>& pSource, ScDocument* pDocument ) :
ScDPTableData(pDocument),
pSourceData( pSource ),
pDoc( pDocument )
@@ -992,7 +993,6 @@ ScDPGroupTableData::ScDPGroupTableData( ScDPTableData* pSource, ScDocument* pDoc
ScDPGroupTableData::~ScDPGroupTableData()
{
delete[] pNumGroups;
- delete pSourceData;
}
void ScDPGroupTableData::AddGroupDimension( const ScDPGroupDimension& rGroup )
diff --git a/sc/source/core/data/dpobject.cxx b/sc/source/core/data/dpobject.cxx
index fa58a8b3c277..cd7d58964a96 100644
--- a/sc/source/core/data/dpobject.cxx
+++ b/sc/source/core/data/dpobject.cxx
@@ -78,6 +78,7 @@
using namespace com::sun::star;
using ::std::vector;
+using ::boost::shared_ptr;
using ::com::sun::star::uno::Sequence;
using ::com::sun::star::uno::Reference;
using ::com::sun::star::uno::UNO_QUERY;
@@ -162,6 +163,7 @@ ScDPObject::ScDPObject( ScDocument* pD ) :
pSheetDesc( NULL ),
pImpDesc( NULL ),
pServDesc( NULL ),
+ mpTableData(static_cast<ScDPTableData*>(NULL)),
pOutput( NULL ),
bSettingsChanged( FALSE ),
bAlive( FALSE ),
@@ -182,6 +184,7 @@ ScDPObject::ScDPObject(const ScDPObject& r) :
pSheetDesc( NULL ),
pImpDesc( NULL ),
pServDesc( NULL ),
+ mpTableData(static_cast<ScDPTableData*>(NULL)),
pOutput( NULL ),
bSettingsChanged( FALSE ),
bAlive( FALSE ),
@@ -349,6 +352,22 @@ void ScDPObject::SetTag(const String& rNew)
aTableTag = rNew;
}
+bool ScDPObject::IsDataDescriptionCell(const ScAddress& rPos)
+{
+ if (!pSaveData)
+ return false;
+
+ long nDataDimCount = pSaveData->GetDataDimensionCount();
+ if (nDataDimCount != 1)
+ // There has to be exactly one data dimension for the description to
+ // appear at top-left corner.
+ return false;
+
+ CreateOutput();
+ ScRange aTabRange = pOutput->GetOutputRange(sheet::DataPilotOutputRangeType::TABLE);
+ return (rPos == aTabRange.aStart);
+}
+
uno::Reference<sheet::XDimensionsSupplier> ScDPObject::GetSource()
{
CreateObjects();
@@ -390,11 +409,43 @@ void ScDPObject::CreateOutput()
}
}
+ScDPTableData* ScDPObject::GetTableData()
+{
+ if (!mpTableData)
+ {
+ if ( pImpDesc )
+ {
+ // database data
+ mpTableData.reset(new ScDatabaseDPData(pDoc, *pImpDesc));
+ }
+ else
+ {
+ // cell data
+ if (!pSheetDesc)
+ {
+ DBG_ERROR("no source descriptor");
+ pSheetDesc = new ScSheetSourceDesc; // dummy defaults
+ }
+ mpTableData.reset(new ScSheetDPData(pDoc, *pSheetDesc));
+ }
+
+ // grouping (for cell or database data)
+ if ( pSaveData && pSaveData->GetExistingDimensionData() )
+ {
+ shared_ptr<ScDPGroupTableData> pGroupData(new ScDPGroupTableData(mpTableData, pDoc));
+ pSaveData->GetExistingDimensionData()->WriteToData(*pGroupData);
+ mpTableData = pGroupData;
+ }
+ }
+
+ return mpTableData.get();
+}
+
void ScDPObject::CreateObjects()
{
// if groups are involved, create a new source with the ScDPGroupTableData
if ( bSettingsChanged && pSaveData && pSaveData->GetExistingDimensionData() )
- xSource = NULL;
+ InvalidateSource();
if (!xSource.is())
{
@@ -412,33 +463,9 @@ void ScDPObject::CreateObjects()
if ( !xSource.is() ) // database or sheet data, or error in CreateSource
{
DBG_ASSERT( !pServDesc, "DPSource could not be created" );
-
- ScDPTableData* pData = NULL;
- if ( pImpDesc )
- {
- // database data
- pData = new ScDatabaseDPData( pDoc, *pImpDesc );
- }
- else
- {
- // cell data
- if (!pSheetDesc)
- {
- DBG_ERROR("no source descriptor");
- pSheetDesc = new ScSheetSourceDesc; // dummy defaults
- }
- pData = new ScSheetDPData( pDoc, *pSheetDesc );
- }
-
- // grouping (for cell or database data)
- if ( pSaveData && pSaveData->GetExistingDimensionData() )
- {
- ScDPGroupTableData* pGroupData = new ScDPGroupTableData( pData, pDoc );
- pSaveData->GetExistingDimensionData()->WriteToData( *pGroupData );
- pData = pGroupData;
- }
-
- xSource = new ScDPSource( pData );
+ ScDPTableData* pData = GetTableData();
+ ScDPSource* pSource = new ScDPSource( pData );
+ xSource = pSource;
}
if (pSaveData)
@@ -475,6 +502,7 @@ void ScDPObject::InvalidateData()
void ScDPObject::InvalidateSource()
{
xSource = NULL;
+ mpTableData.reset();
}
ScRange ScDPObject::GetNewOutputRange( BOOL& rOverflow )
@@ -556,6 +584,14 @@ void ScDPObject::RefreshAfterLoad()
nHeaderRows = 0; // nothing found, no drop-down lists
}
+void ScDPObject::BuildAllDimensionMembers()
+{
+ if (!pSaveData)
+ return;
+
+ pSaveData->BuildAllDimensionMembers(GetTableData());
+}
+
void ScDPObject::UpdateReference( UpdateRefMode eUpdateRefMode,
const ScRange& rRange, SCsCOL nDx, SCsROW nDy, SCsTAB nDz )
{
@@ -678,23 +714,33 @@ void ScDPObject::GetDrillDownData(const ScAddress& rPos, Sequence< Sequence<Any>
rTableData = xDrillDownData->getDrillDownData(filters);
}
-BOOL ScDPObject::IsDimNameInUse( const String& rName ) const
+bool ScDPObject::IsDimNameInUse(const OUString& rName) const
{
- if ( xSource.is() )
+ if (!xSource.is())
+ return false;
+
+ Reference<container::XNameAccess> xDims = xSource->getDimensions();
+ Sequence<OUString> aDimNames = xDims->getElementNames();
+ sal_Int32 n = aDimNames.getLength();
+ for (sal_Int32 i = 0; i < n; ++i)
{
- uno::Reference<container::XNameAccess> xDimsName = xSource->getDimensions();
- if ( xDimsName.is() )
+ const OUString& rDimName = aDimNames[i];
+ if (rDimName.equalsIgnoreAsciiCase(rName))
+ return true;
+
+ Reference<beans::XPropertySet> xPropSet(xDims->getByName(rDimName), UNO_QUERY);
+ if (!xPropSet.is())
+ continue;
+
+ Any any = xPropSet->getPropertyValue(OUString::createFromAscii(SC_UNO_LAYOUTNAME));
+ OUString aLayoutName;
+ if (any >>= aLayoutName)
{
- rtl::OUString aCompare( rName );
- uno::Sequence<rtl::OUString> aNames = xDimsName->getElementNames();
- long nCount = aNames.getLength();
- const rtl::OUString* pArr = aNames.getConstArray();
- for (long nPos=0; nPos<nCount; nPos++)
- if ( pArr[nPos] == aCompare ) //! ignore case
- return TRUE;
+ if (aLayoutName.equalsIgnoreAsciiCase(rName))
+ return true;
}
}
- return FALSE; // not found
+ return false;
}
String ScDPObject::GetDimName( long nDim, BOOL& rIsDataLayout )
diff --git a/sc/source/core/data/dpoutput.cxx b/sc/source/core/data/dpoutput.cxx
index 567dcc7991f3..d376ed3cd396 100644
--- a/sc/source/core/data/dpoutput.cxx
+++ b/sc/source/core/data/dpoutput.cxx
@@ -81,6 +81,7 @@
using namespace com::sun::star;
using ::std::vector;
+using ::com::sun::star::beans::XPropertySet;
using ::com::sun::star::uno::Sequence;
using ::com::sun::star::uno::UNO_QUERY;
using ::com::sun::star::uno::Reference;
@@ -98,7 +99,6 @@ using ::rtl::OUString;
#define DP_PROP_ORIENTATION "Orientation"
#define DP_PROP_POSITION "Position"
#define DP_PROP_USEDHIERARCHY "UsedHierarchy"
-#define DP_PROP_DATADESCR "DataDescription"
#define DP_PROP_ISDATALAYOUT "IsDataLayoutDimension"
#define DP_PROP_NUMBERFORMAT "NumberFormat"
#define DP_PROP_FILTER "Filter"
@@ -119,7 +119,8 @@ struct ScDPOutLevelData
long nLevel;
long nDimPos;
uno::Sequence<sheet::MemberResult> aResult;
- String aCaption;
+ String maName; /// Name is the internal field name.
+ String aCaption; /// Caption is the name visible in the output table.
ScDPOutLevelData() { nDim = nHier = nLevel = nDimPos = -1; }
@@ -444,7 +445,15 @@ ScDPOutput::ScDPOutput( ScDocument* pD, const uno::Reference<sheet::XDimensionsS
xLevel, uno::UNO_QUERY );
if ( xLevNam.is() && xLevRes.is() )
{
- String aCaption = String(xLevNam->getName()); //! Caption...
+ String aName = xLevNam->getName();
+ OUString aCaption = aName; // Caption equals the field name by default.
+ Reference<XPropertySet> xPropSet(xLevel, UNO_QUERY);
+ if (xPropSet.is())
+ {
+ Any any = xPropSet->getPropertyValue(
+ OUString::createFromAscii(SC_UNO_LAYOUTNAME));
+ any >>= aCaption;
+ }
switch ( eDimOrient )
{
case sheet::DataPilotFieldOrientation_COLUMN:
@@ -453,6 +462,7 @@ ScDPOutput::ScDPOutput( ScDocument* pD, const uno::Reference<sheet::XDimensionsS
pColFields[nColFieldCount].nLevel = nLev;
pColFields[nColFieldCount].nDimPos = nDimPos;
pColFields[nColFieldCount].aResult = xLevRes->getResults();
+ pColFields[nColFieldCount].maName = aName;
pColFields[nColFieldCount].aCaption= aCaption;
if (!lcl_MemberEmpty(pColFields[nColFieldCount].aResult))
++nColFieldCount;
@@ -463,6 +473,7 @@ ScDPOutput::ScDPOutput( ScDocument* pD, const uno::Reference<sheet::XDimensionsS
pRowFields[nRowFieldCount].nLevel = nLev;
pRowFields[nRowFieldCount].nDimPos = nDimPos;
pRowFields[nRowFieldCount].aResult = xLevRes->getResults();
+ pRowFields[nRowFieldCount].maName = aName;
pRowFields[nRowFieldCount].aCaption= aCaption;
if (!lcl_MemberEmpty(pRowFields[nRowFieldCount].aResult))
++nRowFieldCount;
@@ -473,6 +484,7 @@ ScDPOutput::ScDPOutput( ScDocument* pD, const uno::Reference<sheet::XDimensionsS
pPageFields[nPageFieldCount].nLevel = nLev;
pPageFields[nPageFieldCount].nDimPos = nDimPos;
pPageFields[nPageFieldCount].aResult = lcl_GetSelectedPageAsResult(xDimProp);
+ pPageFields[nPageFieldCount].maName = aName;
pPageFields[nPageFieldCount].aCaption= aCaption;
// no check on results for page fields
++nPageFieldCount;
@@ -529,7 +541,7 @@ ScDPOutput::ScDPOutput( ScDocument* pD, const uno::Reference<sheet::XDimensionsS
try
{
uno::Any aAny = xSrcProp->getPropertyValue(
- rtl::OUString::createFromAscii(DP_PROP_DATADESCR) );
+ rtl::OUString::createFromAscii(SC_UNO_DATADESC) );
rtl::OUString aUStr;
aAny >>= aUStr;
aDataDescription = String( aUStr );
@@ -606,9 +618,16 @@ void ScDPOutput::HeaderCell( SCCOL nCol, SCROW nRow, SCTAB nTab,
const sheet::MemberResult& rData, BOOL bColHeader, long nLevel )
{
long nFlags = rData.Flags;
+
+ rtl::OUStringBuffer aCaptionBuf;
+ if (!(nFlags & sheet::MemberResultFlags::NUMERIC))
+ // This caption is not a number. Make sure it won't get parsed as one.
+ aCaptionBuf.append(sal_Unicode('\''));
+ aCaptionBuf.append(rData.Caption);
+
if ( nFlags & sheet::MemberResultFlags::HASMEMBER )
{
- pDoc->SetString( nCol, nRow, nTab, rData.Caption );
+ pDoc->SetString( nCol, nRow, nTab, aCaptionBuf.makeStringAndClear() );
}
else
{
@@ -1161,7 +1180,7 @@ bool ScDPOutput::GetDataResultPositionData(vector<sheet::DataPilotFieldFilter>&
for (SCCOL nColField = 0; nColField < nColFieldCount && bFilterByCol; ++nColField)
{
sheet::DataPilotFieldFilter filter;
- filter.FieldName = pColFields[nColField].aCaption;
+ filter.FieldName = pColFields[nColField].maName;
const uno::Sequence<sheet::MemberResult> rSequence = pColFields[nColField].aResult;
const sheet::MemberResult* pArray = rSequence.getConstArray();
@@ -1178,10 +1197,15 @@ bool ScDPOutput::GetDataResultPositionData(vector<sheet::DataPilotFieldFilter>&
}
// row fields
+ bool bDataLayoutExists = (nDataFieldCount > 1);
for (SCROW nRowField = 0; nRowField < nRowFieldCount && bFilterByRow; ++nRowField)
{
+ if (bDataLayoutExists && nRowField == nRowFieldCount - 1)
+ // There is no sense including the data layout field for filtering.
+ continue;
+
sheet::DataPilotFieldFilter filter;
- filter.FieldName = pRowFields[nRowField].aCaption;
+ filter.FieldName = pRowFields[nRowField].maName;
const uno::Sequence<sheet::MemberResult> rSequence = pRowFields[nRowField].aResult;
const sheet::MemberResult* pArray = rSequence.getConstArray();
@@ -1213,8 +1237,7 @@ bool lcl_IsNamedDataField( const ScDPGetPivotDataField& rTarget, const String& r
bool lcl_IsNamedCategoryField( const ScDPGetPivotDataField& rFilter, const ScDPOutLevelData& rField )
{
- //! name from source instead of caption?
- return ScGlobal::pTransliteration->isEqual( rFilter.maFieldName, rField.aCaption );
+ return ScGlobal::pTransliteration->isEqual( rFilter.maFieldName, rField.maName );
}
bool lcl_IsCondition( const sheet::MemberResult& rResultEntry, const ScDPGetPivotDataField& rFilter )
diff --git a/sc/source/core/data/dpsave.cxx b/sc/source/core/data/dpsave.cxx
index f4180312ce0d..ba1acc97a83a 100644
--- a/sc/source/core/data/dpsave.cxx
+++ b/sc/source/core/data/dpsave.cxx
@@ -58,7 +58,12 @@
#include <com/sun/star/container/XNamed.hpp>
#include <com/sun/star/util/XCloneable.hpp>
+#include <hash_map>
+
using namespace com::sun::star;
+using ::rtl::OUString;
+using ::std::hash_map;
+using ::std::auto_ptr;
// -----------------------------------------------------------------------
@@ -113,6 +118,7 @@ void lcl_SkipExtra( SvStream& rStream )
ScDPSaveMember::ScDPSaveMember(const String& rName) :
aName( rName ),
+ mpLayoutName(NULL),
nVisibleMode( SC_DPSAVEMODE_DONTKNOW ),
nShowDetailsMode( SC_DPSAVEMODE_DONTKNOW )
{
@@ -120,9 +126,12 @@ ScDPSaveMember::ScDPSaveMember(const String& rName) :
ScDPSaveMember::ScDPSaveMember(const ScDPSaveMember& r) :
aName( r.aName ),
+ mpLayoutName(NULL),
nVisibleMode( r.nVisibleMode ),
nShowDetailsMode( r.nShowDetailsMode )
{
+ if (r.mpLayoutName.get())
+ mpLayoutName.reset(new OUString(*r.mpLayoutName));
}
ScDPSaveMember::~ScDPSaveMember()
@@ -167,6 +176,21 @@ void ScDPSaveMember::SetName( const String& rNew )
aName = rNew;
}
+void ScDPSaveMember::SetLayoutName( const OUString& rName )
+{
+ mpLayoutName.reset(new OUString(rName));
+}
+
+const OUString* ScDPSaveMember::GetLayoutName() const
+{
+ return mpLayoutName.get();
+}
+
+void ScDPSaveMember::RemoveLayoutName()
+{
+ mpLayoutName.reset(NULL);
+}
+
void ScDPSaveMember::WriteToSource( const uno::Reference<uno::XInterface>& xMember, sal_Int32 nPosition )
{
// nothing to do?
@@ -187,6 +211,18 @@ void ScDPSaveMember::WriteToSource( const uno::Reference<uno::XInterface>& xMemb
lcl_SetBoolProperty( xMembProp,
rtl::OUString::createFromAscii(DP_PROP_SHOWDETAILS), (BOOL)nShowDetailsMode );
+ if (mpLayoutName.get())
+ {
+ try
+ {
+ uno::Any any;
+ any <<= rtl::OUString(*mpLayoutName);
+ xMembProp->setPropertyValue(rtl::OUString::createFromAscii(SC_UNO_LAYOUTNAME), any);
+ }
+ catch (uno::Exception&)
+ {
+ }
+ }
if ( nPosition >= 0 )
{
try
@@ -205,8 +241,9 @@ void ScDPSaveMember::WriteToSource( const uno::Reference<uno::XInterface>& xMemb
ScDPSaveDimension::ScDPSaveDimension(const String& rName, BOOL bDataLayout) :
aName( rName ),
- pLayoutName( NULL ),
pSelectedPage( NULL ),
+ mpLayoutName(NULL),
+ mpSubtotalName(NULL),
bIsDataLayout( bDataLayout ),
bDupFlag( FALSE ),
nOrientation( sheet::DataPilotFieldOrientation_HIDDEN ),
@@ -225,6 +262,8 @@ ScDPSaveDimension::ScDPSaveDimension(const String& rName, BOOL bDataLayout) :
ScDPSaveDimension::ScDPSaveDimension(const ScDPSaveDimension& r) :
aName( r.aName ),
+ mpLayoutName(NULL),
+ mpSubtotalName(NULL),
bIsDataLayout( r.bIsDataLayout ),
bDupFlag( r.bDupFlag ),
nOrientation( r.nOrientation ),
@@ -265,14 +304,14 @@ ScDPSaveDimension::ScDPSaveDimension(const ScDPSaveDimension& r) :
pLayoutInfo = new sheet::DataPilotFieldLayoutInfo( *(r.pLayoutInfo) );
else
pLayoutInfo = NULL;
- if (r.pLayoutName)
- pLayoutName = new String( *(r.pLayoutName) );
- else
- pLayoutName = NULL;
if (r.pSelectedPage)
pSelectedPage = new String( *(r.pSelectedPage) );
else
pSelectedPage = NULL;
+ if (r.mpLayoutName.get())
+ mpLayoutName.reset(new OUString(*r.mpLayoutName));
+ if (r.mpSubtotalName.get())
+ mpSubtotalName.reset(new OUString(*r.mpSubtotalName));
}
ScDPSaveDimension::~ScDPSaveDimension()
@@ -283,7 +322,6 @@ ScDPSaveDimension::~ScDPSaveDimension()
delete pSortInfo;
delete pAutoShowInfo;
delete pLayoutInfo;
- delete pLayoutName;
delete pSelectedPage;
delete [] pSubTotalFuncs;
}
@@ -395,25 +433,45 @@ void ScDPSaveDimension::SetUsedHierarchy(long nNew)
nUsedHierarchy = nNew;
}
-BOOL ScDPSaveDimension::HasLayoutName() const
+void ScDPSaveDimension::SetSubtotalName(const OUString& rName)
{
- return ( pLayoutName != NULL );
+ mpSubtotalName.reset(new OUString(rName));
}
-void ScDPSaveDimension::SetLayoutName(const String* pName)
+const OUString* ScDPSaveDimension::GetSubtotalName() const
{
- delete pLayoutName;
- if (pName)
- pLayoutName = new String( *pName );
- else
- pLayoutName = NULL;
+ return mpSubtotalName.get();
+}
+
+bool ScDPSaveDimension::IsMemberNameInUse(const OUString& rName) const
+{
+ MemberList::const_iterator itr = maMemberList.begin(), itrEnd = maMemberList.end();
+ for (; itr != itrEnd; ++itr)
+ {
+ const ScDPSaveMember* pMem = *itr;
+ if (rName.equalsIgnoreAsciiCase(pMem->GetName()))
+ return true;
+
+ const OUString* pLayoutName = pMem->GetLayoutName();
+ if (pLayoutName && rName.equalsIgnoreAsciiCase(*pLayoutName))
+ return true;
+ }
+ return false;
+}
+
+void ScDPSaveDimension::SetLayoutName(const OUString& rName)
+{
+ mpLayoutName.reset(new OUString(rName));
}
-const String& ScDPSaveDimension::GetLayoutName() const
+const OUString* ScDPSaveDimension::GetLayoutName() const
{
- if (pLayoutName)
- return *pLayoutName;
- return aName;
+ return mpLayoutName.get();
+}
+
+void ScDPSaveDimension::RemoveLayoutName()
+{
+ mpLayoutName.reset(NULL);
}
void ScDPSaveDimension::SetReferenceValue(const sheet::DataPilotFieldReference* pNew)
@@ -549,6 +607,19 @@ void ScDPSaveDimension::WriteToSource( const uno::Reference<uno::XInterface>& xD
{
aAny <<= aFilter;
xDimProp->setPropertyValue( rtl::OUString::createFromAscii(DP_PROP_FILTER), aAny );
+ if (mpLayoutName.get())
+ {
+ aAny <<= *mpLayoutName;
+ xDimProp->setPropertyValue(rtl::OUString::createFromAscii(SC_UNO_LAYOUTNAME), aAny);
+ }
+
+ const OUString* pSubTotalName = GetSubtotalName();
+ if (pSubTotalName)
+ {
+ // Custom subtotal name, with '?' being replaced by the visible field name later.
+ aAny <<= *pSubTotalName;
+ xDimProp->setPropertyValue(OUString::createFromAscii(SC_UNO_FIELD_SUBTOTALNAME), aAny);
+ }
}
catch ( beans::UnknownPropertyException& )
{
@@ -691,7 +762,9 @@ ScDPSaveData::ScDPSaveData() :
nIgnoreEmptyMode( SC_DPSAVEMODE_DONTKNOW ),
nRepeatEmptyMode( SC_DPSAVEMODE_DONTKNOW ),
bFilterButton( TRUE ),
- bDrillDown( TRUE )
+ bDrillDown( TRUE ),
+ mbDimensionMembersBuilt(false),
+ mpGrandTotalName(NULL)
{
}
@@ -701,7 +774,9 @@ ScDPSaveData::ScDPSaveData(const ScDPSaveData& r) :
nIgnoreEmptyMode( r.nIgnoreEmptyMode ),
nRepeatEmptyMode( r.nRepeatEmptyMode ),
bFilterButton( r.bFilterButton ),
- bDrillDown( r.bDrillDown )
+ bDrillDown( r.bDrillDown ),
+ mbDimensionMembersBuilt(r.mbDimensionMembersBuilt),
+ mpGrandTotalName(NULL)
{
if ( r.pDimensionData )
pDimensionData = new ScDPDimensionSaveData( *r.pDimensionData );
@@ -714,6 +789,9 @@ ScDPSaveData::ScDPSaveData(const ScDPSaveData& r) :
ScDPSaveDimension* pNew = new ScDPSaveDimension( *(ScDPSaveDimension*)r.aDimList.GetObject(i) );
aDimList.Insert( pNew, LIST_APPEND );
}
+
+ if (r.mpGrandTotalName.get())
+ mpGrandTotalName.reset(new OUString(*r.mpGrandTotalName));
}
ScDPSaveData& ScDPSaveData::operator= ( const ScDPSaveData& r )
@@ -732,6 +810,7 @@ ScDPSaveData& ScDPSaveData::operator= ( const ScDPSaveData& r )
nRepeatEmptyMode = r.nRepeatEmptyMode;
bFilterButton = r.bFilterButton;
bDrillDown = r.bDrillDown;
+ mbDimensionMembersBuilt = r.mbDimensionMembersBuilt;
// remove old dimensions
@@ -750,6 +829,9 @@ ScDPSaveData& ScDPSaveData::operator= ( const ScDPSaveData& r )
new ScDPSaveDimension( *(ScDPSaveDimension*)r.aDimList.GetObject(i) );
aDimList.Insert( pNew, LIST_APPEND );
}
+
+ if (r.mpGrandTotalName.get())
+ mpGrandTotalName.reset(new OUString(*r.mpGrandTotalName));
}
return *this;
}
@@ -761,7 +843,8 @@ BOOL ScDPSaveData::operator== ( const ScDPSaveData& r ) const
nIgnoreEmptyMode != r.nIgnoreEmptyMode ||
nRepeatEmptyMode != r.nRepeatEmptyMode ||
bFilterButton != r.bFilterButton ||
- bDrillDown != r.bDrillDown )
+ bDrillDown != r.bDrillDown ||
+ mbDimensionMembersBuilt != r.mbDimensionMembersBuilt)
return FALSE;
if ( pDimensionData || r.pDimensionData )
@@ -777,6 +860,16 @@ BOOL ScDPSaveData::operator== ( const ScDPSaveData& r ) const
*(ScDPSaveDimension*)r.aDimList.GetObject(i) ) )
return FALSE;
+ if (mpGrandTotalName.get())
+ {
+ if (!r.mpGrandTotalName.get())
+ return false;
+ if (!mpGrandTotalName->equals(*r.mpGrandTotalName))
+ return false;
+ }
+ else if (r.mpGrandTotalName.get())
+ return false;
+
return TRUE;
}
@@ -790,6 +883,16 @@ ScDPSaveData::~ScDPSaveData()
delete pDimensionData;
}
+void ScDPSaveData::SetGrandTotalName(const OUString& rName)
+{
+ mpGrandTotalName.reset(new OUString(rName));
+}
+
+const OUString* ScDPSaveData::GetGrandTotalName() const
+{
+ return mpGrandTotalName.get();
+}
+
ScDPSaveDimension* ScDPSaveData::GetDimensionByName(const String& rName)
{
long nCount = aDimList.Count();
@@ -804,7 +907,7 @@ ScDPSaveDimension* ScDPSaveData::GetDimensionByName(const String& rName)
return pNew;
}
-ScDPSaveDimension* ScDPSaveData::GetExistingDimensionByName(const String& rName)
+ScDPSaveDimension* ScDPSaveData::GetExistingDimensionByName(const String& rName) const
{
long nCount = aDimList.Count();
for (long i=0; i<nCount; i++)
@@ -832,16 +935,25 @@ ScDPSaveDimension* ScDPSaveData::GetNewDimensionByName(const String& rName)
ScDPSaveDimension* ScDPSaveData::GetDataLayoutDimension()
{
- ULONG nCount = aDimList.Count();
- for (ULONG i=0; i<nCount; i++)
+ ScDPSaveDimension* pDim = GetExistingDataLayoutDimension();
+ if (pDim)
+ return pDim;
+
+ ScDPSaveDimension* pNew = new ScDPSaveDimension( String(), TRUE );
+ aDimList.Insert( pNew, LIST_APPEND );
+ return pNew;
+}
+
+ScDPSaveDimension* ScDPSaveData::GetExistingDataLayoutDimension() const
+{
+ long nCount = aDimList.Count();
+ for (long i=0; i<nCount; i++)
{
ScDPSaveDimension* pDim = (ScDPSaveDimension*)aDimList.GetObject(i);
if ( pDim->IsDataLayout() )
return pDim;
}
- ScDPSaveDimension* pNew = new ScDPSaveDimension( String(), TRUE );
- aDimList.Insert( pNew, LIST_APPEND );
- return pNew;
+ return NULL;
}
ScDPSaveDimension* ScDPSaveData::DuplicateDimension(const String& rName)
@@ -895,6 +1007,18 @@ ScDPSaveDimension* ScDPSaveData::GetInnermostDimension(USHORT nOrientation)
return pInner; // the last matching one
}
+ScDPSaveDimension* ScDPSaveData::GetFirstDimension(sheet::DataPilotFieldOrientation eOrientation)
+{
+ long nCount = aDimList.Count();
+ for (long i = 0; i < nCount; ++i)
+ {
+ ScDPSaveDimension* pDim = static_cast<ScDPSaveDimension*>(aDimList.GetObject(i));
+ if (pDim->GetOrientation() == eOrientation && !pDim->IsDataLayout())
+ return pDim;
+ }
+ return NULL;
+}
+
long ScDPSaveData::GetDataDimensionCount() const
{
long nDataCount = 0;
@@ -1002,6 +1126,14 @@ void ScDPSaveData::WriteToSource( const uno::Reference<sheet::XDimensionsSupplie
if ( nRepeatEmptyMode != SC_DPSAVEMODE_DONTKNOW )
lcl_SetBoolProperty( xSourceProp,
rtl::OUString::createFromAscii(DP_PROP_REPEATIFEMPTY), (BOOL)nRepeatEmptyMode );
+
+ const OUString* pGrandTotalName = GetGrandTotalName();
+ if (pGrandTotalName)
+ {
+ uno::Any any;
+ any <<= *pGrandTotalName;
+ xSourceProp->setPropertyValue(OUString::createFromAscii(SC_UNO_GRANDTOTAL_NAME), any);
+ }
}
catch(uno::Exception&)
{
@@ -1125,3 +1257,50 @@ void ScDPSaveData::SetDimensionData( const ScDPDimensionSaveData* pNew )
pDimensionData = NULL;
}
+void ScDPSaveData::BuildAllDimensionMembers(ScDPTableData* pData)
+{
+ if (mbDimensionMembersBuilt)
+ return;
+
+ // First, build a dimension name-to-index map.
+ typedef hash_map<OUString, long, ::rtl::OUStringHash> NameIndexMap;
+ NameIndexMap aMap;
+ long nColCount = pData->GetColumnCount();
+ for (long i = 0; i < nColCount; ++i)
+ aMap.insert( NameIndexMap::value_type(pData->getDimensionName(i), i));
+
+ NameIndexMap::const_iterator itrEnd = aMap.end();
+
+ sal_uInt32 n = aDimList.Count();
+ for (sal_uInt32 i = 0; i < n; ++i)
+ {
+ ScDPSaveDimension* pDim = static_cast<ScDPSaveDimension*>(aDimList.GetObject(i));
+ const String& rDimName = pDim->GetName();
+ if (!rDimName.Len())
+ // empty dimension name. It must be data layout.
+ continue;
+
+ NameIndexMap::const_iterator itr = aMap.find(rDimName);
+ if (itr == itrEnd)
+ // dimension name not in the data. This should never happen!
+ continue;
+
+ long nDimIndex = itr->second;
+ const TypedScStrCollection& rMembers = pData->GetColumnEntries(nDimIndex);
+ sal_uInt16 nMemberCount = rMembers.GetCount();
+ for (sal_uInt16 j = 0; j < nMemberCount; ++j)
+ {
+ const String& rMemName = rMembers[j]->GetString();
+ if (pDim->GetExistingMemberByName(rMemName))
+ // this member instance already exists. nothing to do.
+ continue;
+
+ auto_ptr<ScDPSaveMember> pNewMember(new ScDPSaveMember(rMemName));
+ pNewMember->SetIsVisible(true);
+ pDim->AddMember(pNewMember.release());
+ }
+ }
+
+ mbDimensionMembersBuilt = true;
+}
+
diff --git a/sc/source/core/data/dptabres.cxx b/sc/source/core/data/dptabres.cxx
index 398d4d1c7e01..07a783bdb2b1 100644
--- a/sc/source/core/data/dptabres.cxx
+++ b/sc/source/core/data/dptabres.cxx
@@ -67,6 +67,7 @@ using ::std::vector;
using ::std::pair;
using ::std::hash_map;
using ::com::sun::star::uno::Sequence;
+using ::rtl::OUString;
// -----------------------------------------------------------------------
@@ -825,11 +826,11 @@ USHORT ScDPResultData::GetMeasureRefOrient(long nMeasure) const
return pMeasRefOrient[nMeasure];
}
-String ScDPResultData::GetMeasureString(long nMeasure, BOOL bForce, ScSubTotalFunc eForceFunc) const
+String ScDPResultData::GetMeasureString(long nMeasure, BOOL bForce, ScSubTotalFunc eForceFunc, bool& rbTotalResult) const
{
// with bForce==TRUE, return function instead of "result" for single measure
// with eForceFunc != SUBTOTAL_FUNC_NONE, always use eForceFunc
-
+ rbTotalResult = false;
if ( nMeasure < 0 || ( nMeasCount == 1 && !bForce && eForceFunc == SUBTOTAL_FUNC_NONE ) )
{
// for user-specified subtotal function with all measures,
@@ -837,12 +838,19 @@ String ScDPResultData::GetMeasureString(long nMeasure, BOOL bForce, ScSubTotalFu
if ( eForceFunc != SUBTOTAL_FUNC_NONE )
return ScGlobal::GetRscString(nFuncStrIds[eForceFunc]);
+ rbTotalResult = true;
return ScGlobal::GetRscString(STR_TABLE_ERGEBNIS);
}
else
{
DBG_ASSERT( pMeasNames && nMeasure < nMeasCount, "bumm" );
-
+ ScDPDimension* pDataDim = pSource->GetDataDimension(nMeasure);
+ if (pDataDim)
+ {
+ const OUString* pLayoutName = pDataDim->GetLayoutName();
+ if (pLayoutName)
+ return *pLayoutName;
+ }
String aRet;
ScSubTotalFunc eFunc = ( eForceFunc == SUBTOTAL_FUNC_NONE ) ?
GetMeasureFunction(nMeasure) : eForceFunc;
@@ -896,6 +904,11 @@ BOOL ScDPResultData::HasCommonElement( const ScDPItemData& rFirstData, long nFir
return pSource->GetData()->HasCommonElement( rFirstData, nFirstIndex, rSecondData, nSecondIndex );
}
+const ScDPSource* ScDPResultData::GetSource() const
+{
+ return pSource;
+}
+
// -----------------------------------------------------------------------
@@ -1172,6 +1185,25 @@ void ScDPResultMember::ProcessData( const vector<ScDPItemData>& aChildMembers, c
}
}
+/**
+ * Parse subtotal string and replace all occurrences of '?' with the
+ * caption string.
+ */
+static String lcl_parseSubtotalName(const String& rSubStr, const String& rCaption)
+{
+ String aNewStr;
+ xub_StrLen n = rSubStr.Len();
+ for (xub_StrLen i = 0; i < n; ++i)
+ {
+ sal_Unicode c = rSubStr.GetChar(i);
+ if (c == sal_Unicode('?'))
+ aNewStr.Append(rCaption);
+ else
+ aNewStr.Append(c);
+ }
+ return aNewStr;
+}
+
void ScDPResultMember::FillMemberResults( uno::Sequence<sheet::MemberResult>* pSequences,
long& rPos, long nMeasure, BOOL bRoot,
const String* pMemberName,
@@ -1204,17 +1236,25 @@ void ScDPResultMember::FillMemberResults( uno::Sequence<sheet::MemberResult>* pS
}
String aCaption = aName;
+ if (pMemberDesc)
+ {
+ const OUString* pLayoutName = pMemberDesc->GetLayoutName();
+ if (pLayoutName)
+ {
+ aCaption = *pLayoutName;
+ bIsNumeric = false; // layout name is always non-numeric.
+ }
+ }
+
if ( pMemberCaption ) // use pMemberCaption if != NULL
aCaption = *pMemberCaption;
if (!aCaption.Len())
aCaption = ScGlobal::GetRscString(STR_EMPTYDATA);
- if ( !bIsNumeric )
- {
- // add a "'" character so a string isn't parsed as value in the output cell
- //! have a separate bit in Flags (MemberResultFlags) instead?
- aCaption.Insert( (sal_Unicode) '\'', 0 );
- }
+ if (bIsNumeric)
+ pArray[rPos].Flags |= sheet::MemberResultFlags::NUMERIC;
+ else
+ pArray[rPos].Flags &= ~sheet::MemberResultFlags::NUMERIC;
if ( nSize && !bRoot ) // root is overwritten by first dimension
{
@@ -1277,9 +1317,30 @@ void ScDPResultMember::FillMemberResults( uno::Sequence<sheet::MemberResult>* pS
if (bHasChild)
eForce = lcl_GetForceFunc( pParentLevel, nUserPos );
- String aSubStr = aName; //! caption?
+ bool bTotalResult = false;
+ String aSubStr = aCaption;
aSubStr += ' ';
- aSubStr += pResultData->GetMeasureString(nMemberMeasure, FALSE, eForce);
+ aSubStr += pResultData->GetMeasureString(nMemberMeasure, FALSE, eForce, bTotalResult);
+
+ if (bTotalResult)
+ {
+ if (pMemberDesc)
+ {
+ // single data field layout.
+ const OUString* pSubtotalName = pParentDim->GetSubtotalName();
+ if (pSubtotalName)
+ aSubStr = lcl_parseSubtotalName(*pSubtotalName, aCaption);
+ pArray[rPos].Flags &= ~sheet::MemberResultFlags::GRANDTOTAL;
+ }
+ else
+ {
+ // root member - subtotal (grand total?) for multi-data field layout.
+ const rtl::OUString* pGrandTotalName = pResultData->GetSource()->GetGrandTotalName();
+ if (pGrandTotalName)
+ aSubStr = *pGrandTotalName;
+ pArray[rPos].Flags |= sheet::MemberResultFlags::GRANDTOTAL;
+ }
+ }
pArray[rPos].Name = rtl::OUString(aName);
pArray[rPos].Caption = rtl::OUString(aSubStr);
@@ -2796,8 +2857,9 @@ void ScDPResultDimension::FillMemberResults( uno::Sequence<sheet::MemberResult>*
// in data layout dimension, use first member with different measures/names
if ( bIsDataLayout )
{
+ bool bTotalResult = false;
String aMbrName = pResultData->GetMeasureDimensionName( nSorted );
- String aMbrCapt = pResultData->GetMeasureString( nSorted, FALSE, SUBTOTAL_FUNC_NONE );
+ String aMbrCapt = pResultData->GetMeasureString( nSorted, FALSE, SUBTOTAL_FUNC_NONE, bTotalResult );
maMemberArray[0]->FillMemberResults( pSequences, nPos, nSorted, FALSE, &aMbrName, &aMbrCapt );
}
else if ( pMember->IsVisible() )
diff --git a/sc/source/core/data/dptabsrc.cxx b/sc/source/core/data/dptabsrc.cxx
index 5fa5c393df37..bc1394307f26 100644
--- a/sc/source/core/data/dptabsrc.cxx
+++ b/sc/source/core/data/dptabsrc.cxx
@@ -85,6 +85,7 @@ using ::com::sun::star::uno::Reference;
using ::com::sun::star::uno::Sequence;
using ::com::sun::star::uno::Any;
using ::com::sun::star::sheet::DataPilotFieldAutoShowInfo;
+using ::rtl::OUString;
// -----------------------------------------------------------------------
@@ -141,15 +142,14 @@ ScDPSource::ScDPSource( ScDPTableData* pD ) :
pRowResRoot( NULL ),
pColResults( NULL ),
pRowResults( NULL ),
- bResultOverflow( FALSE )
+ bResultOverflow( FALSE ),
+ mpGrandTotalName(NULL)
{
pData->SetEmptyFlags( bIgnoreEmptyRows, bRepeatIfEmpty );
}
ScDPSource::~ScDPSource()
{
- delete pData; // ScDPTableData is not ref-counted
-
if (pDimensions)
pDimensions->release(); // ref-counted
@@ -163,6 +163,16 @@ ScDPSource::~ScDPSource()
delete pResData;
}
+void ScDPSource::SetGrandTotalName(const ::rtl::OUString& rName)
+{
+ mpGrandTotalName.reset(new ::rtl::OUString(rName));
+}
+
+const ::rtl::OUString* ScDPSource::GetGrandTotalName() const
+{
+ return mpGrandTotalName.get();
+}
+
USHORT ScDPSource::GetOrientation(long nColumn)
{
long i;
@@ -186,16 +196,21 @@ long ScDPSource::GetDataDimensionCount()
return nDataDimCount;
}
+ScDPDimension* ScDPSource::GetDataDimension(long nIndex)
+{
+ if (nIndex < 0 || nIndex >= nDataDimCount)
+ return NULL;
+
+ long nDimIndex = nDataDims[nIndex];
+ return GetDimensionsObject()->getByIndex(nDimIndex);
+}
+
String ScDPSource::GetDataDimName( long nIndex )
{
String aRet;
- if ( nIndex >= 0 && nIndex < nDataDimCount )
- {
- long nDimIndex = nDataDims[nIndex];
- ScDPDimension* pDim = GetDimensionsObject()->getByIndex(nDimIndex);
- if (pDim)
- aRet = String( pDim->getName() );
- }
+ ScDPDimension* pDim = GetDataDimension(nIndex);
+ if (pDim)
+ aRet = String(pDim->getName());
return aRet;
}
@@ -488,7 +503,10 @@ String ScDPSource::getDataDescription()
String aRet;
if ( pResData->GetMeasureCount() == 1 )
- aRet = pResData->GetMeasureString( 0, TRUE, SUBTOTAL_FUNC_NONE );
+ {
+ bool bTotalResult = false;
+ aRet = pResData->GetMeasureString( 0, TRUE, SUBTOTAL_FUNC_NONE, bTotalResult );
+ }
// empty for more than one measure
@@ -1132,6 +1150,7 @@ uno::Reference<beans::XPropertySetInfo> SAL_CALL ScDPSource::getPropertySetInfo(
throw(uno::RuntimeException)
{
ScUnoGuard aGuard;
+ using beans::PropertyAttribute::READONLY;
static SfxItemPropertyMapEntry aDPSourceMap_Impl[] =
{
@@ -1140,6 +1159,10 @@ uno::Reference<beans::XPropertySetInfo> SAL_CALL ScDPSource::getPropertySetInfo(
{MAP_CHAR_LEN(SC_UNO_IGNOREEM), 0, &getBooleanCppuType(), 0, 0 }, // for sheet data only
{MAP_CHAR_LEN(SC_UNO_REPEATIF), 0, &getBooleanCppuType(), 0, 0 }, // for sheet data only
{MAP_CHAR_LEN(SC_UNO_ROWGRAND), 0, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_ROWFIELDCOUNT), 0, &getCppuType(static_cast<sal_Int32*>(0)), READONLY, 0 },
+ {MAP_CHAR_LEN(SC_UNO_COLUMNFIELDCOUNT), 0, &getCppuType(static_cast<sal_Int32*>(0)), READONLY, 0 },
+ {MAP_CHAR_LEN(SC_UNO_DATAFIELDCOUNT), 0, &getCppuType(static_cast<sal_Int32*>(0)), READONLY, 0 },
+ {MAP_CHAR_LEN(SC_UNO_GRANDTOTAL_NAME), 0, &getCppuType(static_cast<OUString*>(0)), 0, 0 },
{0,0,0,0,0,0}
};
static uno::Reference<beans::XPropertySetInfo> aRef =
@@ -1161,6 +1184,12 @@ void SAL_CALL ScDPSource::setPropertyValue( const rtl::OUString& aPropertyName,
setIgnoreEmptyRows( lcl_GetBoolFromAny( aValue ) );
else if ( aNameStr.EqualsAscii( SC_UNO_REPEATIF ) )
setRepeatIfEmpty( lcl_GetBoolFromAny( aValue ) );
+ else if (aNameStr.EqualsAscii(SC_UNO_GRANDTOTAL_NAME))
+ {
+ OUString aName;
+ if (aValue >>= aName)
+ mpGrandTotalName.reset(new OUString(aName));
+ }
else
{
DBG_ERROR("unknown property");
@@ -1190,6 +1219,11 @@ uno::Any SAL_CALL ScDPSource::getPropertyValue( const rtl::OUString& aPropertyNa
aRet <<= static_cast<sal_Int32>(nColDimCount);
else if ( aNameStr.EqualsAscii( SC_UNO_DATAFIELDCOUNT ) ) // read-only
aRet <<= static_cast<sal_Int32>(nDataDimCount);
+ else if (aNameStr.EqualsAscii(SC_UNO_GRANDTOTAL_NAME))
+ {
+ if (mpGrandTotalName.get())
+ aRet <<= *mpGrandTotalName;
+ }
else
{
DBG_ERROR("unknown property");
@@ -1337,6 +1371,8 @@ ScDPDimension::ScDPDimension( ScDPSource* pSrc, long nD ) :
pHierarchies( NULL ),
nUsedHier( 0 ),
nFunction( SUBTOTAL_FUNC_SUM ), // sum is default
+ mpLayoutName(NULL),
+ mpSubtotalName(NULL),
nSourceDim( -1 ),
bHasSelectedPage( FALSE ),
pSelectedData( NULL )
@@ -1364,6 +1400,16 @@ ScDPHierarchies* ScDPDimension::GetHierarchiesObject()
return pHierarchies;
}
+const rtl::OUString* ScDPDimension::GetLayoutName() const
+{
+ return mpLayoutName.get();
+}
+
+const rtl::OUString* ScDPDimension::GetSubtotalName() const
+{
+ return mpSubtotalName.get();
+}
+
uno::Reference<container::XNameAccess> SAL_CALL ScDPDimension::getHierarchies()
throw(uno::RuntimeException)
{
@@ -1523,6 +1569,8 @@ uno::Reference<beans::XPropertySetInfo> SAL_CALL ScDPDimension::getPropertySetIn
{MAP_CHAR_LEN(SC_UNO_POSITION), 0, &getCppuType((sal_Int32*)0), 0, 0 },
{MAP_CHAR_LEN(SC_UNO_REFVALUE), 0, &getCppuType((sheet::DataPilotFieldReference*)0), 0, 0 },
{MAP_CHAR_LEN(SC_UNO_USEDHIER), 0, &getCppuType((sal_Int32*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_LAYOUTNAME), 0, &getCppuType(static_cast<rtl::OUString*>(0)), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_FIELD_SUBTOTALNAME), 0, &getCppuType(static_cast<rtl::OUString*>(0)), 0, 0 },
{0,0,0,0,0,0}
};
static uno::Reference<beans::XPropertySetInfo> aRef =
@@ -1593,6 +1641,18 @@ void SAL_CALL ScDPDimension::setPropertyValue( const rtl::OUString& aPropertyNam
}
DELETEZ( pSelectedData ); // invalid after changing aSelectedPage
}
+ else if (aNameStr.EqualsAscii(SC_UNO_LAYOUTNAME))
+ {
+ OUString aTmpName;
+ if (aValue >>= aTmpName)
+ mpLayoutName.reset(new OUString(aTmpName));
+ }
+ else if (aNameStr.EqualsAscii(SC_UNO_FIELD_SUBTOTALNAME))
+ {
+ OUString aTmpName;
+ if (aValue >>= aTmpName)
+ mpSubtotalName.reset(new OUString(aTmpName));
+ }
else
{
DBG_ERROR("unknown property");
@@ -1652,6 +1712,10 @@ uno::Any SAL_CALL ScDPDimension::getPropertyValue( const rtl::OUString& aPropert
else
aRet <<= uno::Sequence<sheet::TableFilterField>(0);
}
+ else if (aNameStr.EqualsAscii(SC_UNO_LAYOUTNAME))
+ aRet <<= mpLayoutName.get() ? *mpLayoutName : OUString::createFromAscii("");
+ else if (aNameStr.EqualsAscii(SC_UNO_FIELD_SUBTOTALNAME))
+ aRet <<= mpSubtotalName.get() ? *mpSubtotalName : OUString::createFromAscii("");
else
{
DBG_ERROR("unknown property");
@@ -2155,7 +2219,11 @@ uno::Sequence<sheet::MemberResult> SAL_CALL ScDPLevel::getResults() throw(uno::R
return aRet;
}
- return pSource->GetData()->getDimensionName( nSrcDim ); // (original) dimension name
+ ScDPDimension* pDim = pSource->GetDimensionsObject()->getByIndex(nSrcDim);
+ if (!pDim)
+ return rtl::OUString();
+
+ return pDim->getName();
}
void SAL_CALL ScDPLevel::setName( const ::rtl::OUString& /* rNewName */ ) throw(uno::RuntimeException)
@@ -2258,6 +2326,20 @@ uno::Any SAL_CALL ScDPLevel::getPropertyValue( const rtl::OUString& aPropertyNam
aRet <<= aAutoShowInfo;
else if ( aNameStr.EqualsAscii( SC_UNO_LAYOUT ) )
aRet <<= aLayoutInfo;
+ else if (aNameStr.EqualsAscii(SC_UNO_LAYOUTNAME))
+ {
+ // read only property
+ long nSrcDim = pSource->GetSourceDim(nDim);
+ ScDPDimension* pDim = pSource->GetDimensionsObject()->getByIndex(nSrcDim);
+ if (!pDim)
+ return aRet;
+
+ const OUString* pLayoutName = pDim->GetLayoutName();
+ if (!pLayoutName)
+ return aRet;
+
+ aRet <<= *pLayoutName;
+ }
else
{
DBG_ERROR("unknown property");
@@ -2550,6 +2632,7 @@ ScDPMember::ScDPMember( ScDPSource* pSrc, long nD, long nH, long nL,
nHier( nH ),
nLev( nL ),
maData( rN, fV, bHV ),
+ mpLayoutName(NULL),
nPosition( -1 ),
bVisible( TRUE ),
bShowDet( TRUE )
@@ -2610,6 +2693,11 @@ void ScDPMember::FillItemData( ScDPItemData& rData ) const
rData = maData;
}
+const OUString* ScDPMember::GetLayoutName() const
+{
+ return mpLayoutName.get();
+}
+
String ScDPMember::GetNameStr() const
{
return maData.aString;
@@ -2669,6 +2757,7 @@ uno::Reference<beans::XPropertySetInfo> SAL_CALL ScDPMember::getPropertySetInfo(
{MAP_CHAR_LEN(SC_UNO_ISVISIBL), 0, &getBooleanCppuType(), 0, 0 },
{MAP_CHAR_LEN(SC_UNO_POSITION), 0, &getCppuType((sal_Int32*)0), 0, 0 },
{MAP_CHAR_LEN(SC_UNO_SHOWDETA), 0, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_LAYOUTNAME), 0, &getCppuType(static_cast<rtl::OUString*>(0)), 0, 0 },
{0,0,0,0,0,0}
};
static uno::Reference<beans::XPropertySetInfo> aRef =
@@ -2692,6 +2781,12 @@ void SAL_CALL ScDPMember::setPropertyValue( const rtl::OUString& aPropertyName,
if (aValue >>= nInt)
setPosition( nInt );
}
+ else if (aNameStr.EqualsAscii(SC_UNO_LAYOUTNAME))
+ {
+ rtl::OUString aName;
+ if (aValue >>= aName)
+ mpLayoutName.reset(new rtl::OUString(aName));
+ }
else
{
DBG_ERROR("unknown property");
@@ -2711,6 +2806,8 @@ uno::Any SAL_CALL ScDPMember::getPropertyValue( const rtl::OUString& aPropertyNa
lcl_SetBoolInAny( aRet, getShowDetails() );
else if ( aNameStr.EqualsAscii( SC_UNO_POSITION ) )
aRet <<= (sal_Int32) getPosition();
+ else if (aNameStr.EqualsAscii(SC_UNO_LAYOUTNAME))
+ aRet <<= mpLayoutName.get() ? *mpLayoutName : rtl::OUString();
else
{
DBG_ERROR("unknown property");
diff --git a/sc/source/filter/excel/read.cxx b/sc/source/filter/excel/read.cxx
index d1ae00376cde..f87c12f8c26d 100644
--- a/sc/source/filter/excel/read.cxx
+++ b/sc/source/filter/excel/read.cxx
@@ -1178,6 +1178,9 @@ FltError ImportExcel8::Read( void )
eLastErr = SCWARN_IMPORT_ROW_OVERFLOW;
else if( rAddrConv.IsColTruncated() )
eLastErr = SCWARN_IMPORT_COLUMN_OVERFLOW;
+
+ if( GetBiff() == EXC_BIFF8 )
+ GetPivotTableManager().MaybeRefreshPivotTables();
}
return eLastErr;
diff --git a/sc/source/filter/excel/xepivot.cxx b/sc/source/filter/excel/xepivot.cxx
index 0b10ded5aa9e..78bc0e0b2f99 100644
--- a/sc/source/filter/excel/xepivot.cxx
+++ b/sc/source/filter/excel/xepivot.cxx
@@ -67,6 +67,7 @@ using ::com::sun::star::sheet::DataPilotFieldSortInfo;
using ::com::sun::star::sheet::DataPilotFieldAutoShowInfo;
using ::com::sun::star::sheet::DataPilotFieldLayoutInfo;
using ::com::sun::star::sheet::DataPilotFieldReference;
+using ::rtl::OUString;
using ::rtl::OString;
using ::rtl::OUString;
@@ -972,6 +973,11 @@ void XclExpPTItem::SetPropertiesFromMember( const ScDPSaveMember& rSaveMem )
{
::set_flag( maItemInfo.mnFlags, EXC_SXVI_HIDDEN, !rSaveMem.GetIsVisible() );
::set_flag( maItemInfo.mnFlags, EXC_SXVI_HIDEDETAIL, !rSaveMem.GetShowDetails() );
+
+ // visible name
+ const OUString* pVisName = rSaveMem.GetLayoutName();
+ if (pVisName && !pVisName->equals(GetItemName()))
+ maItemInfo.SetVisName(*pVisName);
}
void XclExpPTItem::WriteBody( XclExpStream& rStrm )
@@ -1040,8 +1046,13 @@ void XclExpPTField::SetPropertiesFromDim( const ScDPSaveDimension& rSaveDim )
::set_flag( maFieldExtInfo.mnFlags, EXC_SXVDEX_SHOWALL, rSaveDim.GetShowEmpty() );
// visible name
- if( rSaveDim.HasLayoutName() && (rSaveDim.GetLayoutName() != GetFieldName()) )
- maFieldInfo.SetVisName( rSaveDim.GetLayoutName() );
+ const OUString* pLayoutName = rSaveDim.GetLayoutName();
+ if (pLayoutName && !pLayoutName->equals(GetFieldName()))
+ maFieldInfo.SetVisName(*pLayoutName);
+
+ const rtl::OUString* pSubtotalName = rSaveDim.GetSubtotalName();
+ if (pSubtotalName)
+ maFieldExtInfo.mpFieldTotalName.reset(new rtl::OUString(*pSubtotalName));
// subtotals
XclPTSubtotalVec aSubtotals;
@@ -1108,7 +1119,11 @@ void XclExpPTField::SetDataPropertiesFromDim( const ScDPSaveDimension& rSaveDim
rDataInfo.SetApiAggFunc( eFunc );
// visible name
- rDataInfo.SetVisName( lclGetDataFieldCaption( GetFieldName(), eFunc ) );
+ const rtl::OUString* pVisName = rSaveDim.GetLayoutName();
+ if (pVisName)
+ rDataInfo.SetVisName(*pVisName);
+ else
+ rDataInfo.SetVisName( lclGetDataFieldCaption( GetFieldName(), eFunc ) );
// result field reference
if( const DataPilotFieldReference* pFieldRef = rSaveDim.GetReferenceValue() )
@@ -1217,10 +1232,9 @@ XclExpPivotTable::XclExpPivotTable( const XclExpRoot& rRoot, const ScDPObject& r
// pivot table properties from DP object
mnOutScTab = rOutScRange.aStart.Tab();
maPTInfo.maTableName = rDPObj.GetName();
- maPTInfo.maDataName = ScGlobal::GetRscString( STR_PIVOT_DATA );
maPTInfo.mnCacheIdx = mrPCache.GetCacheIndex();
- maPTAutoFormat.Init( rDPObj );
+ maPTViewEx9Info.Init( rDPObj );
if( const ScDPSaveData* pSaveData = rDPObj.GetSaveData() )
{
@@ -1301,8 +1315,10 @@ void XclExpPivotTable::Save( XclExpStream& rStrm )
WriteSxli( rStrm, maPTInfo.mnDataCols, maPTInfo.mnColFields );
// SXEX
WriteSxex( rStrm );
- // SX_AUTOFORMAT
- WriteSxAutoformat( rStrm );
+ // QSISXTAG
+ WriteQsiSxTag( rStrm );
+ // SXVIEWEX9
+ WriteSxViewEx9( rStrm );
}
}
@@ -1336,6 +1352,15 @@ void XclExpPivotTable::SetPropertiesFromDP( const ScDPSaveData& rSaveData )
::set_flag( maPTInfo.mnFlags, EXC_SXVIEW_COLGRAND, rSaveData.GetColumnGrand() );
::set_flag( maPTExtInfo.mnFlags, EXC_SXEX_DRILLDOWN, rSaveData.GetDrillDown() );
mbFilterBtn = rSaveData.GetFilterButton();
+ const ScDPSaveDimension* pDim = rSaveData.GetExistingDataLayoutDimension();
+ if (!pDim)
+ return;
+
+ const rtl::OUString* pLayoutName = pDim->GetLayoutName();
+ if (pLayoutName)
+ maPTInfo.maDataName = *pLayoutName;
+ else
+ maPTInfo.maDataName = ScGlobal::GetRscString(STR_PIVOT_DATA);
}
void XclExpPivotTable::SetFieldPropertiesFromDim( const ScDPSaveDimension& rSaveDim )
@@ -1443,17 +1468,21 @@ void XclExpPivotTable::Finalize()
rnDataXclRow = rnXclRow1 + maPTInfo.mnColFields + 1;
if( maDataFields.empty() )
++rnDataXclRow;
- if( 0 == maPTAutoFormat.mnGridLayout )
+
+ bool bExtraHeaderRow = (0 == maPTViewEx9Info.mnGridLayout && maPTInfo.mnColFields == 0);
+ if (bExtraHeaderRow)
+ // Insert an extra row only when there is no column field.
++rnDataXclRow;
+
rnXclCol2 = ::std::max( rnXclCol2, rnDataXclCol );
rnXclRow2 = ::std::max( rnXclRow2, rnDataXclRow );
maPTInfo.mnDataCols = rnXclCol2 - rnDataXclCol + 1;
maPTInfo.mnDataRows = rnXclRow2 - rnDataXclRow + 1;
// first heading
- maPTInfo.mnFirstHeadRow = rnXclRow1 + 1;
- if( 0 == maPTAutoFormat.mnGridLayout )
- maPTInfo.mnFirstHeadRow++;
+ maPTInfo.mnFirstHeadRow = rnXclRow1;
+ if (bExtraHeaderRow)
+ maPTInfo.mnFirstHeadRow += 2;
}
// records ----------------------------------------------------------------
@@ -1533,14 +1562,68 @@ void XclExpPivotTable::WriteSxex( XclExpStream& rStrm ) const
rStrm.EndRecord();
}
-void XclExpPivotTable::WriteSxAutoformat( XclExpStream& rStrm ) const
+void XclExpPivotTable::WriteQsiSxTag( XclExpStream& rStrm ) const
+{
+ rStrm.StartRecord( 0x0802, 32 );
+
+ sal_uInt16 nRecordType = 0x0802;
+ sal_uInt16 nDummyFlags = 0x0000;
+ sal_uInt16 nTableType = 1; // 0 = query table : 1 = pivot table
+
+ rStrm << nRecordType << nDummyFlags << nTableType;
+
+ // General flags
+ bool bEnableRefresh = true;
+ bool bPCacheInvalid = false;
+ bool bOlapPTReport = false;
+
+ sal_uInt16 nFlags = 0x0000;
+ if (bEnableRefresh) nFlags |= 0x0001;
+ if (bPCacheInvalid) nFlags |= 0x0002;
+ if (bOlapPTReport) nFlags |= 0x0004;
+ rStrm << nFlags;
+
+ // Feature-specific options. The value differs depending on the table
+ // type, but we assume the table type is always pivot table.
+ sal_uInt32 nOptions = 0x00000000;
+ bool bNoStencil = false;
+ bool bHideTotal = false;
+ bool bEmptyRows = false;
+ bool bEmptyCols = false;
+ if (bNoStencil) nOptions |= 0x00000001;
+ if (bHideTotal) nOptions |= 0x00000002;
+ if (bEmptyRows) nOptions |= 0x00000008;
+ if (bEmptyCols) nOptions |= 0x00000010;
+ rStrm << nOptions;
+
+ enum ExcelVersion
+ {
+ Excel2000 = 0,
+ ExcelXP = 1,
+ Excel2003 = 2,
+ Excel2007 = 3
+ };
+ ExcelVersion eXclVer = Excel2000;
+ sal_uInt8 nOffsetBytes = 16;
+ rStrm << static_cast<sal_uInt8>(eXclVer) // version table last refreshed
+ << static_cast<sal_uInt8>(eXclVer) // minimum version to refresh
+ << nOffsetBytes
+ << static_cast<sal_uInt8>(eXclVer); // first version created
+
+ rStrm << XclExpString(maPTInfo.maTableName);
+ rStrm << static_cast<sal_uInt16>(0x0001); // no idea what this is for.
+
+ rStrm.EndRecord();
+}
+
+void XclExpPivotTable::WriteSxViewEx9( XclExpStream& rStrm ) const
{
// Until we sync the autoformat ids only export if using grid header layout
// That could only have been set via xls import so far.
- if ( 0 == maPTAutoFormat.mnGridLayout )
+ if ( 0 == maPTViewEx9Info.mnGridLayout )
{
rStrm.StartRecord( EXC_ID_SXVIEWEX9, 17 );
- rStrm << maPTAutoFormat;
+ rStrm << maPTViewEx9Info;
rStrm.EndRecord();
}
}
diff --git a/sc/source/filter/excel/xestring.cxx b/sc/source/filter/excel/xestring.cxx
index 9af8dbfdd851..b657e3b1f1d0 100644
--- a/sc/source/filter/excel/xestring.cxx
+++ b/sc/source/filter/excel/xestring.cxx
@@ -423,7 +423,8 @@ void XclExpString::WriteFormats( XclExpStream& rStrm, bool bWriteSize ) const
void XclExpString::Write( XclExpStream& rStrm ) const
{
- WriteHeader( rStrm );
+ if (!mbSkipHeader)
+ WriteHeader( rStrm );
WriteBuffer( rStrm );
if( IsWriteFormats() ) // only in BIFF8 included in string
WriteFormats( rStrm );
@@ -589,6 +590,7 @@ void XclExpString::Init( sal_Int32 nCurrLen, XclStrFlags nFlags, sal_uInt16 nMax
mbSmartFlags = bBiff8 && ::get_flag( nFlags, EXC_STR_SMARTFLAGS );
mbSkipFormats = ::get_flag( nFlags, EXC_STR_SEPARATEFORMATS );
mbWrapped = false;
+ mbSkipHeader = ::get_flag( nFlags, EXC_STR_NOHEADER );
mnMaxLen = nMaxLen;
SetStrLen( nCurrLen );
diff --git a/sc/source/filter/excel/xipivot.cxx b/sc/source/filter/excel/xipivot.cxx
index 495f73d75a68..29e20e52e64a 100644
--- a/sc/source/filter/excel/xipivot.cxx
+++ b/sc/source/filter/excel/xipivot.cxx
@@ -847,6 +847,11 @@ void XclImpPivotCache::ReadPivotCacheStream( XclImpStream& rStrm )
}
}
+bool XclImpPivotCache::IsRefreshOnLoad() const
+{
+ return static_cast<bool>(maPCInfo.mnFlags & 0x0004);
+}
+
// ============================================================================
// Pivot table
// ============================================================================
@@ -882,6 +887,8 @@ void XclImpPTItem::ConvertItem( ScDPSaveDimension& rSaveDim ) const
ScDPSaveMember& rMember = *rSaveDim.GetMemberByName( *pItemName );
rMember.SetIsVisible( !::get_flag( maItemInfo.mnFlags, EXC_SXVI_HIDDEN ) );
rMember.SetShowDetails( !::get_flag( maItemInfo.mnFlags, EXC_SXVI_HIDEDETAIL ) );
+ if (maItemInfo.HasVisName())
+ rMember.SetLayoutName(*maItemInfo.GetVisName());
}
}
@@ -1043,7 +1050,7 @@ ScDPSaveDimension* XclImpPTField::ConvertRCPField( ScDPSaveData& rSaveData ) con
// visible name
if( const String* pVisName = maFieldInfo.GetVisName() )
if( pVisName->Len() > 0 )
- rSaveDim.SetLayoutName( pVisName );
+ rSaveDim.SetLayoutName( *pVisName );
// subtotal function(s)
XclPTSubtotalVec aSubtotalVec;
@@ -1075,6 +1082,10 @@ ScDPSaveDimension* XclImpPTField::ConvertRCPField( ScDPSaveData& rSaveData ) con
// grouping info
pCacheField->ConvertGroupField( rSaveData, mrPTable.GetVisFieldNames() );
+ // custom subtotal name
+ if (maFieldExtInfo.mpFieldTotalName.get())
+ rSaveDim.SetSubtotalName(*maFieldExtInfo.mpFieldTotalName);
+
return &rSaveDim;
}
@@ -1099,7 +1110,7 @@ void XclImpPTField::ConvertDataFieldInfo( ScDPSaveDimension& rSaveDim, const Xcl
// visible name
if( const String* pVisName = rDataInfo.GetVisName() )
if( pVisName->Len() > 0 )
- rSaveDim.SetLayoutName( pVisName );
+ rSaveDim.SetLayoutName( *pVisName );
// aggregation function
rSaveDim.SetFunction( static_cast< USHORT >( rDataInfo.GetApiAggFunc() ) );
@@ -1134,7 +1145,8 @@ void XclImpPTField::ConvertItems( ScDPSaveDimension& rSaveDim ) const
XclImpPivotTable::XclImpPivotTable( const XclImpRoot& rRoot ) :
XclImpRoot( rRoot ),
- maDataOrientField( *this, EXC_SXIVD_DATA )
+ maDataOrientField( *this, EXC_SXIVD_DATA ),
+ mpDPObj(NULL)
{
}
@@ -1298,7 +1310,7 @@ void XclImpPivotTable::ReadSxex( XclImpStream& rStrm )
void XclImpPivotTable::ReadSxViewEx9( XclImpStream& rStrm )
{
- rStrm >> maPTAutoFormat;
+ rStrm >> maPTViewEx9Info;
}
// ----------------------------------------------------------------------------
@@ -1336,11 +1348,14 @@ void XclImpPivotTable::Convert()
if( const XclImpPTField* pField = GetField( *aIt ) )
pField->ConvertPageField( aSaveData );
+#if 0 // Why do we do this ???
+
// hidden fields
for( sal_uInt16 nField = 0, nCount = GetFieldCount(); nField < nCount; ++nField )
if( const XclImpPTField* pField = GetField( nField ) )
if( (pField->GetAxes() & EXC_SXVD_AXIS_ROWCOLPAGE) == 0 )
pField->ConvertHiddenField( aSaveData );
+#endif
// data fields
for( aIt = maFiltDataFields.begin(), aEnd = maFiltDataFields.end(); aIt != aEnd; ++aIt )
@@ -1364,12 +1379,30 @@ void XclImpPivotTable::Convert()
// create the DataPilot
ScDPObject* pDPObj = new ScDPObject( GetDocPtr() );
pDPObj->SetName( maPTInfo.maTableName );
+ if (maPTInfo.maDataName.Len() > 0)
+ aSaveData.GetDataLayoutDimension()->SetLayoutName(maPTInfo.maDataName);
+
+ if (maPTViewEx9Info.maGrandTotalName.Len() > 0)
+ aSaveData.SetGrandTotalName(maPTViewEx9Info.maGrandTotalName);
+
pDPObj->SetSaveData( aSaveData );
pDPObj->SetSheetDesc( aDesc );
pDPObj->SetOutRange( aOutRange );
pDPObj->SetAlive( TRUE );
- pDPObj->SetHeaderLayout( maPTAutoFormat.mnGridLayout == 0 );
+ pDPObj->SetHeaderLayout( maPTViewEx9Info.mnGridLayout == 0 );
+
GetDoc().GetDPCollection()->Insert( pDPObj );
+ mpDPObj = pDPObj;
+}
+
+void XclImpPivotTable::MaybeRefresh()
+{
+ if (mpDPObj && mxPCache->IsRefreshOnLoad())
+ {
+ // 'refresh table on load' flag is set. Refresh the table now. Some
+ // Excel files contain partial table output when this flag is set.
+ mpDPObj->Output();
+ }
}
// ============================================================================
@@ -1484,85 +1517,10 @@ void XclImpPivotTableManager::ConvertPivotTables()
(*aIt)->Convert();
}
-// ============================================================================
-
-// Pivot table autoformat settings ============================================
-
-/**
-classic : 10 08 00 00 00 00 00 00 20 00 00 00 01 00 00 00 00
-default : 10 08 00 00 00 00 00 00 20 00 00 00 01 00 00 00 00
-report01 : 10 08 02 00 00 00 00 00 20 00 00 00 00 10 00 00 00
-report02 : 10 08 02 00 00 00 00 00 20 00 00 00 01 10 00 00 00
-report03 : 10 08 02 00 00 00 00 00 20 00 00 00 02 10 00 00 00
-report04 : 10 08 02 00 00 00 00 00 20 00 00 00 03 10 00 00 00
-report05 : 10 08 02 00 00 00 00 00 20 00 00 00 04 10 00 00 00
-report06 : 10 08 02 00 00 00 00 00 20 00 00 00 05 10 00 00 00
-report07 : 10 08 02 00 00 00 00 00 20 00 00 00 06 10 00 00 00
-report08 : 10 08 02 00 00 00 00 00 20 00 00 00 07 10 00 00 00
-report09 : 10 08 02 00 00 00 00 00 20 00 00 00 08 10 00 00 00
-report10 : 10 08 02 00 00 00 00 00 20 00 00 00 09 10 00 00 00
-table01 : 10 08 00 00 00 00 00 00 20 00 00 00 0a 10 00 00 00
-table02 : 10 08 00 00 00 00 00 00 20 00 00 00 0b 10 00 00 00
-table03 : 10 08 00 00 00 00 00 00 20 00 00 00 0c 10 00 00 00
-table04 : 10 08 00 00 00 00 00 00 20 00 00 00 0d 10 00 00 00
-table05 : 10 08 00 00 00 00 00 00 20 00 00 00 0e 10 00 00 00
-table06 : 10 08 00 00 00 00 00 00 20 00 00 00 0f 10 00 00 00
-table07 : 10 08 00 00 00 00 00 00 20 00 00 00 10 10 00 00 00
-table08 : 10 08 00 00 00 00 00 00 20 00 00 00 11 10 00 00 00
-table09 : 10 08 00 00 00 00 00 00 20 00 00 00 12 10 00 00 00
-table10 : 10 08 00 00 00 00 00 00 20 00 00 00 13 10 00 00 00
-none : 10 08 00 00 00 00 00 00 20 00 00 00 15 10 00 00 00
-**/
-
-XclPTAutoFormat::XclPTAutoFormat() :
- mbReport( 0 ),
- mnAutoFormat( 0 ),
- mnGridLayout( 0x10 )
-{
-}
-
-void XclPTAutoFormat::Init( const ScDPObject& rDPObj )
-{
- if( rDPObj.GetHeaderLayout() )
- {
- mbReport = 0;
- mnAutoFormat = 1;
- mnGridLayout = 0;
- }
- else
- {
- // Report1 for now
- // TODO : sync with autoformat indicies
- mbReport = 2;
- mnAutoFormat = 1;
- mnGridLayout = 0x10;
- }
-}
-
-XclImpStream& operator>>( XclImpStream& rStrm, XclPTAutoFormat& rInfo )
-{
- rStrm.Ignore( 2 );
- rStrm >> rInfo.mbReport; /// 2 for report* fmts ?
- rStrm.Ignore( 6 );
- sal_uInt8 nDummy;
- return rStrm
- >> rInfo.mnAutoFormat
- >> rInfo.mnGridLayout
- >> nDummy >> nDummy >> nDummy;
-}
-
-XclExpStream& operator<<( XclExpStream& rStrm, const XclPTAutoFormat& rInfo )
+void XclImpPivotTableManager::MaybeRefreshPivotTables()
{
- return rStrm
- << EXC_PT_AUTOFMT_HEADER
- << rInfo.mbReport
- << EXC_PT_AUTOFMT_ZERO
- << EXC_PT_AUTOFMT_FLAGS
- << rInfo.mnAutoFormat
- << rInfo.mnGridLayout
- << static_cast<sal_uInt8>(0x00)
- << static_cast<sal_uInt8>(0x00)
- << static_cast<sal_uInt8>(0x00);
+ for( XclImpPivotTableVec::iterator aIt = maPTables.begin(), aEnd = maPTables.end(); aIt != aEnd; ++aIt )
+ (*aIt)->MaybeRefresh();
}
// ============================================================================
diff --git a/sc/source/filter/excel/xlpivot.cxx b/sc/source/filter/excel/xlpivot.cxx
index d36950b2494d..8f5d026379d9 100644
--- a/sc/source/filter/excel/xlpivot.cxx
+++ b/sc/source/filter/excel/xlpivot.cxx
@@ -31,6 +31,7 @@
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sc.hxx"
#include "dpgroup.hxx"
+#include "dpsave.hxx"
#include "xestream.hxx"
#include "xistream.hxx"
#include "xestring.hxx"
@@ -581,7 +582,9 @@ XclExpStream& operator<<( XclExpStream& rStrm, const XclPTFieldInfo& rInfo )
XclPTFieldExtInfo::XclPTFieldExtInfo() :
mnFlags( EXC_SXVDEX_DEFAULTFLAGS ),
mnSortField( EXC_SXVDEX_SORT_OWN ),
- mnShowField( EXC_SXVDEX_SHOW_NONE )
+ mnShowField( EXC_SXVDEX_SHOW_NONE ),
+ mnNumFmt(0),
+ mpFieldTotalName(NULL)
{
}
@@ -639,10 +642,19 @@ void XclPTFieldExtInfo::SetApiLayoutMode( sal_Int32 nLayoutMode )
XclImpStream& operator>>( XclImpStream& rStrm, XclPTFieldExtInfo& rInfo )
{
- return rStrm
- >> rInfo.mnFlags
- >> rInfo.mnSortField
- >> rInfo.mnShowField;
+ sal_uInt8 nNameLen = 0;
+ rStrm >> rInfo.mnFlags
+ >> rInfo.mnSortField
+ >> rInfo.mnShowField
+ >> rInfo.mnNumFmt
+ >> nNameLen;
+
+ rStrm.Ignore(10);
+ if (nNameLen != 0xFF)
+ // Custom field total name is used. Pick it up.
+ rInfo.mpFieldTotalName.reset(new rtl::OUString(rStrm.ReadUniString(nNameLen, 0)));
+
+ return rStrm;
}
XclExpStream& operator<<( XclExpStream& rStrm, const XclPTFieldExtInfo& rInfo )
@@ -650,9 +662,23 @@ XclExpStream& operator<<( XclExpStream& rStrm, const XclPTFieldExtInfo& rInfo )
rStrm << rInfo.mnFlags
<< rInfo.mnSortField
<< rInfo.mnShowField
- << EXC_SXVDEX_FORMAT_NONE
- << sal_uInt16( 0xFFFF ); // unknown
- rStrm.WriteZeroBytes( 8 ); // unknown
+ << EXC_SXVDEX_FORMAT_NONE;
+
+ if (rInfo.mpFieldTotalName.get() && rInfo.mpFieldTotalName->getLength() > 0)
+ {
+ rtl::OUString aFinalName = *rInfo.mpFieldTotalName;
+ if (aFinalName.getLength() >= 254)
+ aFinalName = aFinalName.copy(0, 254);
+ sal_uInt8 nNameLen = static_cast<sal_uInt8>(aFinalName.getLength());
+ rStrm << nNameLen;
+ rStrm.WriteZeroBytes(10);
+ rStrm << XclExpString(aFinalName, EXC_STR_NOHEADER);
+ }
+ else
+ {
+ rStrm << sal_uInt16(0xFFFF);
+ rStrm.WriteZeroBytes(8);
+ }
return rStrm;
}
@@ -923,3 +949,86 @@ XclExpStream& operator<<( XclExpStream& rStrm, const XclPTExtInfo& rInfo )
// ============================================================================
+// Pivot table autoformat settings ============================================
+
+/**
+classic : 10 08 00 00 00 00 00 00 20 00 00 00 01 00 00 00 00
+default : 10 08 00 00 00 00 00 00 20 00 00 00 01 00 00 00 00
+report01 : 10 08 02 00 00 00 00 00 20 00 00 00 00 10 00 00 00
+report02 : 10 08 02 00 00 00 00 00 20 00 00 00 01 10 00 00 00
+report03 : 10 08 02 00 00 00 00 00 20 00 00 00 02 10 00 00 00
+report04 : 10 08 02 00 00 00 00 00 20 00 00 00 03 10 00 00 00
+report05 : 10 08 02 00 00 00 00 00 20 00 00 00 04 10 00 00 00
+report06 : 10 08 02 00 00 00 00 00 20 00 00 00 05 10 00 00 00
+report07 : 10 08 02 00 00 00 00 00 20 00 00 00 06 10 00 00 00
+report08 : 10 08 02 00 00 00 00 00 20 00 00 00 07 10 00 00 00
+report09 : 10 08 02 00 00 00 00 00 20 00 00 00 08 10 00 00 00
+report10 : 10 08 02 00 00 00 00 00 20 00 00 00 09 10 00 00 00
+table01 : 10 08 00 00 00 00 00 00 20 00 00 00 0a 10 00 00 00
+table02 : 10 08 00 00 00 00 00 00 20 00 00 00 0b 10 00 00 00
+table03 : 10 08 00 00 00 00 00 00 20 00 00 00 0c 10 00 00 00
+table04 : 10 08 00 00 00 00 00 00 20 00 00 00 0d 10 00 00 00
+table05 : 10 08 00 00 00 00 00 00 20 00 00 00 0e 10 00 00 00
+table06 : 10 08 00 00 00 00 00 00 20 00 00 00 0f 10 00 00 00
+table07 : 10 08 00 00 00 00 00 00 20 00 00 00 10 10 00 00 00
+table08 : 10 08 00 00 00 00 00 00 20 00 00 00 11 10 00 00 00
+table09 : 10 08 00 00 00 00 00 00 20 00 00 00 12 10 00 00 00
+table10 : 10 08 00 00 00 00 00 00 20 00 00 00 13 10 00 00 00
+none : 10 08 00 00 00 00 00 00 20 00 00 00 15 10 00 00 00
+**/
+
+XclPTViewEx9Info::XclPTViewEx9Info() :
+ mbReport( 0 ),
+ mnAutoFormat( 0 ),
+ mnGridLayout( 0x10 )
+{
+}
+
+void XclPTViewEx9Info::Init( const ScDPObject& rDPObj )
+{
+ if( rDPObj.GetHeaderLayout() )
+ {
+ mbReport = 0;
+ mnAutoFormat = 1;
+ mnGridLayout = 0;
+ }
+ else
+ {
+ // Report1 for now
+ // TODO : sync with autoformat indicies
+ mbReport = 2;
+ mnAutoFormat = 1;
+ mnGridLayout = 0x10;
+ }
+
+ const ScDPSaveData* pData = rDPObj.GetSaveData();
+ if (pData)
+ {
+ const rtl::OUString* pGrandTotal = pData->GetGrandTotalName();
+ if (pGrandTotal)
+ maGrandTotalName = *pGrandTotal;
+ }
+}
+
+XclImpStream& operator>>( XclImpStream& rStrm, XclPTViewEx9Info& rInfo )
+{
+ rStrm.Ignore( 2 );
+ rStrm >> rInfo.mbReport; /// 2 for report* fmts ?
+ rStrm.Ignore( 6 );
+ rStrm >> rInfo.mnAutoFormat >> rInfo.mnGridLayout;
+ rInfo.maGrandTotalName = rStrm.ReadUniString();
+ return rStrm;
+}
+
+XclExpStream& operator<<( XclExpStream& rStrm, const XclPTViewEx9Info& rInfo )
+{
+ return rStrm
+ << EXC_PT_AUTOFMT_HEADER
+ << rInfo.mbReport
+ << EXC_PT_AUTOFMT_ZERO
+ << EXC_PT_AUTOFMT_FLAGS
+ << rInfo.mnAutoFormat
+ << rInfo.mnGridLayout
+ << XclExpString(rInfo.maGrandTotalName, EXC_STR_DEFAULT, EXC_PT_MAXSTRLEN);
+}
+
diff --git a/sc/source/filter/inc/xepivot.hxx b/sc/source/filter/inc/xepivot.hxx
index 67ef2ff6fcd8..e9d2403c29f2 100644
--- a/sc/source/filter/inc/xepivot.hxx
+++ b/sc/source/filter/inc/xepivot.hxx
@@ -412,8 +412,10 @@ private:
void WriteSxli( XclExpStream& rStrm, sal_uInt16 nLineCount, sal_uInt16 nIndexCount ) const;
/** Writes the SXEX records containing additional pivot table info. */
void WriteSxex( XclExpStream& rStrm ) const;
+
+ void WriteQsiSxTag( XclExpStream& rStrm ) const;
/** Writes the SX_AUTOFORMAT records with the autoformat id and header layout */
- void WriteSxAutoformat( XclExpStream& rStrm ) const;
+ void WriteSxViewEx9( XclExpStream& rStrm ) const;
// ------------------------------------------------------------------------
private:
@@ -424,7 +426,7 @@ private:
const XclExpPivotCache& mrPCache; /// The pivot cache this pivot table bases on.
XclPTInfo maPTInfo; /// Info about the pivot table (SXVIEW record).
XclPTExtInfo maPTExtInfo; /// Extended info about the pivot table (SXEX record).
- XclPTAutoFormat maPTAutoFormat; /// The selected autoformat (SXVIEWEX9)
+ XclPTViewEx9Info maPTViewEx9Info; /// The selected autoformat (SXVIEWEX9)
XclExpPTFieldList maFieldList; /// All fields in pivot cache order.
ScfUInt16Vec maRowFields; /// Row field indexes.
ScfUInt16Vec maColFields; /// Column field indexes.
diff --git a/sc/source/filter/inc/xestring.hxx b/sc/source/filter/inc/xestring.hxx
index 69a1a7af09fb..5fe5e4fb813f 100644
--- a/sc/source/filter/inc/xestring.hxx
+++ b/sc/source/filter/inc/xestring.hxx
@@ -323,6 +323,7 @@ private:
bool mbSmartFlags; /// true = omit flags on empty string; false = always write flags.
bool mbSkipFormats; /// true = skip formats on export; false = write complete formatted string.
bool mbWrapped; /// true = text contains several paragraphs.
+ bool mbSkipHeader; /// ture = skip length and flags when writing string bytes.
};
inline bool operator==( const XclExpString& rLeft, const XclExpString& rRight )
diff --git a/sc/source/filter/inc/xipivot.hxx b/sc/source/filter/inc/xipivot.hxx
index 5a98c0793740..15227b8fb1a3 100644
--- a/sc/source/filter/inc/xipivot.hxx
+++ b/sc/source/filter/inc/xipivot.hxx
@@ -186,6 +186,8 @@ public:
/** Reads the entire pivot cache stream. Uses decrypter from passed stream. */
void ReadPivotCacheStream( XclImpStream& rStrm );
+ bool IsRefreshOnLoad() const;
+
private:
typedef ::std::vector< XclImpPCFieldRef > XclImpPCFieldVec;
@@ -359,6 +361,8 @@ public:
/** Inserts the pivot table into the Calc document. */
void Convert();
+ void MaybeRefresh();
+
// ------------------------------------------------------------------------
private:
typedef ::std::vector< XclImpPTFieldRef > XclImpPTFieldVec;
@@ -367,7 +371,7 @@ private:
XclPTInfo maPTInfo; /// General info about the pivot table (SXVIEW record).
XclPTExtInfo maPTExtInfo; /// Extended info about the pivot table (SXEX record).
- XclPTAutoFormat maPTAutoFormat; /// The selected autoformat (SX_AUTOFORMAT)
+ XclPTViewEx9Info maPTViewEx9Info; /// (SXVIEWEX9 record)
XclImpPTFieldVec maFields; /// Vector containing all fields.
XclImpPTFieldRef mxCurrField; /// Current field for importing additional info.
ScfStringVec maVisFieldNames; /// Vector containing all visible field names.
@@ -378,6 +382,7 @@ private:
ScfUInt16Vec maFiltDataFields; /// Filtered data field indexes.
XclImpPTField maDataOrientField; /// Special data field orientation field.
ScRange maOutScRange; /// Output range in the Calc document.
+ ScDPObject* mpDPObj;
};
typedef ScfRef< XclImpPivotTable > XclImpPivotTableRef;
@@ -437,6 +442,8 @@ public:
/** Inserts all pivot tables into the Calc document. */
void ConvertPivotTables();
+ void MaybeRefreshPivotTables();
+
private:
typedef ::std::vector< XclImpPivotCacheRef > XclImpPivotCacheVec;
typedef ::std::vector< XclImpPivotTableRef > XclImpPivotTableVec;
diff --git a/sc/source/filter/inc/xlpivot.hxx b/sc/source/filter/inc/xlpivot.hxx
index 52251ed62294..3ea464e7b919 100644
--- a/sc/source/filter/inc/xlpivot.hxx
+++ b/sc/source/filter/inc/xlpivot.hxx
@@ -43,6 +43,8 @@
#include "xladdress.hxx"
#include "dpobject.hxx"
+#include <memory>
+
class XclImpStream;
class XclExpStream;
@@ -671,6 +673,8 @@ struct XclPTFieldExtInfo
sal_uInt32 mnFlags; /// Several flags and number of items for AutoShow.
sal_uInt16 mnSortField; /// Index to data field sorting bases on.
sal_uInt16 mnShowField; /// Index to data field AutoShow bases on.
+ sal_uInt16 mnNumFmt;
+ ::std::auto_ptr<rtl::OUString> mpFieldTotalName;
explicit XclPTFieldExtInfo();
@@ -796,19 +800,20 @@ XclExpStream& operator<<( XclExpStream& rStrm, const XclPTExtInfo& rInfo );
// Pivot table autoformat settings ==============================================
-/** Pivot table autoformat settings (SX_AUTOFORMAT record). */
-struct XclPTAutoFormat
+/** Pivot table autoformat settings (SXVIEWEX9 record). */
+struct XclPTViewEx9Info
{
sal_uInt32 mbReport; /// 2 for report* fmts ?
sal_uInt8 mnAutoFormat; /// AutoFormat ID
sal_uInt8 mnGridLayout; /// 0 == gridlayout, 0x10 == modern
+ String maGrandTotalName;
- explicit XclPTAutoFormat();
+ explicit XclPTViewEx9Info();
void Init( const ScDPObject& rDPObj );
};
-XclImpStream& operator>>( XclImpStream& rStrm, XclPTAutoFormat& rInfo );
-XclExpStream& operator<<( XclExpStream& rStrm, const XclPTAutoFormat& rInfo );
+XclImpStream& operator>>( XclImpStream& rStrm, XclPTViewEx9Info& rInfo );
+XclExpStream& operator<<( XclExpStream& rStrm, const XclPTViewEx9Info& rInfo );
// ============================================================================
#endif
diff --git a/sc/source/filter/inc/xlstring.hxx b/sc/source/filter/inc/xlstring.hxx
index 0970fafd1ed6..32ee23f83d85 100644
--- a/sc/source/filter/inc/xlstring.hxx
+++ b/sc/source/filter/inc/xlstring.hxx
@@ -43,6 +43,7 @@ const XclStrFlags EXC_STR_FORCEUNICODE = 0x0001; /// Always use UCS-2 cha
const XclStrFlags EXC_STR_8BITLENGTH = 0x0002; /// 8-bit string length field (default: 16-bit).
const XclStrFlags EXC_STR_SMARTFLAGS = 0x0004; /// Omit flags on empty string (default: read/write always). BIFF8 only.
const XclStrFlags EXC_STR_SEPARATEFORMATS = 0x0008; /// Import: Keep old formats when reading unformatted string (default: clear formats); Export: Write unformatted string.
+const XclStrFlags EXC_STR_NOHEADER = 0x0010; /// Export: Don't write the length and flag fields.
// ----------------------------------------------------------------------------
diff --git a/sc/source/ui/dbgui/pvfundlg.cxx b/sc/source/ui/dbgui/pvfundlg.cxx
index d44791ff6972..dac8ee1e5e04 100644
--- a/sc/source/ui/dbgui/pvfundlg.cxx
+++ b/sc/source/ui/dbgui/pvfundlg.cxx
@@ -705,7 +705,9 @@ ScDPShowDetailDlg::ScDPShowDetailDlg( Window* pParent, ScDPObject& rDPObj, USHOR
maLbDims ( this, ScResId( LB_DIMS ) ),
maBtnOk ( this, ScResId( BTN_OK ) ),
maBtnCancel ( this, ScResId( BTN_CANCEL ) ),
- maBtnHelp ( this, ScResId( BTN_HELP ) )
+ maBtnHelp ( this, ScResId( BTN_HELP ) ),
+
+ mrDPObj(rDPObj)
{
FreeResource();
@@ -719,7 +721,13 @@ ScDPShowDetailDlg::ScDPShowDetailDlg( Window* pParent, ScDPObject& rDPObj, USHOR
{
const ScDPSaveDimension* pDimension = pSaveData ? pSaveData->GetExistingDimensionByName(aName) : 0;
if ( !pDimension || (pDimension->GetOrientation() != nOrient) )
+ {
+ const OUString* pLayoutName = pDimension->GetLayoutName();
+ if (pLayoutName)
+ aName = *pLayoutName;
maLbDims.InsertEntry( aName );
+ maNameIndexMap.insert(DimNameIndexMap::value_type(aName, nDim));
+ }
}
}
if( maLbDims.GetEntryCount() )
@@ -735,7 +743,17 @@ short ScDPShowDetailDlg::Execute()
String ScDPShowDetailDlg::GetDimensionName() const
{
- return maLbDims.GetSelectEntry();
+ // Look up the internal dimension name which may be different from the
+ // displayed field name.
+ String aSelectedName = maLbDims.GetSelectEntry();
+ DimNameIndexMap::const_iterator itr = maNameIndexMap.find(aSelectedName);
+ if (itr == maNameIndexMap.end())
+ // This should never happen!
+ return aSelectedName;
+
+ long nDim = itr->second;
+ BOOL bIsDataLayout = false;
+ return mrDPObj.GetDimName(nDim, bIsDataLayout);
}
IMPL_LINK( ScDPShowDetailDlg, DblClickHdl, ListBox*, pLBox )
diff --git a/sc/source/ui/dbgui/pvlaydlg.cxx b/sc/source/ui/dbgui/pvlaydlg.cxx
index 7b03e067a865..c23068b82200 100644
--- a/sc/source/ui/dbgui/pvlaydlg.cxx
+++ b/sc/source/ui/dbgui/pvlaydlg.cxx
@@ -63,6 +63,7 @@
#include "sc.hrc" //CHINA001
#include "scabstdlg.hxx" //CHINA001
using namespace com::sun::star;
+using ::rtl::OUString;
//----------------------------------------------------------------------------
@@ -1491,6 +1492,8 @@ IMPL_LINK( ScDPLayoutDlg, OkHdl, OKButton *, EMPTYARG )
nPageCount, nColCount, nRowCount, nDataCount );
if ( bFit )
{
+ ScDPSaveData* pOldSaveData = xDlgDPObject->GetSaveData();
+
ScRange aOutRange( aAdrDest ); // bToNewTable is passed separately
ScDPSaveData aSaveData;
@@ -1522,6 +1525,22 @@ IMPL_LINK( ScDPLayoutDlg, OkHdl, OKButton *, EMPTYARG )
pDim->SetSortInfo( &aIt->maSortInfo );
pDim->SetLayoutInfo( &aIt->maLayoutInfo );
pDim->SetAutoShowInfo( &aIt->maShowInfo );
+ ScDPSaveDimension* pOldDim = NULL;
+ if (pOldSaveData)
+ {
+ // Transfer the existing layout names to new dimension instance.
+ pOldDim = pOldSaveData->GetExistingDimensionByName(aIt->maName);
+ if (pOldDim)
+ {
+ const OUString* pLayoutName = pOldDim->GetLayoutName();
+ if (pLayoutName)
+ pDim->SetLayoutName(*pLayoutName);
+
+ const OUString* pSubtotalName = pOldDim->GetSubtotalName();
+ if (pSubtotalName)
+ pDim->SetSubtotalName(*pSubtotalName);
+ }
+ }
bool bManualSort = ( aIt->maSortInfo.Mode == sheet::DataPilotFieldSortMode::MANUAL );
@@ -1542,11 +1561,33 @@ IMPL_LINK( ScDPLayoutDlg, OkHdl, OKButton *, EMPTYARG )
ScDPSaveMember* pMember = pDim->GetMemberByName( *pItem );
pMember->SetIsVisible( bIsVisible );
pMember->SetShowDetails( bShowDetails );
+ if (pOldDim)
+ {
+ // Transfer the existing layout name.
+ ScDPSaveMember* pOldMember = pOldDim->GetMemberByName(*pItem);
+ if (pOldMember)
+ {
+ const OUString* pLayoutName = pOldMember->GetLayoutName();
+ if (pLayoutName)
+ pMember->SetLayoutName(*pLayoutName);
+ }
+ }
}
}
}
}
}
+ ScDPSaveDimension* pDim = aSaveData.GetDataLayoutDimension();
+ if (pDim && pOldSaveData)
+ {
+ ScDPSaveDimension* pOldDim = pOldSaveData->GetDataLayoutDimension();
+ if (pOldDim)
+ {
+ const OUString* pLayoutName = pOldDim->GetLayoutName();
+ if (pLayoutName)
+ pDim->SetLayoutName(*pLayoutName);
+ }
+ }
USHORT nWhichPivot = SC_MOD()->GetPool().GetWhich( SID_PIVOT_TABLE );
ScPivotItem aOutItem( nWhichPivot, &aSaveData, &aOutRange, bToNewTable );
diff --git a/sc/source/ui/inc/pvfundlg.hxx b/sc/source/ui/inc/pvfundlg.hxx
index eeeb9c4094c4..6b9aa62c37a3 100644
--- a/sc/source/ui/inc/pvfundlg.hxx
+++ b/sc/source/ui/inc/pvfundlg.hxx
@@ -55,6 +55,8 @@
#include <sfx2/itemconnect.hxx>
#include "pivot.hxx"
+#include <hash_map>
+
// ============================================================================
typedef sfx::ListBoxWrapper< sal_Int32 > ScDPListBoxWrapper;
@@ -217,6 +219,11 @@ public:
virtual short Execute();
+ /**
+ * @return String internal name of the selected field. Note that this may
+ * be different from the name displayed in the dialog if the field
+ * has a layout name.
+ */
String GetDimensionName() const;
private:
@@ -228,6 +235,10 @@ private:
OKButton maBtnOk;
CancelButton maBtnCancel;
HelpButton maBtnHelp;
+
+ typedef ::std::hash_map<String, long, ScStringHashCode> DimNameIndexMap;
+ DimNameIndexMap maNameIndexMap;
+ ScDPObject& mrDPObj;
};
// ============================================================================
diff --git a/sc/source/ui/unoobj/dapiuno.cxx b/sc/source/ui/unoobj/dapiuno.cxx
index c68baf36ba2b..c52921f7c5de 100644
--- a/sc/source/ui/unoobj/dapiuno.cxx
+++ b/sc/source/ui/unoobj/dapiuno.cxx
@@ -1626,8 +1626,13 @@ OUString SAL_CALL ScDataPilotFieldObj::getName() throw(RuntimeException)
if( pDim->IsDataLayout() )
aName = OUString( RTL_CONSTASCII_USTRINGPARAM( SC_DATALAYOUT_NAME ) );
else
- aName = pDim->GetLayoutName();
- }
+ {
+ const rtl::OUString* pLayoutName = pDim->GetLayoutName();
+ if (pLayoutName)
+ aName = *pLayoutName;
+ else
+ aName = pDim->GetName();
+ } }
return aName;
}
@@ -1639,7 +1644,7 @@ void SAL_CALL ScDataPilotFieldObj::setName( const OUString& rName ) throw(Runtim
if( pDim && !pDim->IsDataLayout() )
{
String aName( rName );
- pDim->SetLayoutName( &aName );
+ pDim->SetLayoutName(aName);
SetDPObject( pDPObj );
}
}
diff --git a/sc/source/ui/view/dbfunc3.cxx b/sc/source/ui/view/dbfunc3.cxx
index 8dcb47c927a2..41a5e9d0e050 100644
--- a/sc/source/ui/view/dbfunc3.cxx
+++ b/sc/source/ui/view/dbfunc3.cxx
@@ -91,6 +91,10 @@ using ::com::sun::star::uno::Sequence;
using ::com::sun::star::uno::Reference;
using ::com::sun::star::uno::UNO_QUERY;
using ::com::sun::star::beans::XPropertySet;
+using ::com::sun::star::container::XNameAccess;
+using ::com::sun::star::sheet::XDimensionsSupplier;
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
using ::std::auto_ptr;
// STATIC DATA -----------------------------------------------------------
@@ -1351,123 +1355,304 @@ void ScDBFunc::UngroupDataPilot()
}
}
+OUString lcl_replaceMemberNameInSubtotal(const OUString& rSubtotal, const OUString& rMemberName)
+{
+ sal_Int32 n = rSubtotal.getLength();
+ const sal_Unicode* p = rSubtotal.getStr();
+ OUStringBuffer aBuf, aWordBuf;
+ for (sal_Int32 i = 0; i < n; ++i)
+ {
+ sal_Unicode c = p[i];
+ if (c == sal_Unicode(' '))
+ {
+ OUString aWord = aWordBuf.makeStringAndClear();
+ if (aWord.equals(rMemberName))
+ aBuf.append(sal_Unicode('?'));
+ else
+ aBuf.append(aWord);
+ aBuf.append(c);
+ }
+ else
+ aWordBuf.append(c);
+ }
+
+ if (aWordBuf.getLength() > 0)
+ {
+ OUString aWord = aWordBuf.makeStringAndClear();
+ if (aWord.equals(rMemberName))
+ aBuf.append(sal_Unicode('?'));
+ else
+ aBuf.append(aWord);
+ }
+
+ return aBuf.makeStringAndClear();
+}
+
void ScDBFunc::DataPilotInput( const ScAddress& rPos, const String& rString )
{
+ using namespace ::com::sun::star::sheet;
+
String aNewName( rString );
ScDocument* pDoc = GetViewData()->GetDocument();
ScDPObject* pDPObj = pDoc->GetDPAtCursor( rPos.Col(), rPos.Row(), rPos.Tab() );
- if ( pDPObj )
+ if (!pDPObj)
+ return;
+
+ String aOldText;
+ pDoc->GetString( rPos.Col(), rPos.Row(), rPos.Tab(), aOldText );
+
+ if ( aOldText == rString )
{
- String aOldText;
- pDoc->GetString( rPos.Col(), rPos.Row(), rPos.Tab(), aOldText );
+ // nothing to do: silently exit
+ return;
+ }
- if ( aOldText == rString )
+ USHORT nErrorId = 0;
+
+ pDPObj->BuildAllDimensionMembers();
+ ScDPSaveData aData( *pDPObj->GetSaveData() );
+ BOOL bChange = FALSE;
+
+ USHORT nOrient = DataPilotFieldOrientation_HIDDEN;
+ long nField = pDPObj->GetHeaderDim( rPos, nOrient );
+ if ( nField >= 0 )
+ {
+ // changing a field title
+ if ( aData.GetExistingDimensionData() )
{
- // nothing to do: silently exit
- return;
- }
+ // only group dimensions can be renamed
- USHORT nErrorId = 0;
+ ScDPDimensionSaveData* pDimData = aData.GetDimensionData();
+ ScDPSaveGroupDimension* pGroupDim = pDimData->GetNamedGroupDimAcc( aOldText );
+ if ( pGroupDim )
+ {
+ // valid name: not empty, no existing dimension (group or other)
+ if ( rString.Len() && !pDPObj->IsDimNameInUse(rString) )
+ {
+ pGroupDim->Rename( aNewName );
- ScDPSaveData aData( *pDPObj->GetSaveData() );
- BOOL bChange = FALSE;
+ // also rename in SaveData to preserve the field settings
+ ScDPSaveDimension* pSaveDim = aData.GetDimensionByName( aOldText );
+ pSaveDim->SetName( aNewName );
- USHORT nOrient = sheet::DataPilotFieldOrientation_HIDDEN;
- long nField = pDPObj->GetHeaderDim( rPos, nOrient );
- if ( nField >= 0 )
+ bChange = TRUE;
+ }
+ else
+ nErrorId = STR_INVALIDNAME;
+ }
+ }
+ else if (nOrient == DataPilotFieldOrientation_COLUMN || nOrient == DataPilotFieldOrientation_ROW)
+ {
+ BOOL bDataLayout = false;
+ String aDimName = pDPObj->GetDimName(nField, bDataLayout);
+ ScDPSaveDimension* pDim = bDataLayout ? aData.GetDataLayoutDimension() : aData.GetDimensionByName(aDimName);
+ if (pDim)
+ {
+ if (rString.Len())
+ {
+ if (rString.EqualsIgnoreCaseAscii(aDimName))
+ {
+ pDim->RemoveLayoutName();
+ bChange = true;
+ }
+ else if (!pDPObj->IsDimNameInUse(rString))
+ {
+ pDim->SetLayoutName(rString);
+ bChange = true;
+ }
+ else
+ nErrorId = STR_INVALIDNAME;
+ }
+ else
+ nErrorId = STR_INVALIDNAME;
+ }
+ }
+ }
+ else if (pDPObj->IsDataDescriptionCell(rPos))
+ {
+ // There is only one data dimension.
+ ScDPSaveDimension* pDim = aData.GetFirstDimension(sheet::DataPilotFieldOrientation_DATA);
+ if (pDim)
{
- // changing a field title
+ if (rString.Len())
+ {
+ if (rString.EqualsIgnoreCaseAscii(pDim->GetName()))
+ {
+ pDim->RemoveLayoutName();
+ bChange = true;
+ }
+ else if (!pDPObj->IsDimNameInUse(rString))
+ {
+ pDim->SetLayoutName(rString);
+ bChange = true;
+ }
+ else
+ nErrorId = STR_INVALIDNAME;
+ }
+ else
+ nErrorId = STR_INVALIDNAME;
+ }
+ }
+ else
+ {
+ // This is not a field header.
+ sheet::DataPilotTableHeaderData aPosData;
+ pDPObj->GetHeaderPositionData(rPos, aPosData);
- if ( aData.GetExistingDimensionData() )
+ if ( (aPosData.Flags & MemberResultFlags::HASMEMBER) && aOldText.Len() )
+ {
+ if ( aData.GetExistingDimensionData() && !(aPosData.Flags & MemberResultFlags::SUBTOTAL))
{
- // only group dimensions can be renamed
+ BOOL bIsDataLayout;
+ String aDimName = pDPObj->GetDimName( aPosData.Dimension, bIsDataLayout );
ScDPDimensionSaveData* pDimData = aData.GetDimensionData();
- ScDPSaveGroupDimension* pGroupDim = pDimData->GetNamedGroupDimAcc( aOldText );
+ ScDPSaveGroupDimension* pGroupDim = pDimData->GetNamedGroupDimAcc( aDimName );
if ( pGroupDim )
{
- // valid name: not empty, no existing dimension (group or other)
- if ( aNewName.Len() && !pDPObj->IsDimNameInUse( aNewName ) )
+ // valid name: not empty, no existing group in this dimension
+ //! ignore case?
+ if ( aNewName.Len() && !pGroupDim->GetNamedGroup( aNewName ) )
{
- pGroupDim->Rename( aNewName );
+ ScDPSaveGroupItem* pGroup = pGroupDim->GetNamedGroupAcc( aOldText );
+ if ( pGroup )
+ pGroup->Rename( aNewName ); // rename the existing group
+ else
+ {
+ // create a new group to replace the automatic group
+ ScDPSaveGroupItem aGroup( aNewName );
+ aGroup.AddElement( aOldText );
+ pGroupDim->AddGroupItem( aGroup );
+ }
- // also rename in SaveData to preserve the field settings
- ScDPSaveDimension* pSaveDim = aData.GetDimensionByName( aOldText );
- pSaveDim->SetName( aNewName );
+ // in both cases also adjust savedata, to preserve member settings (show details)
+ ScDPSaveDimension* pSaveDim = aData.GetDimensionByName( aDimName );
+ ScDPSaveMember* pSaveMember = pSaveDim->GetExistingMemberByName( aOldText );
+ if ( pSaveMember )
+ pSaveMember->SetName( aNewName );
bChange = TRUE;
}
else
nErrorId = STR_INVALIDNAME;
- }
+ }
}
- }
- else
- {
- // renaming a group (item)?
- // allow only on the item name itself - not on empty cells, not on subtotals
-
- sheet::DataPilotTableHeaderData aPosData;
- pDPObj->GetHeaderPositionData(rPos, aPosData);
- if ( ( aPosData.Flags & sheet::MemberResultFlags::HASMEMBER ) &&
- ! ( aPosData.Flags & sheet::MemberResultFlags::SUBTOTAL ) &&
- aOldText.Len() )
+ else if ((aPosData.Flags & MemberResultFlags::GRANDTOTAL))
{
- if ( aData.GetExistingDimensionData() )
+ aData.SetGrandTotalName(rString);
+ bChange = true;
+ }
+ else if (aPosData.Dimension >= 0 && aPosData.MemberName.getLength() > 0)
+ {
+ BOOL bDataLayout = false;
+ String aDimName = pDPObj->GetDimName(static_cast<long>(aPosData.Dimension), bDataLayout);
+ if (bDataLayout)
{
- BOOL bIsDataLayout;
- String aDimName = pDPObj->GetDimName( aPosData.Dimension, bIsDataLayout );
+ // data dimension
+ do
+ {
+ if ((aPosData.Flags & MemberResultFlags::SUBTOTAL))
+ break;
+
+ ScDPSaveDimension* pDim = aData.GetDimensionByName(aPosData.MemberName);
+ if (!pDim)
+ break;
- ScDPDimensionSaveData* pDimData = aData.GetDimensionData();
- ScDPSaveGroupDimension* pGroupDim = pDimData->GetNamedGroupDimAcc( aDimName );
- if ( pGroupDim )
+ if (!rString.Len())
+ {
+ nErrorId = STR_INVALIDNAME;
+ break;
+ }
+
+ if (aPosData.MemberName.equalsIgnoreAsciiCase(rString))
+ {
+ pDim->RemoveLayoutName();
+ bChange = true;
+ }
+ else if (!pDPObj->IsDimNameInUse(rString))
+ {
+ pDim->SetLayoutName(rString);
+ bChange = true;
+ }
+ else
+ nErrorId = STR_INVALIDNAME;
+ }
+ while (false);
+ }
+ else
+ {
+ // field member
+ do
{
- // valid name: not empty, no existing group in this dimension
- //! ignore case?
- if ( aNewName.Len() && !pGroupDim->GetNamedGroup( aNewName ) )
+ ScDPSaveDimension* pDim = aData.GetDimensionByName(aDimName);
+ if (!pDim)
+ break;
+
+ ScDPSaveMember* pMem = pDim->GetExistingMemberByName(aPosData.MemberName);
+ if (!pMem)
+ break;
+
+ if ((aPosData.Flags & MemberResultFlags::SUBTOTAL))
{
- ScDPSaveGroupItem* pGroup = pGroupDim->GetNamedGroupAcc( aOldText );
- if ( pGroup )
- pGroup->Rename( aNewName ); // rename the existing group
+ // Change subtotal only when the table has one data dimension.
+ if (aData.GetDataDimensionCount() > 1)
+ break;
+
+ const OUString* pLayoutName = pMem->GetLayoutName();
+ String aMemberName;
+ if (pLayoutName)
+ aMemberName = *pLayoutName;
else
- {
- // create a new group to replace the automatic group
- ScDPSaveGroupItem aGroup( aNewName );
- aGroup.AddElement( aOldText );
- pGroupDim->AddGroupItem( aGroup );
- }
+ aMemberName = aPosData.MemberName;
- // in both cases also adjust savedata, to preserve member settings (show details)
- ScDPSaveDimension* pSaveDim = aData.GetDimensionByName( aDimName );
- ScDPSaveMember* pSaveMember = pSaveDim->GetExistingMemberByName( aOldText );
- if ( pSaveMember )
- pSaveMember->SetName( aNewName );
-
- bChange = TRUE;
+ String aNew = lcl_replaceMemberNameInSubtotal(rString, aMemberName);
+ pDim->SetSubtotalName(aNew);
+ bChange = true;
}
else
- nErrorId = STR_INVALIDNAME;
+ {
+ // Check to make sure the member name isn't
+ // already used.
+ if (rString.Len())
+ {
+ if (rString.EqualsIgnoreCaseAscii(pMem->GetName()))
+ {
+ pMem->RemoveLayoutName();
+ bChange = true;
+ }
+ else if (!pDim->IsMemberNameInUse(rString))
+ {
+ pMem->SetLayoutName(rString);
+ bChange = true;
+ }
+ else
+ nErrorId = STR_INVALIDNAME;
+ }
+ else
+ nErrorId = STR_INVALIDNAME;
+ }
}
+ while (false);
}
}
}
+ }
- if ( bChange )
- {
- // apply changes
- ScDBDocFunc aFunc( *GetViewData()->GetDocShell() );
- ScDPObject* pNewObj = new ScDPObject( *pDPObj );
- pNewObj->SetSaveData( aData );
- aFunc.DataPilotUpdate( pDPObj, pNewObj, TRUE, FALSE );
- delete pNewObj;
- }
- else
- {
- if ( !nErrorId )
- nErrorId = STR_ERR_DATAPILOT_INPUT;
- ErrorMessage( nErrorId );
- }
+ if ( bChange )
+ {
+ // apply changes
+ ScDBDocFunc aFunc( *GetViewData()->GetDocShell() );
+ ScDPObject* pNewObj = new ScDPObject( *pDPObj );
+ pNewObj->SetSaveData( aData );
+ aFunc.DataPilotUpdate( pDPObj, pNewObj, TRUE, FALSE );
+ delete pNewObj;
+ }
+ else
+ {
+ if ( !nErrorId )
+ nErrorId = STR_ERR_DATAPILOT_INPUT;
+ ErrorMessage( nErrorId );
}
}