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: dpobject.cxx,v $
10 * $Revision: 1.23.30.5 $
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 ---------------------------------------------------------------
38 #include "dpobject.hxx"
39 #include "dptabsrc.hxx"
41 #include "dpdimsave.hxx"
42 #include "dpoutput.hxx"
43 #include "dpshttab.hxx"
44 #include "dpsdbtab.hxx"
45 #include "dpgroup.hxx"
46 #include "document.hxx"
47 #include "rechead.hxx"
48 #include "pivot.hxx" // PIVOT_DATA_FIELD
49 #include "dapiuno.hxx" // ScDataPilotConversion
50 #include "miscuno.hxx"
51 #include "scerrors.hxx"
52 #include "refupdat.hxx"
53 #include "scresid.hxx"
56 #include "scitems.hxx"
57 #include "unonames.hxx"
59 #include <com/sun/star/beans/XPropertySet.hpp>
60 #include <com/sun/star/sheet/GeneralFunction.hpp>
61 #include <com/sun/star/sheet/DataPilotFieldFilter.hpp>
62 #include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
63 #include <com/sun/star/sheet/DataPilotFieldReferenceType.hpp>
64 #include <com/sun/star/sheet/DataPilotTableHeaderData.hpp>
65 #include <com/sun/star/sheet/DataPilotTablePositionData.hpp>
66 #include <com/sun/star/sheet/DataPilotTablePositionType.hpp>
67 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
68 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
69 #include <com/sun/star/lang/XInitialization.hpp>
70 #include <com/sun/star/container/XContentEnumerationAccess.hpp>
71 #include <com/sun/star/sheet/XDrillDownDataSupplier.hpp>
73 #include <comphelper/processfactory.hxx>
74 #include <tools/debug.hxx>
75 #include <svtools/zforlist.hxx> // IsNumberFormat
79 using namespace com::sun::star
;
81 using ::boost::shared_ptr
;
82 using ::com::sun::star::uno::Sequence
;
83 using ::com::sun::star::uno::Reference
;
84 using ::com::sun::star::uno::UNO_QUERY
;
85 using ::com::sun::star::uno::Any
;
86 using ::com::sun::star::sheet::DataPilotTableHeaderData
;
87 using ::com::sun::star::sheet::DataPilotTablePositionData
;
88 using ::com::sun::star::beans::XPropertySet
;
89 using ::rtl::OUString
;
91 // -----------------------------------------------------------------------
93 #define MAX_LABELS 256 //!!! from fieldwnd.hxx, must be moved to global.hxx
95 // -----------------------------------------------------------------------
97 #define SCDPSOURCE_SERVICE "com.sun.star.sheet.DataPilotSource"
99 // -----------------------------------------------------------------------
101 // incompatible versions of data pilot files
102 #define SC_DP_VERSION_CURRENT 6
104 // type of source data
105 #define SC_DP_SOURCE_SHEET 0
106 #define SC_DP_SOURCE_DATABASE 1
107 #define SC_DP_SOURCE_SERVICE 2
109 // -----------------------------------------------------------------------
111 //! move to a header file
112 #define DP_PROP_COLUMNGRAND "ColumnGrand"
113 #define DP_PROP_FUNCTION "Function"
114 #define DP_PROP_IGNOREEMPTY "IgnoreEmptyRows"
115 #define DP_PROP_ISDATALAYOUT "IsDataLayoutDimension"
116 //#define DP_PROP_ISVISIBLE "IsVisible"
117 #define DP_PROP_ORIENTATION "Orientation"
118 #define DP_PROP_ORIGINAL "Original"
119 #define DP_PROP_POSITION "Position"
120 #define DP_PROP_REPEATIFEMPTY "RepeatIfEmpty"
121 #define DP_PROP_ROWGRAND "RowGrand"
122 #define DP_PROP_SHOWDETAILS "ShowDetails"
123 #define DP_PROP_SHOWEMPTY "ShowEmpty"
124 #define DP_PROP_SUBTOTALS "SubTotals"
125 #define DP_PROP_USEDHIERARCHY "UsedHierarchy"
127 // -----------------------------------------------------------------------
129 USHORT
lcl_GetDataGetOrientation( const uno::Reference
<sheet::XDimensionsSupplier
>& xSource
)
131 long nRet
= sheet::DataPilotFieldOrientation_HIDDEN
;
134 uno::Reference
<container::XNameAccess
> xDimsName
= xSource
->getDimensions();
135 uno::Reference
<container::XIndexAccess
> xIntDims
= new ScNameToIndexAccess( xDimsName
);
136 long nIntCount
= xIntDims
->getCount();
138 for (long nIntDim
=0; nIntDim
<nIntCount
&& !bFound
; nIntDim
++)
140 uno::Reference
<uno::XInterface
> xIntDim
=
141 ScUnoHelpFunctions::AnyToInterface( xIntDims
->getByIndex(nIntDim
) );
142 uno::Reference
<beans::XPropertySet
> xDimProp( xIntDim
, uno::UNO_QUERY
);
145 bFound
= ScUnoHelpFunctions::GetBoolProperty( xDimProp
,
146 rtl::OUString::createFromAscii(DP_PROP_ISDATALAYOUT
) );
147 //! error checking -- is "IsDataLayoutDimension" property required??
149 nRet
= ScUnoHelpFunctions::GetEnumProperty(
150 xDimProp
, rtl::OUString::createFromAscii(DP_PROP_ORIENTATION
),
151 sheet::DataPilotFieldOrientation_HIDDEN
);
155 return static_cast< USHORT
>( nRet
);
158 // -----------------------------------------------------------------------
160 ScDPObject::ScDPObject( ScDocument
* pD
) :
166 mpTableData(static_cast<ScDPTableData
*>(NULL
)),
168 bSettingsChanged( FALSE
),
170 nAutoFormatIndex( 65535 ),
174 bHeaderLayout( false )
178 ScDPObject::ScDPObject(const ScDPObject
& r
) :
182 aTableName( r
.aTableName
),
183 aTableTag( r
.aTableTag
),
184 aOutRange( r
.aOutRange
),
188 mpTableData(static_cast<ScDPTableData
*>(NULL
)),
190 bSettingsChanged( FALSE
),
192 nAutoFormatIndex( r
.nAutoFormatIndex
),
194 bInfoValid( r
.bInfoValid
),
195 nHeaderRows( r
.nHeaderRows
),
196 bHeaderLayout( r
.bHeaderLayout
)
199 pSaveData
= new ScDPSaveData(*r
.pSaveData
);
201 pSheetDesc
= new ScSheetSourceDesc(*r
.pSheetDesc
);
203 pImpDesc
= new ScImportSourceDesc(*r
.pImpDesc
);
205 pServDesc
= new ScDPServiceDesc(*r
.pServDesc
);
206 // xSource (and pOutput) is not copied
209 ScDPObject::~ScDPObject()
218 ScDataObject
* ScDPObject::Clone() const
220 return new ScDPObject(*this);
223 void ScDPObject::SetAlive(BOOL bSet
)
228 void ScDPObject::SetAllowMove(BOOL bSet
)
233 void ScDPObject::SetSaveData(const ScDPSaveData
& rData
)
235 if ( pSaveData
!= &rData
) // API implementation modifies the original SaveData object
238 pSaveData
= new ScDPSaveData( rData
);
241 InvalidateData(); // re-init source from SaveData
244 void ScDPObject::SetAutoFormatIndex(const USHORT nIndex
)
246 nAutoFormatIndex
= nIndex
;
249 void ScDPObject::SetHeaderLayout (bool bUseGrid
)
251 bHeaderLayout
= bUseGrid
;
254 void ScDPObject::SetOutRange(const ScRange
& rRange
)
259 pOutput
->SetPosition( rRange
.aStart
);
262 void ScDPObject::SetSheetDesc(const ScSheetSourceDesc
& rDesc
)
264 if ( pSheetDesc
&& rDesc
== *pSheetDesc
)
265 return; // nothing to do
268 DELETEZ( pServDesc
);
271 pSheetDesc
= new ScSheetSourceDesc(rDesc
);
273 // make valid QueryParam
275 pSheetDesc
->aQueryParam
.nCol1
= pSheetDesc
->aSourceRange
.aStart
.Col();
276 pSheetDesc
->aQueryParam
.nRow1
= pSheetDesc
->aSourceRange
.aStart
.Row();
277 pSheetDesc
->aQueryParam
.nCol2
= pSheetDesc
->aSourceRange
.aEnd
.Col();
278 pSheetDesc
->aQueryParam
.nRow2
= pSheetDesc
->aSourceRange
.aEnd
.Row();;
279 pSheetDesc
->aQueryParam
.bHasHeader
= TRUE
;
281 InvalidateSource(); // new source must be created
284 void ScDPObject::SetImportDesc(const ScImportSourceDesc
& rDesc
)
286 if ( pImpDesc
&& rDesc
== *pImpDesc
)
287 return; // nothing to do
289 DELETEZ( pSheetDesc
);
290 DELETEZ( pServDesc
);
293 pImpDesc
= new ScImportSourceDesc(rDesc
);
295 InvalidateSource(); // new source must be created
298 void ScDPObject::SetServiceData(const ScDPServiceDesc
& rDesc
)
300 if ( pServDesc
&& rDesc
== *pServDesc
)
301 return; // nothing to do
303 DELETEZ( pSheetDesc
);
307 pServDesc
= new ScDPServiceDesc(rDesc
);
309 InvalidateSource(); // new source must be created
312 void ScDPObject::WriteSourceDataTo( ScDPObject
& rDest
) const
315 rDest
.SetSheetDesc( *pSheetDesc
);
317 rDest
.SetImportDesc( *pImpDesc
);
318 else if ( pServDesc
)
319 rDest
.SetServiceData( *pServDesc
);
321 // name/tag are not source data, but needed along with source data
323 rDest
.aTableName
= aTableName
;
324 rDest
.aTableTag
= aTableTag
;
327 void ScDPObject::WriteTempDataTo( ScDPObject
& rDest
) const
329 rDest
.nHeaderRows
= nHeaderRows
;
330 rDest
.bInfoValid
= bInfoValid
;
333 BOOL
ScDPObject::IsSheetData() const
335 return ( pSheetDesc
!= NULL
);
338 void ScDPObject::SetName(const String
& rNew
)
343 void ScDPObject::SetTag(const String
& rNew
)
348 bool ScDPObject::IsDataDescriptionCell(const ScAddress
& rPos
)
353 long nDataDimCount
= pSaveData
->GetDataDimensionCount();
354 if (nDataDimCount
!= 1)
355 // There has to be exactly one data dimension for the description to
356 // appear at top-left corner.
360 ScRange aTabRange
= pOutput
->GetOutputRange(sheet::DataPilotOutputRangeType::TABLE
);
361 return (rPos
== aTabRange
.aStart
);
364 uno::Reference
<sheet::XDimensionsSupplier
> ScDPObject::GetSource()
370 void ScDPObject::CreateOutput()
375 BOOL bFilterButton
= IsSheetData() && pSaveData
&& pSaveData
->GetFilterButton();
376 pOutput
= new ScDPOutput( pDoc
, xSource
, aOutRange
.aStart
, bFilterButton
);
377 pOutput
->SetHeaderLayout ( bHeaderLayout
);
379 long nOldRows
= nHeaderRows
;
380 nHeaderRows
= pOutput
->GetHeaderRows();
383 if ( bAllowMove
&& nHeaderRows
!= nOldRows
)
385 long nDiff
= nOldRows
- nHeaderRows
;
388 if ( nHeaderRows
== 0 )
391 long nNewRow
= aOutRange
.aStart
.Row() + nDiff
;
395 ScAddress
aStart( aOutRange
.aStart
);
396 aStart
.SetRow(nNewRow
);
397 pOutput
->SetPosition( aStart
);
399 //! modify aOutRange?
401 bAllowMove
= FALSE
; // use only once
406 ScDPTableData
* ScDPObject::GetTableData()
413 mpTableData
.reset(new ScDatabaseDPData(pDoc
, *pImpDesc
));
420 DBG_ERROR("no source descriptor");
421 pSheetDesc
= new ScSheetSourceDesc
; // dummy defaults
423 mpTableData
.reset(new ScSheetDPData(pDoc
, *pSheetDesc
));
426 // grouping (for cell or database data)
427 if ( pSaveData
&& pSaveData
->GetExistingDimensionData() )
429 shared_ptr
<ScDPGroupTableData
> pGroupData(new ScDPGroupTableData(mpTableData
, pDoc
));
430 pSaveData
->GetExistingDimensionData()->WriteToData(*pGroupData
);
431 mpTableData
= pGroupData
;
435 return mpTableData
.get();
438 void ScDPObject::CreateObjects()
440 // if groups are involved, create a new source with the ScDPGroupTableData
441 if ( bSettingsChanged
&& pSaveData
&& pSaveData
->GetExistingDimensionData() )
446 //! cache DPSource and/or Output?
448 DBG_ASSERT( bAlive
, "CreateObjects on non-inserted DPObject" );
450 DELETEZ( pOutput
); // not valid when xSource is changed
454 xSource
= CreateSource( *pServDesc
);
457 if ( !xSource
.is() ) // database or sheet data, or error in CreateSource
459 DBG_ASSERT( !pServDesc
, "DPSource could not be created" );
460 ScDPTableData
* pData
= GetTableData();
461 ScDPSource
* pSource
= new ScDPSource( pData
);
466 pSaveData
->WriteToSource( xSource
);
468 else if (bSettingsChanged
)
470 DELETEZ( pOutput
); // not valid when xSource is changed
472 uno::Reference
<util::XRefreshable
> xRef( xSource
, uno::UNO_QUERY
);
479 catch(uno::Exception
&)
481 DBG_ERROR("exception in refresh");
486 pSaveData
->WriteToSource( xSource
);
488 bSettingsChanged
= FALSE
;
491 void ScDPObject::InvalidateData()
493 bSettingsChanged
= TRUE
;
497 void ScDPObject::InvalidateSource()
504 ScRange
ScDPObject::GetNewOutputRange( BOOL
& rOverflow
)
506 CreateOutput(); // create xSource and pOutput if not already done
508 rOverflow
= pOutput
->HasError(); // range overflow or exception from source
510 return ScRange( aOutRange
.aStart
);
513 // don't store the result in aOutRange, because nothing has been output yet
514 return pOutput
->GetOutputRange();
518 void ScDPObject::Output()
520 // clear old output area
521 pDoc
->DeleteAreaTab( aOutRange
.aStart
.Col(), aOutRange
.aStart
.Row(),
522 aOutRange
.aEnd
.Col(), aOutRange
.aEnd
.Row(),
523 aOutRange
.aStart
.Tab(), IDF_ALL
);
524 pDoc
->RemoveFlagsTab( aOutRange
.aStart
.Col(), aOutRange
.aStart
.Row(),
525 aOutRange
.aEnd
.Col(), aOutRange
.aEnd
.Row(),
526 aOutRange
.aStart
.Tab(), SC_MF_AUTO
);
528 CreateOutput(); // create xSource and pOutput if not already done
532 // aOutRange is always the range that was last output to the document
533 aOutRange
= pOutput
->GetOutputRange();
534 const ScAddress
& s
= aOutRange
.aStart
;
535 const ScAddress
& e
= aOutRange
.aEnd
;
536 pDoc
->ApplyFlagsTab(s
.Col(), s
.Row(), e
.Col(), e
.Row(), s
.Tab(), SC_MF_DP_TABLE
);
539 const ScRange
ScDPObject::GetOutputRangeByType( sal_Int32 nType
)
543 if (pOutput
->HasError())
544 return ScRange(aOutRange
.aStart
);
546 return pOutput
->GetOutputRange(nType
);
549 BOOL
lcl_HasButton( ScDocument
* pDoc
, SCCOL nCol
, SCROW nRow
, SCTAB nTab
)
551 return ((const ScMergeFlagAttr
*)pDoc
->GetAttr( nCol
, nRow
, nTab
, ATTR_MERGE_FLAG
))->HasButton();
554 void ScDPObject::RefreshAfterLoad()
556 // apply drop-down attribute, initialize nHeaderRows, without accessing the source
557 // (button attribute must be present)
559 // simple test: block of button cells at the top, followed by an empty cell
561 SCCOL nFirstCol
= aOutRange
.aStart
.Col();
562 SCROW nFirstRow
= aOutRange
.aStart
.Row();
563 SCTAB nTab
= aOutRange
.aStart
.Tab();
566 SCROW nOutRows
= aOutRange
.aEnd
.Row() + 1 - aOutRange
.aStart
.Row();
567 while ( nInitial
+ 1 < nOutRows
&& lcl_HasButton( pDoc
, nFirstCol
, nFirstRow
+ nInitial
, nTab
) )
570 if ( nInitial
+ 1 < nOutRows
&&
571 pDoc
->IsBlockEmpty( nTab
, nFirstCol
, nFirstRow
+ nInitial
, nFirstCol
, nFirstRow
+ nInitial
) &&
572 aOutRange
.aEnd
.Col() > nFirstCol
)
574 BOOL bFilterButton
= IsSheetData(); // when available, filter button setting must be checked here
576 SCROW nSkip
= bFilterButton
? 1 : 0;
577 for (SCROW nPos
=nSkip
; nPos
<nInitial
; nPos
++)
578 pDoc
->ApplyAttr( nFirstCol
+ 1, nFirstRow
+ nPos
, nTab
, ScMergeFlagAttr(SC_MF_AUTO
) );
580 nHeaderRows
= nInitial
;
583 nHeaderRows
= 0; // nothing found, no drop-down lists
588 void ScDPObject::BuildAllDimensionMembers()
593 pSaveData
->BuildAllDimensionMembers(GetTableData());
596 void ScDPObject::UpdateReference( UpdateRefMode eUpdateRefMode
,
597 const ScRange
& rRange
, SCsCOL nDx
, SCsROW nDy
, SCsTAB nDz
)
601 SCCOL nCol1
= aOutRange
.aStart
.Col();
602 SCROW nRow1
= aOutRange
.aStart
.Row();
603 SCTAB nTab1
= aOutRange
.aStart
.Tab();
604 SCCOL nCol2
= aOutRange
.aEnd
.Col();
605 SCROW nRow2
= aOutRange
.aEnd
.Row();
606 SCTAB nTab2
= aOutRange
.aEnd
.Tab();
608 ScRefUpdateRes eRes
=
609 ScRefUpdate::Update( pDoc
, eUpdateRefMode
,
610 rRange
.aStart
.Col(), rRange
.aStart
.Row(), rRange
.aStart
.Tab(),
611 rRange
.aEnd
.Col(), rRange
.aEnd
.Row(), rRange
.aEnd
.Tab(), nDx
, nDy
, nDz
,
612 nCol1
, nRow1
, nTab1
, nCol2
, nRow2
, nTab2
);
613 if ( eRes
!= UR_NOTHING
)
614 SetOutRange( ScRange( nCol1
, nRow1
, nTab1
, nCol2
, nRow2
, nTab2
) );
620 nCol1
= pSheetDesc
->aSourceRange
.aStart
.Col();
621 nRow1
= pSheetDesc
->aSourceRange
.aStart
.Row();
622 nTab1
= pSheetDesc
->aSourceRange
.aStart
.Tab();
623 nCol2
= pSheetDesc
->aSourceRange
.aEnd
.Col();
624 nRow2
= pSheetDesc
->aSourceRange
.aEnd
.Row();
625 nTab2
= pSheetDesc
->aSourceRange
.aEnd
.Tab();
627 eRes
= ScRefUpdate::Update( pDoc
, eUpdateRefMode
,
628 rRange
.aStart
.Col(), rRange
.aStart
.Row(), rRange
.aStart
.Tab(),
629 rRange
.aEnd
.Col(), rRange
.aEnd
.Row(), rRange
.aEnd
.Tab(), nDx
, nDy
, nDz
,
630 nCol1
, nRow1
, nTab1
, nCol2
, nRow2
, nTab2
);
631 if ( eRes
!= UR_NOTHING
)
633 ScSheetSourceDesc aNewDesc
;
634 aNewDesc
.aSourceRange
= ScRange( nCol1
, nRow1
, nTab1
, nCol2
, nRow2
, nTab2
);
636 SCsCOL nDiffX
= nCol1
- (SCsCOL
) pSheetDesc
->aSourceRange
.aStart
.Col();
637 SCsROW nDiffY
= nRow1
- (SCsROW
) pSheetDesc
->aSourceRange
.aStart
.Row();
639 aNewDesc
.aQueryParam
= pSheetDesc
->aQueryParam
;
640 aNewDesc
.aQueryParam
.nCol1
= sal::static_int_cast
<SCCOL
>( aNewDesc
.aQueryParam
.nCol1
+ nDiffX
);
641 aNewDesc
.aQueryParam
.nCol2
= sal::static_int_cast
<SCCOL
>( aNewDesc
.aQueryParam
.nCol2
+ nDiffX
);
642 aNewDesc
.aQueryParam
.nRow1
+= nDiffY
; //! used?
643 aNewDesc
.aQueryParam
.nRow2
+= nDiffY
; //! used?
644 SCSIZE nEC
= aNewDesc
.aQueryParam
.GetEntryCount();
645 for (SCSIZE i
=0; i
<nEC
; i
++)
646 if (aNewDesc
.aQueryParam
.GetEntry(i
).bDoQuery
)
647 aNewDesc
.aQueryParam
.GetEntry(i
).nField
+= nDiffX
;
649 SetSheetDesc( aNewDesc
); // allocates new pSheetDesc
654 BOOL
ScDPObject::RefsEqual( const ScDPObject
& r
) const
656 if ( aOutRange
!= r
.aOutRange
)
659 if ( pSheetDesc
&& r
.pSheetDesc
)
661 if ( pSheetDesc
->aSourceRange
!= r
.pSheetDesc
->aSourceRange
)
664 else if ( pSheetDesc
|| r
.pSheetDesc
)
666 DBG_ERROR("RefsEqual: SheetDesc set at only one object");
673 void ScDPObject::WriteRefsTo( ScDPObject
& r
) const
675 r
.SetOutRange( aOutRange
);
677 r
.SetSheetDesc( *pSheetDesc
);
680 void ScDPObject::GetPositionData(const ScAddress
& rPos
, DataPilotTablePositionData
& rPosData
)
683 pOutput
->GetPositionData(rPos
, rPosData
);
686 bool ScDPObject::GetDataFieldPositionData(
687 const ScAddress
& rPos
, Sequence
<sheet::DataPilotFieldFilter
>& rFilters
)
691 vector
<sheet::DataPilotFieldFilter
> aFilters
;
692 if (!pOutput
->GetDataResultPositionData(aFilters
, rPos
))
695 sal_Int32 n
= static_cast<sal_Int32
>(aFilters
.size());
697 for (sal_Int32 i
= 0; i
< n
; ++i
)
698 rFilters
[i
] = aFilters
[i
];
703 void ScDPObject::GetDrillDownData(const ScAddress
& rPos
, Sequence
< Sequence
<Any
> >& rTableData
)
707 Reference
<sheet::XDrillDownDataSupplier
> xDrillDownData(xSource
, UNO_QUERY
);
708 if (!xDrillDownData
.is())
711 Sequence
<sheet::DataPilotFieldFilter
> filters
;
712 if (!GetDataFieldPositionData(rPos
, filters
))
715 rTableData
= xDrillDownData
->getDrillDownData(filters
);
718 bool ScDPObject::IsDimNameInUse(const OUString
& rName
) const
723 Reference
<container::XNameAccess
> xDims
= xSource
->getDimensions();
724 Sequence
<OUString
> aDimNames
= xDims
->getElementNames();
725 sal_Int32 n
= aDimNames
.getLength();
726 for (sal_Int32 i
= 0; i
< n
; ++i
)
728 const OUString
& rDimName
= aDimNames
[i
];
729 if (rDimName
.equalsIgnoreAsciiCase(rName
))
732 Reference
<beans::XPropertySet
> xPropSet(xDims
->getByName(rDimName
), UNO_QUERY
);
736 Any any
= xPropSet
->getPropertyValue(OUString::createFromAscii(SC_UNO_LAYOUTNAME
));
737 OUString aLayoutName
;
738 if (any
>>= aLayoutName
)
740 if (aLayoutName
.equalsIgnoreAsciiCase(rName
))
747 String
ScDPObject::GetDimName( long nDim
, BOOL
& rIsDataLayout
)
749 rIsDataLayout
= FALSE
;
754 uno::Reference
<container::XNameAccess
> xDimsName
= xSource
->getDimensions();
755 uno::Reference
<container::XIndexAccess
> xDims
= new ScNameToIndexAccess( xDimsName
);
756 long nDimCount
= xDims
->getCount();
757 if ( nDim
< nDimCount
)
759 uno::Reference
<uno::XInterface
> xIntDim
=
760 ScUnoHelpFunctions::AnyToInterface( xDims
->getByIndex(nDim
) );
761 uno::Reference
<container::XNamed
> xDimName( xIntDim
, uno::UNO_QUERY
);
762 uno::Reference
<beans::XPropertySet
> xDimProp( xIntDim
, uno::UNO_QUERY
);
763 if ( xDimName
.is() && xDimProp
.is() )
765 BOOL bData
= ScUnoHelpFunctions::GetBoolProperty( xDimProp
,
766 rtl::OUString::createFromAscii(DP_PROP_ISDATALAYOUT
) );
767 //! error checking -- is "IsDataLayoutDimension" property required??
772 aName
= xDimName
->getName();
774 catch(uno::Exception
&)
778 rIsDataLayout
= TRUE
;
780 aRet
= String( aName
);
788 BOOL
ScDPObject::IsDuplicated( long nDim
)
790 BOOL bDuplicated
= FALSE
;
793 uno::Reference
<container::XNameAccess
> xDimsName
= xSource
->getDimensions();
794 uno::Reference
<container::XIndexAccess
> xDims
= new ScNameToIndexAccess( xDimsName
);
795 long nDimCount
= xDims
->getCount();
796 if ( nDim
< nDimCount
)
798 uno::Reference
<uno::XInterface
> xIntDim
=
799 ScUnoHelpFunctions::AnyToInterface( xDims
->getByIndex(nDim
) );
800 uno::Reference
<beans::XPropertySet
> xDimProp( xIntDim
, uno::UNO_QUERY
);
805 uno::Any aOrigAny
= xDimProp
->getPropertyValue(
806 rtl::OUString::createFromAscii(DP_PROP_ORIGINAL
) );
807 uno::Reference
<uno::XInterface
> xIntOrig
;
808 if ( (aOrigAny
>>= xIntOrig
) && xIntOrig
.is() )
811 catch(uno::Exception
&)
820 long ScDPObject::GetDimCount()
827 uno::Reference
<container::XNameAccess
> xDimsName
= xSource
->getDimensions();
828 if ( xDimsName
.is() )
829 nRet
= xDimsName
->getElementNames().getLength();
831 catch(uno::Exception
&)
838 void ScDPObject::FillPageList( TypedScStrCollection
& rStrings
, long nField
)
840 //! merge members access with ToggleDetails?
842 //! convert field index to dimension index?
844 DBG_ASSERT( xSource
.is(), "no source" );
845 if ( !xSource
.is() ) return;
847 uno::Reference
<container::XNamed
> xDim
;
848 uno::Reference
<container::XNameAccess
> xDimsName
= xSource
->getDimensions();
849 uno::Reference
<container::XIndexAccess
> xIntDims
= new ScNameToIndexAccess( xDimsName
);
850 long nIntCount
= xIntDims
->getCount();
851 if ( nField
< nIntCount
)
853 uno::Reference
<uno::XInterface
> xIntDim
= ScUnoHelpFunctions::AnyToInterface(
854 xIntDims
->getByIndex(nField
) );
855 xDim
= uno::Reference
<container::XNamed
>( xIntDim
, uno::UNO_QUERY
);
857 DBG_ASSERT( xDim
.is(), "dimension not found" );
858 if ( !xDim
.is() ) return;
860 uno::Reference
<beans::XPropertySet
> xDimProp( xDim
, uno::UNO_QUERY
);
861 long nHierarchy
= ScUnoHelpFunctions::GetLongProperty( xDimProp
,
862 rtl::OUString::createFromAscii(DP_PROP_USEDHIERARCHY
) );
866 uno::Reference
<container::XIndexAccess
> xHiers
;
867 uno::Reference
<sheet::XHierarchiesSupplier
> xHierSupp( xDim
, uno::UNO_QUERY
);
868 if ( xHierSupp
.is() )
870 uno::Reference
<container::XNameAccess
> xHiersName
= xHierSupp
->getHierarchies();
871 xHiers
= new ScNameToIndexAccess( xHiersName
);
872 nHierCount
= xHiers
->getCount();
874 uno::Reference
<uno::XInterface
> xHier
;
875 if ( nHierarchy
< nHierCount
)
876 xHier
= ScUnoHelpFunctions::AnyToInterface( xHiers
->getByIndex(nHierarchy
) );
877 DBG_ASSERT( xHier
.is(), "hierarchy not found" );
878 if ( !xHier
.is() ) return;
881 uno::Reference
<container::XIndexAccess
> xLevels
;
882 uno::Reference
<sheet::XLevelsSupplier
> xLevSupp( xHier
, uno::UNO_QUERY
);
885 uno::Reference
<container::XNameAccess
> xLevsName
= xLevSupp
->getLevels();
886 xLevels
= new ScNameToIndexAccess( xLevsName
);
887 nLevCount
= xLevels
->getCount();
889 uno::Reference
<uno::XInterface
> xLevel
;
890 if ( nLevel
< nLevCount
)
891 xLevel
= ScUnoHelpFunctions::AnyToInterface( xLevels
->getByIndex(nLevel
) );
892 DBG_ASSERT( xLevel
.is(), "level not found" );
893 if ( !xLevel
.is() ) return;
895 uno::Reference
<container::XNameAccess
> xMembers
;
896 uno::Reference
<sheet::XMembersSupplier
> xMbrSupp( xLevel
, uno::UNO_QUERY
);
898 xMembers
= xMbrSupp
->getMembers();
899 DBG_ASSERT( xMembers
.is(), "members not found" );
900 if ( !xMembers
.is() ) return;
902 uno::Sequence
<rtl::OUString
> aNames
= xMembers
->getElementNames();
903 long nNameCount
= aNames
.getLength();
904 const rtl::OUString
* pNameArr
= aNames
.getConstArray();
905 for (long nPos
= 0; nPos
< nNameCount
; ++nPos
)
907 // Make sure to insert only visible members.
908 Reference
<XPropertySet
> xPropSet(xMembers
->getByName(pNameArr
[nPos
]), UNO_QUERY
);
909 sal_Bool bVisible
= false;
912 Any any
= xPropSet
->getPropertyValue(OUString::createFromAscii(SC_UNO_ISVISIBL
));
918 // use the order from getElementNames
919 TypedStrData
* pData
= new TypedStrData( pNameArr
[nPos
] );
920 if ( !rStrings
.AtInsert( rStrings
.GetCount(), pData
) )
925 // add "-all-" entry to the top (unsorted)
926 TypedStrData
* pAllData
= new TypedStrData( String( ScResId( SCSTR_ALL
) ) ); //! separate string? (also output)
927 if ( !rStrings
.AtInsert( 0, pAllData
) )
931 void ScDPObject::GetHeaderPositionData(const ScAddress
& rPos
, DataPilotTableHeaderData
& rData
)
933 using namespace ::com::sun::star::sheet::DataPilotTablePositionType
;
935 CreateOutput(); // create xSource and pOutput if not already done
937 // Reset member values to invalid state.
938 rData
.Dimension
= rData
.Hierarchy
= rData
.Level
= -1;
941 DataPilotTablePositionData aPosData
;
942 pOutput
->GetPositionData(rPos
, aPosData
);
943 const sal_Int32 nPosType
= aPosData
.PositionType
;
944 if (nPosType
== COLUMN_HEADER
|| nPosType
== ROW_HEADER
)
945 aPosData
.PositionData
>>= rData
;
948 // Returns TRUE on success and stores the result in rTarget
949 BOOL
ScDPObject::GetPivotData( ScDPGetPivotDataField
& rTarget
,
950 const std::vector
< ScDPGetPivotDataField
>& rFilters
)
952 CreateOutput(); // create xSource and pOutput if not already done
954 return pOutput
->GetPivotData( rTarget
, rFilters
);
957 BOOL
ScDPObject::IsFilterButton( const ScAddress
& rPos
)
959 CreateOutput(); // create xSource and pOutput if not already done
961 return pOutput
->IsFilterButton( rPos
);
964 long ScDPObject::GetHeaderDim( const ScAddress
& rPos
, USHORT
& rOrient
)
966 CreateOutput(); // create xSource and pOutput if not already done
968 return pOutput
->GetHeaderDim( rPos
, rOrient
);
971 BOOL
ScDPObject::GetHeaderDrag( const ScAddress
& rPos
, BOOL bMouseLeft
, BOOL bMouseTop
, long nDragDim
,
972 Rectangle
& rPosRect
, USHORT
& rOrient
, long& rDimPos
)
974 CreateOutput(); // create xSource and pOutput if not already done
976 return pOutput
->GetHeaderDrag( rPos
, bMouseLeft
, bMouseTop
, nDragDim
, rPosRect
, rOrient
, rDimPos
);
979 void ScDPObject::GetMemberResultNames( ScStrCollection
& rNames
, long nDimension
)
981 CreateOutput(); // create xSource and pOutput if not already done
983 pOutput
->GetMemberResultNames( rNames
, nDimension
); // used only with table data -> level not needed
986 bool lcl_Dequote( const String
& rSource
, xub_StrLen nStartPos
, xub_StrLen
& rEndPos
, String
& rResult
)
988 // nStartPos has to point to opening quote
991 const sal_Unicode cQuote
= '\'';
993 if ( rSource
.GetChar(nStartPos
) == cQuote
)
995 rtl::OUStringBuffer aBuffer
;
996 xub_StrLen nPos
= nStartPos
+ 1;
997 const xub_StrLen nLen
= rSource
.Len();
999 while ( nPos
< nLen
)
1001 const sal_Unicode cNext
= rSource
.GetChar(nPos
);
1002 if ( cNext
== cQuote
)
1004 if ( nPos
+1 < nLen
&& rSource
.GetChar(nPos
+1) == cQuote
)
1006 // double quote is used for an embedded quote
1007 aBuffer
.append( cNext
); // append one quote
1008 ++nPos
; // skip the next one
1012 // end of quoted string
1013 rResult
= aBuffer
.makeStringAndClear();
1014 rEndPos
= nPos
+ 1; // behind closing quote
1019 aBuffer
.append( cNext
);
1023 // no closing quote before the end of the string -> error (bRet still false)
1029 struct ScGetPivotDataFunctionEntry
1031 const sal_Char
* pName
;
1032 sheet::GeneralFunction eFunc
;
1035 bool lcl_ParseFunction( const String
& rList
, xub_StrLen nStartPos
, xub_StrLen
& rEndPos
, sheet::GeneralFunction
& rFunc
)
1037 static const ScGetPivotDataFunctionEntry aFunctions
[] =
1040 { "Sum", sheet::GeneralFunction_SUM
},
1041 { "Count", sheet::GeneralFunction_COUNT
},
1042 { "Average", sheet::GeneralFunction_AVERAGE
},
1043 { "Max", sheet::GeneralFunction_MAX
},
1044 { "Min", sheet::GeneralFunction_MIN
},
1045 { "Product", sheet::GeneralFunction_PRODUCT
},
1046 { "CountNums", sheet::GeneralFunction_COUNTNUMS
},
1047 { "StDev", sheet::GeneralFunction_STDEV
},
1048 { "StDevp", sheet::GeneralFunction_STDEVP
},
1049 { "Var", sheet::GeneralFunction_VAR
},
1050 { "VarP", sheet::GeneralFunction_VARP
},
1051 // compatibility names
1052 { "Count Nums", sheet::GeneralFunction_COUNTNUMS
},
1053 { "StdDev", sheet::GeneralFunction_STDEV
},
1054 { "StdDevp", sheet::GeneralFunction_STDEVP
}
1057 const xub_StrLen nListLen
= rList
.Len();
1058 while ( nStartPos
< nListLen
&& rList
.GetChar(nStartPos
) == ' ' )
1061 bool bParsed
= false;
1062 bool bFound
= false;
1064 xub_StrLen nFuncEnd
= 0;
1065 if ( nStartPos
< nListLen
&& rList
.GetChar(nStartPos
) == '\'' )
1066 bParsed
= lcl_Dequote( rList
, nStartPos
, nFuncEnd
, aFuncStr
);
1069 nFuncEnd
= rList
.Search( static_cast<sal_Unicode
>(']'), nStartPos
);
1070 if ( nFuncEnd
!= STRING_NOTFOUND
)
1072 aFuncStr
= rList
.Copy( nStartPos
, nFuncEnd
- nStartPos
);
1079 aFuncStr
.EraseLeadingAndTrailingChars( ' ' );
1081 const sal_Int32 nFuncCount
= sizeof(aFunctions
) / sizeof(aFunctions
[0]);
1082 for ( sal_Int32 nFunc
=0; nFunc
<nFuncCount
&& !bFound
; nFunc
++ )
1084 if ( aFuncStr
.EqualsIgnoreCaseAscii( aFunctions
[nFunc
].pName
) )
1086 rFunc
= aFunctions
[nFunc
].eFunc
;
1089 while ( nFuncEnd
< nListLen
&& rList
.GetChar(nFuncEnd
) == ' ' )
1099 bool lcl_IsAtStart( const String
& rList
, const String
& rSearch
, sal_Int32
& rMatched
,
1100 bool bAllowBracket
, sheet::GeneralFunction
* pFunc
)
1102 sal_Int32 nMatchList
= 0;
1103 sal_Int32 nMatchSearch
= 0;
1104 sal_Unicode cFirst
= rList
.GetChar(0);
1105 if ( cFirst
== '\'' || cFirst
== '[' )
1107 // quoted string or string in brackets must match completely
1110 xub_StrLen nQuoteEnd
= 0;
1111 bool bParsed
= false;
1113 if ( cFirst
== '\'' )
1114 bParsed
= lcl_Dequote( rList
, 0, nQuoteEnd
, aDequoted
);
1115 else if ( cFirst
== '[' )
1117 // skip spaces after the opening bracket
1119 xub_StrLen nStartPos
= 1;
1120 const xub_StrLen nListLen
= rList
.Len();
1121 while ( nStartPos
< nListLen
&& rList
.GetChar(nStartPos
) == ' ' )
1124 if ( rList
.GetChar(nStartPos
) == '\'' ) // quoted within the brackets?
1126 if ( lcl_Dequote( rList
, nStartPos
, nQuoteEnd
, aDequoted
) )
1128 // after the quoted string, there must be the closing bracket, optionally preceded by spaces,
1129 // and/or a function name
1130 while ( nQuoteEnd
< nListLen
&& rList
.GetChar(nQuoteEnd
) == ' ' )
1133 // semicolon separates function name
1134 if ( nQuoteEnd
< nListLen
&& rList
.GetChar(nQuoteEnd
) == ';' && pFunc
)
1136 xub_StrLen nFuncEnd
= 0;
1137 if ( lcl_ParseFunction( rList
, nQuoteEnd
+ 1, nFuncEnd
, *pFunc
) )
1138 nQuoteEnd
= nFuncEnd
;
1140 if ( nQuoteEnd
< nListLen
&& rList
.GetChar(nQuoteEnd
) == ']' )
1142 ++nQuoteEnd
; // include the closing bracket for the matched length
1149 // implicit quoting to the closing bracket
1151 xub_StrLen nClosePos
= rList
.Search( static_cast<sal_Unicode
>(']'), nStartPos
);
1152 if ( nClosePos
!= STRING_NOTFOUND
)
1154 xub_StrLen nNameEnd
= nClosePos
;
1155 xub_StrLen nSemiPos
= rList
.Search( static_cast<sal_Unicode
>(';'), nStartPos
);
1156 if ( nSemiPos
!= STRING_NOTFOUND
&& nSemiPos
< nClosePos
&& pFunc
)
1158 xub_StrLen nFuncEnd
= 0;
1159 if ( lcl_ParseFunction( rList
, nSemiPos
+ 1, nFuncEnd
, *pFunc
) )
1160 nNameEnd
= nSemiPos
;
1163 aDequoted
= rList
.Copy( nStartPos
, nNameEnd
- nStartPos
);
1164 aDequoted
.EraseTrailingChars( ' ' ); // spaces before the closing bracket or semicolon
1165 nQuoteEnd
= nClosePos
+ 1;
1171 if ( bParsed
&& ScGlobal::pTransliteration
->isEqual( aDequoted
, rSearch
) )
1173 nMatchList
= nQuoteEnd
; // match count in the list string, including quotes
1174 nMatchSearch
= rSearch
.Len();
1179 // otherwise look for search string at the start of rList
1180 ScGlobal::pTransliteration
->equals( rList
, 0, rList
.Len(), nMatchList
,
1181 rSearch
, 0, rSearch
.Len(), nMatchSearch
);
1184 if ( nMatchSearch
== rSearch
.Len() )
1186 // search string is at start of rList - look for following space or end of string
1188 bool bValid
= false;
1189 if ( sal::static_int_cast
<xub_StrLen
>(nMatchList
) >= rList
.Len() )
1193 sal_Unicode cNext
= rList
.GetChar(sal::static_int_cast
<xub_StrLen
>(nMatchList
));
1194 if ( cNext
== ' ' || ( bAllowBracket
&& cNext
== '[' ) )
1200 rMatched
= nMatchList
;
1208 BOOL
ScDPObject::ParseFilters( ScDPGetPivotDataField
& rTarget
,
1209 std::vector
< ScDPGetPivotDataField
>& rFilters
,
1210 const String
& rFilterList
)
1212 // parse the string rFilterList into parameters for GetPivotData
1214 CreateObjects(); // create xSource if not already done
1216 std::vector
<String
> aDataNames
; // data fields (source name)
1217 std::vector
<String
> aGivenNames
; // data fields (compound name)
1218 std::vector
<String
> aFieldNames
; // column/row/data fields
1219 std::vector
< uno::Sequence
<rtl::OUString
> > aFieldValues
;
1222 // get all the field and item names
1225 uno::Reference
<container::XNameAccess
> xDimsName
= xSource
->getDimensions();
1226 uno::Reference
<container::XIndexAccess
> xIntDims
= new ScNameToIndexAccess( xDimsName
);
1227 sal_Int32 nDimCount
= xIntDims
->getCount();
1228 for ( sal_Int32 nDim
= 0; nDim
<nDimCount
; nDim
++ )
1230 uno::Reference
<uno::XInterface
> xIntDim
= ScUnoHelpFunctions::AnyToInterface( xIntDims
->getByIndex(nDim
) );
1231 uno::Reference
<container::XNamed
> xDim( xIntDim
, uno::UNO_QUERY
);
1232 uno::Reference
<beans::XPropertySet
> xDimProp( xDim
, uno::UNO_QUERY
);
1233 uno::Reference
<sheet::XHierarchiesSupplier
> xDimSupp( xDim
, uno::UNO_QUERY
);
1234 BOOL bDataLayout
= ScUnoHelpFunctions::GetBoolProperty( xDimProp
,
1235 rtl::OUString::createFromAscii(DP_PROP_ISDATALAYOUT
) );
1236 sal_Int32 nOrient
= ScUnoHelpFunctions::GetEnumProperty(
1237 xDimProp
, rtl::OUString::createFromAscii(DP_PROP_ORIENTATION
),
1238 sheet::DataPilotFieldOrientation_HIDDEN
);
1241 if ( nOrient
== sheet::DataPilotFieldOrientation_DATA
)
1245 ScDPOutput::GetDataDimensionNames( aSourceName
, aGivenName
, xIntDim
);
1246 aDataNames
.push_back( aSourceName
);
1247 aGivenNames
.push_back( aGivenName
);
1249 else if ( nOrient
!= sheet::DataPilotFieldOrientation_HIDDEN
)
1251 // get level names, as in ScDPOutput
1253 uno::Reference
<container::XIndexAccess
> xHiers
= new ScNameToIndexAccess( xDimSupp
->getHierarchies() );
1254 sal_Int32 nHierarchy
= ScUnoHelpFunctions::GetLongProperty( xDimProp
,
1255 rtl::OUString::createFromAscii(DP_PROP_USEDHIERARCHY
) );
1256 if ( nHierarchy
>= xHiers
->getCount() )
1259 uno::Reference
<uno::XInterface
> xHier
= ScUnoHelpFunctions::AnyToInterface(
1260 xHiers
->getByIndex(nHierarchy
) );
1261 uno::Reference
<sheet::XLevelsSupplier
> xHierSupp( xHier
, uno::UNO_QUERY
);
1262 if ( xHierSupp
.is() )
1264 uno::Reference
<container::XIndexAccess
> xLevels
= new ScNameToIndexAccess( xHierSupp
->getLevels() );
1265 sal_Int32 nLevCount
= xLevels
->getCount();
1266 for (sal_Int32 nLev
=0; nLev
<nLevCount
; nLev
++)
1268 uno::Reference
<uno::XInterface
> xLevel
= ScUnoHelpFunctions::AnyToInterface(
1269 xLevels
->getByIndex(nLev
) );
1270 uno::Reference
<container::XNamed
> xLevNam( xLevel
, uno::UNO_QUERY
);
1271 uno::Reference
<sheet::XMembersSupplier
> xLevSupp( xLevel
, uno::UNO_QUERY
);
1272 if ( xLevNam
.is() && xLevSupp
.is() )
1274 uno::Reference
<container::XNameAccess
> xMembers
= xLevSupp
->getMembers();
1276 String
aFieldName( xLevNam
->getName() );
1277 uno::Sequence
<rtl::OUString
> aMemberNames( xMembers
->getElementNames() );
1279 aFieldNames
.push_back( aFieldName
);
1280 aFieldValues
.push_back( aMemberNames
);
1289 // compare and build filters
1292 SCSIZE nDataFields
= aDataNames
.size();
1293 SCSIZE nFieldCount
= aFieldNames
.size();
1294 DBG_ASSERT( aGivenNames
.size() == nDataFields
&& aFieldValues
.size() == nFieldCount
, "wrong count" );
1296 bool bError
= false;
1297 bool bHasData
= false;
1298 String
aRemaining( rFilterList
);
1299 aRemaining
.EraseLeadingAndTrailingChars( ' ' );
1300 while ( aRemaining
.Len() && !bError
)
1304 // look for data field name
1306 for ( SCSIZE nDataPos
=0; nDataPos
<nDataFields
&& !bUsed
; nDataPos
++ )
1309 sal_Int32 nMatched
= 0;
1310 if ( lcl_IsAtStart( aRemaining
, aDataNames
[nDataPos
], nMatched
, false, NULL
) )
1311 aFound
= aDataNames
[nDataPos
];
1312 else if ( lcl_IsAtStart( aRemaining
, aGivenNames
[nDataPos
], nMatched
, false, NULL
) )
1313 aFound
= aGivenNames
[nDataPos
];
1317 rTarget
.maFieldName
= aFound
;
1318 aRemaining
.Erase( 0, sal::static_int_cast
<xub_StrLen
>(nMatched
) );
1324 // look for field name
1327 bool bHasFieldName
= false;
1330 sal_Int32 nMatched
= 0;
1331 for ( SCSIZE nField
=0; nField
<nFieldCount
&& !bHasFieldName
; nField
++ )
1333 if ( lcl_IsAtStart( aRemaining
, aFieldNames
[nField
], nMatched
, true, NULL
) )
1335 aSpecField
= aFieldNames
[nField
];
1336 aRemaining
.Erase( 0, sal::static_int_cast
<xub_StrLen
>(nMatched
) );
1337 aRemaining
.EraseLeadingChars( ' ' );
1339 // field name has to be followed by item name in brackets
1340 if ( aRemaining
.GetChar(0) == '[' )
1342 bHasFieldName
= true;
1343 // bUsed remains false - still need the item
1354 // look for field item
1358 bool bItemFound
= false;
1359 sal_Int32 nMatched
= 0;
1362 sheet::GeneralFunction eFunc
= sheet::GeneralFunction_NONE
;
1363 sheet::GeneralFunction eFoundFunc
= sheet::GeneralFunction_NONE
;
1365 for ( SCSIZE nField
=0; nField
<nFieldCount
; nField
++ )
1367 // If a field name is given, look in that field only, otherwise in all fields.
1368 // aSpecField is initialized from aFieldNames array, so exact comparison can be used.
1369 if ( !bHasFieldName
|| aFieldNames
[nField
] == aSpecField
)
1371 const uno::Sequence
<rtl::OUString
>& rItems
= aFieldValues
[nField
];
1372 sal_Int32 nItemCount
= rItems
.getLength();
1373 const rtl::OUString
* pItemArr
= rItems
.getConstArray();
1374 for ( sal_Int32 nItem
=0; nItem
<nItemCount
; nItem
++ )
1376 if ( lcl_IsAtStart( aRemaining
, pItemArr
[nItem
], nMatched
, false, &eFunc
) )
1379 bError
= true; // duplicate (also across fields)
1382 aFoundName
= aFieldNames
[nField
];
1383 aFoundValue
= pItemArr
[nItem
];
1393 if ( bItemFound
&& !bError
)
1395 ScDPGetPivotDataField aField
;
1396 aField
.maFieldName
= aFoundName
;
1397 aField
.meFunction
= eFoundFunc
;
1398 aField
.mbValIsStr
= true;
1399 aField
.maValStr
= aFoundValue
;
1400 aField
.mnValNum
= 0.0;
1401 rFilters
.push_back( aField
);
1403 aRemaining
.Erase( 0, sal::static_int_cast
<xub_StrLen
>(nMatched
) );
1410 aRemaining
.EraseLeadingChars( ' ' ); // remove any number of spaces between entries
1413 if ( !bError
&& !bHasData
&& aDataNames
.size() == 1 )
1415 // if there's only one data field, its name need not be specified
1416 rTarget
.maFieldName
= aDataNames
[0];
1420 return bHasData
&& !bError
;
1423 void ScDPObject::ToggleDetails(const DataPilotTableHeaderData
& rElemDesc
, ScDPObject
* pDestObj
)
1425 CreateObjects(); // create xSource if not already done
1427 // find dimension name
1429 uno::Reference
<container::XNamed
> xDim
;
1430 uno::Reference
<container::XNameAccess
> xDimsName
= xSource
->getDimensions();
1431 uno::Reference
<container::XIndexAccess
> xIntDims
= new ScNameToIndexAccess( xDimsName
);
1432 long nIntCount
= xIntDims
->getCount();
1433 if ( rElemDesc
.Dimension
< nIntCount
)
1435 uno::Reference
<uno::XInterface
> xIntDim
= ScUnoHelpFunctions::AnyToInterface(
1436 xIntDims
->getByIndex(rElemDesc
.Dimension
) );
1437 xDim
= uno::Reference
<container::XNamed
>( xIntDim
, uno::UNO_QUERY
);
1439 DBG_ASSERT( xDim
.is(), "dimension not found" );
1440 if ( !xDim
.is() ) return;
1441 String aDimName
= xDim
->getName();
1443 uno::Reference
<beans::XPropertySet
> xDimProp( xDim
, uno::UNO_QUERY
);
1444 BOOL bDataLayout
= ScUnoHelpFunctions::GetBoolProperty( xDimProp
,
1445 rtl::OUString::createFromAscii(DP_PROP_ISDATALAYOUT
) );
1448 // the elements of the data layout dimension can't be found by their names
1449 // -> don't change anything
1455 long nHierCount
= 0;
1456 uno::Reference
<container::XIndexAccess
> xHiers
;
1457 uno::Reference
<sheet::XHierarchiesSupplier
> xHierSupp( xDim
, uno::UNO_QUERY
);
1458 if ( xHierSupp
.is() )
1460 uno::Reference
<container::XNameAccess
> xHiersName
= xHierSupp
->getHierarchies();
1461 xHiers
= new ScNameToIndexAccess( xHiersName
);
1462 nHierCount
= xHiers
->getCount();
1464 uno::Reference
<uno::XInterface
> xHier
;
1465 if ( rElemDesc
.Hierarchy
< nHierCount
)
1466 xHier
= ScUnoHelpFunctions::AnyToInterface( xHiers
->getByIndex(rElemDesc
.Hierarchy
) );
1467 DBG_ASSERT( xHier
.is(), "hierarchy not found" );
1468 if ( !xHier
.is() ) return;
1471 uno::Reference
<container::XIndexAccess
> xLevels
;
1472 uno::Reference
<sheet::XLevelsSupplier
> xLevSupp( xHier
, uno::UNO_QUERY
);
1473 if ( xLevSupp
.is() )
1475 uno::Reference
<container::XNameAccess
> xLevsName
= xLevSupp
->getLevels();
1476 xLevels
= new ScNameToIndexAccess( xLevsName
);
1477 nLevCount
= xLevels
->getCount();
1479 uno::Reference
<uno::XInterface
> xLevel
;
1480 if ( rElemDesc
.Level
< nLevCount
)
1481 xLevel
= ScUnoHelpFunctions::AnyToInterface( xLevels
->getByIndex(rElemDesc
.Level
) );
1482 DBG_ASSERT( xLevel
.is(), "level not found" );
1483 if ( !xLevel
.is() ) return;
1485 uno::Reference
<container::XNameAccess
> xMembers
;
1486 uno::Reference
<sheet::XMembersSupplier
> xMbrSupp( xLevel
, uno::UNO_QUERY
);
1487 if ( xMbrSupp
.is() )
1488 xMembers
= xMbrSupp
->getMembers();
1490 BOOL bFound
= FALSE
;
1491 BOOL bShowDetails
= TRUE
;
1493 if ( xMembers
.is() )
1495 if ( xMembers
->hasByName(rElemDesc
.MemberName
) )
1497 uno::Reference
<uno::XInterface
> xMemberInt
= ScUnoHelpFunctions::AnyToInterface(
1498 xMembers
->getByName(rElemDesc
.MemberName
) );
1499 uno::Reference
<beans::XPropertySet
> xMbrProp( xMemberInt
, uno::UNO_QUERY
);
1500 if ( xMbrProp
.is() )
1502 bShowDetails
= ScUnoHelpFunctions::GetBoolProperty( xMbrProp
,
1503 rtl::OUString::createFromAscii(DP_PROP_SHOWDETAILS
) );
1504 //! don't set bFound if property is unknown?
1510 DBG_ASSERT( bFound
, "member not found" );
1512 //! use Hierarchy and Level in SaveData !!!!
1514 // modify pDestObj if set, this object otherwise
1515 ScDPSaveData
* pModifyData
= pDestObj
? ( pDestObj
->pSaveData
) : pSaveData
;
1516 DBG_ASSERT( pModifyData
, "no data?" );
1519 const String aName
= rElemDesc
.MemberName
;
1520 pModifyData
->GetDimensionByName(aDimName
)->
1521 GetMemberByName(aName
)->SetShowDetails( !bShowDetails
); // toggle
1524 pDestObj
->InvalidateData(); // re-init source from SaveData
1526 InvalidateData(); // re-init source from SaveData
1530 long lcl_FindName( const rtl::OUString
& rString
, const uno::Reference
<container::XNameAccess
>& xCollection
)
1532 if ( xCollection
.is() )
1534 uno::Sequence
<rtl::OUString
> aSeq
= xCollection
->getElementNames();
1535 long nCount
= aSeq
.getLength();
1536 const rtl::OUString
* pArr
= aSeq
.getConstArray();
1537 for (long nPos
=0; nPos
<nCount
; nPos
++)
1538 if ( pArr
[nPos
] == rString
)
1541 return -1; // not found
1544 USHORT
lcl_FirstSubTotal( const uno::Reference
<beans::XPropertySet
>& xDimProp
) // PIVOT_FUNC mask
1546 uno::Reference
<sheet::XHierarchiesSupplier
> xDimSupp( xDimProp
, uno::UNO_QUERY
);
1547 if ( xDimProp
.is() && xDimSupp
.is() )
1549 uno::Reference
<container::XIndexAccess
> xHiers
= new ScNameToIndexAccess( xDimSupp
->getHierarchies() );
1550 long nHierarchy
= ScUnoHelpFunctions::GetLongProperty( xDimProp
,
1551 rtl::OUString::createFromAscii(DP_PROP_USEDHIERARCHY
) );
1552 if ( nHierarchy
>= xHiers
->getCount() )
1555 uno::Reference
<uno::XInterface
> xHier
= ScUnoHelpFunctions::AnyToInterface(
1556 xHiers
->getByIndex(nHierarchy
) );
1557 uno::Reference
<sheet::XLevelsSupplier
> xHierSupp( xHier
, uno::UNO_QUERY
);
1558 if ( xHierSupp
.is() )
1560 uno::Reference
<container::XIndexAccess
> xLevels
= new ScNameToIndexAccess( xHierSupp
->getLevels() );
1561 uno::Reference
<uno::XInterface
> xLevel
=
1562 ScUnoHelpFunctions::AnyToInterface( xLevels
->getByIndex( 0 ) );
1563 uno::Reference
<beans::XPropertySet
> xLevProp( xLevel
, uno::UNO_QUERY
);
1564 if ( xLevProp
.is() )
1569 aSubAny
= xLevProp
->getPropertyValue(
1570 rtl::OUString::createFromAscii(DP_PROP_SUBTOTALS
) );
1572 catch(uno::Exception
&)
1575 uno::Sequence
<sheet::GeneralFunction
> aSeq
;
1576 if ( aSubAny
>>= aSeq
)
1579 const sheet::GeneralFunction
* pArray
= aSeq
.getConstArray();
1580 long nCount
= aSeq
.getLength();
1581 for (long i
=0; i
<nCount
; i
++)
1582 nMask
|= ScDataPilotConversion::FunctionBit(pArray
[i
]);
1589 DBG_ERROR("FirstSubTotal: NULL");
1593 USHORT
lcl_CountBits( USHORT nBits
)
1595 if (!nBits
) return 0;
1599 for (USHORT i
=0; i
<16; i
++)
1601 if ( nBits
& nMask
)
1608 SCSIZE
lcl_FillOldFields( PivotField
* pFields
,
1609 const uno::Reference
<sheet::XDimensionsSupplier
>& xSource
,
1610 USHORT nOrient
, SCCOL nColAdd
, BOOL bAddData
)
1612 SCSIZE nOutCount
= 0;
1613 BOOL bDataFound
= FALSE
;
1615 SCSIZE nCount
= (nOrient
== sheet::DataPilotFieldOrientation_PAGE
) ? PIVOT_MAXPAGEFIELD
: PIVOT_MAXFIELD
;
1617 //! merge multiple occurences (data field with different functions)
1618 //! force data field in one dimension
1620 std::vector
< long > aPos( nCount
, 0 );
1622 uno::Reference
<container::XNameAccess
> xDimsName
= xSource
->getDimensions();
1623 uno::Reference
<container::XIndexAccess
> xDims
= new ScNameToIndexAccess( xDimsName
);
1624 long nDimCount
= xDims
->getCount();
1625 for (long nDim
=0; nDim
< nDimCount
&& nOutCount
< nCount
; nDim
++)
1627 uno::Reference
<uno::XInterface
> xIntDim
=
1628 ScUnoHelpFunctions::AnyToInterface( xDims
->getByIndex(nDim
) );
1629 uno::Reference
<beans::XPropertySet
> xDimProp( xIntDim
, uno::UNO_QUERY
);
1630 long nDimOrient
= ScUnoHelpFunctions::GetEnumProperty(
1631 xDimProp
, rtl::OUString::createFromAscii(DP_PROP_ORIENTATION
),
1632 sheet::DataPilotFieldOrientation_HIDDEN
);
1633 if ( xDimProp
.is() && nDimOrient
== nOrient
)
1636 if ( nOrient
== sheet::DataPilotFieldOrientation_DATA
)
1638 sheet::GeneralFunction eFunc
= (sheet::GeneralFunction
)ScUnoHelpFunctions::GetEnumProperty(
1639 xDimProp
, rtl::OUString::createFromAscii(DP_PROP_FUNCTION
),
1640 sheet::GeneralFunction_NONE
);
1641 if ( eFunc
== sheet::GeneralFunction_AUTO
)
1643 //! test for numeric data
1644 eFunc
= sheet::GeneralFunction_SUM
;
1646 nMask
= ScDataPilotConversion::FunctionBit(eFunc
);
1649 nMask
= lcl_FirstSubTotal( xDimProp
); // from first hierarchy
1651 BOOL bDataLayout
= ScUnoHelpFunctions::GetBoolProperty( xDimProp
,
1652 rtl::OUString::createFromAscii(DP_PROP_ISDATALAYOUT
) );
1656 aOrigAny
= xDimProp
->getPropertyValue(
1657 rtl::OUString::createFromAscii(DP_PROP_ORIGINAL
) );
1659 catch(uno::Exception
&)
1663 long nDupSource
= -1;
1664 uno::Reference
<uno::XInterface
> xIntOrig
= ScUnoHelpFunctions::AnyToInterface( aOrigAny
);
1665 if ( xIntOrig
.is() )
1667 uno::Reference
<container::XNamed
> xNameOrig( xIntOrig
, uno::UNO_QUERY
);
1668 if ( xNameOrig
.is() )
1669 nDupSource
= lcl_FindName( xNameOrig
->getName(), xDimsName
);
1672 BOOL bDupUsed
= FALSE
;
1673 if ( nDupSource
>= 0 )
1675 // add function bit to previous entry
1679 nCompCol
= PIVOT_DATA_FIELD
;
1681 nCompCol
= static_cast<SCsCOL
>(nDupSource
)+nColAdd
; //! seek source column from name
1683 for (SCSIZE nOld
=0; nOld
<nOutCount
&& !bDupUsed
; nOld
++)
1684 if ( pFields
[nOld
].nCol
== nCompCol
)
1686 // add to previous column only if new bits aren't already set there
1687 if ( ( pFields
[nOld
].nFuncMask
& nMask
) == 0 )
1689 pFields
[nOld
].nFuncMask
|= nMask
;
1690 pFields
[nOld
].nFuncCount
= lcl_CountBits( pFields
[nOld
].nFuncMask
);
1696 if ( !bDupUsed
) // also for duplicated dim if original has different orientation
1700 pFields
[nOutCount
].nCol
= PIVOT_DATA_FIELD
;
1703 else if ( nDupSource
>= 0 ) // if source was not found (different orientation)
1704 pFields
[nOutCount
].nCol
= static_cast<SCsCOL
>(nDupSource
)+nColAdd
; //! seek from name
1706 pFields
[nOutCount
].nCol
= static_cast<SCsCOL
>(nDim
)+nColAdd
; //! seek source column from name
1708 pFields
[nOutCount
].nFuncMask
= nMask
;
1709 pFields
[nOutCount
].nFuncCount
= lcl_CountBits( nMask
);
1710 aPos
[nOutCount
] = ScUnoHelpFunctions::GetLongProperty( xDimProp
,
1711 rtl::OUString::createFromAscii(DP_PROP_POSITION
) );
1715 if( nOrient
== sheet::DataPilotFieldOrientation_DATA
)
1716 xDimProp
->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_REFVALUE
) ) )
1717 >>= pFields
[nOutCount
].maFieldRef
;
1719 catch( uno::Exception
& )
1728 // sort by getPosition() value
1730 for (SCSIZE i
=0; i
+1<nOutCount
; i
++)
1732 for (SCSIZE j
=0; j
+i
+1<nOutCount
; j
++)
1733 if ( aPos
[j
+1] < aPos
[j
] )
1735 std::swap( aPos
[j
], aPos
[j
+1] );
1736 std::swap( pFields
[j
], pFields
[j
+1] );
1740 if ( bAddData
&& !bDataFound
)
1742 if ( nOutCount
>= nCount
) // space for data field?
1743 --nOutCount
; //! error?
1744 pFields
[nOutCount
].nCol
= PIVOT_DATA_FIELD
;
1745 pFields
[nOutCount
].nFuncMask
= 0;
1746 pFields
[nOutCount
].nFuncCount
= 0;
1753 BOOL
ScDPObject::FillOldParam(ScPivotParam
& rParam
, BOOL bForFile
) const
1755 ((ScDPObject
*)this)->CreateObjects(); // xSource is needed for field numbers
1757 rParam
.nCol
= aOutRange
.aStart
.Col();
1758 rParam
.nRow
= aOutRange
.aStart
.Row();
1759 rParam
.nTab
= aOutRange
.aStart
.Tab();
1760 // ppLabelArr / nLabels is not changed
1765 // in old file format, columns are within document, not within source range
1767 DBG_ASSERT( pSheetDesc
, "FillOldParam: bForFile, !pSheetDesc" );
1768 nColAdd
= pSheetDesc
->aSourceRange
.aStart
.Col();
1771 BOOL bAddData
= ( lcl_GetDataGetOrientation( xSource
) == sheet::DataPilotFieldOrientation_HIDDEN
);
1772 rParam
.nPageCount
= lcl_FillOldFields( rParam
.aPageArr
,
1773 xSource
, sheet::DataPilotFieldOrientation_PAGE
, nColAdd
, FALSE
);
1774 rParam
.nColCount
= lcl_FillOldFields( rParam
.aColArr
,
1775 xSource
, sheet::DataPilotFieldOrientation_COLUMN
, nColAdd
, bAddData
);
1776 rParam
.nRowCount
= lcl_FillOldFields( rParam
.aRowArr
,
1777 xSource
, sheet::DataPilotFieldOrientation_ROW
, nColAdd
, FALSE
);
1778 rParam
.nDataCount
= lcl_FillOldFields( rParam
.aDataArr
,
1779 xSource
, sheet::DataPilotFieldOrientation_DATA
, nColAdd
, FALSE
);
1781 uno::Reference
<beans::XPropertySet
> xProp( xSource
, uno::UNO_QUERY
);
1786 rParam
.bMakeTotalCol
= ScUnoHelpFunctions::GetBoolProperty( xProp
,
1787 rtl::OUString::createFromAscii(DP_PROP_COLUMNGRAND
), TRUE
);
1788 rParam
.bMakeTotalRow
= ScUnoHelpFunctions::GetBoolProperty( xProp
,
1789 rtl::OUString::createFromAscii(DP_PROP_ROWGRAND
), TRUE
);
1791 // following properties may be missing for external sources
1792 rParam
.bIgnoreEmptyRows
= ScUnoHelpFunctions::GetBoolProperty( xProp
,
1793 rtl::OUString::createFromAscii(DP_PROP_IGNOREEMPTY
) );
1794 rParam
.bDetectCategories
= ScUnoHelpFunctions::GetBoolProperty( xProp
,
1795 rtl::OUString::createFromAscii(DP_PROP_REPEATIFEMPTY
) );
1797 catch(uno::Exception
&)
1805 void lcl_FillLabelData( ScDPLabelData
& rData
, const uno::Reference
< beans::XPropertySet
>& xDimProp
)
1807 uno::Reference
<sheet::XHierarchiesSupplier
> xDimSupp( xDimProp
, uno::UNO_QUERY
);
1808 if ( xDimProp
.is() && xDimSupp
.is() )
1810 uno::Reference
<container::XIndexAccess
> xHiers
= new ScNameToIndexAccess( xDimSupp
->getHierarchies() );
1811 long nHierarchy
= ScUnoHelpFunctions::GetLongProperty( xDimProp
,
1812 rtl::OUString::createFromAscii(DP_PROP_USEDHIERARCHY
) );
1813 if ( nHierarchy
>= xHiers
->getCount() )
1815 rData
.mnUsedHier
= nHierarchy
;
1817 uno::Reference
<uno::XInterface
> xHier
= ScUnoHelpFunctions::AnyToInterface(
1818 xHiers
->getByIndex(nHierarchy
) );
1820 uno::Reference
<sheet::XLevelsSupplier
> xHierSupp( xHier
, uno::UNO_QUERY
);
1821 if ( xHierSupp
.is() )
1823 uno::Reference
<container::XIndexAccess
> xLevels
= new ScNameToIndexAccess( xHierSupp
->getLevels() );
1824 uno::Reference
<uno::XInterface
> xLevel
=
1825 ScUnoHelpFunctions::AnyToInterface( xLevels
->getByIndex( 0 ) );
1826 uno::Reference
<beans::XPropertySet
> xLevProp( xLevel
, uno::UNO_QUERY
);
1827 if ( xLevProp
.is() )
1829 rData
.mbShowAll
= ScUnoHelpFunctions::GetBoolProperty( xLevProp
,
1830 rtl::OUString::createFromAscii(DP_PROP_SHOWEMPTY
) );
1834 xLevProp
->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_SORTING
) ) )
1835 >>= rData
.maSortInfo
;
1836 xLevProp
->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_LAYOUT
) ) )
1837 >>= rData
.maLayoutInfo
;
1838 xLevProp
->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_AUTOSHOW
) ) )
1839 >>= rData
.maShowInfo
;
1841 catch(uno::Exception
&)
1849 BOOL
ScDPObject::FillLabelData(ScPivotParam
& rParam
)
1851 rParam
.maLabelArray
.clear();
1853 ((ScDPObject
*)this)->CreateObjects();
1855 uno::Reference
<container::XNameAccess
> xDimsName
= xSource
->getDimensions();
1856 uno::Reference
<container::XIndexAccess
> xDims
= new ScNameToIndexAccess( xDimsName
);
1857 long nDimCount
= xDims
->getCount();
1858 if ( nDimCount
> MAX_LABELS
)
1859 nDimCount
= MAX_LABELS
;
1863 for (long nDim
=0; nDim
< nDimCount
; nDim
++)
1866 uno::Reference
<uno::XInterface
> xIntDim
=
1867 ScUnoHelpFunctions::AnyToInterface( xDims
->getByIndex(nDim
) );
1868 uno::Reference
<container::XNamed
> xDimName( xIntDim
, uno::UNO_QUERY
);
1869 uno::Reference
<beans::XPropertySet
> xDimProp( xIntDim
, uno::UNO_QUERY
);
1871 if ( xDimName
.is() && xDimProp
.is() )
1873 BOOL bDuplicated
= FALSE
;
1874 BOOL bData
= ScUnoHelpFunctions::GetBoolProperty( xDimProp
,
1875 rtl::OUString::createFromAscii(DP_PROP_ISDATALAYOUT
) );
1876 //! error checking -- is "IsDataLayoutDimension" property required??
1880 aFieldName
= String( xDimName
->getName() );
1882 uno::Any aOrigAny
= xDimProp
->getPropertyValue(
1883 rtl::OUString::createFromAscii(DP_PROP_ORIGINAL
) );
1884 uno::Reference
<uno::XInterface
> xIntOrig
;
1885 if ( (aOrigAny
>>= xIntOrig
) && xIntOrig
.is() )
1888 catch(uno::Exception
&)
1892 if ( aFieldName
.Len() && !bData
&& !bDuplicated
)
1894 SCsCOL nCol
= static_cast< SCsCOL
>( nDim
); //! ???
1895 bool bIsValue
= true; //! check
1897 ScDPLabelDataRef
pNewLabel(new ScDPLabelData(aFieldName
, nCol
, bIsValue
));
1898 GetHierarchies(nDim
, pNewLabel
->maHiers
);
1899 GetMembers(nDim
, pNewLabel
->maMembers
, &pNewLabel
->maVisible
, &pNewLabel
->maShowDet
);
1900 lcl_FillLabelData(*pNewLabel
, xDimProp
);
1901 rParam
.maLabelArray
.push_back(pNewLabel
);
1909 BOOL
ScDPObject::GetHierarchiesNA( sal_Int32 nDim
, uno::Reference
< container::XNameAccess
>& xHiers
)
1912 uno::Reference
<container::XNameAccess
> xDimsName( GetSource()->getDimensions() );
1913 uno::Reference
<container::XIndexAccess
> xIntDims(new ScNameToIndexAccess( xDimsName
));
1916 uno::Reference
<sheet::XHierarchiesSupplier
> xHierSup(xIntDims
->getByIndex( nDim
), uno::UNO_QUERY
);
1919 xHiers
.set( xHierSup
->getHierarchies() );
1926 BOOL
ScDPObject::GetHierarchies( sal_Int32 nDim
, uno::Sequence
< rtl::OUString
>& rHiers
)
1929 uno::Reference
< container::XNameAccess
> xHiersNA
;
1930 if( GetHierarchiesNA( nDim
, xHiersNA
) )
1932 rHiers
= xHiersNA
->getElementNames();
1938 sal_Int32
ScDPObject::GetUsedHierarchy( sal_Int32 nDim
)
1940 sal_Int32 nHier
= 0;
1941 uno::Reference
<container::XNameAccess
> xDimsName( GetSource()->getDimensions() );
1942 uno::Reference
<container::XIndexAccess
> xIntDims(new ScNameToIndexAccess( xDimsName
));
1943 uno::Reference
<beans::XPropertySet
> xDim(xIntDims
->getByIndex( nDim
), uno::UNO_QUERY
);
1945 nHier
= ScUnoHelpFunctions::GetLongProperty( xDim
, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( SC_UNO_USEDHIER
) ) );
1949 BOOL
ScDPObject::GetMembersNA( sal_Int32 nDim
, uno::Reference
< container::XNameAccess
>& xMembers
)
1951 return GetMembersNA( nDim
, GetUsedHierarchy( nDim
), xMembers
);
1954 BOOL
ScDPObject::GetMembers( sal_Int32 nDim
,
1955 uno::Sequence
< rtl::OUString
>& rMembers
,
1956 uno::Sequence
< sal_Bool
>* pVisible
,
1957 uno::Sequence
< sal_Bool
>* pShowDet
)
1959 return GetMembers( nDim
, GetUsedHierarchy( nDim
), rMembers
, pVisible
, pShowDet
);
1962 BOOL
ScDPObject::GetMembersNA( sal_Int32 nDim
, sal_Int32 nHier
, uno::Reference
< container::XNameAccess
>& xMembers
)
1965 uno::Reference
<container::XNameAccess
> xDimsName( GetSource()->getDimensions() );
1966 uno::Reference
<container::XIndexAccess
> xIntDims(new ScNameToIndexAccess( xDimsName
));
1967 uno::Reference
<beans::XPropertySet
> xDim(xIntDims
->getByIndex( nDim
), uno::UNO_QUERY
);
1970 uno::Reference
<sheet::XHierarchiesSupplier
> xHierSup(xDim
, uno::UNO_QUERY
);
1973 uno::Reference
<container::XIndexAccess
> xHiers(new ScNameToIndexAccess(xHierSup
->getHierarchies()));
1974 uno::Reference
<sheet::XLevelsSupplier
> xLevSupp( xHiers
->getByIndex(nHier
), uno::UNO_QUERY
);
1975 if ( xLevSupp
.is() )
1977 uno::Reference
<container::XIndexAccess
> xLevels(new ScNameToIndexAccess( xLevSupp
->getLevels()));
1980 sal_Int32 nLevCount
= xLevels
->getCount();
1983 uno::Reference
<sheet::XMembersSupplier
> xMembSupp( xLevels
->getByIndex(0), uno::UNO_QUERY
);
1984 if ( xMembSupp
.is() )
1986 xMembers
.set(xMembSupp
->getMembers());
1997 BOOL
ScDPObject::GetMembers( sal_Int32 nDim
, sal_Int32 nHier
,
1998 uno::Sequence
< rtl::OUString
>& rMembers
,
1999 uno::Sequence
< sal_Bool
>* pVisible
,
2000 uno::Sequence
< sal_Bool
>* pShowDet
)
2003 uno::Reference
< container::XNameAccess
> xMembersNA
;
2004 if( GetMembersNA( nDim
, nHier
, xMembersNA
) )
2006 uno::Reference
< container::XIndexAccess
> xMembersIA( new ScNameToIndexAccess( xMembersNA
) );
2007 sal_Int32 nCount
= xMembersIA
->getCount();
2008 rMembers
.realloc( nCount
);
2010 pVisible
->realloc( nCount
);
2012 pShowDet
->realloc( nCount
);
2014 rtl::OUString
* pAry
= rMembers
.getArray();
2015 for( sal_Int32 nItem
= 0; nItem
< nCount
; ++nItem
)
2017 uno::Reference
< container::XNamed
> xMember( xMembersIA
->getByIndex( nItem
), uno::UNO_QUERY
);
2019 pAry
[ nItem
] = xMember
->getName();
2020 if( pVisible
|| pShowDet
)
2022 uno::Reference
< beans::XPropertySet
> xMemProp( xMember
, uno::UNO_QUERY
);
2025 sal_Bool bVis
= sal_True
;
2027 bVis
= ScUnoHelpFunctions::GetBoolProperty( xMemProp
,
2028 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_ISVISIBL
) ) );
2029 (*pVisible
)[ nItem
] = bVis
;
2033 sal_Bool bShow
= sal_True
;
2035 bShow
= ScUnoHelpFunctions::GetBoolProperty( xMemProp
,
2036 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_SHOWDETA
) ) );
2037 (*pShowDet
)[ nItem
] = bShow
;
2046 //------------------------------------------------------------------------
2047 // convert old pivot tables into new datapilot tables
2049 String
lcl_GetDimName( const uno::Reference
<sheet::XDimensionsSupplier
>& xSource
, long nDim
)
2051 rtl::OUString aName
;
2054 uno::Reference
<container::XNameAccess
> xDimsName
= xSource
->getDimensions();
2055 uno::Reference
<container::XIndexAccess
> xDims
= new ScNameToIndexAccess( xDimsName
);
2056 long nDimCount
= xDims
->getCount();
2057 if ( nDim
< nDimCount
)
2059 uno::Reference
<uno::XInterface
> xIntDim
=
2060 ScUnoHelpFunctions::AnyToInterface( xDims
->getByIndex(nDim
) );
2061 uno::Reference
<container::XNamed
> xDimName( xIntDim
, uno::UNO_QUERY
);
2066 aName
= xDimName
->getName();
2068 catch(uno::Exception
&)
2078 void ScDPObject::ConvertOrientation( ScDPSaveData
& rSaveData
,
2079 PivotField
* pFields
, SCSIZE nCount
, USHORT nOrient
,
2080 ScDocument
* pDoc
, SCROW nRow
, SCTAB nTab
,
2081 const uno::Reference
<sheet::XDimensionsSupplier
>& xSource
,
2083 PivotField
* pRefColFields
, SCSIZE nRefColCount
,
2084 PivotField
* pRefRowFields
, SCSIZE nRefRowCount
,
2085 PivotField
* pRefPageFields
, SCSIZE nRefPageCount
)
2087 // pDoc or xSource must be set
2088 DBG_ASSERT( pDoc
|| xSource
.is(), "missing string source" );
2091 ScDPSaveDimension
* pDim
;
2093 for (SCSIZE i
=0; i
<nCount
; i
++)
2095 SCCOL nCol
= pFields
[i
].nCol
;
2096 USHORT nFuncs
= pFields
[i
].nFuncMask
;
2097 const sheet::DataPilotFieldReference
& rFieldRef
= pFields
[i
].maFieldRef
;
2099 if ( nCol
== PIVOT_DATA_FIELD
)
2100 pDim
= rSaveData
.GetDataLayoutDimension();
2104 pDoc
->GetString( nCol
, nRow
, nTab
, aDocStr
);
2106 aDocStr
= lcl_GetDimName( xSource
, nCol
); // cols must start at 0
2108 if ( aDocStr
.Len() )
2109 pDim
= rSaveData
.GetDimensionByName(aDocStr
);
2116 if ( nOrient
== sheet::DataPilotFieldOrientation_DATA
) // set summary function
2118 // generate an individual entry for each function
2121 // if a dimension is used for column/row/page and data,
2122 // use duplicated dimensions for all data occurrences
2124 for (SCSIZE nRefCol
=0; nRefCol
<nRefColCount
; nRefCol
++)
2125 if (pRefColFields
[nRefCol
].nCol
== nCol
)
2128 for (SCSIZE nRefRow
=0; nRefRow
<nRefRowCount
; nRefRow
++)
2129 if (pRefRowFields
[nRefRow
].nCol
== nCol
)
2132 for (USHORT nRefPage
=0; nRefPage
<nRefPageCount
; ++nRefPage
)
2133 if (pRefPageFields
[nRefPage
].nCol
== nCol
)
2136 // if set via api, a data column may occur several times
2137 // (if the function hasn't been changed yet) -> also look for duplicate data column
2138 for (SCSIZE nPrevData
=0; nPrevData
<i
; nPrevData
++)
2139 if (pFields
[nPrevData
].nCol
== nCol
)
2143 for (USHORT nBit
=0; nBit
<16; nBit
++)
2145 if ( nFuncs
& nMask
)
2147 sheet::GeneralFunction eFunc
= ScDataPilotConversion::FirstFunc( nMask
);
2148 ScDPSaveDimension
* pCurrDim
= bFirst
? pDim
: rSaveData
.DuplicateDimension(pDim
->GetName());
2149 pCurrDim
->SetOrientation( nOrient
);
2150 pCurrDim
->SetFunction( sal::static_int_cast
<USHORT
>(eFunc
) );
2152 if( rFieldRef
.ReferenceType
== sheet::DataPilotFieldReferenceType::NONE
)
2153 pCurrDim
->SetReferenceValue( 0 );
2155 pCurrDim
->SetReferenceValue( &rFieldRef
);
2162 else // set SubTotals
2164 pDim
->SetOrientation( nOrient
);
2166 USHORT nFuncArray
[16];
2167 USHORT nFuncCount
= 0;
2169 for (USHORT nBit
=0; nBit
<16; nBit
++)
2171 if ( nFuncs
& nMask
)
2172 nFuncArray
[nFuncCount
++] = sal::static_int_cast
<USHORT
>(ScDataPilotConversion::FirstFunc( nMask
));
2175 pDim
->SetSubTotals( nFuncCount
, nFuncArray
);
2177 // ShowEmpty was implicit in old tables,
2178 // must be set for data layout dimension (not accessible in dialog)
2179 if ( bOldDefaults
|| nCol
== PIVOT_DATA_FIELD
)
2180 pDim
->SetShowEmpty( TRUE
);
2186 #if OLD_PIVOT_IMPLEMENTATION
2187 void ScDPObject::InitFromOldPivot( const ScPivot
& rOld
, ScDocument
* pDocP
, BOOL bSetSource
)
2189 ScDPSaveData aSaveData
;
2191 ScPivotParam aParam
;
2192 ScQueryParam aQuery
;
2194 rOld
.GetParam( aParam
, aQuery
, aArea
);
2196 ConvertOrientation( aSaveData
, aParam
.aPageArr
, aParam
.nPageCount
,
2197 sheet::DataPilotFieldOrientation_PAGE
, pDocP
, aArea
.nRowStart
, aArea
.nTab
,
2198 uno::Reference
<sheet::XDimensionsSupplier
>(), TRUE
);
2199 ConvertOrientation( aSaveData
, aParam
.aColArr
, aParam
.nColCount
,
2200 sheet::DataPilotFieldOrientation_COLUMN
, pDocP
, aArea
.nRowStart
, aArea
.nTab
,
2201 uno::Reference
<sheet::XDimensionsSupplier
>(), TRUE
);
2202 ConvertOrientation( aSaveData
, aParam
.aRowArr
, aParam
.nRowCount
,
2203 sheet::DataPilotFieldOrientation_ROW
, pDocP
, aArea
.nRowStart
, aArea
.nTab
,
2204 uno::Reference
<sheet::XDimensionsSupplier
>(), TRUE
);
2205 ConvertOrientation( aSaveData
, aParam
.aDataArr
, aParam
.nDataCount
,
2206 sheet::DataPilotFieldOrientation_DATA
, pDocP
, aArea
.nRowStart
, aArea
.nTab
,
2207 uno::Reference
<sheet::XDimensionsSupplier
>(), TRUE
,
2208 aParam
.aColArr
, aParam
.nColCount
, aParam
.aRowArr
, aParam
.nRowCount
);
2210 aSaveData
.SetIgnoreEmptyRows( rOld
.GetIgnoreEmpty() );
2211 aSaveData
.SetRepeatIfEmpty( rOld
.GetDetectCat() );
2212 aSaveData
.SetColumnGrand( rOld
.GetMakeTotalCol() );
2213 aSaveData
.SetRowGrand( rOld
.GetMakeTotalRow() );
2215 SetSaveData( aSaveData
);
2218 ScSheetSourceDesc aDesc
;
2219 aDesc
.aSourceRange
= rOld
.GetSrcArea();
2220 rOld
.GetQuery( aDesc
.aQueryParam
);
2221 SetSheetDesc( aDesc
);
2223 SetOutRange( rOld
.GetDestArea() );
2225 aTableName
= rOld
.GetName();
2226 aTableTag
= rOld
.GetTag();
2230 // -----------------------------------------------------------------------
2233 BOOL
ScDPObject::HasRegisteredSources()
2235 BOOL bFound
= FALSE
;
2237 uno::Reference
<lang::XMultiServiceFactory
> xManager
= comphelper::getProcessServiceFactory();
2238 uno::Reference
<container::XContentEnumerationAccess
> xEnAc( xManager
, uno::UNO_QUERY
);
2241 uno::Reference
<container::XEnumeration
> xEnum
= xEnAc
->createContentEnumeration(
2242 rtl::OUString::createFromAscii( SCDPSOURCE_SERVICE
) );
2243 if ( xEnum
.is() && xEnum
->hasMoreElements() )
2251 uno::Sequence
<rtl::OUString
> ScDPObject::GetRegisteredSources()
2254 uno::Sequence
<rtl::OUString
> aSeq(0);
2256 // use implementation names...
2258 uno::Reference
<lang::XMultiServiceFactory
> xManager
= comphelper::getProcessServiceFactory();
2259 uno::Reference
<container::XContentEnumerationAccess
> xEnAc( xManager
, uno::UNO_QUERY
);
2262 uno::Reference
<container::XEnumeration
> xEnum
= xEnAc
->createContentEnumeration(
2263 rtl::OUString::createFromAscii( SCDPSOURCE_SERVICE
) );
2266 while ( xEnum
->hasMoreElements() )
2268 uno::Any aAddInAny
= xEnum
->nextElement();
2269 // if ( aAddInAny.getReflection()->getTypeClass() == TypeClass_INTERFACE )
2271 uno::Reference
<uno::XInterface
> xIntFac
;
2272 aAddInAny
>>= xIntFac
;
2275 uno::Reference
<lang::XServiceInfo
> xInfo( xIntFac
, uno::UNO_QUERY
);
2278 rtl::OUString sName
= xInfo
->getImplementationName();
2280 aSeq
.realloc( nCount
+1 );
2281 aSeq
.getArray()[nCount
] = sName
;
2294 uno::Reference
<sheet::XDimensionsSupplier
> ScDPObject::CreateSource( const ScDPServiceDesc
& rDesc
)
2296 rtl::OUString aImplName
= rDesc
.aServiceName
;
2297 uno::Reference
<sheet::XDimensionsSupplier
> xRet
= NULL
;
2299 uno::Reference
<lang::XMultiServiceFactory
> xManager
= comphelper::getProcessServiceFactory();
2300 uno::Reference
<container::XContentEnumerationAccess
> xEnAc( xManager
, uno::UNO_QUERY
);
2303 uno::Reference
<container::XEnumeration
> xEnum
= xEnAc
->createContentEnumeration(
2304 rtl::OUString::createFromAscii( SCDPSOURCE_SERVICE
) );
2307 while ( xEnum
->hasMoreElements() && !xRet
.is() )
2309 uno::Any aAddInAny
= xEnum
->nextElement();
2310 // if ( aAddInAny.getReflection()->getTypeClass() == TypeClass_INTERFACE )
2312 uno::Reference
<uno::XInterface
> xIntFac
;
2313 aAddInAny
>>= xIntFac
;
2316 uno::Reference
<lang::XServiceInfo
> xInfo( xIntFac
, uno::UNO_QUERY
);
2317 uno::Reference
<lang::XSingleServiceFactory
> xFac( xIntFac
, uno::UNO_QUERY
);
2318 if ( xFac
.is() && xInfo
.is() && xInfo
->getImplementationName() == aImplName
)
2322 uno::Reference
<uno::XInterface
> xInterface
= xFac
->createInstance();
2323 uno::Reference
<lang::XInitialization
> xInit( xInterface
, uno::UNO_QUERY
);
2327 uno::Sequence
<uno::Any
> aSeq(4);
2328 uno::Any
* pArray
= aSeq
.getArray();
2329 pArray
[0] <<= rtl::OUString( rDesc
.aParSource
);
2330 pArray
[1] <<= rtl::OUString( rDesc
.aParName
);
2331 pArray
[2] <<= rtl::OUString( rDesc
.aParUser
);
2332 pArray
[3] <<= rtl::OUString( rDesc
.aParPass
);
2333 xInit
->initialize( aSeq
);
2335 xRet
= uno::Reference
<sheet::XDimensionsSupplier
>( xInterface
, uno::UNO_QUERY
);
2337 catch(uno::Exception
&)
2350 // ============================================================================
2352 ScDPCacheCell::ScDPCacheCell() :
2353 mnStrId(ScSimpleSharedString::EMPTY
),
2354 mnType(SC_VALTYPE_EMPTY
),
2360 ScDPCacheCell::ScDPCacheCell(const ScDPCacheCell
& r
) :
2364 mbNumeric(r
.mbNumeric
)
2368 ScDPCacheCell::~ScDPCacheCell()
2372 // ============================================================================
2374 size_t ScDPCollection::CacheCellHash::operator()(const ScDPCacheCell
* pCell
) const
2376 return pCell
->mnStrId
+ static_cast<size_t>(pCell
->mnType
) +
2377 static_cast<size_t>(pCell
->mfValue
) + static_cast<size_t>(pCell
->mbNumeric
);
2380 bool ScDPCollection::CacheCellEqual::operator()(const ScDPCacheCell
* p1
, const ScDPCacheCell
* p2
) const
2385 if ((!p1
&& p2
) || (p1
&& !p2
))
2388 return p1
->mnStrId
== p2
->mnStrId
&& p1
->mfValue
== p2
->mfValue
&&
2389 p1
->mbNumeric
== p2
->mbNumeric
&& p1
->mnType
== p2
->mnType
;
2392 // ----------------------------------------------------------------------------
2394 ScDPCollection::ScDPCollection(ScDocument
* pDocument
) :
2399 ScDPCollection::ScDPCollection(const ScDPCollection
& r
) :
2402 maSharedString(r
.maSharedString
),
2403 maCacheCellPool() // #i101725# don't copy hash_set with pointers from the other collection
2407 ScDPCollection::~ScDPCollection()
2409 clearCacheCellPool();
2412 ScDataObject
* ScDPCollection::Clone() const
2414 return new ScDPCollection(*this);
2417 void ScDPCollection::DeleteOnTab( SCTAB nTab
)
2420 while ( nPos
< nCount
)
2422 // look for output positions on the deleted sheet
2423 if ( static_cast<const ScDPObject
*>(At(nPos
))->GetOutRange().aStart
.Tab() == nTab
)
2430 void ScDPCollection::UpdateReference( UpdateRefMode eUpdateRefMode
,
2431 const ScRange
& r
, SCsCOL nDx
, SCsROW nDy
, SCsTAB nDz
)
2433 for (USHORT i
=0; i
<nCount
; i
++)
2434 ((ScDPObject
*)At(i
))->UpdateReference( eUpdateRefMode
, r
, nDx
, nDy
, nDz
);
2437 BOOL
ScDPCollection::RefsEqual( const ScDPCollection
& r
) const
2439 if ( nCount
!= r
.nCount
)
2442 for (USHORT i
=0; i
<nCount
; i
++)
2443 if ( ! ((const ScDPObject
*)At(i
))->RefsEqual( *((const ScDPObject
*)r
.At(i
)) ) )
2446 return TRUE
; // all equal
2449 void ScDPCollection::WriteRefsTo( ScDPCollection
& r
) const
2451 if ( nCount
== r
.nCount
)
2453 //! assert equal names?
2454 for (USHORT i
=0; i
<nCount
; i
++)
2455 ((const ScDPObject
*)At(i
))->WriteRefsTo( *((ScDPObject
*)r
.At(i
)) );
2459 // #i8180# If data pilot tables were deleted with their sheet,
2460 // this collection contains extra entries that must be restored.
2461 // Matching objects are found by their names.
2463 DBG_ASSERT( nCount
>= r
.nCount
, "WriteRefsTo: missing entries in document" );
2464 for (USHORT nSourcePos
=0; nSourcePos
<nCount
; nSourcePos
++)
2466 const ScDPObject
* pSourceObj
= static_cast<const ScDPObject
*>(At(nSourcePos
));
2467 String aName
= pSourceObj
->GetName();
2468 bool bFound
= false;
2469 for (USHORT nDestPos
=0; nDestPos
<r
.nCount
&& !bFound
; nDestPos
++)
2471 ScDPObject
* pDestObj
= static_cast<ScDPObject
*>(r
.At(nDestPos
));
2472 if ( pDestObj
->GetName() == aName
)
2474 pSourceObj
->WriteRefsTo( *pDestObj
); // found object, copy refs
2480 // none found, re-insert deleted object (see ScUndoDataPilot::Undo)
2482 ScDPObject
* pDestObj
= new ScDPObject( *pSourceObj
);
2483 pDestObj
->SetAlive(TRUE
);
2484 if ( !r
.InsertNewTable(pDestObj
) )
2486 DBG_ERROR("cannot insert DPObject");
2487 DELETEZ( pDestObj
);
2491 DBG_ASSERT( nCount
== r
.nCount
, "WriteRefsTo: couldn't restore all entries" );
2495 String
ScDPCollection::CreateNewName( USHORT nMin
) const
2497 String aBase
= String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("DataPilot"));
2500 for (USHORT nAdd
=0; nAdd
<=nCount
; nAdd
++) // nCount+1 tries
2502 String aNewName
= aBase
;
2503 aNewName
+= String::CreateFromInt32( nMin
+ nAdd
);
2504 BOOL bFound
= FALSE
;
2505 for (USHORT i
=0; i
<nCount
&& !bFound
; i
++)
2506 if (((const ScDPObject
*)pItems
[i
])->GetName() == aNewName
)
2509 return aNewName
; // found unused Name
2511 return String(); // should not happen
2514 ScSimpleSharedString
& ScDPCollection::GetSharedString()
2516 return maSharedString
;
2519 void ScDPCollection::FreeTable(ScDPObject
* pDPObj
)
2521 const ScRange
& rOutRange
= pDPObj
->GetOutRange();
2522 const ScAddress
& s
= rOutRange
.aStart
;
2523 const ScAddress
& e
= rOutRange
.aEnd
;
2524 pDoc
->RemoveFlagsTab(s
.Col(), s
.Row(), e
.Col(), e
.Row(), s
.Tab(), SC_MF_DP_TABLE
);
2528 bool ScDPCollection::InsertNewTable(ScDPObject
* pDPObj
)
2530 bool bSuccess
= Insert(pDPObj
);
2533 const ScRange
& rOutRange
= pDPObj
->GetOutRange();
2534 const ScAddress
& s
= rOutRange
.aStart
;
2535 const ScAddress
& e
= rOutRange
.aEnd
;
2536 pDoc
->ApplyFlagsTab(s
.Col(), s
.Row(), e
.Col(), e
.Row(), s
.Tab(), SC_MF_DP_TABLE
);
2541 bool ScDPCollection::HasDPTable(SCCOL nCol
, SCROW nRow
, SCTAB nTab
) const
2543 const ScMergeFlagAttr
* pMergeAttr
= static_cast<const ScMergeFlagAttr
*>(
2544 pDoc
->GetAttr(nCol
, nRow
, nTab
, ATTR_MERGE_FLAG
));
2549 return pMergeAttr
->HasDPTable();
2552 ScDPCacheCell
* ScDPCollection::getCacheCellFromPool(const ScDPCacheCell
& rCell
)
2554 ScDPCacheCell
aCell(rCell
);
2555 CacheCellPoolType::iterator itr
= maCacheCellPool
.find(&aCell
);
2556 if (itr
== maCacheCellPool
.end())
2558 // Insert a new instance.
2559 ScDPCacheCell
* p
= new ScDPCacheCell(rCell
);
2560 ::std::pair
<CacheCellPoolType::iterator
, bool> r
=
2561 maCacheCellPool
.insert(p
);
2565 ScDPCacheCell
* p2
= r
.second
? *r
.first
: NULL
;
2566 DBG_ASSERT(p
== p2
, "ScDPCollection::getCacheCellFromPool: pointer addresses differ");
2574 class DeleteCacheCells
: public ::std::unary_function
<ScDPCacheCell
*, void>
2577 void operator()(ScDPCacheCell
* p
) const
2585 void ScDPCollection::clearCacheCellPool()
2587 // Transferring all stored pointers to a vector first. For some unknown
2588 // reason, deleting cell content instances by directly iterating through
2589 // the hash set causes the iteration to return an identical pointer
2590 // value twice, causing a double-delete. I have no idea why this happens.
2593 using ::std::back_inserter
;
2595 vector
<ScDPCacheCell
*> ps
;
2596 ps
.reserve(maCacheCellPool
.size());
2597 copy(maCacheCellPool
.begin(), maCacheCellPool
.end(), back_inserter(ps
));
2598 maCacheCellPool
.clear();
2599 // for correctness' sake, delete the elements after clearing the hash_set
2600 for_each(ps
.begin(), ps
.end(), DeleteCacheCells());
2603 //------------------------------------------------------------------------
2604 // convert old pivot tables into new datapilot tables
2606 #if OLD_PIVOT_IMPLEMENTATION
2607 void ScDPCollection::ConvertOldTables( ScPivotCollection
& rOldColl
)
2609 // convert old pivot tables into new datapilot tables
2611 USHORT nOldCount
= rOldColl
.GetCount();
2612 for (USHORT i
=0; i
<nOldCount
; i
++)
2614 ScDPObject
* pNewObj
= new ScDPObject(pDoc
);
2615 pNewObj
->InitFromOldPivot( *(rOldColl
)[i
], pDoc
, TRUE
);
2616 pNewObj
->SetAlive( TRUE
);