1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include "dpdimsave.hxx"
22 #include "miscuno.hxx"
23 #include "scerrors.hxx"
24 #include "unonames.hxx"
26 #include "dptabsrc.hxx"
29 #include <sal/types.h>
30 #include <osl/diagnose.h>
31 #include <comphelper/string.hxx>
33 #include <com/sun/star/sheet/GeneralFunction.hpp>
34 #include <com/sun/star/sheet/DataPilotFieldAutoShowInfo.hpp>
35 #include <com/sun/star/sheet/DataPilotFieldLayoutInfo.hpp>
36 #include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
37 #include <com/sun/star/sheet/DataPilotFieldReference.hpp>
38 #include <com/sun/star/sheet/DataPilotFieldSortInfo.hpp>
39 #include <com/sun/star/sheet/DataPilotFieldSortMode.hpp>
40 #include <com/sun/star/sheet/TableFilterField.hpp>
41 #include <com/sun/star/sheet/XHierarchiesSupplier.hpp>
42 #include <com/sun/star/sheet/XLevelsSupplier.hpp>
43 #include <com/sun/star/sheet/XMembersSupplier.hpp>
44 #include <com/sun/star/container/XNamed.hpp>
45 #include <com/sun/star/util/XCloneable.hpp>
47 #include <com/sun/star/sheet/DataPilotFieldReferenceType.hpp>
48 #include <com/sun/star/sheet/DataPilotFieldReferenceItemType.hpp>
50 #include <unordered_map>
51 #include <unordered_set>
53 using namespace com::sun::star
;
54 using namespace com::sun::star::sheet
;
55 using ::com::sun::star::uno::Reference
;
56 using ::com::sun::star::uno::Any
;
57 using ::std::unique_ptr
;
59 #define SC_DPSAVEMODE_DONTKNOW 2
61 static void lcl_SetBoolProperty( const uno::Reference
<beans::XPropertySet
>& xProp
,
62 const OUString
& rName
, bool bValue
)
64 //TODO: move to ScUnoHelpFunctions?
66 xProp
->setPropertyValue( rName
, uno::Any( &bValue
, cppu::UnoType
<bool>::get() ) );
69 ScDPSaveMember::ScDPSaveMember(const OUString
& rName
) :
72 nVisibleMode( SC_DPSAVEMODE_DONTKNOW
),
73 nShowDetailsMode( SC_DPSAVEMODE_DONTKNOW
)
77 ScDPSaveMember::ScDPSaveMember(const ScDPSaveMember
& r
) :
80 nVisibleMode( r
.nVisibleMode
),
81 nShowDetailsMode( r
.nShowDetailsMode
)
84 mpLayoutName
.reset(new OUString(*r
.mpLayoutName
));
87 ScDPSaveMember::~ScDPSaveMember()
91 bool ScDPSaveMember::operator== ( const ScDPSaveMember
& r
) const
93 if ( aName
!= r
.aName
||
94 nVisibleMode
!= r
.nVisibleMode
||
95 nShowDetailsMode
!= r
.nShowDetailsMode
)
101 bool ScDPSaveMember::HasIsVisible() const
103 return nVisibleMode
!= SC_DPSAVEMODE_DONTKNOW
;
106 void ScDPSaveMember::SetIsVisible(bool bSet
)
108 nVisibleMode
= sal_uInt16(bSet
);
111 bool ScDPSaveMember::HasShowDetails() const
113 return nShowDetailsMode
!= SC_DPSAVEMODE_DONTKNOW
;
116 void ScDPSaveMember::SetShowDetails(bool bSet
)
118 nShowDetailsMode
= sal_uInt16(bSet
);
121 void ScDPSaveMember::SetName( const OUString
& rNew
)
123 // Used only if the source member was renamed (groups).
124 // For UI renaming of members, a layout name must be used.
129 void ScDPSaveMember::SetLayoutName( const OUString
& rName
)
131 mpLayoutName
.reset(new OUString(rName
));
134 const OUString
* ScDPSaveMember::GetLayoutName() const
136 return mpLayoutName
.get();
139 void ScDPSaveMember::RemoveLayoutName()
141 mpLayoutName
.reset();
144 void ScDPSaveMember::WriteToSource( const uno::Reference
<uno::XInterface
>& xMember
, sal_Int32 nPosition
)
146 uno::Reference
<beans::XPropertySet
> xMembProp( xMember
, uno::UNO_QUERY
);
147 OSL_ENSURE( xMembProp
.is(), "no properties at member" );
148 if ( xMembProp
.is() )
150 // exceptions are caught at ScDPSaveData::WriteToSource
152 if ( nVisibleMode
!= SC_DPSAVEMODE_DONTKNOW
)
153 lcl_SetBoolProperty( xMembProp
,
154 OUString(SC_UNO_DP_ISVISIBLE
), (bool)nVisibleMode
);
156 if ( nShowDetailsMode
!= SC_DPSAVEMODE_DONTKNOW
)
157 lcl_SetBoolProperty( xMembProp
,
158 OUString(SC_UNO_DP_SHOWDETAILS
), (bool)nShowDetailsMode
);
161 ScUnoHelpFunctions::SetOptionalPropertyValue(xMembProp
, SC_UNO_DP_LAYOUTNAME
, *mpLayoutName
);
163 if ( nPosition
>= 0 )
164 ScUnoHelpFunctions::SetOptionalPropertyValue(xMembProp
, SC_UNO_DP_POSITION
, nPosition
);
168 #if DEBUG_PIVOT_TABLE
170 void ScDPSaveMember::Dump(int nIndent
) const
172 std::string
aIndent(nIndent
*4, ' ');
173 cout
<< aIndent
<< "* member name: '" << aName
<< "'" << endl
;
175 cout
<< aIndent
<< " + layout name: ";
177 cout
<< "'" << *mpLayoutName
<< "'";
182 cout
<< aIndent
<< " + visibility: ";
183 if (nVisibleMode
== SC_DPSAVEMODE_DONTKNOW
)
186 cout
<< (nVisibleMode
? "visible" : "hidden");
192 ScDPSaveDimension::ScDPSaveDimension(const OUString
& rName
, bool bDataLayout
) :
195 mpSubtotalName(NULL
),
196 bIsDataLayout( bDataLayout
),
198 nOrientation( sheet::DataPilotFieldOrientation_HIDDEN
),
199 nFunction( sheet::GeneralFunction_AUTO
),
200 nUsedHierarchy( -1 ),
201 nShowEmptyMode( SC_DPSAVEMODE_DONTKNOW
),
202 bRepeatItemLabels( false ),
203 bSubTotalDefault( true ),
205 pSubTotalFuncs( NULL
),
206 pReferenceValue( NULL
),
208 pAutoShowInfo( NULL
),
213 ScDPSaveDimension::ScDPSaveDimension(const ScDPSaveDimension
& r
) :
216 mpSubtotalName(NULL
),
217 bIsDataLayout( r
.bIsDataLayout
),
218 bDupFlag( r
.bDupFlag
),
219 nOrientation( r
.nOrientation
),
220 nFunction( r
.nFunction
),
221 nUsedHierarchy( r
.nUsedHierarchy
),
222 nShowEmptyMode( r
.nShowEmptyMode
),
223 bRepeatItemLabels( r
.bRepeatItemLabels
),
224 bSubTotalDefault( r
.bSubTotalDefault
),
225 nSubTotalCount( r
.nSubTotalCount
),
226 pSubTotalFuncs( NULL
)
228 if ( nSubTotalCount
&& r
.pSubTotalFuncs
)
230 pSubTotalFuncs
= new sal_uInt16
[nSubTotalCount
];
231 for (long nSub
=0; nSub
<nSubTotalCount
; nSub
++)
232 pSubTotalFuncs
[nSub
] = r
.pSubTotalFuncs
[nSub
];
235 for (MemberList::const_iterator i
=r
.maMemberList
.begin(); i
!= r
.maMemberList
.end() ; ++i
)
237 const OUString
& rName
= (*i
)->GetName();
238 ScDPSaveMember
* pNew
= new ScDPSaveMember( **i
);
239 maMemberHash
[rName
] = pNew
;
240 maMemberList
.push_back( pNew
);
242 if (r
.pReferenceValue
)
243 pReferenceValue
= new sheet::DataPilotFieldReference( *(r
.pReferenceValue
) );
245 pReferenceValue
= NULL
;
247 pSortInfo
= new sheet::DataPilotFieldSortInfo( *(r
.pSortInfo
) );
251 pAutoShowInfo
= new sheet::DataPilotFieldAutoShowInfo( *(r
.pAutoShowInfo
) );
253 pAutoShowInfo
= NULL
;
255 pLayoutInfo
= new sheet::DataPilotFieldLayoutInfo( *(r
.pLayoutInfo
) );
259 mpLayoutName
.reset(new OUString(*r
.mpLayoutName
));
260 if (r
.mpSubtotalName
)
261 mpSubtotalName
.reset(new OUString(*r
.mpSubtotalName
));
264 ScDPSaveDimension::~ScDPSaveDimension()
266 for (MemberHash::const_iterator i
=maMemberHash
.begin(); i
!= maMemberHash
.end() ; ++i
)
268 delete pReferenceValue
;
270 delete pAutoShowInfo
;
272 delete [] pSubTotalFuncs
;
275 bool ScDPSaveDimension::operator== ( const ScDPSaveDimension
& r
) const
277 if ( aName
!= r
.aName
||
278 bIsDataLayout
!= r
.bIsDataLayout
||
279 bDupFlag
!= r
.bDupFlag
||
280 nOrientation
!= r
.nOrientation
||
281 nFunction
!= r
.nFunction
||
282 nUsedHierarchy
!= r
.nUsedHierarchy
||
283 nShowEmptyMode
!= r
.nShowEmptyMode
||
284 bRepeatItemLabels
!= r
.bRepeatItemLabels
||
285 bSubTotalDefault
!= r
.bSubTotalDefault
||
286 nSubTotalCount
!= r
.nSubTotalCount
)
289 if ( nSubTotalCount
&& ( !pSubTotalFuncs
|| !r
.pSubTotalFuncs
) ) // should not happen
293 for (i
=0; i
<nSubTotalCount
; i
++)
294 if ( pSubTotalFuncs
[i
] != r
.pSubTotalFuncs
[i
] )
297 if (maMemberHash
.size() != r
.maMemberHash
.size() )
300 MemberList::const_iterator a
=maMemberList
.begin();
301 MemberList::const_iterator b
=r
.maMemberList
.begin();
302 for (; a
!= maMemberList
.end() ; ++a
, ++b
)
306 if( pReferenceValue
&& r
.pReferenceValue
)
308 if ( !(*pReferenceValue
== *r
.pReferenceValue
) )
313 else if ( pReferenceValue
|| r
.pReferenceValue
)
317 if( this->pSortInfo
&& r
.pSortInfo
)
319 if ( !(*this->pSortInfo
== *r
.pSortInfo
) )
324 else if ( this->pSortInfo
|| r
.pSortInfo
)
328 if( this->pAutoShowInfo
&& r
.pAutoShowInfo
)
330 if ( !(*this->pAutoShowInfo
== *r
.pAutoShowInfo
) )
335 else if ( this->pAutoShowInfo
|| r
.pAutoShowInfo
)
343 void ScDPSaveDimension::AddMember(ScDPSaveMember
* pMember
)
345 const OUString
& rName
= pMember
->GetName();
346 MemberHash::iterator aExisting
= maMemberHash
.find( rName
);
347 if ( aExisting
== maMemberHash
.end() )
349 std::pair
< const OUString
, ScDPSaveMember
*> key( rName
, pMember
);
350 maMemberHash
.insert ( key
);
354 maMemberList
.remove( aExisting
->second
);
355 delete aExisting
->second
;
356 aExisting
->second
= pMember
;
358 maMemberList
.push_back( pMember
);
361 void ScDPSaveDimension::SetName( const OUString
& rNew
)
363 // Used only if the source dim was renamed (groups).
364 // For UI renaming of dimensions, the layout name must be used.
369 void ScDPSaveDimension::SetOrientation(sal_uInt16 nNew
)
374 void ScDPSaveDimension::SetSubTotals(long nCount
, const sal_uInt16
* pFuncs
)
377 delete [] pSubTotalFuncs
;
378 nSubTotalCount
= nCount
;
379 if ( nCount
&& pFuncs
)
381 pSubTotalFuncs
= new sal_uInt16
[nCount
];
382 for (long i
=0; i
<nCount
; i
++)
383 pSubTotalFuncs
[i
] = pFuncs
[i
];
386 pSubTotalFuncs
= NULL
;
388 bSubTotalDefault
= false;
391 bool ScDPSaveDimension::HasShowEmpty() const
393 return nShowEmptyMode
!= SC_DPSAVEMODE_DONTKNOW
;
396 void ScDPSaveDimension::SetShowEmpty(bool bSet
)
398 nShowEmptyMode
= sal_uInt16(bSet
);
401 void ScDPSaveDimension::SetRepeatItemLabels(bool bSet
)
403 bRepeatItemLabels
= bSet
;
406 void ScDPSaveDimension::SetFunction(sal_uInt16 nNew
)
411 void ScDPSaveDimension::SetUsedHierarchy(long nNew
)
413 nUsedHierarchy
= nNew
;
416 void ScDPSaveDimension::SetSubtotalName(const OUString
& rName
)
418 mpSubtotalName
.reset(new OUString(rName
));
421 const OUString
* ScDPSaveDimension::GetSubtotalName() const
423 return mpSubtotalName
.get();
426 void ScDPSaveDimension::RemoveSubtotalName()
428 mpSubtotalName
.reset();
431 bool ScDPSaveDimension::IsMemberNameInUse(const OUString
& rName
) const
433 MemberList::const_iterator itr
= maMemberList
.begin(), itrEnd
= maMemberList
.end();
434 for (; itr
!= itrEnd
; ++itr
)
436 const ScDPSaveMember
* pMem
= *itr
;
437 if (rName
.equalsIgnoreAsciiCase(pMem
->GetName()))
440 const OUString
* pLayoutName
= pMem
->GetLayoutName();
441 if (pLayoutName
&& rName
.equalsIgnoreAsciiCase(*pLayoutName
))
447 void ScDPSaveDimension::SetLayoutName(const OUString
& rName
)
449 mpLayoutName
.reset(new OUString(rName
));
452 const OUString
* ScDPSaveDimension::GetLayoutName() const
454 return mpLayoutName
.get();
457 void ScDPSaveDimension::RemoveLayoutName()
459 mpLayoutName
.reset();
462 void ScDPSaveDimension::SetReferenceValue(const sheet::DataPilotFieldReference
* pNew
)
464 delete pReferenceValue
;
466 pReferenceValue
= new sheet::DataPilotFieldReference(*pNew
);
468 pReferenceValue
= NULL
;
471 void ScDPSaveDimension::SetSortInfo(const sheet::DataPilotFieldSortInfo
* pNew
)
475 pSortInfo
= new sheet::DataPilotFieldSortInfo(*pNew
);
480 void ScDPSaveDimension::SetAutoShowInfo(const sheet::DataPilotFieldAutoShowInfo
* pNew
)
482 delete pAutoShowInfo
;
484 pAutoShowInfo
= new sheet::DataPilotFieldAutoShowInfo(*pNew
);
486 pAutoShowInfo
= NULL
;
489 void ScDPSaveDimension::SetLayoutInfo(const sheet::DataPilotFieldLayoutInfo
* pNew
)
493 pLayoutInfo
= new sheet::DataPilotFieldLayoutInfo(*pNew
);
498 void ScDPSaveDimension::SetCurrentPage( const OUString
* pPage
)
500 // We use member's visibility attribute to filter by page dimension.
502 // pPage == NULL -> all members visible.
503 MemberList::iterator it
= maMemberList
.begin(), itEnd
= maMemberList
.end();
504 for (; it
!= itEnd
; ++it
)
506 ScDPSaveMember
* pMem
= *it
;
507 bool bVisible
= !pPage
|| pMem
->GetName() == *pPage
;
508 pMem
->SetIsVisible(bVisible
);
512 OUString
ScDPSaveDimension::GetCurrentPage() const
514 MemberList::const_iterator it
= maMemberList
.begin(), itEnd
= maMemberList
.end();
515 for (; it
!= itEnd
; ++it
)
517 const ScDPSaveMember
* pMem
= *it
;
518 if (pMem
->GetIsVisible())
519 return pMem
->GetName();
525 ScDPSaveMember
* ScDPSaveDimension::GetExistingMemberByName(const OUString
& rName
)
527 MemberHash::const_iterator res
= maMemberHash
.find (rName
);
528 if (res
!= maMemberHash
.end())
533 ScDPSaveMember
* ScDPSaveDimension::GetMemberByName(const OUString
& rName
)
535 MemberHash::const_iterator res
= maMemberHash
.find (rName
);
536 if (res
!= maMemberHash
.end())
539 ScDPSaveMember
* pNew
= new ScDPSaveMember( rName
);
540 maMemberHash
[rName
] = pNew
;
541 maMemberList
.push_back( pNew
);
545 void ScDPSaveDimension::SetMemberPosition( const OUString
& rName
, sal_Int32 nNewPos
)
547 ScDPSaveMember
* pMember
= GetMemberByName( rName
); // make sure it exists and is in the hash
549 maMemberList
.remove( pMember
);
551 MemberList::iterator aIter
= maMemberList
.begin();
552 for (sal_Int32 i
=0; i
<nNewPos
&& aIter
!= maMemberList
.end(); i
++)
554 maMemberList
.insert( aIter
, pMember
);
557 void ScDPSaveDimension::WriteToSource( const uno::Reference
<uno::XInterface
>& xDim
)
559 uno::Reference
<beans::XPropertySet
> xDimProp( xDim
, uno::UNO_QUERY
);
560 OSL_ENSURE( xDimProp
.is(), "no properties at dimension" );
563 // exceptions are caught at ScDPSaveData::WriteToSource
566 sheet::DataPilotFieldOrientation eOrient
= (sheet::DataPilotFieldOrientation
)nOrientation
;
568 xDimProp
->setPropertyValue( OUString(SC_UNO_DP_ORIENTATION
), aAny
);
570 sheet::GeneralFunction eFunc
= (sheet::GeneralFunction
)nFunction
;
572 xDimProp
->setPropertyValue( OUString(SC_UNO_DP_FUNCTION
), aAny
);
574 if ( nUsedHierarchy
>= 0 )
576 aAny
<<= (sal_Int32
)nUsedHierarchy
;
577 xDimProp
->setPropertyValue( OUString(SC_UNO_DP_USEDHIERARCHY
), aAny
);
580 if ( pReferenceValue
)
582 aAny
<<= *pReferenceValue
;
583 xDimProp
->setPropertyValue( OUString(SC_UNO_DP_REFVALUE
), aAny
);
587 ScUnoHelpFunctions::SetOptionalPropertyValue(xDimProp
, SC_UNO_DP_LAYOUTNAME
, *mpLayoutName
);
589 const OUString
* pSubTotalName
= GetSubtotalName();
591 // Custom subtotal name, with '?' being replaced by the visible field name later.
592 ScUnoHelpFunctions::SetOptionalPropertyValue(xDimProp
, SC_UNO_DP_FIELD_SUBTOTALNAME
, *pSubTotalName
);
595 // Level loop outside of maMemberList loop
596 // because SubTotals have to be set independently of known members
598 long nCount
= maMemberHash
.size();
601 uno::Reference
<container::XIndexAccess
> xHiers
;
602 uno::Reference
<sheet::XHierarchiesSupplier
> xHierSupp( xDim
, uno::UNO_QUERY
);
603 if ( xHierSupp
.is() )
605 uno::Reference
<container::XNameAccess
> xHiersName
= xHierSupp
->getHierarchies();
606 xHiers
= new ScNameToIndexAccess( xHiersName
);
607 nHierCount
= xHiers
->getCount();
610 bool bHasHiddenMember
= false;
612 for (long nHier
=0; nHier
<nHierCount
; nHier
++)
614 uno::Reference
<uno::XInterface
> xHierarchy
= ScUnoHelpFunctions::AnyToInterface( xHiers
->getByIndex(nHier
) );
617 uno::Reference
<container::XIndexAccess
> xLevels
;
618 uno::Reference
<sheet::XLevelsSupplier
> xLevSupp( xHierarchy
, uno::UNO_QUERY
);
621 uno::Reference
<container::XNameAccess
> xLevelsName
= xLevSupp
->getLevels();
622 xLevels
= new ScNameToIndexAccess( xLevelsName
);
623 nLevCount
= xLevels
->getCount();
626 for (long nLev
=0; nLev
<nLevCount
; nLev
++)
628 uno::Reference
<uno::XInterface
> xLevel
= ScUnoHelpFunctions::AnyToInterface( xLevels
->getByIndex(nLev
) );
629 uno::Reference
<beans::XPropertySet
> xLevProp( xLevel
, uno::UNO_QUERY
);
630 OSL_ENSURE( xLevProp
.is(), "no properties at level" );
634 if ( !bSubTotalDefault
)
636 if ( !pSubTotalFuncs
)
639 uno::Sequence
<sheet::GeneralFunction
> aSeq(nSubTotalCount
);
640 sheet::GeneralFunction
* pArray
= aSeq
.getArray();
641 for (long i
=0; i
<nSubTotalCount
; i
++)
642 pArray
[i
] = (sheet::GeneralFunction
)pSubTotalFuncs
[i
];
644 xLevProp
->setPropertyValue( OUString(SC_UNO_DP_SUBTOTAL
), aAny
);
646 if ( nShowEmptyMode
!= SC_DPSAVEMODE_DONTKNOW
)
647 lcl_SetBoolProperty( xLevProp
,
648 OUString(SC_UNO_DP_SHOWEMPTY
), (bool)nShowEmptyMode
);
650 lcl_SetBoolProperty( xLevProp
,
651 OUString(SC_UNO_DP_REPEATITEMLABELS
), bRepeatItemLabels
);
654 ScUnoHelpFunctions::SetOptionalPropertyValue(xLevProp
, SC_UNO_DP_SORTING
, *pSortInfo
);
657 ScUnoHelpFunctions::SetOptionalPropertyValue(xLevProp
, SC_UNO_DP_AUTOSHOW
, *pAutoShowInfo
);
660 ScUnoHelpFunctions::SetOptionalPropertyValue(xLevProp
, SC_UNO_DP_LAYOUT
, *pLayoutInfo
);
662 // exceptions are caught at ScDPSaveData::WriteToSource
667 uno::Reference
<sheet::XMembersSupplier
> xMembSupp( xLevel
, uno::UNO_QUERY
);
668 if ( xMembSupp
.is() )
670 uno::Reference
<container::XNameAccess
> xMembers
= xMembSupp
->getMembers();
673 sal_Int32 nPosition
= -1; // set position only in manual mode
674 if ( !pSortInfo
|| pSortInfo
->Mode
== sheet::DataPilotFieldSortMode::MANUAL
)
677 for (MemberList::const_iterator i
=maMemberList
.begin(); i
!= maMemberList
.end() ; ++i
)
679 ScDPSaveMember
* pMember
= *i
;
680 if (!pMember
->GetIsVisible())
681 bHasHiddenMember
= true;
682 OUString aMemberName
= pMember
->GetName();
683 if ( xMembers
->hasByName( aMemberName
) )
685 uno::Reference
<uno::XInterface
> xMemberInt
= ScUnoHelpFunctions::AnyToInterface(
686 xMembers
->getByName( aMemberName
) );
687 pMember
->WriteToSource( xMemberInt
, nPosition
);
689 if ( nPosition
>= 0 )
690 ++nPosition
; // increase if initialized
692 // missing member is no error
701 ScUnoHelpFunctions::SetOptionalPropertyValue(xDimProp
, SC_UNO_DP_HAS_HIDDEN_MEMBER
, bHasHiddenMember
);
704 void ScDPSaveDimension::UpdateMemberVisibility(const std::unordered_map
<OUString
, bool, OUStringHash
>& rData
)
706 typedef std::unordered_map
<OUString
, bool, OUStringHash
> DataMap
;
707 MemberList::iterator itrMem
= maMemberList
.begin(), itrMemEnd
= maMemberList
.end();
708 for (; itrMem
!= itrMemEnd
; ++itrMem
)
710 ScDPSaveMember
* pMem
= *itrMem
;
711 const OUString
& rMemName
= pMem
->GetName();
712 DataMap::const_iterator itr
= rData
.find(rMemName
);
713 if (itr
!= rData
.end())
714 pMem
->SetIsVisible(itr
->second
);
718 bool ScDPSaveDimension::HasInvisibleMember() const
720 MemberList::const_iterator itrMem
= maMemberList
.begin(), itrMemEnd
= maMemberList
.end();
721 for (; itrMem
!= itrMemEnd
; ++itrMem
)
723 const ScDPSaveMember
* pMem
= *itrMem
;
724 if (!pMem
->GetIsVisible())
730 void ScDPSaveDimension::RemoveObsoleteMembers(const MemberSetType
& rMembers
)
732 maMemberHash
.clear();
734 MemberList::iterator it
= maMemberList
.begin(), itEnd
= maMemberList
.end();
735 for (; it
!= itEnd
; ++it
)
737 ScDPSaveMember
* pMem
= *it
;
738 if (rMembers
.count(pMem
->GetName()))
740 // This member still exists.
741 maMemberHash
.insert(MemberHash::value_type(pMem
->GetName(), pMem
));
742 aNew
.push_back(pMem
);
746 // This member no longer exists.
751 maMemberList
.swap(aNew
);
754 #if DEBUG_PIVOT_TABLE
756 void ScDPSaveDimension::Dump(int nIndent
) const
758 static const char* pOrientNames
[] = { "hidden", "column", "row", "page", "data" };
759 std::string
aIndent(nIndent
*4, ' ');
761 cout
<< aIndent
<< "* dimension name: '" << aName
<< "'" << endl
;
763 cout
<< aIndent
<< " + orientation: ";
764 if (nOrientation
<= 4)
765 cout
<< pOrientNames
[nOrientation
];
770 cout
<< aIndent
<< " + layout name: ";
772 cout
<< "'" << *mpLayoutName
<< "'";
777 cout
<< aIndent
<< " + subtotal name: ";
779 cout
<< "'" << *mpSubtotalName
<< "'";
784 cout
<< aIndent
<< " + is data layout: " << (bIsDataLayout
? "yes" : "no") << endl
;
785 cout
<< aIndent
<< " + is duplicate: " << (bDupFlag
? "yes" : "no") << endl
;
787 MemberList::const_iterator itMem
= maMemberList
.begin(), itMemEnd
= maMemberList
.end();
788 for (; itMem
!= itMemEnd
; ++itMem
)
790 ScDPSaveMember
* pMem
= *itMem
;
791 pMem
->Dump(nIndent
+1);
794 cout
<< endl
; // blank line
799 ScDPSaveData::ScDPSaveData() :
800 pDimensionData( NULL
),
801 nColumnGrandMode( SC_DPSAVEMODE_DONTKNOW
),
802 nRowGrandMode( SC_DPSAVEMODE_DONTKNOW
),
803 nIgnoreEmptyMode( SC_DPSAVEMODE_DONTKNOW
),
804 nRepeatEmptyMode( SC_DPSAVEMODE_DONTKNOW
),
805 bFilterButton( true ),
807 mbDimensionMembersBuilt(false),
808 mpGrandTotalName(NULL
)
812 ScDPSaveData::ScDPSaveData(const ScDPSaveData
& r
) :
813 nColumnGrandMode( r
.nColumnGrandMode
),
814 nRowGrandMode( r
.nRowGrandMode
),
815 nIgnoreEmptyMode( r
.nIgnoreEmptyMode
),
816 nRepeatEmptyMode( r
.nRepeatEmptyMode
),
817 bFilterButton( r
.bFilterButton
),
818 bDrillDown( r
.bDrillDown
),
819 mbDimensionMembersBuilt(r
.mbDimensionMembersBuilt
),
820 mpGrandTotalName(NULL
),
823 if ( r
.pDimensionData
)
824 pDimensionData
= new ScDPDimensionSaveData( *r
.pDimensionData
);
826 pDimensionData
= NULL
;
828 aDimList
= r
.aDimList
.clone();
830 if (r
.mpGrandTotalName
)
831 mpGrandTotalName
.reset(new OUString(*r
.mpGrandTotalName
));
834 ScDPSaveData
& ScDPSaveData::operator= ( const ScDPSaveData
& r
)
838 this->~ScDPSaveData();
839 new( this ) ScDPSaveData ( r
);
844 bool ScDPSaveData::operator== ( const ScDPSaveData
& r
) const
846 if ( nColumnGrandMode
!= r
.nColumnGrandMode
||
847 nRowGrandMode
!= r
.nRowGrandMode
||
848 nIgnoreEmptyMode
!= r
.nIgnoreEmptyMode
||
849 nRepeatEmptyMode
!= r
.nRepeatEmptyMode
||
850 bFilterButton
!= r
.bFilterButton
||
851 bDrillDown
!= r
.bDrillDown
||
852 mbDimensionMembersBuilt
!= r
.mbDimensionMembersBuilt
)
855 if ( pDimensionData
|| r
.pDimensionData
)
856 if ( !pDimensionData
|| !r
.pDimensionData
|| !( *pDimensionData
== *r
.pDimensionData
) )
859 if ( aDimList
.size() != r
.aDimList
.size() )
862 if (aDimList
!= r
.aDimList
)
865 if (mpGrandTotalName
)
867 if (!r
.mpGrandTotalName
)
869 if (!mpGrandTotalName
->equals(*r
.mpGrandTotalName
))
872 else if (r
.mpGrandTotalName
)
878 ScDPSaveData::~ScDPSaveData()
880 delete pDimensionData
;
883 void ScDPSaveData::SetGrandTotalName(const OUString
& rName
)
885 mpGrandTotalName
.reset(new OUString(rName
));
888 const OUString
* ScDPSaveData::GetGrandTotalName() const
890 return mpGrandTotalName
.get();
895 class DimOrderInserter
: std::unary_function
<const ScDPSaveDimension
*, void>
897 ScDPSaveData::DimOrderType
& mrNames
;
899 DimOrderInserter(ScDPSaveData::DimOrderType
& rNames
) : mrNames(rNames
) {}
901 void operator() (const ScDPSaveDimension
* pDim
)
903 size_t nRank
= mrNames
.size();
905 ScDPSaveData::DimOrderType::value_type(pDim
->GetName(), nRank
));
911 const ScDPSaveData::DimOrderType
& ScDPSaveData::GetDimensionSortOrder() const
915 mpDimOrder
.reset(new DimOrderType
);
916 std::vector
<const ScDPSaveDimension
*> aRowDims
, aColDims
;
917 GetAllDimensionsByOrientation(sheet::DataPilotFieldOrientation_ROW
, aRowDims
);
918 GetAllDimensionsByOrientation(sheet::DataPilotFieldOrientation_COLUMN
, aColDims
);
920 std::for_each(aRowDims
.begin(), aRowDims
.end(), DimOrderInserter(*mpDimOrder
));
921 std::for_each(aColDims
.begin(), aColDims
.end(), DimOrderInserter(*mpDimOrder
));
926 void ScDPSaveData::GetAllDimensionsByOrientation(
927 sheet::DataPilotFieldOrientation eOrientation
, std::vector
<const ScDPSaveDimension
*>& rDims
) const
929 std::vector
<const ScDPSaveDimension
*> aDims
;
930 DimsType::const_iterator it
= aDimList
.begin(), itEnd
= aDimList
.end();
931 for (; it
!= itEnd
; ++it
)
933 const ScDPSaveDimension
& rDim
= *it
;
934 if (rDim
.GetOrientation() != static_cast<sal_uInt16
>(eOrientation
))
937 aDims
.push_back(&rDim
);
943 void ScDPSaveData::AddDimension(ScDPSaveDimension
* pDim
)
948 CheckDuplicateName(*pDim
);
949 aDimList
.push_back(pDim
);
954 ScDPSaveDimension
* ScDPSaveData::GetDimensionByName(const OUString
& rName
)
956 boost::ptr_vector
<ScDPSaveDimension
>::const_iterator iter
;
957 for (iter
= aDimList
.begin(); iter
!= aDimList
.end(); ++iter
)
959 if (iter
->GetName() == rName
&& !iter
->IsDataLayout() )
960 return const_cast<ScDPSaveDimension
*>(&(*iter
));
963 return AppendNewDimension(rName
, false);
966 ScDPSaveDimension
* ScDPSaveData::GetExistingDimensionByName(const OUString
& rName
) const
968 boost::ptr_vector
<ScDPSaveDimension
>::const_iterator iter
;
969 for (iter
= aDimList
.begin(); iter
!= aDimList
.end(); ++iter
)
971 if (iter
->GetName() == rName
&& !iter
->IsDataLayout() )
972 return const_cast<ScDPSaveDimension
*>(&(*iter
));
974 return NULL
; // don't create new
977 ScDPSaveDimension
* ScDPSaveData::GetNewDimensionByName(const OUString
& rName
)
979 boost::ptr_vector
<ScDPSaveDimension
>::const_iterator iter
;
980 for (iter
= aDimList
.begin(); iter
!= aDimList
.end(); ++iter
)
982 if (iter
->GetName() == rName
&& !iter
->IsDataLayout() )
983 return DuplicateDimension(rName
);
986 return AppendNewDimension(rName
, false);
989 ScDPSaveDimension
* ScDPSaveData::GetDataLayoutDimension()
991 ScDPSaveDimension
* pDim
= GetExistingDataLayoutDimension();
995 return AppendNewDimension(OUString(), true);
998 ScDPSaveDimension
* ScDPSaveData::GetExistingDataLayoutDimension() const
1000 boost::ptr_vector
<ScDPSaveDimension
>::const_iterator iter
;
1001 for (iter
= aDimList
.begin(); iter
!= aDimList
.end(); ++iter
)
1003 if ( iter
->IsDataLayout() )
1004 return const_cast<ScDPSaveDimension
*>(&(*iter
));
1009 ScDPSaveDimension
* ScDPSaveData::DuplicateDimension(const OUString
& rName
)
1011 // always insert new
1013 ScDPSaveDimension
* pOld
= GetExistingDimensionByName(rName
);
1017 ScDPSaveDimension
* pNew
= new ScDPSaveDimension( *pOld
);
1022 void ScDPSaveData::RemoveDimensionByName(const OUString
& rName
)
1024 boost::ptr_vector
<ScDPSaveDimension
>::iterator iter
;
1025 for (iter
= aDimList
.begin(); iter
!= aDimList
.end(); ++iter
)
1027 if (iter
->GetName() != rName
|| iter
->IsDataLayout())
1030 aDimList
.erase(iter
);
1031 RemoveDuplicateNameCount(rName
);
1032 DimensionsChanged();
1037 ScDPSaveDimension
& ScDPSaveData::DuplicateDimension( const ScDPSaveDimension
& rDim
)
1039 ScDPSaveDimension
* pNew
= new ScDPSaveDimension( rDim
);
1044 ScDPSaveDimension
* ScDPSaveData::GetInnermostDimension(sal_uInt16 nOrientation
)
1046 // return the innermost dimension for the given orientation,
1047 // excluding data layout dimension
1049 boost::ptr_vector
<ScDPSaveDimension
>::const_reverse_iterator iter
;
1050 for (iter
= aDimList
.rbegin(); iter
!= aDimList
.rend(); ++iter
)
1052 if (iter
->GetOrientation() == nOrientation
&& !iter
->IsDataLayout())
1053 return const_cast<ScDPSaveDimension
*>(&(*iter
));
1059 ScDPSaveDimension
* ScDPSaveData::GetFirstDimension(sheet::DataPilotFieldOrientation eOrientation
)
1061 boost::ptr_vector
<ScDPSaveDimension
>::const_iterator iter
;
1062 for (iter
= aDimList
.begin(); iter
!= aDimList
.end(); ++iter
)
1064 if (iter
->GetOrientation() == eOrientation
&& !iter
->IsDataLayout())
1065 return const_cast<ScDPSaveDimension
*>(&(*iter
));
1070 long ScDPSaveData::GetDataDimensionCount() const
1072 long nDataCount
= 0;
1074 boost::ptr_vector
<ScDPSaveDimension
>::const_iterator iter
;
1075 for (iter
= aDimList
.begin(); iter
!= aDimList
.end(); ++iter
)
1077 if (iter
->GetOrientation() == sheet::DataPilotFieldOrientation_DATA
)
1084 void ScDPSaveData::SetPosition( ScDPSaveDimension
* pDim
, long nNew
)
1086 // position (nNew) is counted within dimensions of the same orientation
1088 sal_uInt16 nOrient
= pDim
->GetOrientation();
1090 boost::ptr_vector
<ScDPSaveDimension
>::iterator it
;
1091 for ( it
= aDimList
.begin(); it
!= aDimList
.end(); ++it
)
1095 // Tell ptr_vector to give up ownership of this element. Don't
1096 // delete this instance as it is re-inserted into the container
1098 aDimList
.release(it
).release();
1103 boost::ptr_vector
<ScDPSaveDimension
>::iterator iterInsert
= aDimList
.begin();
1104 while ( nNew
> 0 && iterInsert
!= aDimList
.end())
1106 if (iterInsert
->GetOrientation() == nOrient
)
1112 aDimList
.insert(iterInsert
,pDim
);
1113 DimensionsChanged();
1116 void ScDPSaveData::SetColumnGrand(bool bSet
)
1118 nColumnGrandMode
= sal_uInt16(bSet
);
1121 void ScDPSaveData::SetRowGrand(bool bSet
)
1123 nRowGrandMode
= sal_uInt16(bSet
);
1126 void ScDPSaveData::SetIgnoreEmptyRows(bool bSet
)
1128 nIgnoreEmptyMode
= sal_uInt16(bSet
);
1131 void ScDPSaveData::SetRepeatIfEmpty(bool bSet
)
1133 nRepeatEmptyMode
= sal_uInt16(bSet
);
1136 void ScDPSaveData::SetFilterButton(bool bSet
)
1138 bFilterButton
= bSet
;
1141 void ScDPSaveData::SetDrillDown(bool bSet
)
1146 static void lcl_ResetOrient( const uno::Reference
<sheet::XDimensionsSupplier
>& xSource
)
1148 sheet::DataPilotFieldOrientation eOrient
= sheet::DataPilotFieldOrientation_HIDDEN
;
1150 uno::Reference
<container::XNameAccess
> xDimsName
= xSource
->getDimensions();
1151 uno::Reference
<container::XIndexAccess
> xIntDims
= new ScNameToIndexAccess( xDimsName
);
1152 long nIntCount
= xIntDims
->getCount();
1153 for (long nIntDim
=0; nIntDim
<nIntCount
; nIntDim
++)
1155 uno::Reference
<uno::XInterface
> xIntDim
= ScUnoHelpFunctions::AnyToInterface( xIntDims
->getByIndex(nIntDim
) );
1156 uno::Reference
<beans::XPropertySet
> xDimProp( xIntDim
, uno::UNO_QUERY
);
1161 xDimProp
->setPropertyValue( OUString(SC_UNO_DP_ORIENTATION
), aAny
);
1166 void ScDPSaveData::WriteToSource( const uno::Reference
<sheet::XDimensionsSupplier
>& xSource
)
1171 // source options must be first!
1173 uno::Reference
<beans::XPropertySet
> xSourceProp( xSource
, uno::UNO_QUERY
);
1174 OSL_ENSURE( xSourceProp
.is(), "no properties at source" );
1175 if ( xSourceProp
.is() )
1177 // source options are not available for external sources
1178 //TODO: use XPropertySetInfo to test for availability?
1182 if ( nIgnoreEmptyMode
!= SC_DPSAVEMODE_DONTKNOW
)
1183 lcl_SetBoolProperty( xSourceProp
,
1184 OUString(SC_UNO_DP_IGNOREEMPTY
), (bool)nIgnoreEmptyMode
);
1185 if ( nRepeatEmptyMode
!= SC_DPSAVEMODE_DONTKNOW
)
1186 lcl_SetBoolProperty( xSourceProp
,
1187 OUString(SC_UNO_DP_REPEATEMPTY
), (bool)nRepeatEmptyMode
);
1189 catch(uno::Exception
&)
1194 const OUString
* pGrandTotalName
= GetGrandTotalName();
1195 if (pGrandTotalName
)
1196 ScUnoHelpFunctions::SetOptionalPropertyValue(xSourceProp
, SC_UNO_DP_GRANDTOTAL_NAME
, *pGrandTotalName
);
1199 // exceptions in the other calls are errors
1202 // reset all orientations
1203 //TODO: "forgetSettings" or similar at source ?????
1204 //TODO: reset all duplicated dimensions, or reuse them below !!!
1205 OSL_FAIL( "ScDPSaveData::WriteToSource" );
1207 lcl_ResetOrient( xSource
);
1209 uno::Reference
<container::XNameAccess
> xDimsName
= xSource
->getDimensions();
1210 uno::Reference
<container::XIndexAccess
> xIntDims
= new ScNameToIndexAccess( xDimsName
);
1211 long nIntCount
= xIntDims
->getCount();
1213 boost::ptr_vector
<ScDPSaveDimension
>::iterator iter
= aDimList
.begin();
1214 for (long i
= 0; iter
!= aDimList
.end(); ++iter
, ++i
)
1216 OUString aName
= iter
->GetName();
1217 OUString aCoreName
= ScDPUtil::getSourceDimensionName(aName
);
1219 SAL_INFO("sc.core", aName
);
1221 bool bData
= iter
->IsDataLayout();
1223 //TODO: getByName for ScDPSource, including DataLayoutDimension !!!!!!!!
1225 bool bFound
= false;
1226 for (long nIntDim
=0; nIntDim
<nIntCount
&& !bFound
; nIntDim
++)
1228 uno::Reference
<uno::XInterface
> xIntDim
= ScUnoHelpFunctions::AnyToInterface( xIntDims
->getByIndex(nIntDim
) );
1231 uno::Reference
<beans::XPropertySet
> xDimProp( xIntDim
, uno::UNO_QUERY
);
1232 if ( xDimProp
.is() )
1234 bFound
= ScUnoHelpFunctions::GetBoolProperty( xDimProp
,
1235 OUString(SC_UNO_DP_ISDATALAYOUT
) );
1236 //TODO: error checking -- is "IsDataLayoutDimension" property required??
1241 uno::Reference
<container::XNamed
> xDimName( xIntDim
, uno::UNO_QUERY
);
1242 if (xDimName
.is() && xDimName
->getName() == aCoreName
)
1248 if (iter
->GetDupFlag())
1250 uno::Reference
<util::XCloneable
> xCloneable(xIntDim
, uno::UNO_QUERY
);
1251 OSL_ENSURE(xCloneable
.is(), "cannot clone dimension");
1252 if (xCloneable
.is())
1254 uno::Reference
<util::XCloneable
> xNew
= xCloneable
->createClone();
1255 uno::Reference
<container::XNamed
> xNewName(xNew
, uno::UNO_QUERY
);
1258 xNewName
->setName(aName
);
1259 iter
->WriteToSource(xNew
);
1264 iter
->WriteToSource( xIntDim
);
1267 OSL_ENSURE(bFound
, "WriteToSource: Dimension not found");
1270 if ( xSourceProp
.is() )
1272 if ( nColumnGrandMode
!= SC_DPSAVEMODE_DONTKNOW
)
1273 lcl_SetBoolProperty( xSourceProp
,
1274 OUString(SC_UNO_DP_COLGRAND
), (bool)nColumnGrandMode
);
1275 if ( nRowGrandMode
!= SC_DPSAVEMODE_DONTKNOW
)
1276 lcl_SetBoolProperty( xSourceProp
,
1277 OUString(SC_UNO_DP_ROWGRAND
), (bool)nRowGrandMode
);
1280 catch(uno::Exception
&)
1282 OSL_FAIL("exception in WriteToSource");
1286 bool ScDPSaveData::IsEmpty() const
1288 boost::ptr_vector
<ScDPSaveDimension
>::const_iterator iter
;
1289 for (iter
= aDimList
.begin(); iter
!= aDimList
.end(); ++iter
)
1291 if (iter
->GetOrientation() != sheet::DataPilotFieldOrientation_HIDDEN
&& !iter
->IsDataLayout())
1294 return true; // no entries that are not hidden
1297 void ScDPSaveData::RemoveAllGroupDimensions( const OUString
& rSrcDimName
, std::vector
<OUString
>* pDeletedNames
)
1299 if (!pDimensionData
)
1300 // No group dimensions exist. Nothing to do.
1303 // Remove numeric group dimension (exists once at most). No need to delete
1304 // anything in save data (grouping was done inplace in an existing base
1306 pDimensionData
->RemoveNumGroupDimension(rSrcDimName
);
1308 // Remove named group dimension(s). Dimensions have to be removed from
1309 // dimension save data and from save data too.
1310 const ScDPSaveGroupDimension
* pExistingGroup
= pDimensionData
->GetGroupDimForBase(rSrcDimName
);
1311 while ( pExistingGroup
)
1313 OUString aGroupDimName
= pExistingGroup
->GetGroupDimName();
1314 pDimensionData
->RemoveGroupDimension(aGroupDimName
); // pExistingGroup is deleted
1316 // also remove SaveData settings for the dimension that no longer exists
1317 RemoveDimensionByName(aGroupDimName
);
1320 pDeletedNames
->push_back(aGroupDimName
);
1322 // see if there are more group dimensions
1323 pExistingGroup
= pDimensionData
->GetGroupDimForBase(rSrcDimName
);
1325 if ( pExistingGroup
&& pExistingGroup
->GetGroupDimName() == aGroupDimName
)
1327 // still get the same group dimension?
1328 OSL_FAIL("couldn't remove group dimension");
1329 pExistingGroup
= NULL
; // avoid endless loop
1334 ScDPDimensionSaveData
* ScDPSaveData::GetDimensionData()
1336 if (!pDimensionData
)
1337 pDimensionData
= new ScDPDimensionSaveData
;
1338 return pDimensionData
;
1341 void ScDPSaveData::SetDimensionData( const ScDPDimensionSaveData
* pNew
)
1343 delete pDimensionData
;
1345 pDimensionData
= new ScDPDimensionSaveData( *pNew
);
1347 pDimensionData
= NULL
;
1350 void ScDPSaveData::BuildAllDimensionMembers(ScDPTableData
* pData
)
1352 if (mbDimensionMembersBuilt
)
1355 // First, build a dimension name-to-index map.
1356 typedef std::unordered_map
<OUString
, long, OUStringHash
> NameIndexMap
;
1358 long nColCount
= pData
->GetColumnCount();
1359 for (long i
= 0; i
< nColCount
; ++i
)
1360 aMap
.insert( NameIndexMap::value_type(pData
->getDimensionName(i
), i
));
1362 NameIndexMap::const_iterator itrEnd
= aMap
.end();
1364 boost::ptr_vector
<ScDPSaveDimension
>::iterator iter
;
1365 for (iter
= aDimList
.begin(); iter
!= aDimList
.end(); ++iter
)
1367 const OUString
& rDimName
= iter
->GetName();
1368 if (rDimName
.isEmpty())
1369 // empty dimension name. It must be data layout.
1372 NameIndexMap::const_iterator itr
= aMap
.find(rDimName
);
1374 // dimension name not in the data. This should never happen!
1377 long nDimIndex
= itr
->second
;
1378 const std::vector
<SCROW
>& rMembers
= pData
->GetColumnEntries(nDimIndex
);
1379 size_t mMemberCount
= rMembers
.size();
1380 for (size_t j
= 0; j
< mMemberCount
; ++j
)
1382 const ScDPItemData
* pMemberData
= pData
->GetMemberById( nDimIndex
, rMembers
[j
] );
1383 OUString aMemName
= pData
->GetFormattedString(nDimIndex
, *pMemberData
);
1384 if (iter
->GetExistingMemberByName(aMemName
))
1385 // this member instance already exists. nothing to do.
1388 unique_ptr
<ScDPSaveMember
> pNewMember(new ScDPSaveMember(aMemName
));
1389 pNewMember
->SetIsVisible(true);
1390 iter
->AddMember(pNewMember
.release());
1394 mbDimensionMembersBuilt
= true;
1397 void ScDPSaveData::SyncAllDimensionMembers(ScDPTableData
* pData
)
1399 typedef std::unordered_map
<OUString
, long, OUStringHash
> NameIndexMap
;
1401 // First, build a dimension name-to-index map.
1403 long nColCount
= pData
->GetColumnCount();
1404 for (long i
= 0; i
< nColCount
; ++i
)
1405 aMap
.insert(NameIndexMap::value_type(pData
->getDimensionName(i
), i
));
1407 NameIndexMap::const_iterator itMapEnd
= aMap
.end();
1409 DimsType::iterator it
= aDimList
.begin(), itEnd
= aDimList
.end();
1410 for (it
= aDimList
.begin(); it
!= itEnd
; ++it
)
1412 const OUString
& rDimName
= it
->GetName();
1413 if (rDimName
.isEmpty())
1414 // empty dimension name. It must be data layout.
1417 NameIndexMap::const_iterator itMap
= aMap
.find(rDimName
);
1418 if (itMap
== itMapEnd
)
1419 // dimension name not in the data. This should never happen!
1422 ScDPSaveDimension::MemberSetType aMemNames
;
1423 long nDimIndex
= itMap
->second
;
1424 const std::vector
<SCROW
>& rMembers
= pData
->GetColumnEntries(nDimIndex
);
1425 size_t nMemberCount
= rMembers
.size();
1426 for (size_t j
= 0; j
< nMemberCount
; ++j
)
1428 const ScDPItemData
* pMemberData
= pData
->GetMemberById(nDimIndex
, rMembers
[j
]);
1429 OUString aMemName
= pData
->GetFormattedString(nDimIndex
, *pMemberData
);
1430 aMemNames
.insert(aMemName
);
1433 it
->RemoveObsoleteMembers(aMemNames
);
1437 bool ScDPSaveData::HasInvisibleMember(const OUString
& rDimName
) const
1439 ScDPSaveDimension
* pDim
= GetExistingDimensionByName(rDimName
);
1443 return pDim
->HasInvisibleMember();
1446 #if DEBUG_PIVOT_TABLE
1448 void ScDPSaveData::Dump() const
1450 DimsType::const_iterator itDim
= aDimList
.begin(), itDimEnd
= aDimList
.end();
1451 for (; itDim
!= itDimEnd
; ++itDim
)
1453 const ScDPSaveDimension
& rDim
= *itDim
;
1460 void ScDPSaveData::CheckDuplicateName(ScDPSaveDimension
& rDim
)
1462 const OUString aName
= ScDPUtil::getSourceDimensionName(rDim
.GetName());
1463 DupNameCountType::iterator it
= maDupNameCounts
.find(aName
);
1464 if (it
!= maDupNameCounts
.end())
1466 rDim
.SetName(ScDPUtil::createDuplicateDimensionName(aName
, ++it
->second
));
1467 rDim
.SetDupFlag(true);
1471 maDupNameCounts
.insert(DupNameCountType::value_type(aName
, 0));
1474 void ScDPSaveData::RemoveDuplicateNameCount(const OUString
& rName
)
1476 OUString aCoreName
= rName
;
1477 if (ScDPUtil::isDuplicateDimension(rName
))
1478 aCoreName
= ScDPUtil::getSourceDimensionName(rName
);
1480 DupNameCountType::iterator it
= maDupNameCounts
.find(aCoreName
);
1481 if (it
== maDupNameCounts
.end())
1486 maDupNameCounts
.erase(it
);
1494 ScDPSaveDimension
* ScDPSaveData::AppendNewDimension(const OUString
& rName
, bool bDataLayout
)
1496 if (ScDPUtil::isDuplicateDimension(rName
))
1497 // This call is for original dimensions only.
1500 ScDPSaveDimension
* pNew
= new ScDPSaveDimension(rName
, bDataLayout
);
1501 aDimList
.push_back(pNew
);
1502 if (!maDupNameCounts
.count(rName
))
1503 maDupNameCounts
.insert(DupNameCountType::value_type(rName
, 0));
1505 DimensionsChanged();
1509 void ScDPSaveData::DimensionsChanged()
1514 bool operator == (const ::com::sun::star::sheet::DataPilotFieldSortInfo
&l
, const ::com::sun::star::sheet::DataPilotFieldSortInfo
&r
)
1516 return l
.Field
== r
.Field
&& l
.IsAscending
== r
.IsAscending
&& l
.Mode
== r
.Mode
;
1518 bool operator == (const ::com::sun::star::sheet::DataPilotFieldAutoShowInfo
&l
, const ::com::sun::star::sheet::DataPilotFieldAutoShowInfo
&r
)
1520 return l
.IsEnabled
== r
.IsEnabled
&&
1521 l
.ShowItemsMode
== r
.ShowItemsMode
&&
1522 l
.ItemCount
== r
.ItemCount
&&
1523 l
.DataField
== r
.DataField
;
1525 bool operator == (const ::com::sun::star::sheet::DataPilotFieldReference
&l
, const ::com::sun::star::sheet::DataPilotFieldReference
&r
)
1527 return l
.ReferenceType
== r
.ReferenceType
&&
1528 l
.ReferenceField
== r
.ReferenceField
&&
1529 l
.ReferenceItemType
== r
.ReferenceItemType
&&
1530 l
.ReferenceItemName
== r
.ReferenceItemName
;
1533 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */