diff options
Diffstat (limited to 'bf_sc/source/core/data/sc_dpobject.cxx')
-rw-r--r-- | bf_sc/source/core/data/sc_dpobject.cxx | 848 |
1 files changed, 848 insertions, 0 deletions
diff --git a/bf_sc/source/core/data/sc_dpobject.cxx b/bf_sc/source/core/data/sc_dpobject.cxx new file mode 100644 index 000000000..bf5bca697 --- /dev/null +++ b/bf_sc/source/core/data/sc_dpobject.cxx @@ -0,0 +1,848 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#include "dpobject.hxx" +#include "dptabsrc.hxx" +#include "dpsave.hxx" +#include "dpoutput.hxx" +#include "dpshttab.hxx" +#include "dpsdbtab.hxx" +#include "document.hxx" +#include "rechead.hxx" +#include "pivot.hxx" // PIVOT_DATA_FIELD +#include "dapiuno.hxx" // ScDataPilotConversion +#include "miscuno.hxx" +#include "scerrors.hxx" +#include "refupdat.hxx" + +#include <com/sun/star/sheet/GeneralFunction.hpp> +#include <com/sun/star/sheet/DataPilotFieldOrientation.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/lang/XSingleServiceFactory.hpp> +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/container/XContentEnumerationAccess.hpp> + +#include <comphelper/processfactory.hxx> +#include <tools/debug.hxx> +#include <bf_svtools/zforlist.hxx> // IsNumberFormat +#include <legacysmgr/legacy_binfilters_smgr.hxx> +namespace binfilter { +using namespace ::com::sun::star; + +// ----------------------------------------------------------------------- + +#define MAX_LABELS 256 //!!! from fieldwnd.hxx, must be moved to global.hxx + +// ----------------------------------------------------------------------- + +#define SCDPSOURCE_SERVICE "com.sun.star.sheet.DataPilotSource" + +// ----------------------------------------------------------------------- + +// incompatible versions of data pilot files +#define SC_DP_VERSION_CURRENT 6 + +// type of source data +#define SC_DP_SOURCE_SHEET 0 +#define SC_DP_SOURCE_DATABASE 1 +#define SC_DP_SOURCE_SERVICE 2 + +// ----------------------------------------------------------------------- + +//! move to a header file +#define DP_PROP_COLUMNGRAND "ColumnGrand" +#define DP_PROP_FUNCTION "Function" +#define DP_PROP_IGNOREEMPTY "IgnoreEmptyRows" +#define DP_PROP_ISDATALAYOUT "IsDataLayoutDimension" +//#define DP_PROP_ISVISIBLE "IsVisible" +#define DP_PROP_ORIENTATION "Orientation" +#define DP_PROP_ORIGINAL "Original" +#define DP_PROP_POSITION "Position" +#define DP_PROP_REPEATIFEMPTY "RepeatIfEmpty" +#define DP_PROP_ROWGRAND "RowGrand" +#define DP_PROP_SHOWDETAILS "ShowDetails" +#define DP_PROP_SHOWEMPTY "ShowEmpty" +#define DP_PROP_SUBTOTALS "SubTotals" +#define DP_PROP_USEDHIERARCHY "UsedHierarchy" + +// ----------------------------------------------------------------------- + +/*N*/ USHORT lcl_GetDataGetOrientation( const uno::Reference<sheet::XDimensionsSupplier>& xSource ) +/*N*/ { +/*N*/ long nRet = sheet::DataPilotFieldOrientation_HIDDEN; +/*N*/ if ( xSource.is() ) +/*N*/ { +/*N*/ uno::Reference<container::XNameAccess> xDimsName = xSource->getDimensions(); +/*N*/ uno::Reference<container::XIndexAccess> xIntDims = new ScNameToIndexAccess( xDimsName ); +/*N*/ long nIntCount = xIntDims->getCount(); +/*N*/ BOOL bFound = FALSE; +/*N*/ for (long nIntDim=0; nIntDim<nIntCount && !bFound; nIntDim++) +/*N*/ { +/*N*/ uno::Reference<uno::XInterface> xIntDim = +/*N*/ ScUnoHelpFunctions::AnyToInterface( xIntDims->getByIndex(nIntDim) ); +/*N*/ uno::Reference<beans::XPropertySet> xDimProp( xIntDim, uno::UNO_QUERY ); +/*N*/ if ( xDimProp.is() ) +/*N*/ { +/*N*/ bFound = ScUnoHelpFunctions::GetBoolProperty( xDimProp, +/*N*/ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(DP_PROP_ISDATALAYOUT)) ); +/*N*/ //! error checking -- is "IsDataLayoutDimension" property required?? +/*N*/ if (bFound) +/*N*/ nRet = ScUnoHelpFunctions::GetEnumProperty( +/*N*/ xDimProp, ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(DP_PROP_ORIENTATION)), +/*N*/ sheet::DataPilotFieldOrientation_HIDDEN ); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ return nRet; +/*N*/ } + +// ----------------------------------------------------------------------- + +/*N*/ ScDPObject::ScDPObject( ScDocument* pD ) : +/*N*/ pDoc( pD ), +/*N*/ pSaveData( NULL ), +/*N*/ pSheetDesc( NULL ), +/*N*/ pImpDesc( NULL ), +/*N*/ pServDesc( NULL ), +/*N*/ pOutput( NULL ), +/*N*/ bSettingsChanged( FALSE ), +/*N*/ bAlive( FALSE ) +/*N*/ { +/*N*/ } + +/*N*/ ScDPObject::ScDPObject(const ScDPObject& r) : DataObject(r), +/*N*/ pDoc( r.pDoc ), +/*N*/ pSaveData( NULL ), +/*N*/ aTableName( r.aTableName ), +/*N*/ aTableTag( r.aTableTag ), +/*N*/ aOutRange( r.aOutRange ), +/*N*/ pSheetDesc( NULL ), +/*N*/ pImpDesc( NULL ), +/*N*/ pServDesc( NULL ), +/*N*/ pOutput( NULL ), +/*N*/ bSettingsChanged( FALSE ), +/*N*/ bAlive( FALSE ) +/*N*/ { +/*N*/ if (r.pSaveData) +/*N*/ pSaveData = new ScDPSaveData(*r.pSaveData); +/*N*/ if (r.pSheetDesc) +/*N*/ pSheetDesc = new ScSheetSourceDesc(*r.pSheetDesc); +/*N*/ if (r.pImpDesc) +/*N*/ pImpDesc = new ScImportSourceDesc(*r.pImpDesc); +/*N*/ if (r.pServDesc) +/*N*/ pServDesc = new ScDPServiceDesc(*r.pServDesc); +/*N*/ // xSource (and pOutput) is not copied +/*N*/ } + +/*N*/ ScDPObject::~ScDPObject() +/*N*/ { +/*N*/ delete pOutput; +/*N*/ delete pSaveData; +/*N*/ delete pSheetDesc; +/*N*/ delete pImpDesc; +/*N*/ delete pServDesc; +/*N*/ } + +/*N*/ void ScDPObject::SetAlive(BOOL bSet) +/*N*/ { +/*N*/ bAlive = bSet; +/*N*/ } + +/*N*/ void ScDPObject::SetSaveData(const ScDPSaveData& rData) +/*N*/ { +/*N*/ delete pSaveData; +/*N*/ pSaveData = new ScDPSaveData( rData ); +/*N*/ +/*N*/ InvalidateData(); // re-init source from SaveData +/*N*/ } + +/*N*/ void ScDPObject::SetOutRange(const ScRange& rRange) +/*N*/ { +/*N*/ aOutRange = rRange; +/*N*/ +/*N*/ if ( pOutput ) +/*N*/ pOutput->SetPosition( rRange.aStart ); +/*N*/ } + +/*N*/ void ScDPObject::SetSheetDesc(const ScSheetSourceDesc& rDesc) +/*N*/ { +/*N*/ DELETEZ( pImpDesc ); +/*N*/ DELETEZ( pServDesc ); +/*N*/ +/*N*/ delete pImpDesc; +/*N*/ pSheetDesc = new ScSheetSourceDesc(rDesc); +/*N*/ +/*N*/ // make valid QueryParam +/*N*/ +/*N*/ pSheetDesc->aQueryParam.nCol1 = pSheetDesc->aSourceRange.aStart.Col(); +/*N*/ pSheetDesc->aQueryParam.nRow1 = pSheetDesc->aSourceRange.aStart.Row(); +/*N*/ pSheetDesc->aQueryParam.nCol2 = pSheetDesc->aSourceRange.aEnd.Col(); +/*N*/ pSheetDesc->aQueryParam.nRow2 = pSheetDesc->aSourceRange.aEnd.Row();; +/*N*/ pSheetDesc->aQueryParam.bHasHeader = TRUE; +/*N*/ /*USHORT nCount =*/ pSheetDesc->aQueryParam.GetEntryCount(); +/*N*/ +/*N*/ InvalidateSource(); // new source must be created +/*N*/ } + +/*N*/ BOOL ScDPObject::IsSheetData() const +/*N*/ { +/*N*/ return ( pSheetDesc != NULL ); +/*N*/ } + +/*N*/ void ScDPObject::SetName(const String& rNew) +/*N*/ { +/*N*/ aTableName = rNew; +/*N*/ } + +/*N*/ void ScDPObject::SetTag(const String& rNew) +/*N*/ { +/*N*/ aTableTag = rNew; +/*N*/ } + + + +/*N*/ void ScDPObject::CreateObjects() +/*N*/ { +/*N*/ if (!xSource.is()) +/*N*/ { +/*N*/ //! cache DPSource and/or Output? +/*N*/ +/*N*/ DBG_ASSERT( bAlive, "CreateObjects on non-inserted DPObject" ); +/*N*/ +/*N*/ DELETEZ( pOutput ); // not valid when xSource is changed +/*N*/ +/*N*/ if ( !xSource.is() ) // sheet data or error in above cases +/*N*/ { +/*N*/ DBG_ASSERT( !pImpDesc && !pServDesc, "DPSource could not be created" ); +/*N*/ if (!pSheetDesc) +/*N*/ { +/*?*/ OSL_FAIL("no source descriptor"); +/*?*/ pSheetDesc = new ScSheetSourceDesc; // dummy defaults +/*N*/ } +/*N*/ ScSheetDPData* pData = new ScSheetDPData( pDoc, *pSheetDesc ); +/*N*/ xSource = new ScDPSource( pData ); +/*N*/ } +/*N*/ +/*N*/ if (pSaveData) +/*N*/ pSaveData->WriteToSource( xSource ); +/*N*/ } +/*N*/ else if (bSettingsChanged) +/*N*/ { +/*?*/ DELETEZ( pOutput ); // not valid when xSource is changed +/*?*/ +/*?*/ uno::Reference<util::XRefreshable> xRef( xSource, uno::UNO_QUERY ); +/*?*/ if (xRef.is()) +/*?*/ { +/*?*/ try +/*?*/ { +/*?*/ xRef->refresh(); +/*?*/ } +/*?*/ catch(uno::Exception&) +/*?*/ { +/*?*/ OSL_FAIL("exception in refresh"); +/*?*/ } +/*?*/ } +/*?*/ +/*?*/ if (pSaveData) +/*?*/ pSaveData->WriteToSource( xSource ); +/*N*/ } +/*N*/ bSettingsChanged = FALSE; +/*N*/ } + +/*N*/ void ScDPObject::InvalidateData() +/*N*/ { +/*N*/ bSettingsChanged = TRUE; +/*N*/ } + +/*N*/ void ScDPObject::InvalidateSource() +/*N*/ { +/*N*/ xSource = NULL; +/*N*/ } + + + +/*N*/ USHORT lcl_FirstSubTotal( const uno::Reference<beans::XPropertySet>& xDimProp ) // PIVOT_FUNC mask +/*N*/ { +/*N*/ uno::Reference<sheet::XHierarchiesSupplier> xDimSupp( xDimProp, uno::UNO_QUERY ); +/*N*/ if ( xDimProp.is() && xDimSupp.is() ) +/*N*/ { +/*N*/ uno::Reference<container::XIndexAccess> xHiers = new ScNameToIndexAccess( xDimSupp->getHierarchies() ); +/*N*/ long nHierarchy = ScUnoHelpFunctions::GetLongProperty( xDimProp, +/*N*/ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(DP_PROP_USEDHIERARCHY)) ); +/*N*/ if ( nHierarchy >= xHiers->getCount() ) +/*N*/ nHierarchy = 0; +/*N*/ +/*N*/ uno::Reference<uno::XInterface> xHier = ScUnoHelpFunctions::AnyToInterface( +/*N*/ xHiers->getByIndex(nHierarchy) ); +/*N*/ uno::Reference<sheet::XLevelsSupplier> xHierSupp( xHier, uno::UNO_QUERY ); +/*N*/ if ( xHierSupp.is() ) +/*N*/ { +/*N*/ uno::Reference<container::XIndexAccess> xLevels = new ScNameToIndexAccess( xHierSupp->getLevels() ); +/*N*/ uno::Reference<uno::XInterface> xLevel = +/*N*/ ScUnoHelpFunctions::AnyToInterface( xLevels->getByIndex( 0 ) ); +/*N*/ uno::Reference<beans::XPropertySet> xLevProp( xLevel, uno::UNO_QUERY ); +/*N*/ if ( xLevProp.is() ) +/*N*/ { +/*N*/ uno::Any aSubAny; +/*N*/ try +/*N*/ { +/*N*/ aSubAny = xLevProp->getPropertyValue( +/*N*/ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(DP_PROP_SUBTOTALS)) ); +/*N*/ } +/*N*/ catch(uno::Exception&) +/*N*/ { +/*N*/ } +/*N*/ uno::Sequence<sheet::GeneralFunction> aSeq; +/*N*/ if ( aSubAny >>= aSeq ) +/*N*/ { +/*N*/ USHORT nMask = 0; +/*N*/ const sheet::GeneralFunction* pArray = aSeq.getConstArray(); +/*N*/ long nCount = aSeq.getLength(); +/*N*/ for (long i=0; i<nCount; i++) +/*?*/ nMask |= ScDataPilotConversion::FunctionBit(pArray[i]); +/*N*/ return nMask; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ +/*?*/ OSL_FAIL("FirstSubTotal: NULL"); +/*?*/ return 0; +/*N*/ } + +/*N*/ USHORT lcl_CountBits( USHORT nBits ) +/*N*/ { +/*N*/ if (!nBits) return 0; +/*N*/ +/*N*/ USHORT nCount = 0; +/*N*/ USHORT nMask = 1; +/*N*/ for (USHORT i=0; i<16; i++) +/*N*/ { +/*N*/ if ( nBits & nMask ) +/*N*/ ++nCount; +/*N*/ nMask <<= 1; +/*N*/ } +/*N*/ return nCount; +/*N*/ } + +/*N*/ USHORT lcl_FillOldFields( PivotField* pFields, +/*N*/ const uno::Reference<sheet::XDimensionsSupplier>& xSource, +/*N*/ USHORT nOrient, USHORT nColAdd, BOOL bAddData ) +/*N*/ { +/*N*/ USHORT nOutCount = 0; +/*N*/ BOOL bDataFound = FALSE; +/*N*/ +/*N*/ //! merge multiple occurrences (data field with different functions) +/*N*/ //! force data field in one dimension +/*N*/ +/*N*/ long nPos[PIVOT_MAXFIELD]; +/*N*/ +/*N*/ uno::Reference<container::XNameAccess> xDimsName = xSource->getDimensions(); +/*N*/ uno::Reference<container::XIndexAccess> xDims = new ScNameToIndexAccess( xDimsName ); +/*N*/ long nDimCount = xDims->getCount(); +/*N*/ for (long nDim=0; nDim < nDimCount && nOutCount < PIVOT_MAXFIELD; nDim++) +/*N*/ { +/*N*/ uno::Reference<uno::XInterface> xIntDim = +/*N*/ ScUnoHelpFunctions::AnyToInterface( xDims->getByIndex(nDim) ); +/*N*/ uno::Reference<beans::XPropertySet> xDimProp( xIntDim, uno::UNO_QUERY ); +/*N*/ long nDimOrient = ScUnoHelpFunctions::GetEnumProperty( +/*N*/ xDimProp, ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(DP_PROP_ORIENTATION)), +/*N*/ sheet::DataPilotFieldOrientation_HIDDEN ); +/*N*/ if ( xDimProp.is() && nDimOrient == nOrient ) +/*N*/ { +/*N*/ USHORT nMask = 0; +/*N*/ if ( nOrient == sheet::DataPilotFieldOrientation_DATA ) +/*N*/ { +/*N*/ sheet::GeneralFunction eFunc = (sheet::GeneralFunction)ScUnoHelpFunctions::GetEnumProperty( +/*N*/ xDimProp, ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(DP_PROP_FUNCTION)), +/*N*/ sheet::GeneralFunction_NONE ); +/*N*/ if ( eFunc == sheet::GeneralFunction_AUTO ) +/*N*/ { +/*N*/ //! test for numeric data +/*?*/ eFunc = sheet::GeneralFunction_SUM; +/*N*/ } +/*N*/ nMask = ScDataPilotConversion::FunctionBit(eFunc); +/*N*/ } +/*N*/ else +/*N*/ nMask = lcl_FirstSubTotal( xDimProp ); // from first hierarchy +/*N*/ +/*N*/ BOOL bDataLayout = ScUnoHelpFunctions::GetBoolProperty( xDimProp, +/*N*/ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(DP_PROP_ISDATALAYOUT)) ); +/*N*/ uno::Any aOrigAny; +/*N*/ try +/*N*/ { +/*N*/ aOrigAny = xDimProp->getPropertyValue( +/*N*/ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(DP_PROP_ORIGINAL)) ); +/*N*/ } +/*N*/ catch(uno::Exception&) +/*N*/ { +/*N*/ } +/*N*/ +/*N*/ long nDupSource = -1; +/*N*/ uno::Reference<uno::XInterface> xIntOrig = ScUnoHelpFunctions::AnyToInterface( aOrigAny ); +/*N*/ +/*N*/ BOOL bDupUsed = FALSE; +/*N*/ if ( nDupSource >= 0 ) +/*N*/ { +/*?*/ // add function bit to previous entry +/*?*/ +/*?*/ short nCompCol; +/*?*/ if ( bDataLayout ) +/*?*/ nCompCol = PIVOT_DATA_FIELD; +/*?*/ else +/*?*/ nCompCol = (short)(nDupSource+nColAdd); //! seek source column from name +/*?*/ +/*?*/ for (USHORT nOld=0; nOld<nOutCount && !bDupUsed; nOld++) +/*?*/ if ( pFields[nOld].nCol == nCompCol ) +/*?*/ { +/*?*/ // add to previous column only if new bits aren't already set there +/*?*/ if ( ( pFields[nOld].nFuncMask & nMask ) == 0 ) +/*?*/ { +/*?*/ pFields[nOld].nFuncMask |= nMask; +/*?*/ pFields[nOld].nFuncCount = lcl_CountBits( pFields[nOld].nFuncMask ); +/*?*/ bDupUsed = TRUE; +/*?*/ } +/*?*/ } +/*N*/ } +/*N*/ +/*N*/ if ( !bDupUsed ) // also for duplicated dim if original has different orientation +/*N*/ { +/*N*/ if ( bDataLayout ) +/*N*/ { +/*N*/ pFields[nOutCount].nCol = PIVOT_DATA_FIELD; +/*N*/ bDataFound = TRUE; +/*N*/ } +/*N*/ else if ( nDupSource >= 0 ) // if source was not found (different orientation) +/*?*/ pFields[nOutCount].nCol = (short)(nDupSource+nColAdd); //! seek from name +/*N*/ else +/*N*/ pFields[nOutCount].nCol = (short)(nDim+nColAdd); //! seek source column from name +/*N*/ +/*N*/ pFields[nOutCount].nFuncMask = nMask; +/*N*/ pFields[nOutCount].nFuncCount = lcl_CountBits( nMask ); +/*N*/ nPos[nOutCount] = ScUnoHelpFunctions::GetLongProperty( xDimProp, +/*N*/ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(DP_PROP_POSITION)) ); +/*N*/ ++nOutCount; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ // sort by getPosition() value +/*N*/ +/*N*/ for (long i=0; i+1<nOutCount; i++) +/*N*/ { +/*N*/ for (long j=0; j+i+1<nOutCount; j++) +/*N*/ if ( nPos[j+1] < nPos[j] ) +/*N*/ { +/*?*/ long nTemp = nPos[j+1]; +/*?*/ nPos[j+1] = nPos[j]; +/*?*/ nPos[j] = nTemp; +/*?*/ PivotField aField = pFields[j+1]; +/*?*/ pFields[j+1] = pFields[j]; +/*?*/ pFields[j] = aField; +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ if ( bAddData && !bDataFound ) +/*N*/ { +/*?*/ if ( nOutCount >= PIVOT_MAXFIELD ) // space for data field? +/*?*/ --nOutCount; //! error? +/*?*/ pFields[nOutCount].nCol = PIVOT_DATA_FIELD; +/*?*/ pFields[nOutCount].nFuncMask = 0; +/*?*/ pFields[nOutCount].nFuncCount = 0; +/*?*/ ++nOutCount; +/*N*/ } +/*N*/ +/*N*/ return nOutCount; +/*N*/ } + +/*N*/ BOOL ScDPObject::LoadNew(SvStream& rStream, ScMultipleReadHeader& rHdr ) +/*N*/ { +/*N*/ rHdr.StartEntry(); +/*N*/ +/*N*/ DELETEZ( pImpDesc ); +/*N*/ DELETEZ( pSheetDesc ); +/*N*/ DELETEZ( pServDesc ); +/*N*/ +/*N*/ BYTE nType; +/*N*/ rStream >> nType; +/*N*/ switch (nType) +/*N*/ { +/*N*/ case SC_DP_SOURCE_DATABASE: +/*N*/ pImpDesc = new ScImportSourceDesc; +/*N*/ pImpDesc->aDBName = rStream.ReadUniOrByteString( rStream.GetStreamCharSet() ); +/*N*/ pImpDesc->aObject = rStream.ReadUniOrByteString( rStream.GetStreamCharSet() ); +/*N*/ rStream >> pImpDesc->nType; // USHORT +/*N*/ rStream >> pImpDesc->bNative; +/*N*/ break; +/*N*/ +/*N*/ case SC_DP_SOURCE_SHEET: +/*N*/ pSheetDesc = new ScSheetSourceDesc; +/*N*/ rStream >> pSheetDesc->aSourceRange; +/*N*/ pSheetDesc->aQueryParam.Load( rStream ); +/*N*/ break; +/*N*/ +/*N*/ case SC_DP_SOURCE_SERVICE: +/*N*/ { +/*N*/ String aServiceName, aParSource, aParName, aParUser, aParPass; +/*N*/ aServiceName = rStream.ReadUniOrByteString( rStream.GetStreamCharSet() ); +/*N*/ aParSource = rStream.ReadUniOrByteString( rStream.GetStreamCharSet() ); +/*N*/ aParName = rStream.ReadUniOrByteString( rStream.GetStreamCharSet() ); +/*N*/ aParUser = rStream.ReadUniOrByteString( rStream.GetStreamCharSet() ); +/*N*/ aParPass = rStream.ReadUniOrByteString( rStream.GetStreamCharSet() ); +/*N*/ pServDesc = new ScDPServiceDesc( aServiceName, +/*N*/ aParSource, aParName, aParUser, aParPass ); +/*N*/ } +/*N*/ break; +/*N*/ +/*N*/ default: +/*N*/ OSL_FAIL("unknown source type"); +/*N*/ } +/*N*/ +/*N*/ rStream >> aOutRange; +/*N*/ +/*N*/ SetSaveData(ScDPSaveData()); +/*N*/ pSaveData->Load( rStream ); +/*N*/ +/*N*/ if (rHdr.BytesLeft()) // additional data starting from 561b +/*N*/ { +/*N*/ aTableName = rStream.ReadUniOrByteString( rStream.GetStreamCharSet() ); +/*N*/ aTableTag = rStream.ReadUniOrByteString( rStream.GetStreamCharSet() ); +/*N*/ } +/*N*/ +/*N*/ rHdr.EndEntry(); +/*N*/ return TRUE; +/*N*/ } + +/*N*/ BOOL ScDPObject::FillOldParam(ScPivotParam& rParam, BOOL bForFile) const +/*N*/ { +/*N*/ ((ScDPObject*)this)->CreateObjects(); // xSource is needed for field numbers +/*N*/ +/*N*/ rParam.nCol = aOutRange.aStart.Col(); +/*N*/ rParam.nRow = aOutRange.aStart.Row(); +/*N*/ rParam.nTab = aOutRange.aStart.Tab(); +/*N*/ // ppLabelArr / nLabels is not changed +/*N*/ +/*N*/ USHORT nColAdd = 0; +/*N*/ if ( bForFile ) +/*N*/ { +/*N*/ // in old file format, columns are within document, not within source range +/*N*/ +/*N*/ DBG_ASSERT( pSheetDesc, "FillOldParam: bForFile, !pSheetDesc" ); +/*N*/ nColAdd = pSheetDesc->aSourceRange.aStart.Col(); +/*N*/ } +/*N*/ +/*N*/ BOOL bAddData = ( lcl_GetDataGetOrientation( xSource ) == sheet::DataPilotFieldOrientation_HIDDEN ); +/*N*/ rParam.nColCount = lcl_FillOldFields( rParam.aColArr, +/*N*/ xSource, sheet::DataPilotFieldOrientation_COLUMN, nColAdd, bAddData ); +/*N*/ rParam.nRowCount = lcl_FillOldFields( rParam.aRowArr, +/*N*/ xSource, sheet::DataPilotFieldOrientation_ROW, nColAdd, FALSE ); +/*N*/ rParam.nDataCount = lcl_FillOldFields( rParam.aDataArr, +/*N*/ xSource, sheet::DataPilotFieldOrientation_DATA, nColAdd, FALSE ); +/*N*/ +/*N*/ uno::Reference<beans::XPropertySet> xProp( xSource, uno::UNO_QUERY ); +/*N*/ if (xProp.is()) +/*N*/ { +/*N*/ try +/*N*/ { +/*N*/ rParam.bMakeTotalCol = ScUnoHelpFunctions::GetBoolProperty( xProp, +/*N*/ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(DP_PROP_COLUMNGRAND)), TRUE ); +/*N*/ rParam.bMakeTotalRow = ScUnoHelpFunctions::GetBoolProperty( xProp, +/*N*/ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(DP_PROP_ROWGRAND)), TRUE ); +/*N*/ +/*N*/ // following properties may be missing for external sources +/*N*/ rParam.bIgnoreEmptyRows = ScUnoHelpFunctions::GetBoolProperty( xProp, +/*N*/ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(DP_PROP_IGNOREEMPTY)) ); +/*N*/ rParam.bDetectCategories = ScUnoHelpFunctions::GetBoolProperty( xProp, +/*N*/ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(DP_PROP_REPEATIFEMPTY)) ); +/*N*/ } +/*N*/ catch(uno::Exception&) +/*N*/ { +/*N*/ // no error +/*N*/ } +/*N*/ } +/*N*/ return TRUE; +/*N*/ } + + + + +//------------------------------------------------------------------------ +// convert old pivot tables into new datapilot tables + + +// static +/*N*/ void ScDPObject::ConvertOrientation( ScDPSaveData& rSaveData, +/*N*/ PivotField* pFields, USHORT nCount, USHORT nOrient, +/*N*/ ScDocument* pDoc, USHORT nRow, USHORT nTab, +/*N*/ const uno::Reference<sheet::XDimensionsSupplier>& /*xSource*/, +/*N*/ BOOL bOldDefaults, +/*N*/ PivotField* pRefColFields, USHORT nRefColCount, +/*N*/ PivotField* pRefRowFields, USHORT nRefRowCount ) +/*N*/ { +/*N*/ String aDocStr; +/*N*/ ScDPSaveDimension* pDim; +/*N*/ +/*N*/ for (USHORT i=0; i<nCount; i++) +/*N*/ { +/*N*/ USHORT nCol = pFields[i].nCol; +/*N*/ USHORT nFuncs = pFields[i].nFuncMask; +/*N*/ if ( nCol == PIVOT_DATA_FIELD ) +/*N*/ pDim = rSaveData.GetDataLayoutDimension(); +/*N*/ else +/*N*/ { +/*N*/ if ( pDoc ) +/*N*/ pDoc->GetString( nCol, nRow, nTab, aDocStr ); +/*N*/ +/*N*/ if ( aDocStr.Len() ) +/*N*/ pDim = rSaveData.GetDimensionByName(aDocStr); +/*N*/ else +/*?*/ pDim = NULL; +/*N*/ } +/*N*/ +/*N*/ if ( pDim ) +/*N*/ { +/*N*/ if ( nOrient == sheet::DataPilotFieldOrientation_DATA ) // set summary function +/*N*/ { +/*N*/ // generate an individual entry for each function +/*N*/ BOOL bFirst = TRUE; +/*N*/ +/*N*/ // if a dimension is used for column or row and data, +/*N*/ // use duplicated dimensions for all data occurrences +/*N*/ if (pRefColFields) +/*N*/ for (USHORT nRefCol=0; nRefCol<nRefColCount; nRefCol++) +/*N*/ if (pRefColFields[nRefCol].nCol == nCol) +/*?*/ bFirst = FALSE; +/*N*/ if (pRefRowFields) +/*N*/ for (USHORT nRefRow=0; nRefRow<nRefRowCount; nRefRow++) +/*N*/ if (pRefRowFields[nRefRow].nCol == nCol) +/*?*/ bFirst = FALSE; +/*N*/ +/*N*/ // if set via api, a data column may occur several times +/*N*/ // (if the function hasn't been changed yet) -> also look for duplicate data column +/*N*/ for (USHORT nPrevData=0; nPrevData<i; nPrevData++) +/*?*/ if (pFields[nPrevData].nCol == nCol) +/*?*/ bFirst = FALSE; +/*N*/ +/*N*/ USHORT nMask = 1; +/*N*/ for (USHORT nBit=0; nBit<16; nBit++) +/*N*/ { +/*N*/ if ( nFuncs & nMask ) +/*N*/ { +/*N*/ sheet::GeneralFunction eFunc = ScDataPilotConversion::FirstFunc( nMask ); +/*N*/ if (bFirst) +/*N*/ { +/*N*/ pDim->SetOrientation( nOrient ); +/*N*/ pDim->SetFunction( eFunc ); +/*N*/ bFirst = FALSE; +/*N*/ } +/*N*/ else +/*N*/ { +/*?*/ ScDPSaveDimension* pDup = rSaveData.DuplicateDimension(pDim->GetName()); +/*?*/ pDup->SetOrientation( nOrient ); +/*?*/ pDup->SetFunction( eFunc ); +/*N*/ } +/*N*/ } +/*N*/ nMask *= 2; +/*N*/ } +/*N*/ } +/*N*/ else // set SubTotals +/*N*/ { +/*N*/ pDim->SetOrientation( nOrient ); +/*N*/ +/*N*/ USHORT nFuncArray[16]; +/*N*/ USHORT nFuncCount = 0; +/*N*/ USHORT nMask = 1; +/*N*/ for (USHORT nBit=0; nBit<16; nBit++) +/*N*/ { +/*N*/ if ( nFuncs & nMask ) +/*?*/ nFuncArray[nFuncCount++] = ScDataPilotConversion::FirstFunc( nMask ); +/*N*/ nMask *= 2; +/*N*/ } +/*N*/ pDim->SetSubTotals( nFuncCount, nFuncArray ); +/*N*/ +/*N*/ // ShowEmpty was implicit in old tables, +/*N*/ // must be set for data layout dimension (not accessible in dialog) +/*N*/ if ( bOldDefaults || nCol == PIVOT_DATA_FIELD ) +/*N*/ pDim->SetShowEmpty( TRUE ); +/*N*/ } +/*N*/ } +/*N*/ } +} + +/*N*/ void ScDPObject::InitFromOldPivot( const ScPivot& rOld, ScDocument* pInDoc, BOOL bSetSource ) +/*N*/ { +/*N*/ ScDPSaveData aSaveData; +/*N*/ +/*N*/ ScPivotParam aParam; +/*N*/ ScQueryParam aQuery; +/*N*/ ScArea aArea; +/*N*/ rOld.GetParam( aParam, aQuery, aArea ); +/*N*/ +/*N*/ ConvertOrientation( aSaveData, aParam.aColArr, aParam.nColCount, +/*N*/ sheet::DataPilotFieldOrientation_COLUMN, pInDoc, aArea.nRowStart, aArea.nTab, +/*N*/ uno::Reference<sheet::XDimensionsSupplier>(), TRUE ); +/*N*/ ConvertOrientation( aSaveData, aParam.aRowArr, aParam.nRowCount, +/*N*/ sheet::DataPilotFieldOrientation_ROW, pInDoc, aArea.nRowStart, aArea.nTab, +/*N*/ uno::Reference<sheet::XDimensionsSupplier>(), TRUE ); +/*N*/ ConvertOrientation( aSaveData, aParam.aDataArr, aParam.nDataCount, +/*N*/ sheet::DataPilotFieldOrientation_DATA, pInDoc, aArea.nRowStart, aArea.nTab, +/*N*/ uno::Reference<sheet::XDimensionsSupplier>(), TRUE, +/*N*/ aParam.aColArr, aParam.nColCount, aParam.aRowArr, aParam.nRowCount ); +/*N*/ +/*N*/ aSaveData.SetIgnoreEmptyRows( rOld.GetIgnoreEmpty() ); +/*N*/ aSaveData.SetRepeatIfEmpty( rOld.GetDetectCat() ); +/*N*/ aSaveData.SetColumnGrand( rOld.GetMakeTotalCol() ); +/*N*/ aSaveData.SetRowGrand( rOld.GetMakeTotalRow() ); +/*N*/ +/*N*/ SetSaveData( aSaveData ); +/*N*/ if (bSetSource) +/*N*/ { +/*N*/ ScSheetSourceDesc aDesc; +/*N*/ aDesc.aSourceRange = rOld.GetSrcArea(); +/*N*/ rOld.GetQuery( aDesc.aQueryParam ); +/*N*/ SetSheetDesc( aDesc ); +/*N*/ } +/*N*/ SetOutRange( rOld.GetDestArea() ); +/*N*/ +/*N*/ aTableName = rOld.GetName(); +/*N*/ aTableTag = rOld.GetTag(); +/*N*/ } + +// ----------------------------------------------------------------------- + +// static + +// static + +// static + +// ----------------------------------------------------------------------- + +/*N*/ ScDPCollection::ScDPCollection(ScDocument* pDocument) : +/*N*/ pDoc( pDocument ) +/*N*/ { +/*N*/ } + +/*N*/ ScDPCollection::ScDPCollection(const ScDPCollection& r) : +/*N*/ Collection(r), +/*N*/ pDoc(r.pDoc) +/*N*/ { +/*N*/ } + +/*N*/ ScDPCollection::~ScDPCollection() +/*N*/ { +/*N*/ } + +/*N*/ BOOL ScDPCollection::LoadNew( SvStream& rStream ) +/*N*/ { +/*N*/ BOOL bSuccess = TRUE; +/*N*/ +/*N*/ FreeAll(); +/*N*/ ScMultipleReadHeader aHdr( rStream ); +/*N*/ +/*N*/ long nVer; +/*N*/ rStream >> nVer; +/*N*/ +/*N*/ // check for all supported versions here.. +/*N*/ +/*N*/ if ( nVer != SC_DP_VERSION_CURRENT ) +/*N*/ { +/*N*/ OSL_FAIL("skipping unknown version of data pilot obejct"); +/*N*/ if ( rStream.GetError() == SVSTREAM_OK ) +/*N*/ rStream.SetError( SCWARN_IMPORT_INFOLOST ); +/*N*/ return FALSE; +/*N*/ } +/*N*/ +/*N*/ long nNewCount; +/*N*/ rStream >> nNewCount; +/*N*/ for (long i=0; i<nNewCount; i++) +/*N*/ { +/*N*/ ScDPObject* pObj = new ScDPObject( pDoc ); +/*N*/ if ( pObj->LoadNew(rStream, aHdr) ) +/*N*/ { +/*N*/ pObj->SetAlive( TRUE ); +/*N*/ Insert( pObj ); +/*N*/ } +/*N*/ else +/*N*/ delete pObj; +/*N*/ } +/*N*/ +/*N*/ return bSuccess; +/*N*/ } + +/*N*/ String ScDPCollection::CreateNewName( USHORT nMin ) const +/*N*/ { +/*N*/ String aBase = String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("DataPilot")); +/*N*/ //! from Resource? +/*N*/ +/*N*/ for (USHORT nAdd=0; nAdd<=nCount; nAdd++) // nCount+1 tries +/*N*/ { +/*N*/ String aNewName = aBase; +/*N*/ aNewName += String::CreateFromInt32( nMin + nAdd ); +/*N*/ BOOL bFound = FALSE; +/*N*/ for (USHORT i=0; i<nCount && !bFound; i++) +/*N*/ if (((const ScDPObject*)pItems[i])->GetName() == aNewName) +/*N*/ bFound = TRUE; +/*N*/ if (!bFound) +/*N*/ return aNewName; // found unused Name +/*N*/ } +/*N*/ return String(); // should not happen +/*N*/ } + +/*N*/ void ScDPCollection::EnsureNames() +/*N*/ { +/*N*/ for (USHORT i=0; i<nCount; i++) +/*N*/ if (!((const ScDPObject*)At(i))->GetName().Len()) +/*?*/ ((ScDPObject*)At(i))->SetName( CreateNewName() ); +/*N*/ } + +//------------------------------------------------------------------------ +// convert old pivot tables into new datapilot tables + +/*N*/ void ScDPCollection::ConvertOldTables( ScPivotCollection& rOldColl ) +/*N*/ { +/*N*/ // convert old pivot tables into new datapilot tables +/*N*/ +/*N*/ USHORT nOldCount = rOldColl.GetCount(); +/*N*/ for (USHORT i=0; i<nOldCount; i++) +/*N*/ { +/*N*/ ScDPObject* pNewObj = new ScDPObject(pDoc); +/*N*/ pNewObj->InitFromOldPivot( *(rOldColl)[i], pDoc, TRUE ); +/*N*/ pNewObj->SetAlive( TRUE ); +/*N*/ Insert( pNewObj ); +/*N*/ } +/*N*/ rOldColl.FreeAll(); +/*N*/ } + + + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |