1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: dpsave.cxx,v $
10 * $Revision: 1.13.32.3 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
36 // INCLUDE ---------------------------------------------------------------
39 #include "dpdimsave.hxx"
40 #include "miscuno.hxx"
41 #include "scerrors.hxx"
42 #include "unonames.hxx"
45 #include <tools/debug.hxx>
47 #include <com/sun/star/sheet/GeneralFunction.hpp>
48 #include <com/sun/star/sheet/DataPilotFieldAutoShowInfo.hpp>
49 #include <com/sun/star/sheet/DataPilotFieldLayoutInfo.hpp>
50 #include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
51 #include <com/sun/star/sheet/DataPilotFieldReference.hpp>
52 #include <com/sun/star/sheet/DataPilotFieldSortInfo.hpp>
53 #include <com/sun/star/sheet/DataPilotFieldSortMode.hpp>
54 #include <com/sun/star/sheet/TableFilterField.hpp>
55 #include <com/sun/star/sheet/XHierarchiesSupplier.hpp>
56 #include <com/sun/star/sheet/XLevelsSupplier.hpp>
57 #include <com/sun/star/sheet/XMembersSupplier.hpp>
58 #include <com/sun/star/container/XNamed.hpp>
59 #include <com/sun/star/util/XCloneable.hpp>
63 using namespace com::sun::star
;
64 using ::com::sun::star::uno::Reference
;
65 using ::com::sun::star::uno::Any
;
66 using ::rtl::OUString
;
67 using ::rtl::OUStringHash
;
68 using ::std::hash_map
;
69 using ::std::auto_ptr
;
71 // -----------------------------------------------------------------------
73 #define SC_DPSAVEMODE_NO 0
74 #define SC_DPSAVEMODE_YES 1
75 #define SC_DPSAVEMODE_DONTKNOW 2
77 // -----------------------------------------------------------------------
79 //! move to a header file
80 //! use names from unonames.hxx?
81 #define DP_PROP_COLUMNGRAND "ColumnGrand"
82 #define DP_PROP_FUNCTION "Function"
83 #define DP_PROP_IGNOREEMPTY "IgnoreEmptyRows"
84 #define DP_PROP_ISDATALAYOUT "IsDataLayoutDimension"
85 #define DP_PROP_ISVISIBLE "IsVisible"
86 #define DP_PROP_ORIENTATION "Orientation"
87 #define DP_PROP_REPEATIFEMPTY "RepeatIfEmpty"
88 #define DP_PROP_ROWGRAND "RowGrand"
89 #define DP_PROP_SHOWDETAILS "ShowDetails"
90 #define DP_PROP_SHOWEMPTY "ShowEmpty"
91 #define DP_PROP_SUBTOTALS "SubTotals"
92 #define DP_PROP_USEDHIERARCHY "UsedHierarchy"
93 #define DP_PROP_FILTER "Filter"
94 #define DP_PROP_POSITION "Position"
96 // -----------------------------------------------------------------------
98 void lcl_SetBoolProperty( const uno::Reference
<beans::XPropertySet
>& xProp
,
99 const rtl::OUString
& rName
, sal_Bool bValue
)
101 //! move to ScUnoHelpFunctions?
103 xProp
->setPropertyValue( rName
, uno::Any( &bValue
, getBooleanCppuType() ) );
106 // -----------------------------------------------------------------------
108 ScDPSaveMember::ScDPSaveMember(const String
& rName
) :
111 nVisibleMode( SC_DPSAVEMODE_DONTKNOW
),
112 nShowDetailsMode( SC_DPSAVEMODE_DONTKNOW
)
116 ScDPSaveMember::ScDPSaveMember(const ScDPSaveMember
& r
) :
119 nVisibleMode( r
.nVisibleMode
),
120 nShowDetailsMode( r
.nShowDetailsMode
)
122 if (r
.mpLayoutName
.get())
123 mpLayoutName
.reset(new OUString(*r
.mpLayoutName
));
126 ScDPSaveMember::~ScDPSaveMember()
130 BOOL
ScDPSaveMember::operator== ( const ScDPSaveMember
& r
) const
132 if ( aName
!= r
.aName
||
133 nVisibleMode
!= r
.nVisibleMode
||
134 nShowDetailsMode
!= r
.nShowDetailsMode
)
140 BOOL
ScDPSaveMember::HasIsVisible() const
142 return nVisibleMode
!= SC_DPSAVEMODE_DONTKNOW
;
145 void ScDPSaveMember::SetIsVisible(BOOL bSet
)
150 BOOL
ScDPSaveMember::HasShowDetails() const
152 return nShowDetailsMode
!= SC_DPSAVEMODE_DONTKNOW
;
155 void ScDPSaveMember::SetShowDetails(BOOL bSet
)
157 nShowDetailsMode
= bSet
;
160 void ScDPSaveMember::SetName( const String
& rNew
)
162 // Used only if the source member was renamed (groups).
163 // For UI renaming of members, a layout name must be used.
168 void ScDPSaveMember::SetLayoutName( const OUString
& rName
)
170 mpLayoutName
.reset(new OUString(rName
));
173 const OUString
* ScDPSaveMember::GetLayoutName() const
175 return mpLayoutName
.get();
178 void ScDPSaveMember::RemoveLayoutName()
180 mpLayoutName
.reset(NULL
);
183 void ScDPSaveMember::WriteToSource( const uno::Reference
<uno::XInterface
>& xMember
, sal_Int32 nPosition
)
185 uno::Reference
<beans::XPropertySet
> xMembProp( xMember
, uno::UNO_QUERY
);
186 DBG_ASSERT( xMembProp
.is(), "no properties at member" );
187 if ( xMembProp
.is() )
189 // exceptions are caught at ScDPSaveData::WriteToSource
191 if ( nVisibleMode
!= SC_DPSAVEMODE_DONTKNOW
)
192 lcl_SetBoolProperty( xMembProp
,
193 rtl::OUString::createFromAscii(DP_PROP_ISVISIBLE
), (BOOL
)nVisibleMode
);
195 if ( nShowDetailsMode
!= SC_DPSAVEMODE_DONTKNOW
)
196 lcl_SetBoolProperty( xMembProp
,
197 rtl::OUString::createFromAscii(DP_PROP_SHOWDETAILS
), (BOOL
)nShowDetailsMode
);
199 if (mpLayoutName
.get())
200 ScUnoHelpFunctions::SetOptionalPropertyValue(xMembProp
, SC_UNO_LAYOUTNAME
, *mpLayoutName
);
202 if ( nPosition
>= 0 )
203 ScUnoHelpFunctions::SetOptionalPropertyValue(xMembProp
, DP_PROP_POSITION
, nPosition
);
207 // -----------------------------------------------------------------------
209 ScDPSaveDimension::ScDPSaveDimension(const String
& rName
, BOOL bDataLayout
) :
211 pSelectedPage( NULL
),
213 mpSubtotalName(NULL
),
214 bIsDataLayout( bDataLayout
),
216 nOrientation( sheet::DataPilotFieldOrientation_HIDDEN
),
217 nFunction( sheet::GeneralFunction_AUTO
),
218 nUsedHierarchy( -1 ),
219 nShowEmptyMode( SC_DPSAVEMODE_DONTKNOW
),
220 bSubTotalDefault( TRUE
),
222 pSubTotalFuncs( NULL
),
223 pReferenceValue( NULL
),
225 pAutoShowInfo( NULL
),
230 ScDPSaveDimension::ScDPSaveDimension(const ScDPSaveDimension
& r
) :
233 mpSubtotalName(NULL
),
234 bIsDataLayout( r
.bIsDataLayout
),
235 bDupFlag( r
.bDupFlag
),
236 nOrientation( r
.nOrientation
),
237 nFunction( r
.nFunction
),
238 nUsedHierarchy( r
.nUsedHierarchy
),
239 nShowEmptyMode( r
.nShowEmptyMode
),
240 bSubTotalDefault( r
.bSubTotalDefault
),
241 nSubTotalCount( r
.nSubTotalCount
),
242 pSubTotalFuncs( NULL
)
244 if ( nSubTotalCount
&& r
.pSubTotalFuncs
)
246 pSubTotalFuncs
= new USHORT
[nSubTotalCount
];
247 for (long nSub
=0; nSub
<nSubTotalCount
; nSub
++)
248 pSubTotalFuncs
[nSub
] = r
.pSubTotalFuncs
[nSub
];
251 for (MemberList::const_iterator i
=r
.maMemberList
.begin(); i
!= r
.maMemberList
.end() ; i
++)
253 const String
& rName
= (*i
)->GetName();
254 ScDPSaveMember
* pNew
= new ScDPSaveMember( **i
);
255 maMemberHash
[rName
] = pNew
;
256 maMemberList
.push_back( pNew
);
258 if (r
.pReferenceValue
)
259 pReferenceValue
= new sheet::DataPilotFieldReference( *(r
.pReferenceValue
) );
261 pReferenceValue
= NULL
;
263 pSortInfo
= new sheet::DataPilotFieldSortInfo( *(r
.pSortInfo
) );
267 pAutoShowInfo
= new sheet::DataPilotFieldAutoShowInfo( *(r
.pAutoShowInfo
) );
269 pAutoShowInfo
= NULL
;
271 pLayoutInfo
= new sheet::DataPilotFieldLayoutInfo( *(r
.pLayoutInfo
) );
275 pSelectedPage
= new String( *(r
.pSelectedPage
) );
277 pSelectedPage
= NULL
;
278 if (r
.mpLayoutName
.get())
279 mpLayoutName
.reset(new OUString(*r
.mpLayoutName
));
280 if (r
.mpSubtotalName
.get())
281 mpSubtotalName
.reset(new OUString(*r
.mpSubtotalName
));
284 ScDPSaveDimension::~ScDPSaveDimension()
286 for (MemberHash::const_iterator i
=maMemberHash
.begin(); i
!= maMemberHash
.end() ; i
++)
288 delete pReferenceValue
;
290 delete pAutoShowInfo
;
292 delete pSelectedPage
;
293 delete [] pSubTotalFuncs
;
296 BOOL
ScDPSaveDimension::operator== ( const ScDPSaveDimension
& r
) const
298 if ( aName
!= r
.aName
||
299 bIsDataLayout
!= r
.bIsDataLayout
||
300 bDupFlag
!= r
.bDupFlag
||
301 nOrientation
!= r
.nOrientation
||
302 nFunction
!= r
.nFunction
||
303 nUsedHierarchy
!= r
.nUsedHierarchy
||
304 nShowEmptyMode
!= r
.nShowEmptyMode
||
305 bSubTotalDefault
!= r
.bSubTotalDefault
||
306 nSubTotalCount
!= r
.nSubTotalCount
)
309 if ( nSubTotalCount
&& ( !pSubTotalFuncs
|| !r
.pSubTotalFuncs
) ) // should not happen
313 for (i
=0; i
<nSubTotalCount
; i
++)
314 if ( pSubTotalFuncs
[i
] != r
.pSubTotalFuncs
[i
] )
317 if (maMemberHash
.size() != r
.maMemberHash
.size() )
320 MemberList::const_iterator a
=maMemberList
.begin();
321 MemberList::const_iterator b
=r
.maMemberList
.begin();
322 for (; a
!= maMemberList
.end() ; ++a
, ++b
)
329 void ScDPSaveDimension::AddMember(ScDPSaveMember
* pMember
)
331 const String
& rName
= pMember
->GetName();
332 MemberHash::iterator aExisting
= maMemberHash
.find( rName
);
333 if ( aExisting
== maMemberHash
.end() )
335 std::pair
< const String
, ScDPSaveMember
*> key( rName
, pMember
);
336 maMemberHash
.insert ( key
);
340 maMemberList
.remove( aExisting
->second
);
341 delete aExisting
->second
;
342 aExisting
->second
= pMember
;
344 maMemberList
.push_back( pMember
);
347 void ScDPSaveDimension::SetName( const String
& rNew
)
349 // Used only if the source dim was renamed (groups).
350 // For UI renaming of dimensions, the layout name must be used.
355 void ScDPSaveDimension::SetOrientation(USHORT nNew
)
360 void ScDPSaveDimension::SetSubTotals(long nCount
, const USHORT
* pFuncs
)
363 delete [] pSubTotalFuncs
;
364 nSubTotalCount
= nCount
;
365 if ( nCount
&& pFuncs
)
367 pSubTotalFuncs
= new USHORT
[nCount
];
368 for (long i
=0; i
<nCount
; i
++)
369 pSubTotalFuncs
[i
] = pFuncs
[i
];
372 pSubTotalFuncs
= NULL
;
374 bSubTotalDefault
= FALSE
;
377 void ScDPSaveDimension::SetShowEmpty(BOOL bSet
)
379 nShowEmptyMode
= bSet
;
382 void ScDPSaveDimension::SetFunction(USHORT nNew
)
387 void ScDPSaveDimension::SetUsedHierarchy(long nNew
)
389 nUsedHierarchy
= nNew
;
392 void ScDPSaveDimension::SetSubtotalName(const OUString
& rName
)
394 mpSubtotalName
.reset(new OUString(rName
));
397 const OUString
* ScDPSaveDimension::GetSubtotalName() const
399 return mpSubtotalName
.get();
402 bool ScDPSaveDimension::IsMemberNameInUse(const OUString
& rName
) const
404 MemberList::const_iterator itr
= maMemberList
.begin(), itrEnd
= maMemberList
.end();
405 for (; itr
!= itrEnd
; ++itr
)
407 const ScDPSaveMember
* pMem
= *itr
;
408 if (rName
.equalsIgnoreAsciiCase(pMem
->GetName()))
411 const OUString
* pLayoutName
= pMem
->GetLayoutName();
412 if (pLayoutName
&& rName
.equalsIgnoreAsciiCase(*pLayoutName
))
418 void ScDPSaveDimension::SetLayoutName(const OUString
& rName
)
420 mpLayoutName
.reset(new OUString(rName
));
423 const OUString
* ScDPSaveDimension::GetLayoutName() const
425 return mpLayoutName
.get();
428 void ScDPSaveDimension::RemoveLayoutName()
430 mpLayoutName
.reset(NULL
);
433 void ScDPSaveDimension::SetReferenceValue(const sheet::DataPilotFieldReference
* pNew
)
435 delete pReferenceValue
;
437 pReferenceValue
= new sheet::DataPilotFieldReference(*pNew
);
439 pReferenceValue
= NULL
;
442 void ScDPSaveDimension::SetSortInfo(const sheet::DataPilotFieldSortInfo
* pNew
)
446 pSortInfo
= new sheet::DataPilotFieldSortInfo(*pNew
);
451 void ScDPSaveDimension::SetAutoShowInfo(const sheet::DataPilotFieldAutoShowInfo
* pNew
)
453 delete pAutoShowInfo
;
455 pAutoShowInfo
= new sheet::DataPilotFieldAutoShowInfo(*pNew
);
457 pAutoShowInfo
= NULL
;
460 void ScDPSaveDimension::SetLayoutInfo(const sheet::DataPilotFieldLayoutInfo
* pNew
)
464 pLayoutInfo
= new sheet::DataPilotFieldLayoutInfo(*pNew
);
469 void ScDPSaveDimension::SetCurrentPage( const String
* pPage
)
471 delete pSelectedPage
;
473 pSelectedPage
= new String( *pPage
);
475 pSelectedPage
= NULL
;
478 BOOL
ScDPSaveDimension::HasCurrentPage() const
480 return ( pSelectedPage
!= NULL
);
483 const String
& ScDPSaveDimension::GetCurrentPage() const
486 return *pSelectedPage
;
490 ScDPSaveMember
* ScDPSaveDimension::GetExistingMemberByName(const String
& rName
)
492 MemberHash::const_iterator res
= maMemberHash
.find (rName
);
493 if (res
!= maMemberHash
.end())
499 ScDPSaveMember
* ScDPSaveDimension::GetMemberByName(const String
& rName
)
501 MemberHash::const_iterator res
= maMemberHash
.find (rName
);
502 if (res
!= maMemberHash
.end())
505 ScDPSaveMember
* pNew
= new ScDPSaveMember( rName
);
506 maMemberHash
[rName
] = pNew
;
507 maMemberList
.push_back( pNew
);
511 void ScDPSaveDimension::SetMemberPosition( const String
& rName
, sal_Int32 nNewPos
)
513 ScDPSaveMember
* pMember
= GetMemberByName( rName
); // make sure it exists and is in the hash
515 maMemberList
.remove( pMember
);
517 MemberList::iterator aIter
= maMemberList
.begin();
518 for (sal_Int32 i
=0; i
<nNewPos
&& aIter
!= maMemberList
.end(); i
++)
520 maMemberList
.insert( aIter
, pMember
);
523 void ScDPSaveDimension::WriteToSource( const uno::Reference
<uno::XInterface
>& xDim
)
525 uno::Reference
<beans::XPropertySet
> xDimProp( xDim
, uno::UNO_QUERY
);
526 DBG_ASSERT( xDimProp
.is(), "no properties at dimension" );
529 // exceptions are caught at ScDPSaveData::WriteToSource
532 sheet::DataPilotFieldOrientation eOrient
= (sheet::DataPilotFieldOrientation
)nOrientation
;
534 xDimProp
->setPropertyValue( rtl::OUString::createFromAscii(DP_PROP_ORIENTATION
), aAny
);
536 sheet::GeneralFunction eFunc
= (sheet::GeneralFunction
)nFunction
;
538 xDimProp
->setPropertyValue( rtl::OUString::createFromAscii(DP_PROP_FUNCTION
), aAny
);
540 if ( nUsedHierarchy
>= 0 )
542 aAny
<<= (INT32
)nUsedHierarchy
;
543 xDimProp
->setPropertyValue( rtl::OUString::createFromAscii(DP_PROP_USEDHIERARCHY
), aAny
);
546 if ( pReferenceValue
)
548 aAny
<<= *pReferenceValue
;
549 xDimProp
->setPropertyValue( rtl::OUString::createFromAscii(SC_UNO_REFVALUE
), aAny
);
552 uno::Sequence
<sheet::TableFilterField
> aFilter
;
553 // set the selected page field only if the dimension is used as page dimension
554 if ( pSelectedPage
&& nOrientation
== sheet::DataPilotFieldOrientation_PAGE
)
556 // single filter field: first field equal to selected string
557 sheet::TableFilterField
aField( sheet::FilterConnection_AND
, 0,
558 sheet::FilterOperator_EQUAL
, sal_False
, 0.0, *pSelectedPage
);
559 aFilter
= uno::Sequence
<sheet::TableFilterField
>( &aField
, 1 );
561 // else keep empty sequence
563 ScUnoHelpFunctions::SetOptionalPropertyValue(xDimProp
, DP_PROP_FILTER
, aFilter
);
564 if (mpLayoutName
.get())
565 ScUnoHelpFunctions::SetOptionalPropertyValue(xDimProp
, SC_UNO_LAYOUTNAME
, *mpLayoutName
);
567 const OUString
* pSubTotalName
= GetSubtotalName();
569 // Custom subtotal name, with '?' being replaced by the visible field name later.
570 ScUnoHelpFunctions::SetOptionalPropertyValue(xDimProp
, SC_UNO_FIELD_SUBTOTALNAME
, *pSubTotalName
);
573 // Level loop outside of maMemberList loop
574 // because SubTotals have to be set independently of known members
576 long nCount
= maMemberHash
.size();
579 uno::Reference
<container::XIndexAccess
> xHiers
;
580 uno::Reference
<sheet::XHierarchiesSupplier
> xHierSupp( xDim
, uno::UNO_QUERY
);
581 if ( xHierSupp
.is() )
583 uno::Reference
<container::XNameAccess
> xHiersName
= xHierSupp
->getHierarchies();
584 xHiers
= new ScNameToIndexAccess( xHiersName
);
585 nHierCount
= xHiers
->getCount();
588 sal_Bool bHasHiddenMember
= false;
590 for (long nHier
=0; nHier
<nHierCount
; nHier
++)
592 uno::Reference
<uno::XInterface
> xHierarchy
= ScUnoHelpFunctions::AnyToInterface( xHiers
->getByIndex(nHier
) );
595 uno::Reference
<container::XIndexAccess
> xLevels
;
596 uno::Reference
<sheet::XLevelsSupplier
> xLevSupp( xHierarchy
, uno::UNO_QUERY
);
599 uno::Reference
<container::XNameAccess
> xLevelsName
= xLevSupp
->getLevels();
600 xLevels
= new ScNameToIndexAccess( xLevelsName
);
601 nLevCount
= xLevels
->getCount();
604 for (long nLev
=0; nLev
<nLevCount
; nLev
++)
606 uno::Reference
<uno::XInterface
> xLevel
= ScUnoHelpFunctions::AnyToInterface( xLevels
->getByIndex(nLev
) );
607 uno::Reference
<beans::XPropertySet
> xLevProp( xLevel
, uno::UNO_QUERY
);
608 DBG_ASSERT( xLevProp
.is(), "no properties at level" );
612 if ( !bSubTotalDefault
)
614 if ( !pSubTotalFuncs
)
617 uno::Sequence
<sheet::GeneralFunction
> aSeq(nSubTotalCount
);
618 sheet::GeneralFunction
* pArray
= aSeq
.getArray();
619 for (long i
=0; i
<nSubTotalCount
; i
++)
620 pArray
[i
] = (sheet::GeneralFunction
)pSubTotalFuncs
[i
];
622 xLevProp
->setPropertyValue( rtl::OUString::createFromAscii(DP_PROP_SUBTOTALS
), aAny
);
624 if ( nShowEmptyMode
!= SC_DPSAVEMODE_DONTKNOW
)
625 lcl_SetBoolProperty( xLevProp
,
626 rtl::OUString::createFromAscii(DP_PROP_SHOWEMPTY
), (BOOL
)nShowEmptyMode
);
629 ScUnoHelpFunctions::SetOptionalPropertyValue(xLevProp
, SC_UNO_SORTING
, *pSortInfo
);
632 ScUnoHelpFunctions::SetOptionalPropertyValue(xLevProp
, SC_UNO_AUTOSHOW
, *pAutoShowInfo
);
635 ScUnoHelpFunctions::SetOptionalPropertyValue(xLevProp
, SC_UNO_LAYOUT
, *pLayoutInfo
);
637 // exceptions are caught at ScDPSaveData::WriteToSource
642 uno::Reference
<sheet::XMembersSupplier
> xMembSupp( xLevel
, uno::UNO_QUERY
);
643 if ( xMembSupp
.is() )
645 uno::Reference
<container::XNameAccess
> xMembers
= xMembSupp
->getMembers();
648 sal_Int32 nPosition
= -1; // set position only in manual mode
649 if ( !pSortInfo
|| pSortInfo
->Mode
== sheet::DataPilotFieldSortMode::MANUAL
)
652 for (MemberList::const_iterator i
=maMemberList
.begin(); i
!= maMemberList
.end() ; i
++)
654 ScDPSaveMember
* pMember
= *i
;
655 if (!pMember
->GetIsVisible())
656 bHasHiddenMember
= true;
657 rtl::OUString aMemberName
= pMember
->GetName();
658 if ( xMembers
->hasByName( aMemberName
) )
660 uno::Reference
<uno::XInterface
> xMemberInt
= ScUnoHelpFunctions::AnyToInterface(
661 xMembers
->getByName( aMemberName
) );
662 pMember
->WriteToSource( xMemberInt
, nPosition
);
664 if ( nPosition
>= 0 )
665 ++nPosition
; // increase if initialized
667 // missing member is no error
676 ScUnoHelpFunctions::SetOptionalPropertyValue(xDimProp
, SC_UNO_HAS_HIDDEN_MEMBER
, bHasHiddenMember
);
679 void ScDPSaveDimension::UpdateMemberVisibility(const hash_map
<OUString
, bool, OUStringHash
>& rData
)
681 typedef hash_map
<OUString
, bool, OUStringHash
> DataMap
;
682 MemberList::iterator itrMem
= maMemberList
.begin(), itrMemEnd
= maMemberList
.end();
683 for (; itrMem
!= itrMemEnd
; ++itrMem
)
685 ScDPSaveMember
* pMem
= *itrMem
;
686 const String
& rMemName
= pMem
->GetName();
687 DataMap::const_iterator itr
= rData
.find(rMemName
);
688 if (itr
!= rData
.end())
689 pMem
->SetIsVisible(itr
->second
);
693 bool ScDPSaveDimension::HasInvisibleMember() const
695 MemberList::const_iterator itrMem
= maMemberList
.begin(), itrMemEnd
= maMemberList
.end();
696 for (; itrMem
!= itrMemEnd
; ++itrMem
)
698 const ScDPSaveMember
* pMem
= *itrMem
;
699 if (!pMem
->GetIsVisible())
705 // -----------------------------------------------------------------------
707 ScDPSaveData::ScDPSaveData() :
708 pDimensionData( NULL
),
709 nColumnGrandMode( SC_DPSAVEMODE_DONTKNOW
),
710 nRowGrandMode( SC_DPSAVEMODE_DONTKNOW
),
711 nIgnoreEmptyMode( SC_DPSAVEMODE_DONTKNOW
),
712 nRepeatEmptyMode( SC_DPSAVEMODE_DONTKNOW
),
713 bFilterButton( TRUE
),
715 mbDimensionMembersBuilt(false),
716 mpGrandTotalName(NULL
)
720 ScDPSaveData::ScDPSaveData(const ScDPSaveData
& r
) :
721 nColumnGrandMode( r
.nColumnGrandMode
),
722 nRowGrandMode( r
.nRowGrandMode
),
723 nIgnoreEmptyMode( r
.nIgnoreEmptyMode
),
724 nRepeatEmptyMode( r
.nRepeatEmptyMode
),
725 bFilterButton( r
.bFilterButton
),
726 bDrillDown( r
.bDrillDown
),
727 mbDimensionMembersBuilt(r
.mbDimensionMembersBuilt
),
728 mpGrandTotalName(NULL
)
730 if ( r
.pDimensionData
)
731 pDimensionData
= new ScDPDimensionSaveData( *r
.pDimensionData
);
733 pDimensionData
= NULL
;
735 long nCount
= r
.aDimList
.Count();
736 for (long i
=0; i
<nCount
; i
++)
738 ScDPSaveDimension
* pNew
= new ScDPSaveDimension( *(ScDPSaveDimension
*)r
.aDimList
.GetObject(i
) );
739 aDimList
.Insert( pNew
, LIST_APPEND
);
742 if (r
.mpGrandTotalName
.get())
743 mpGrandTotalName
.reset(new OUString(*r
.mpGrandTotalName
));
746 ScDPSaveData
& ScDPSaveData::operator= ( const ScDPSaveData
& r
)
750 delete pDimensionData
;
751 if ( r
.pDimensionData
)
752 pDimensionData
= new ScDPDimensionSaveData( *r
.pDimensionData
);
754 pDimensionData
= NULL
;
756 nColumnGrandMode
= r
.nColumnGrandMode
;
757 nRowGrandMode
= r
.nRowGrandMode
;
758 nIgnoreEmptyMode
= r
.nIgnoreEmptyMode
;
759 nRepeatEmptyMode
= r
.nRepeatEmptyMode
;
760 bFilterButton
= r
.bFilterButton
;
761 bDrillDown
= r
.bDrillDown
;
762 mbDimensionMembersBuilt
= r
.mbDimensionMembersBuilt
;
764 // remove old dimensions
766 long nCount
= aDimList
.Count();
768 for (i
=0; i
<nCount
; i
++)
769 delete (ScDPSaveDimension
*)aDimList
.GetObject(i
);
772 // copy new dimensions
774 nCount
= r
.aDimList
.Count();
775 for (i
=0; i
<nCount
; i
++)
777 ScDPSaveDimension
* pNew
=
778 new ScDPSaveDimension( *(ScDPSaveDimension
*)r
.aDimList
.GetObject(i
) );
779 aDimList
.Insert( pNew
, LIST_APPEND
);
782 if (r
.mpGrandTotalName
.get())
783 mpGrandTotalName
.reset(new OUString(*r
.mpGrandTotalName
));
788 BOOL
ScDPSaveData::operator== ( const ScDPSaveData
& r
) const
790 if ( nColumnGrandMode
!= r
.nColumnGrandMode
||
791 nRowGrandMode
!= r
.nRowGrandMode
||
792 nIgnoreEmptyMode
!= r
.nIgnoreEmptyMode
||
793 nRepeatEmptyMode
!= r
.nRepeatEmptyMode
||
794 bFilterButton
!= r
.bFilterButton
||
795 bDrillDown
!= r
.bDrillDown
||
796 mbDimensionMembersBuilt
!= r
.mbDimensionMembersBuilt
)
799 if ( pDimensionData
|| r
.pDimensionData
)
800 if ( !pDimensionData
|| !r
.pDimensionData
|| !( *pDimensionData
== *r
.pDimensionData
) )
803 ULONG nCount
= aDimList
.Count();
804 if ( nCount
!= r
.aDimList
.Count() )
807 for (ULONG i
=0; i
<nCount
; i
++)
808 if ( !( *(ScDPSaveDimension
*)aDimList
.GetObject(i
) ==
809 *(ScDPSaveDimension
*)r
.aDimList
.GetObject(i
) ) )
812 if (mpGrandTotalName
.get())
814 if (!r
.mpGrandTotalName
.get())
816 if (!mpGrandTotalName
->equals(*r
.mpGrandTotalName
))
819 else if (r
.mpGrandTotalName
.get())
825 ScDPSaveData::~ScDPSaveData()
827 long nCount
= aDimList
.Count();
828 for (long i
=0; i
<nCount
; i
++)
829 delete (ScDPSaveDimension
*)aDimList
.GetObject(i
);
832 delete pDimensionData
;
835 void ScDPSaveData::SetGrandTotalName(const OUString
& rName
)
837 mpGrandTotalName
.reset(new OUString(rName
));
840 const OUString
* ScDPSaveData::GetGrandTotalName() const
842 return mpGrandTotalName
.get();
845 ScDPSaveDimension
* ScDPSaveData::GetDimensionByName(const String
& rName
)
847 long nCount
= aDimList
.Count();
848 for (long i
=0; i
<nCount
; i
++)
850 ScDPSaveDimension
* pDim
= (ScDPSaveDimension
*)aDimList
.GetObject(i
);
851 if ( pDim
->GetName() == rName
&& !pDim
->IsDataLayout() )
854 ScDPSaveDimension
* pNew
= new ScDPSaveDimension( rName
, FALSE
);
855 aDimList
.Insert( pNew
, LIST_APPEND
);
859 ScDPSaveDimension
* ScDPSaveData::GetExistingDimensionByName(const String
& rName
) const
861 long nCount
= aDimList
.Count();
862 for (long i
=0; i
<nCount
; i
++)
864 ScDPSaveDimension
* pDim
= (ScDPSaveDimension
*)aDimList
.GetObject(i
);
865 if ( pDim
->GetName() == rName
&& !pDim
->IsDataLayout() )
868 return NULL
; // don't create new
871 ScDPSaveDimension
* ScDPSaveData::GetNewDimensionByName(const String
& rName
)
873 long nCount
= aDimList
.Count();
874 for (long i
=0; i
<nCount
; i
++)
876 ScDPSaveDimension
* pDim
= (ScDPSaveDimension
*)aDimList
.GetObject(i
);
877 if ( pDim
->GetName() == rName
&& !pDim
->IsDataLayout() )
878 return DuplicateDimension(rName
);
880 ScDPSaveDimension
* pNew
= new ScDPSaveDimension( rName
, FALSE
);
881 aDimList
.Insert( pNew
, LIST_APPEND
);
885 ScDPSaveDimension
* ScDPSaveData::GetDataLayoutDimension()
887 ScDPSaveDimension
* pDim
= GetExistingDataLayoutDimension();
891 ScDPSaveDimension
* pNew
= new ScDPSaveDimension( String(), TRUE
);
892 aDimList
.Insert( pNew
, LIST_APPEND
);
896 ScDPSaveDimension
* ScDPSaveData::GetExistingDataLayoutDimension() const
898 long nCount
= aDimList
.Count();
899 for (long i
=0; i
<nCount
; i
++)
901 ScDPSaveDimension
* pDim
= (ScDPSaveDimension
*)aDimList
.GetObject(i
);
902 if ( pDim
->IsDataLayout() )
908 ScDPSaveDimension
* ScDPSaveData::DuplicateDimension(const String
& rName
)
911 //! check if dimension is there?
913 ScDPSaveDimension
* pOld
= GetDimensionByName( rName
);
914 ScDPSaveDimension
* pNew
= new ScDPSaveDimension( *pOld
);
915 pNew
->SetDupFlag( TRUE
);
916 aDimList
.Insert( pNew
, LIST_APPEND
);
920 void ScDPSaveData::RemoveDimensionByName(const String
& rName
)
922 long nCount
= aDimList
.Count();
923 for (long i
=0; i
<nCount
; i
++)
925 ScDPSaveDimension
* pDim
= (ScDPSaveDimension
*)aDimList
.GetObject(i
);
926 if ( pDim
->GetName() == rName
&& !pDim
->IsDataLayout() )
935 ScDPSaveDimension
& ScDPSaveData::DuplicateDimension( const ScDPSaveDimension
& rDim
)
937 ScDPSaveDimension
* pNew
= new ScDPSaveDimension( rDim
);
938 pNew
->SetDupFlag( TRUE
);
939 aDimList
.Insert( pNew
, LIST_APPEND
);
943 ScDPSaveDimension
* ScDPSaveData::GetInnermostDimension(USHORT nOrientation
)
945 // return the innermost dimension for the given orientation,
946 // excluding data layout dimension
948 ScDPSaveDimension
* pInner
= NULL
;
949 long nCount
= aDimList
.Count();
950 for (long i
=0; i
<nCount
; i
++)
952 ScDPSaveDimension
* pDim
= static_cast<ScDPSaveDimension
*>(aDimList
.GetObject(i
));
953 if ( pDim
->GetOrientation() == nOrientation
&& !pDim
->IsDataLayout() )
956 return pInner
; // the last matching one
959 ScDPSaveDimension
* ScDPSaveData::GetFirstDimension(sheet::DataPilotFieldOrientation eOrientation
)
961 long nCount
= aDimList
.Count();
962 for (long i
= 0; i
< nCount
; ++i
)
964 ScDPSaveDimension
* pDim
= static_cast<ScDPSaveDimension
*>(aDimList
.GetObject(i
));
965 if (pDim
->GetOrientation() == eOrientation
&& !pDim
->IsDataLayout())
971 long ScDPSaveData::GetDataDimensionCount() const
975 long nCount
= aDimList
.Count();
976 for (long i
=0; i
<nCount
; i
++)
978 const ScDPSaveDimension
* pDim
= static_cast<const ScDPSaveDimension
*>(aDimList
.GetObject(i
));
979 if ( pDim
->GetOrientation() == sheet::DataPilotFieldOrientation_DATA
)
986 void ScDPSaveData::SetPosition( ScDPSaveDimension
* pDim
, long nNew
)
988 // position (nNew) is counted within dimensions of the same orientation
990 USHORT nOrient
= pDim
->GetOrientation();
992 aDimList
.Remove( pDim
);
993 ULONG nCount
= aDimList
.Count(); // after remove
996 while ( nNew
> 0 && nInsPos
< nCount
)
998 if ( ((ScDPSaveDimension
*)aDimList
.GetObject(nInsPos
))->GetOrientation() == nOrient
)
1003 aDimList
.Insert( pDim
, nInsPos
);
1006 void ScDPSaveData::SetColumnGrand(BOOL bSet
)
1008 nColumnGrandMode
= bSet
;
1011 void ScDPSaveData::SetRowGrand(BOOL bSet
)
1013 nRowGrandMode
= bSet
;
1016 void ScDPSaveData::SetIgnoreEmptyRows(BOOL bSet
)
1018 nIgnoreEmptyMode
= bSet
;
1021 void ScDPSaveData::SetRepeatIfEmpty(BOOL bSet
)
1023 nRepeatEmptyMode
= bSet
;
1026 void ScDPSaveData::SetFilterButton(BOOL bSet
)
1028 bFilterButton
= bSet
;
1031 void ScDPSaveData::SetDrillDown(BOOL bSet
)
1036 void lcl_ResetOrient( const uno::Reference
<sheet::XDimensionsSupplier
>& xSource
)
1038 sheet::DataPilotFieldOrientation eOrient
= sheet::DataPilotFieldOrientation_HIDDEN
;
1040 uno::Reference
<container::XNameAccess
> xDimsName
= xSource
->getDimensions();
1041 uno::Reference
<container::XIndexAccess
> xIntDims
= new ScNameToIndexAccess( xDimsName
);
1042 long nIntCount
= xIntDims
->getCount();
1043 for (long nIntDim
=0; nIntDim
<nIntCount
; nIntDim
++)
1045 uno::Reference
<uno::XInterface
> xIntDim
= ScUnoHelpFunctions::AnyToInterface( xIntDims
->getByIndex(nIntDim
) );
1046 uno::Reference
<beans::XPropertySet
> xDimProp( xIntDim
, uno::UNO_QUERY
);
1051 xDimProp
->setPropertyValue( rtl::OUString::createFromAscii(DP_PROP_ORIENTATION
), aAny
);
1056 void ScDPSaveData::WriteToSource( const uno::Reference
<sheet::XDimensionsSupplier
>& xSource
)
1061 // source options must be first!
1063 uno::Reference
<beans::XPropertySet
> xSourceProp( xSource
, uno::UNO_QUERY
);
1064 DBG_ASSERT( xSourceProp
.is(), "no properties at source" );
1065 if ( xSourceProp
.is() )
1067 // source options are not available for external sources
1068 //! use XPropertySetInfo to test for availability?
1072 if ( nIgnoreEmptyMode
!= SC_DPSAVEMODE_DONTKNOW
)
1073 lcl_SetBoolProperty( xSourceProp
,
1074 rtl::OUString::createFromAscii(DP_PROP_IGNOREEMPTY
), (BOOL
)nIgnoreEmptyMode
);
1075 if ( nRepeatEmptyMode
!= SC_DPSAVEMODE_DONTKNOW
)
1076 lcl_SetBoolProperty( xSourceProp
,
1077 rtl::OUString::createFromAscii(DP_PROP_REPEATIFEMPTY
), (BOOL
)nRepeatEmptyMode
);
1079 catch(uno::Exception
&)
1084 const OUString
* pGrandTotalName
= GetGrandTotalName();
1085 if (pGrandTotalName
)
1086 ScUnoHelpFunctions::SetOptionalPropertyValue(xSourceProp
, SC_UNO_GRANDTOTAL_NAME
, *pGrandTotalName
);
1089 // exceptions in the other calls are errors
1092 // reset all orientations
1093 //! "forgetSettings" or similar at source ?????
1094 //! reset all duplicated dimensions, or reuse them below !!!
1096 lcl_ResetOrient( xSource
);
1098 long nCount
= aDimList
.Count();
1099 for (long i
=0; i
<nCount
; i
++)
1101 ScDPSaveDimension
* pDim
= (ScDPSaveDimension
*)aDimList
.GetObject(i
);
1102 rtl::OUString aName
= pDim
->GetName();
1103 BOOL bData
= pDim
->IsDataLayout();
1105 //! getByName for ScDPSource, including DataLayoutDimension !!!!!!!!
1107 uno::Reference
<container::XNameAccess
> xDimsName
= xSource
->getDimensions();
1108 uno::Reference
<container::XIndexAccess
> xIntDims
= new ScNameToIndexAccess( xDimsName
);
1109 long nIntCount
= xIntDims
->getCount();
1110 BOOL bFound
= FALSE
;
1111 for (long nIntDim
=0; nIntDim
<nIntCount
&& !bFound
; nIntDim
++)
1113 uno::Reference
<uno::XInterface
> xIntDim
= ScUnoHelpFunctions::AnyToInterface( xIntDims
->getByIndex(nIntDim
) );
1116 uno::Reference
<beans::XPropertySet
> xDimProp( xIntDim
, uno::UNO_QUERY
);
1117 if ( xDimProp
.is() )
1119 bFound
= ScUnoHelpFunctions::GetBoolProperty( xDimProp
,
1120 rtl::OUString::createFromAscii(DP_PROP_ISDATALAYOUT
) );
1121 //! error checking -- is "IsDataLayoutDimension" property required??
1126 uno::Reference
<container::XNamed
> xDimName( xIntDim
, uno::UNO_QUERY
);
1127 if ( xDimName
.is() && xDimName
->getName() == aName
)
1133 if ( pDim
->GetDupFlag() )
1135 String aNewName
= pDim
->GetName();
1137 // different name for each duplication of a (real) dimension...
1138 for (long j
=0; j
<=i
; j
++) //! Test !!!!!!
1139 aNewName
+= '*'; //! modify name at creation of SaveDimension
1141 uno::Reference
<util::XCloneable
> xCloneable( xIntDim
, uno::UNO_QUERY
);
1142 DBG_ASSERT( xCloneable
.is(), "cannot clone dimension" );
1143 if (xCloneable
.is())
1145 uno::Reference
<util::XCloneable
> xNew
= xCloneable
->createClone();
1146 uno::Reference
<container::XNamed
> xNewName( xNew
, uno::UNO_QUERY
);
1149 xNewName
->setName( aNewName
);
1150 pDim
->WriteToSource( xNew
);
1155 pDim
->WriteToSource( xIntDim
);
1158 DBG_ASSERT(bFound
, "WriteToSource: Dimension not found");
1161 if ( xSourceProp
.is() )
1163 if ( nColumnGrandMode
!= SC_DPSAVEMODE_DONTKNOW
)
1164 lcl_SetBoolProperty( xSourceProp
,
1165 rtl::OUString::createFromAscii(DP_PROP_COLUMNGRAND
), (BOOL
)nColumnGrandMode
);
1166 if ( nRowGrandMode
!= SC_DPSAVEMODE_DONTKNOW
)
1167 lcl_SetBoolProperty( xSourceProp
,
1168 rtl::OUString::createFromAscii(DP_PROP_ROWGRAND
), (BOOL
)nRowGrandMode
);
1171 catch(uno::Exception
&)
1173 DBG_ERROR("exception in WriteToSource");
1177 BOOL
ScDPSaveData::IsEmpty() const
1179 long nCount
= aDimList
.Count();
1180 for (long i
=0; i
<nCount
; i
++)
1182 ScDPSaveDimension
* pDim
= (ScDPSaveDimension
*)aDimList
.GetObject(i
);
1183 if ( pDim
->GetOrientation() != sheet::DataPilotFieldOrientation_HIDDEN
&& !pDim
->IsDataLayout() )
1186 return TRUE
; // no entries that are not hidden
1189 ScDPDimensionSaveData
* ScDPSaveData::GetDimensionData()
1191 if (!pDimensionData
)
1192 pDimensionData
= new ScDPDimensionSaveData
;
1193 return pDimensionData
;
1196 void ScDPSaveData::SetDimensionData( const ScDPDimensionSaveData
* pNew
)
1198 delete pDimensionData
;
1200 pDimensionData
= new ScDPDimensionSaveData( *pNew
);
1202 pDimensionData
= NULL
;
1205 void ScDPSaveData::BuildAllDimensionMembers(ScDPTableData
* pData
)
1207 if (mbDimensionMembersBuilt
)
1210 // First, build a dimension name-to-index map.
1211 typedef hash_map
<OUString
, long, ::rtl::OUStringHash
> NameIndexMap
;
1213 long nColCount
= pData
->GetColumnCount();
1214 for (long i
= 0; i
< nColCount
; ++i
)
1215 aMap
.insert( NameIndexMap::value_type(pData
->getDimensionName(i
), i
));
1217 NameIndexMap::const_iterator itrEnd
= aMap
.end();
1219 sal_uInt32 n
= aDimList
.Count();
1220 for (sal_uInt32 i
= 0; i
< n
; ++i
)
1222 ScDPSaveDimension
* pDim
= static_cast<ScDPSaveDimension
*>(aDimList
.GetObject(i
));
1223 const String
& rDimName
= pDim
->GetName();
1224 if (!rDimName
.Len())
1225 // empty dimension name. It must be data layout.
1228 NameIndexMap::const_iterator itr
= aMap
.find(rDimName
);
1230 // dimension name not in the data. This should never happen!
1233 long nDimIndex
= itr
->second
;
1234 const TypedScStrCollection
& rMembers
= pData
->GetColumnEntries(nDimIndex
);
1235 sal_uInt16 nMemberCount
= rMembers
.GetCount();
1236 for (sal_uInt16 j
= 0; j
< nMemberCount
; ++j
)
1238 const String
& rMemName
= rMembers
[j
]->GetString();
1239 if (pDim
->GetExistingMemberByName(rMemName
))
1240 // this member instance already exists. nothing to do.
1243 auto_ptr
<ScDPSaveMember
> pNewMember(new ScDPSaveMember(rMemName
));
1244 pNewMember
->SetIsVisible(true);
1245 pDim
->AddMember(pNewMember
.release());
1249 mbDimensionMembersBuilt
= true;
1252 bool ScDPSaveData::HasInvisibleMember(const OUString
& rDimName
) const
1254 ScDPSaveDimension
* pDim
= GetExistingDimensionByName(rDimName
);
1258 return pDim
->HasInvisibleMember();