summaryrefslogtreecommitdiff
path: root/sc/source/core/data/dpsave.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sc/source/core/data/dpsave.cxx')
-rw-r--r--sc/source/core/data/dpsave.cxx327
1 files changed, 242 insertions, 85 deletions
diff --git a/sc/source/core/data/dpsave.cxx b/sc/source/core/data/dpsave.cxx
index 62798076afb9..e66bd8dfe705 100644
--- a/sc/source/core/data/dpsave.cxx
+++ b/sc/source/core/data/dpsave.cxx
@@ -58,7 +58,15 @@
#include <com/sun/star/container/XNamed.hpp>
#include <com/sun/star/util/XCloneable.hpp>
+#include <hash_map>
+
using namespace com::sun::star;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Any;
+using ::rtl::OUString;
+using ::rtl::OUStringHash;
+using ::std::hash_map;
+using ::std::auto_ptr;
// -----------------------------------------------------------------------
@@ -99,6 +107,7 @@ void lcl_SetBoolProperty( const uno::Reference<beans::XPropertySet>& xProp,
ScDPSaveMember::ScDPSaveMember(const String& rName) :
aName( rName ),
+ mpLayoutName(NULL),
nVisibleMode( SC_DPSAVEMODE_DONTKNOW ),
nShowDetailsMode( SC_DPSAVEMODE_DONTKNOW )
{
@@ -106,9 +115,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()
@@ -153,12 +165,23 @@ void ScDPSaveMember::SetName( const String& rNew )
aName = rNew;
}
-void ScDPSaveMember::WriteToSource( const uno::Reference<uno::XInterface>& xMember, sal_Int32 nPosition )
+void ScDPSaveMember::SetLayoutName( const OUString& rName )
{
- // nothing to do?
- if ( nVisibleMode == SC_DPSAVEMODE_DONTKNOW && nShowDetailsMode == SC_DPSAVEMODE_DONTKNOW && nPosition < 0 )
- return;
+ 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 )
+{
uno::Reference<beans::XPropertySet> xMembProp( xMember, uno::UNO_QUERY );
DBG_ASSERT( xMembProp.is(), "no properties at member" );
if ( xMembProp.is() )
@@ -173,17 +196,11 @@ void ScDPSaveMember::WriteToSource( const uno::Reference<uno::XInterface>& xMemb
lcl_SetBoolProperty( xMembProp,
rtl::OUString::createFromAscii(DP_PROP_SHOWDETAILS), (BOOL)nShowDetailsMode );
+ if (mpLayoutName.get())
+ ScUnoHelpFunctions::SetOptionalPropertyValue(xMembProp, SC_UNO_LAYOUTNAME, *mpLayoutName);
+
if ( nPosition >= 0 )
- {
- try
- {
- xMembProp->setPropertyValue( rtl::OUString::createFromAscii(DP_PROP_POSITION), uno::Any(nPosition) );
- }
- catch ( uno::Exception& )
- {
- // position is optional - exception must be ignored
- }
- }
+ ScUnoHelpFunctions::SetOptionalPropertyValue(xMembProp, DP_PROP_POSITION, nPosition);
}
}
@@ -191,8 +208,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 ),
@@ -211,6 +229,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 ),
@@ -251,14 +271,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()
@@ -269,7 +289,6 @@ ScDPSaveDimension::~ScDPSaveDimension()
delete pSortInfo;
delete pAutoShowInfo;
delete pLayoutInfo;
- delete pLayoutName;
delete pSelectedPage;
delete [] pSubTotalFuncs;
}
@@ -370,25 +389,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 OUString* ScDPSaveDimension::GetLayoutName() const
+{
+ return mpLayoutName.get();
}
-const String& ScDPSaveDimension::GetLayoutName() const
+void ScDPSaveDimension::RemoveLayoutName()
{
- if (pLayoutName)
- return *pLayoutName;
- return aName;
+ mpLayoutName.reset(NULL);
}
void ScDPSaveDimension::SetReferenceValue(const sheet::DataPilotFieldReference* pNew)
@@ -520,15 +559,15 @@ void ScDPSaveDimension::WriteToSource( const uno::Reference<uno::XInterface>& xD
aFilter = uno::Sequence<sheet::TableFilterField>( &aField, 1 );
}
// else keep empty sequence
- try
- {
- aAny <<= aFilter;
- xDimProp->setPropertyValue( rtl::OUString::createFromAscii(DP_PROP_FILTER), aAny );
- }
- catch ( beans::UnknownPropertyException& )
- {
- // recent addition - allow source to not handle it (no error)
- }
+
+ ScUnoHelpFunctions::SetOptionalPropertyValue(xDimProp, DP_PROP_FILTER, aFilter);
+ if (mpLayoutName.get())
+ ScUnoHelpFunctions::SetOptionalPropertyValue(xDimProp, SC_UNO_LAYOUTNAME, *mpLayoutName);
+
+ const OUString* pSubTotalName = GetSubtotalName();
+ if (pSubTotalName)
+ // Custom subtotal name, with '?' being replaced by the visible field name later.
+ ScUnoHelpFunctions::SetOptionalPropertyValue(xDimProp, SC_UNO_FIELD_SUBTOTALNAME, *pSubTotalName);
}
// Level loop outside of maMemberList loop
@@ -546,6 +585,8 @@ void ScDPSaveDimension::WriteToSource( const uno::Reference<uno::XInterface>& xD
nHierCount = xHiers->getCount();
}
+ sal_Bool bHasHiddenMember = false;
+
for (long nHier=0; nHier<nHierCount; nHier++)
{
uno::Reference<uno::XInterface> xHierarchy = ScUnoHelpFunctions::AnyToInterface( xHiers->getByIndex(nHier) );
@@ -585,41 +626,13 @@ void ScDPSaveDimension::WriteToSource( const uno::Reference<uno::XInterface>& xD
rtl::OUString::createFromAscii(DP_PROP_SHOWEMPTY), (BOOL)nShowEmptyMode );
if ( pSortInfo )
- {
- aAny <<= *pSortInfo;
- try
- {
- xLevProp->setPropertyValue( rtl::OUString::createFromAscii(SC_UNO_SORTING), aAny );
- }
- catch ( beans::UnknownPropertyException& )
- {
- // recent addition - allow source to not handle it (no error)
- }
- }
+ ScUnoHelpFunctions::SetOptionalPropertyValue(xLevProp, SC_UNO_SORTING, *pSortInfo);
+
if ( pAutoShowInfo )
- {
- aAny <<= *pAutoShowInfo;
- try
- {
- xLevProp->setPropertyValue( rtl::OUString::createFromAscii(SC_UNO_AUTOSHOW), aAny );
- }
- catch ( beans::UnknownPropertyException& )
- {
- // recent addition - allow source to not handle it (no error)
- }
- }
+ ScUnoHelpFunctions::SetOptionalPropertyValue(xLevProp, SC_UNO_AUTOSHOW, *pAutoShowInfo);
+
if ( pLayoutInfo )
- {
- aAny <<= *pLayoutInfo;
- try
- {
- xLevProp->setPropertyValue( rtl::OUString::createFromAscii(SC_UNO_LAYOUT), aAny );
- }
- catch ( beans::UnknownPropertyException& )
- {
- // recent addition - allow source to not handle it (no error)
- }
- }
+ ScUnoHelpFunctions::SetOptionalPropertyValue(xLevProp, SC_UNO_LAYOUT, *pLayoutInfo);
// exceptions are caught at ScDPSaveData::WriteToSource
}
@@ -638,12 +651,15 @@ void ScDPSaveDimension::WriteToSource( const uno::Reference<uno::XInterface>& xD
for (MemberList::const_iterator i=maMemberList.begin(); i != maMemberList.end() ; i++)
{
- rtl::OUString aMemberName = (*i)->GetName();
+ ScDPSaveMember* pMember = *i;
+ if (!pMember->GetIsVisible())
+ bHasHiddenMember = true;
+ rtl::OUString aMemberName = pMember->GetName();
if ( xMembers->hasByName( aMemberName ) )
{
uno::Reference<uno::XInterface> xMemberInt = ScUnoHelpFunctions::AnyToInterface(
xMembers->getByName( aMemberName ) );
- (*i)->WriteToSource( xMemberInt, nPosition );
+ pMember->WriteToSource( xMemberInt, nPosition );
if ( nPosition >= 0 )
++nPosition; // increase if initialized
@@ -655,6 +671,35 @@ void ScDPSaveDimension::WriteToSource( const uno::Reference<uno::XInterface>& xD
}
}
}
+
+ if (xDimProp.is())
+ ScUnoHelpFunctions::SetOptionalPropertyValue(xDimProp, SC_UNO_HAS_HIDDEN_MEMBER, bHasHiddenMember);
+}
+
+void ScDPSaveDimension::UpdateMemberVisibility(const hash_map<OUString, bool, OUStringHash>& rData)
+{
+ typedef hash_map<OUString, bool, OUStringHash> DataMap;
+ MemberList::iterator itrMem = maMemberList.begin(), itrMemEnd = maMemberList.end();
+ for (; itrMem != itrMemEnd; ++itrMem)
+ {
+ ScDPSaveMember* pMem = *itrMem;
+ const String& rMemName = pMem->GetName();
+ DataMap::const_iterator itr = rData.find(rMemName);
+ if (itr != rData.end())
+ pMem->SetIsVisible(itr->second);
+ }
+}
+
+bool ScDPSaveDimension::HasInvisibleMember() const
+{
+ MemberList::const_iterator itrMem = maMemberList.begin(), itrMemEnd = maMemberList.end();
+ for (; itrMem != itrMemEnd; ++itrMem)
+ {
+ const ScDPSaveMember* pMem = *itrMem;
+ if (!pMem->GetIsVisible())
+ return true;
+ }
+ return false;
}
// -----------------------------------------------------------------------
@@ -666,7 +711,9 @@ ScDPSaveData::ScDPSaveData() :
nIgnoreEmptyMode( SC_DPSAVEMODE_DONTKNOW ),
nRepeatEmptyMode( SC_DPSAVEMODE_DONTKNOW ),
bFilterButton( TRUE ),
- bDrillDown( TRUE )
+ bDrillDown( TRUE ),
+ mbDimensionMembersBuilt(false),
+ mpGrandTotalName(NULL)
{
}
@@ -676,7 +723,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 );
@@ -689,6 +738,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 )
@@ -707,6 +759,7 @@ ScDPSaveData& ScDPSaveData::operator= ( const ScDPSaveData& r )
nRepeatEmptyMode = r.nRepeatEmptyMode;
bFilterButton = r.bFilterButton;
bDrillDown = r.bDrillDown;
+ mbDimensionMembersBuilt = r.mbDimensionMembersBuilt;
// remove old dimensions
@@ -725,6 +778,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;
}
@@ -736,7 +792,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 )
@@ -752,6 +809,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;
}
@@ -765,6 +832,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();
@@ -779,7 +856,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++)
@@ -807,16 +884,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)
@@ -870,6 +956,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;
@@ -982,6 +1080,10 @@ void ScDPSaveData::WriteToSource( const uno::Reference<sheet::XDimensionsSupplie
{
// no error
}
+
+ const OUString* pGrandTotalName = GetGrandTotalName();
+ if (pGrandTotalName)
+ ScUnoHelpFunctions::SetOptionalPropertyValue(xSourceProp, SC_UNO_GRANDTOTAL_NAME, *pGrandTotalName);
}
// exceptions in the other calls are errors
@@ -1100,3 +1202,58 @@ 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;
+}
+
+bool ScDPSaveData::HasInvisibleMember(const OUString& rDimName) const
+{
+ ScDPSaveDimension* pDim = GetExistingDimensionByName(rDimName);
+ if (!pDim)
+ return false;
+
+ return pDim->HasInvisibleMember();
+}