2000-09-18 23:16:46 +00:00
|
|
|
/*************************************************************************
|
|
|
|
*
|
2005-09-08 17:23:14 +00:00
|
|
|
* OpenOffice.org - a multi-platform office productivity suite
|
2000-09-18 23:16:46 +00:00
|
|
|
*
|
2005-09-08 17:23:14 +00:00
|
|
|
* $RCSfile: dpoutput.cxx,v $
|
2000-09-18 23:16:46 +00:00
|
|
|
*
|
2005-09-08 17:23:14 +00:00
|
|
|
* $Revision: 1.11 $
|
2000-09-18 23:16:46 +00:00
|
|
|
*
|
2005-09-08 17:23:14 +00:00
|
|
|
* last change: $Author: rt $ $Date: 2005-09-08 18:23:13 $
|
2000-09-18 23:16:46 +00:00
|
|
|
*
|
2005-09-08 17:23:14 +00:00
|
|
|
* The Contents of this file are made available subject to
|
|
|
|
* the terms of GNU Lesser General Public License Version 2.1.
|
2000-09-18 23:16:46 +00:00
|
|
|
*
|
|
|
|
*
|
2005-09-08 17:23:14 +00:00
|
|
|
* GNU Lesser General Public License Version 2.1
|
|
|
|
* =============================================
|
|
|
|
* Copyright 2005 by Sun Microsystems, Inc.
|
|
|
|
* 901 San Antonio Road, Palo Alto, CA 94303, USA
|
2000-09-18 23:16:46 +00:00
|
|
|
*
|
2005-09-08 17:23:14 +00:00
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License version 2.1, as published by the Free Software Foundation.
|
2000-09-18 23:16:46 +00:00
|
|
|
*
|
2005-09-08 17:23:14 +00:00
|
|
|
* This library 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 for more details.
|
2000-09-18 23:16:46 +00:00
|
|
|
*
|
2005-09-08 17:23:14 +00:00
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
|
|
|
* MA 02111-1307 USA
|
2000-09-18 23:16:46 +00:00
|
|
|
*
|
|
|
|
************************************************************************/
|
|
|
|
|
|
|
|
#ifdef PCH
|
|
|
|
#include "core_pch.hxx"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#pragma hdrstop
|
|
|
|
|
|
|
|
// INCLUDE ---------------------------------------------------------------
|
|
|
|
|
|
|
|
#include "scitems.hxx"
|
|
|
|
#include <svx/algitem.hxx>
|
|
|
|
#include <svx/boxitem.hxx>
|
|
|
|
#include <svx/brshitem.hxx>
|
|
|
|
#include <svx/wghtitem.hxx>
|
|
|
|
|
|
|
|
#include "dpoutput.hxx"
|
|
|
|
#include "document.hxx"
|
|
|
|
#include "patattr.hxx"
|
|
|
|
#include "docpool.hxx"
|
|
|
|
#include "markdata.hxx"
|
|
|
|
#include "attrib.hxx"
|
2004-03-08 10:44:31 +00:00
|
|
|
#include "errorcodes.hxx" // errNoValue
|
2000-09-18 23:16:46 +00:00
|
|
|
#include "miscuno.hxx"
|
|
|
|
#include "globstr.hrc"
|
|
|
|
#include "stlpool.hxx"
|
|
|
|
#include "stlsheet.hxx"
|
2004-07-23 11:53:00 +00:00
|
|
|
#include "collect.hxx"
|
2004-04-13 11:25:50 +00:00
|
|
|
#include "scresid.hxx"
|
|
|
|
#include "sc.hrc"
|
2000-09-18 23:16:46 +00:00
|
|
|
|
|
|
|
#include <com/sun/star/sheet/XLevelsSupplier.hpp>
|
|
|
|
#include <com/sun/star/sheet/XHierarchiesSupplier.hpp>
|
|
|
|
#include <com/sun/star/sheet/XDataPilotResults.hpp>
|
|
|
|
#include <com/sun/star/sheet/XDataPilotMemberResults.hpp>
|
|
|
|
#include <com/sun/star/sheet/DataResultFlags.hpp>
|
|
|
|
#include <com/sun/star/sheet/MemberResultFlags.hpp>
|
|
|
|
#include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
|
2004-04-13 11:25:50 +00:00
|
|
|
#include <com/sun/star/sheet/TableFilterField.hpp>
|
2000-09-18 23:16:46 +00:00
|
|
|
#include <com/sun/star/container/XNamed.hpp>
|
|
|
|
|
|
|
|
using namespace com::sun::star;
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
//! move to a header file
|
2004-04-13 11:25:50 +00:00
|
|
|
//! use names from unonames.hxx?
|
2000-09-18 23:16:46 +00:00
|
|
|
#define DP_PROP_ORIENTATION "Orientation"
|
|
|
|
#define DP_PROP_POSITION "Position"
|
|
|
|
#define DP_PROP_USEDHIERARCHY "UsedHierarchy"
|
|
|
|
#define DP_PROP_DATADESCR "DataDescription"
|
|
|
|
#define DP_PROP_ISDATALAYOUT "IsDataLayoutDimension"
|
|
|
|
#define DP_PROP_NUMBERFORMAT "NumberFormat"
|
2004-04-13 11:25:50 +00:00
|
|
|
#define DP_PROP_FILTER "Filter"
|
2000-09-18 23:16:46 +00:00
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
//! dynamic!!!
|
|
|
|
#define SC_DPOUT_MAXLEVELS 256
|
|
|
|
|
|
|
|
|
|
|
|
struct ScDPOutLevelData
|
|
|
|
{
|
|
|
|
long nDim;
|
|
|
|
long nHier;
|
|
|
|
long nLevel;
|
|
|
|
long nDimPos;
|
|
|
|
uno::Sequence<sheet::MemberResult> aResult;
|
|
|
|
String aCaption;
|
|
|
|
|
|
|
|
ScDPOutLevelData() { nDim = nHier = nLevel = nDimPos = -1; }
|
|
|
|
|
|
|
|
BOOL operator<(const ScDPOutLevelData& r) const
|
|
|
|
{ return nDimPos<r.nDimPos || ( nDimPos==r.nDimPos && nHier<r.nHier ) ||
|
|
|
|
( nDimPos==r.nDimPos && nHier==r.nHier && nLevel<r.nLevel ); }
|
|
|
|
|
|
|
|
void Swap(ScDPOutLevelData& r)
|
|
|
|
//! { ScDPOutLevelData aTemp = r; r = *this; *this = aTemp; }
|
|
|
|
{ ScDPOutLevelData aTemp; aTemp = r; r = *this; *this = aTemp; }
|
|
|
|
|
|
|
|
//! bug (73840) in uno::Sequence - copy and then assign doesn't work!
|
|
|
|
};
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
2004-06-04 09:24:29 +00:00
|
|
|
void lcl_SetStyleById( ScDocument* pDoc, SCTAB nTab,
|
|
|
|
SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
|
2000-09-18 23:16:46 +00:00
|
|
|
USHORT nStrId )
|
|
|
|
{
|
|
|
|
if ( nCol1 > nCol2 || nRow1 > nRow2 )
|
|
|
|
{
|
|
|
|
DBG_ERROR("SetStyleById: invalid range");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
String aStyleName = ScGlobal::GetRscString( nStrId );
|
|
|
|
ScStyleSheetPool* pStlPool = pDoc->GetStyleSheetPool();
|
|
|
|
ScStyleSheet* pStyle = (ScStyleSheet*) pStlPool->Find( aStyleName, SFX_STYLE_FAMILY_PARA );
|
|
|
|
if (!pStyle)
|
|
|
|
{
|
|
|
|
// create new style (was in ScPivot::SetStyle)
|
|
|
|
|
|
|
|
pStyle = (ScStyleSheet*) &pStlPool->Make( aStyleName, SFX_STYLE_FAMILY_PARA,
|
|
|
|
SFXSTYLEBIT_USERDEF );
|
|
|
|
pStyle->SetParent( ScGlobal::GetRscString(STR_STYLENAME_STANDARD) );
|
|
|
|
SfxItemSet& rSet = pStyle->GetItemSet();
|
|
|
|
if ( nStrId==STR_PIVOT_STYLE_RESULT || nStrId==STR_PIVOT_STYLE_TITLE )
|
|
|
|
rSet.Put( SvxWeightItem( WEIGHT_BOLD ) );
|
|
|
|
if ( nStrId==STR_PIVOT_STYLE_CATEGORY || nStrId==STR_PIVOT_STYLE_TITLE )
|
|
|
|
rSet.Put( SvxHorJustifyItem( SVX_HOR_JUSTIFY_LEFT ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
pDoc->ApplyStyleAreaTab( nCol1, nRow1, nCol2, nRow2, nTab, *pStyle );
|
|
|
|
}
|
|
|
|
|
2004-06-04 09:24:29 +00:00
|
|
|
void lcl_SetFrame( ScDocument* pDoc, SCTAB nTab,
|
|
|
|
SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
|
2000-09-18 23:16:46 +00:00
|
|
|
USHORT nWidth )
|
|
|
|
{
|
|
|
|
SvxBorderLine aLine;
|
|
|
|
aLine.SetOutWidth(nWidth);
|
|
|
|
SvxBoxItem aBox;
|
|
|
|
aBox.SetLine(&aLine, BOX_LINE_LEFT);
|
|
|
|
aBox.SetLine(&aLine, BOX_LINE_TOP);
|
|
|
|
aBox.SetLine(&aLine, BOX_LINE_RIGHT);
|
|
|
|
aBox.SetLine(&aLine, BOX_LINE_BOTTOM);
|
|
|
|
SvxBoxInfoItem aBoxInfo;
|
|
|
|
aBoxInfo.SetValid(VALID_HORI,FALSE);
|
|
|
|
aBoxInfo.SetValid(VALID_VERT,FALSE);
|
|
|
|
aBoxInfo.SetValid(VALID_DISTANCE,FALSE);
|
|
|
|
|
2001-03-12 08:30:57 +00:00
|
|
|
pDoc->ApplyFrameAreaTab( ScRange( nCol1, nRow1, nTab, nCol2, nRow2, nTab ), &aBox, &aBoxInfo );
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
|
2004-06-04 09:24:29 +00:00
|
|
|
void lcl_AttrArea( ScDocument* pDoc, SCTAB nTab,
|
|
|
|
SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
|
2000-09-18 23:16:46 +00:00
|
|
|
const SfxPoolItem& rItem )
|
|
|
|
{
|
|
|
|
ScPatternAttr aPattern( pDoc->GetPool() );
|
|
|
|
aPattern.GetItemSet().Put( rItem );
|
|
|
|
pDoc->ApplyPatternAreaTab( nCol1,nRow1, nCol2,nRow2, nTab, aPattern );
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
void lcl_FillNumberFormats( UINT32*& rFormats, long& rCount,
|
|
|
|
const uno::Reference<sheet::XDataPilotMemberResults>& xLevRes,
|
|
|
|
const uno::Reference<container::XIndexAccess>& xDims )
|
|
|
|
{
|
|
|
|
if ( rFormats )
|
|
|
|
return; // already set
|
|
|
|
|
|
|
|
// xLevRes is from the data layout dimension
|
|
|
|
//! use result sequence from ScDPOutLevelData!
|
|
|
|
|
|
|
|
uno::Sequence<sheet::MemberResult> aResult = xLevRes->getResults();
|
|
|
|
|
|
|
|
long nSize = aResult.getLength();
|
|
|
|
if (nSize)
|
|
|
|
{
|
|
|
|
// get names/formats for all data dimensions
|
|
|
|
//! merge this with the loop to collect ScDPOutLevelData?
|
|
|
|
|
|
|
|
String aDataNames[SC_DPOUT_MAXLEVELS];
|
|
|
|
UINT32 nDataFormats[SC_DPOUT_MAXLEVELS];
|
|
|
|
long nDataCount = 0;
|
|
|
|
BOOL bAnySet = FALSE;
|
|
|
|
|
|
|
|
long nDimCount = xDims->getCount();
|
|
|
|
for (long nDim=0; nDim<nDimCount; nDim++)
|
|
|
|
{
|
|
|
|
uno::Reference<uno::XInterface> xDim =
|
|
|
|
ScUnoHelpFunctions::AnyToInterface( xDims->getByIndex(nDim) );
|
|
|
|
uno::Reference<beans::XPropertySet> xDimProp( xDim, uno::UNO_QUERY );
|
|
|
|
uno::Reference<container::XNamed> xDimName( xDim, uno::UNO_QUERY );
|
|
|
|
if ( xDimProp.is() && xDimName.is() )
|
|
|
|
{
|
|
|
|
sheet::DataPilotFieldOrientation eDimOrient =
|
|
|
|
(sheet::DataPilotFieldOrientation) ScUnoHelpFunctions::GetEnumProperty(
|
|
|
|
xDimProp, rtl::OUString::createFromAscii(DP_PROP_ORIENTATION),
|
|
|
|
sheet::DataPilotFieldOrientation_HIDDEN );
|
|
|
|
if ( eDimOrient == sheet::DataPilotFieldOrientation_DATA )
|
|
|
|
{
|
|
|
|
aDataNames[nDataCount] = String( xDimName->getName() );
|
|
|
|
long nFormat = ScUnoHelpFunctions::GetLongProperty(
|
|
|
|
xDimProp,
|
|
|
|
rtl::OUString::createFromAscii(DP_PROP_NUMBERFORMAT) );
|
|
|
|
nDataFormats[nDataCount] = nFormat;
|
|
|
|
if ( nFormat != 0 )
|
|
|
|
bAnySet = TRUE;
|
|
|
|
++nDataCount;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( bAnySet ) // forget everything if all formats are 0 (or no data dimensions)
|
|
|
|
{
|
|
|
|
const sheet::MemberResult* pArray = aResult.getConstArray();
|
|
|
|
|
|
|
|
String aName;
|
|
|
|
UINT32* pNumFmt = new UINT32[nSize];
|
|
|
|
if (nDataCount == 1)
|
|
|
|
{
|
|
|
|
// only one data dimension -> use its numberformat everywhere
|
|
|
|
long nFormat = nDataFormats[0];
|
|
|
|
for (long nPos=0; nPos<nSize; nPos++)
|
|
|
|
pNumFmt[nPos] = nFormat;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for (long nPos=0; nPos<nSize; nPos++)
|
|
|
|
{
|
|
|
|
// if CONTINUE bit is set, keep previous name
|
|
|
|
//! keep number format instead!
|
|
|
|
if ( !(pArray[nPos].Flags & sheet::MemberResultFlags::CONTINUE) )
|
|
|
|
aName = String( pArray[nPos].Name );
|
|
|
|
|
|
|
|
UINT32 nFormat = 0;
|
|
|
|
for (long i=0; i<nDataCount; i++)
|
|
|
|
if (aName == aDataNames[i]) //! search more efficiently?
|
|
|
|
{
|
|
|
|
nFormat = nDataFormats[i];
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
pNumFmt[nPos] = nFormat;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
rFormats = pNumFmt;
|
|
|
|
rCount = nSize;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-09-20 12:44:50 +00:00
|
|
|
UINT32 lcl_GetFirstNumberFormat( const uno::Reference<container::XIndexAccess>& xDims )
|
|
|
|
{
|
|
|
|
long nDimCount = xDims->getCount();
|
|
|
|
for (long nDim=0; nDim<nDimCount; nDim++)
|
|
|
|
{
|
|
|
|
uno::Reference<uno::XInterface> xDim =
|
|
|
|
ScUnoHelpFunctions::AnyToInterface( xDims->getByIndex(nDim) );
|
|
|
|
uno::Reference<beans::XPropertySet> xDimProp( xDim, uno::UNO_QUERY );
|
|
|
|
if ( xDimProp.is() )
|
|
|
|
{
|
|
|
|
sheet::DataPilotFieldOrientation eDimOrient =
|
|
|
|
(sheet::DataPilotFieldOrientation) ScUnoHelpFunctions::GetEnumProperty(
|
|
|
|
xDimProp, rtl::OUString::createFromAscii(DP_PROP_ORIENTATION),
|
|
|
|
sheet::DataPilotFieldOrientation_HIDDEN );
|
|
|
|
if ( eDimOrient == sheet::DataPilotFieldOrientation_DATA )
|
|
|
|
{
|
|
|
|
long nFormat = ScUnoHelpFunctions::GetLongProperty(
|
|
|
|
xDimProp,
|
|
|
|
rtl::OUString::createFromAscii(DP_PROP_NUMBERFORMAT) );
|
|
|
|
|
|
|
|
return nFormat; // use format from first found data dimension
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0; // none found
|
|
|
|
}
|
|
|
|
|
2000-09-18 23:16:46 +00:00
|
|
|
void lcl_SortFields( ScDPOutLevelData* pFields, long nFieldCount )
|
|
|
|
{
|
|
|
|
for (long i=0; i+1<nFieldCount; i++)
|
|
|
|
{
|
|
|
|
for (long j=0; j+i+1<nFieldCount; j++)
|
|
|
|
if ( pFields[j+1] < pFields[j] )
|
|
|
|
pFields[j].Swap( pFields[j+1] );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOL lcl_MemberEmpty( const uno::Sequence<sheet::MemberResult>& rSeq )
|
|
|
|
{
|
|
|
|
// used to skip levels that have no members
|
|
|
|
|
|
|
|
long nLen = rSeq.getLength();
|
|
|
|
const sheet::MemberResult* pArray = rSeq.getConstArray();
|
|
|
|
for (long i=0; i<nLen; i++)
|
|
|
|
if (pArray[i].Flags & sheet::MemberResultFlags::HASMEMBER)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
return TRUE; // no member data -> empty
|
|
|
|
}
|
|
|
|
|
2004-04-13 11:25:50 +00:00
|
|
|
uno::Sequence<sheet::MemberResult> lcl_GetSelectedPageAsResult( const uno::Reference<beans::XPropertySet>& xDimProp )
|
|
|
|
{
|
|
|
|
uno::Sequence<sheet::MemberResult> aRet;
|
|
|
|
if ( xDimProp.is() )
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
//! merge with ScDPDimension::setPropertyValue?
|
|
|
|
|
|
|
|
uno::Any aValue = xDimProp->getPropertyValue( rtl::OUString::createFromAscii(DP_PROP_FILTER) );
|
|
|
|
|
|
|
|
uno::Sequence<sheet::TableFilterField> aSeq;
|
|
|
|
if (aValue >>= aSeq)
|
|
|
|
{
|
|
|
|
if ( aSeq.getLength() == 1 )
|
|
|
|
{
|
|
|
|
const sheet::TableFilterField& rField = aSeq[0];
|
|
|
|
if ( rField.Field == 0 && rField.Operator == sheet::FilterOperator_EQUAL && !rField.IsNumeric )
|
|
|
|
{
|
|
|
|
rtl::OUString aSelectedPage( rField.StringValue );
|
|
|
|
//! different name/caption string?
|
|
|
|
sheet::MemberResult aResult( aSelectedPage, aSelectedPage, 0 );
|
|
|
|
aRet = uno::Sequence<sheet::MemberResult>( &aResult, 1 );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// else return empty sequence
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch ( uno::Exception& )
|
|
|
|
{
|
|
|
|
// recent addition - allow source to not handle it (no error)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return aRet;
|
|
|
|
}
|
|
|
|
|
2000-09-18 23:16:46 +00:00
|
|
|
ScDPOutput::ScDPOutput( ScDocument* pD, const uno::Reference<sheet::XDimensionsSupplier>& xSrc,
|
|
|
|
const ScAddress& rPos, BOOL bFilter ) :
|
|
|
|
pDoc( pD ),
|
|
|
|
xSource( xSrc ),
|
|
|
|
aStartPos( rPos ),
|
|
|
|
bDoFilter( bFilter ),
|
|
|
|
bSizesValid( FALSE ),
|
2001-03-08 13:25:49 +00:00
|
|
|
bSizeOverflow( FALSE ),
|
|
|
|
bResultsError( FALSE ),
|
2000-09-18 23:16:46 +00:00
|
|
|
pColNumFmt( NULL ),
|
|
|
|
pRowNumFmt( NULL ),
|
|
|
|
nColFmtCount( 0 ),
|
2004-09-20 12:44:50 +00:00
|
|
|
nRowFmtCount( 0 ),
|
|
|
|
nSingleNumFmt( 0 )
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
2004-06-04 09:24:29 +00:00
|
|
|
nTabStartCol = nMemberStartCol = nDataStartCol = nTabEndCol = 0;
|
|
|
|
nTabStartRow = nMemberStartRow = nDataStartRow = nTabEndRow = 0;
|
2000-09-18 23:16:46 +00:00
|
|
|
|
|
|
|
pColFields = new ScDPOutLevelData[SC_DPOUT_MAXLEVELS];
|
|
|
|
pRowFields = new ScDPOutLevelData[SC_DPOUT_MAXLEVELS];
|
|
|
|
pPageFields = new ScDPOutLevelData[SC_DPOUT_MAXLEVELS];
|
|
|
|
nColFieldCount = 0;
|
|
|
|
nRowFieldCount = 0;
|
|
|
|
nPageFieldCount = 0;
|
|
|
|
|
|
|
|
uno::Reference<sheet::XDataPilotResults> xResult( xSource, uno::UNO_QUERY );
|
|
|
|
if ( xSource.is() && xResult.is() )
|
|
|
|
{
|
|
|
|
// get dimension results:
|
|
|
|
|
|
|
|
uno::Reference<container::XIndexAccess> xDims =
|
|
|
|
new ScNameToIndexAccess( xSource->getDimensions() );
|
|
|
|
long nDimCount = xDims->getCount();
|
|
|
|
for (long nDim=0; nDim<nDimCount; nDim++)
|
|
|
|
{
|
|
|
|
uno::Reference<uno::XInterface> xDim =
|
|
|
|
ScUnoHelpFunctions::AnyToInterface( xDims->getByIndex(nDim) );
|
|
|
|
uno::Reference<beans::XPropertySet> xDimProp( xDim, uno::UNO_QUERY );
|
|
|
|
uno::Reference<sheet::XHierarchiesSupplier> xDimSupp( xDim, uno::UNO_QUERY );
|
|
|
|
if ( xDimProp.is() && xDimSupp.is() )
|
|
|
|
{
|
|
|
|
sheet::DataPilotFieldOrientation eDimOrient =
|
|
|
|
(sheet::DataPilotFieldOrientation) ScUnoHelpFunctions::GetEnumProperty(
|
|
|
|
xDimProp, rtl::OUString::createFromAscii(DP_PROP_ORIENTATION),
|
|
|
|
sheet::DataPilotFieldOrientation_HIDDEN );
|
|
|
|
long nDimPos = ScUnoHelpFunctions::GetLongProperty( xDimProp,
|
|
|
|
rtl::OUString::createFromAscii(DP_PROP_POSITION) );
|
|
|
|
BOOL bIsDataLayout = ScUnoHelpFunctions::GetBoolProperty(
|
|
|
|
xDimProp,
|
|
|
|
rtl::OUString::createFromAscii(DP_PROP_ISDATALAYOUT) );
|
|
|
|
|
|
|
|
if ( eDimOrient != sheet::DataPilotFieldOrientation_HIDDEN )
|
|
|
|
{
|
|
|
|
uno::Reference<container::XIndexAccess> xHiers =
|
|
|
|
new ScNameToIndexAccess( xDimSupp->getHierarchies() );
|
|
|
|
long nHierarchy = ScUnoHelpFunctions::GetLongProperty(
|
|
|
|
xDimProp,
|
|
|
|
rtl::OUString::createFromAscii(DP_PROP_USEDHIERARCHY) );
|
|
|
|
if ( nHierarchy >= xHiers->getCount() )
|
|
|
|
nHierarchy = 0;
|
|
|
|
|
|
|
|
uno::Reference<uno::XInterface> xHier =
|
|
|
|
ScUnoHelpFunctions::AnyToInterface(
|
|
|
|
xHiers->getByIndex(nHierarchy) );
|
|
|
|
uno::Reference<sheet::XLevelsSupplier> xHierSupp( xHier, uno::UNO_QUERY );
|
|
|
|
if ( xHierSupp.is() )
|
|
|
|
{
|
|
|
|
uno::Reference<container::XIndexAccess> xLevels =
|
|
|
|
new ScNameToIndexAccess( xHierSupp->getLevels() );
|
|
|
|
long nLevCount = xLevels->getCount();
|
|
|
|
for (long nLev=0; nLev<nLevCount; nLev++)
|
|
|
|
{
|
|
|
|
uno::Reference<uno::XInterface> xLevel =
|
|
|
|
ScUnoHelpFunctions::AnyToInterface(
|
|
|
|
xLevels->getByIndex(nLev) );
|
|
|
|
uno::Reference<container::XNamed> xLevNam( xLevel, uno::UNO_QUERY );
|
|
|
|
uno::Reference<sheet::XDataPilotMemberResults> xLevRes(
|
|
|
|
xLevel, uno::UNO_QUERY );
|
|
|
|
if ( xLevNam.is() && xLevRes.is() )
|
|
|
|
{
|
|
|
|
String aCaption = String(xLevNam->getName()); //! Caption...
|
|
|
|
switch ( eDimOrient )
|
|
|
|
{
|
|
|
|
case sheet::DataPilotFieldOrientation_COLUMN:
|
|
|
|
pColFields[nColFieldCount].nDim = nDim;
|
|
|
|
pColFields[nColFieldCount].nHier = nHierarchy;
|
|
|
|
pColFields[nColFieldCount].nLevel = nLev;
|
|
|
|
pColFields[nColFieldCount].nDimPos = nDimPos;
|
|
|
|
pColFields[nColFieldCount].aResult = xLevRes->getResults();
|
|
|
|
pColFields[nColFieldCount].aCaption= aCaption;
|
|
|
|
if (!lcl_MemberEmpty(pColFields[nColFieldCount].aResult))
|
|
|
|
++nColFieldCount;
|
|
|
|
break;
|
|
|
|
case sheet::DataPilotFieldOrientation_ROW:
|
|
|
|
pRowFields[nRowFieldCount].nDim = nDim;
|
|
|
|
pRowFields[nRowFieldCount].nHier = nHierarchy;
|
|
|
|
pRowFields[nRowFieldCount].nLevel = nLev;
|
|
|
|
pRowFields[nRowFieldCount].nDimPos = nDimPos;
|
|
|
|
pRowFields[nRowFieldCount].aResult = xLevRes->getResults();
|
|
|
|
pRowFields[nRowFieldCount].aCaption= aCaption;
|
|
|
|
if (!lcl_MemberEmpty(pRowFields[nRowFieldCount].aResult))
|
|
|
|
++nRowFieldCount;
|
|
|
|
break;
|
|
|
|
case sheet::DataPilotFieldOrientation_PAGE:
|
|
|
|
pPageFields[nPageFieldCount].nDim = nDim;
|
|
|
|
pPageFields[nPageFieldCount].nHier = nHierarchy;
|
|
|
|
pPageFields[nPageFieldCount].nLevel = nLev;
|
|
|
|
pPageFields[nPageFieldCount].nDimPos = nDimPos;
|
2004-04-13 11:25:50 +00:00
|
|
|
pPageFields[nPageFieldCount].aResult = lcl_GetSelectedPageAsResult(xDimProp);
|
2000-09-18 23:16:46 +00:00
|
|
|
pPageFields[nPageFieldCount].aCaption= aCaption;
|
2004-04-13 11:25:50 +00:00
|
|
|
// no check on results for page fields
|
|
|
|
++nPageFieldCount;
|
2000-09-18 23:16:46 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
// get number formats from data dimensions
|
|
|
|
if ( bIsDataLayout )
|
|
|
|
{
|
|
|
|
DBG_ASSERT( nLevCount == 1, "data layout: multiple levels?" );
|
|
|
|
if ( eDimOrient == sheet::DataPilotFieldOrientation_COLUMN )
|
|
|
|
lcl_FillNumberFormats( pColNumFmt, nColFmtCount, xLevRes, xDims );
|
|
|
|
else if ( eDimOrient == sheet::DataPilotFieldOrientation_ROW )
|
|
|
|
lcl_FillNumberFormats( pRowNumFmt, nRowFmtCount, xLevRes, xDims );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2004-09-20 12:44:50 +00:00
|
|
|
else if ( bIsDataLayout )
|
|
|
|
{
|
|
|
|
// data layout dimension is hidden (allowed if there is only one data dimension)
|
|
|
|
// -> use the number format from the first data dimension for all results
|
|
|
|
|
|
|
|
nSingleNumFmt = lcl_GetFirstNumberFormat( xDims );
|
|
|
|
}
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
lcl_SortFields( pColFields, nColFieldCount );
|
|
|
|
lcl_SortFields( pRowFields, nRowFieldCount );
|
|
|
|
lcl_SortFields( pPageFields, nPageFieldCount );
|
|
|
|
|
|
|
|
// get data results:
|
|
|
|
|
2001-03-08 13:25:49 +00:00
|
|
|
try
|
|
|
|
{
|
|
|
|
aData = xResult->getResults();
|
|
|
|
}
|
|
|
|
catch (uno::RuntimeException&)
|
|
|
|
{
|
|
|
|
bResultsError = TRUE;
|
|
|
|
}
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// get "DataDescription" property (may be missing in external sources)
|
|
|
|
|
|
|
|
uno::Reference<beans::XPropertySet> xSrcProp( xSource, uno::UNO_QUERY );
|
|
|
|
if ( xSrcProp.is() )
|
|
|
|
{
|
2000-10-09 16:25:08 +00:00
|
|
|
try
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
|
|
|
uno::Any aAny = xSrcProp->getPropertyValue(
|
|
|
|
rtl::OUString::createFromAscii(DP_PROP_DATADESCR) );
|
|
|
|
rtl::OUString aUStr;
|
|
|
|
aAny >>= aUStr;
|
|
|
|
aDataDescription = String( aUStr );
|
|
|
|
}
|
2000-10-09 16:25:08 +00:00
|
|
|
catch(uno::Exception&)
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ScDPOutput::~ScDPOutput()
|
|
|
|
{
|
|
|
|
delete[] pColFields;
|
|
|
|
delete[] pRowFields;
|
|
|
|
delete[] pPageFields;
|
|
|
|
|
|
|
|
delete[] pColNumFmt;
|
|
|
|
delete[] pRowNumFmt;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ScDPOutput::SetPosition( const ScAddress& rPos )
|
|
|
|
{
|
|
|
|
aStartPos = rPos;
|
2001-03-08 13:25:49 +00:00
|
|
|
bSizesValid = bSizeOverflow = FALSE;
|
2000-09-18 23:16:46 +00:00
|
|
|
}
|
|
|
|
|
2004-06-04 09:24:29 +00:00
|
|
|
void ScDPOutput::DataCell( SCCOL nCol, SCROW nRow, SCTAB nTab, const sheet::DataResult& rData )
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
|
|
|
long nFlags = rData.Flags;
|
|
|
|
if ( nFlags & sheet::DataResultFlags::ERROR )
|
|
|
|
{
|
|
|
|
pDoc->SetError( nCol, nRow, nTab, errNoValue );
|
|
|
|
}
|
|
|
|
else if ( nFlags & sheet::DataResultFlags::HASDATA )
|
|
|
|
{
|
|
|
|
pDoc->SetValue( nCol, nRow, nTab, rData.Value );
|
|
|
|
|
|
|
|
// use number formats from source
|
|
|
|
|
|
|
|
DBG_ASSERT( bSizesValid, "DataCell: !bSizesValid" );
|
|
|
|
UINT32 nFormat = 0;
|
|
|
|
if ( pColNumFmt )
|
|
|
|
{
|
|
|
|
if ( nCol >= nDataStartCol )
|
|
|
|
{
|
|
|
|
long nIndex = nCol - nDataStartCol;
|
|
|
|
if ( nIndex < nColFmtCount )
|
|
|
|
nFormat = pColNumFmt[nIndex];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if ( pRowNumFmt )
|
|
|
|
{
|
|
|
|
if ( nRow >= nDataStartRow )
|
|
|
|
{
|
|
|
|
long nIndex = nRow - nDataStartRow;
|
|
|
|
if ( nIndex < nRowFmtCount )
|
|
|
|
nFormat = pRowNumFmt[nIndex];
|
|
|
|
}
|
|
|
|
}
|
2004-09-20 12:44:50 +00:00
|
|
|
else if ( nSingleNumFmt != 0 )
|
|
|
|
nFormat = nSingleNumFmt; // single format is used everywhere
|
2000-09-18 23:16:46 +00:00
|
|
|
if ( nFormat != 0 )
|
|
|
|
pDoc->ApplyAttr( nCol, nRow, nTab, SfxUInt32Item( ATTR_VALUE_FORMAT, nFormat ) );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
//pDoc->SetString( nCol, nRow, nTab, EMPTY_STRING );
|
|
|
|
}
|
|
|
|
|
|
|
|
// SubTotal formatting is controlled by headers
|
|
|
|
}
|
|
|
|
|
2004-06-04 09:24:29 +00:00
|
|
|
void ScDPOutput::HeaderCell( SCCOL nCol, SCROW nRow, SCTAB nTab,
|
2000-09-18 23:16:46 +00:00
|
|
|
const sheet::MemberResult& rData, BOOL bColHeader, long nLevel )
|
|
|
|
{
|
|
|
|
long nFlags = rData.Flags;
|
|
|
|
if ( nFlags & sheet::MemberResultFlags::HASMEMBER )
|
|
|
|
{
|
|
|
|
pDoc->SetString( nCol, nRow, nTab, rData.Caption );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
//pDoc->SetString( nCol, nRow, nTab, EMPTY_STRING );
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( nFlags & sheet::MemberResultFlags::SUBTOTAL )
|
|
|
|
{
|
|
|
|
// SvxWeightItem aItem( WEIGHT_BOLD ); // weight is in the style
|
|
|
|
|
|
|
|
//! limit frames to horizontal or vertical?
|
|
|
|
if (bColHeader)
|
|
|
|
{
|
2004-06-04 09:24:29 +00:00
|
|
|
// lcl_AttrArea( pDoc,nTab, nCol,nMemberStartRow+(SCROW)nLevel, nCol,nTabEndRow, aItem );
|
|
|
|
lcl_SetFrame( pDoc,nTab, nCol,nMemberStartRow+(SCROW)nLevel, nCol,nTabEndRow, 20 );
|
|
|
|
lcl_SetStyleById( pDoc,nTab, nCol,nMemberStartRow+(SCROW)nLevel, nCol,nDataStartRow-1,
|
2000-09-18 23:16:46 +00:00
|
|
|
STR_PIVOT_STYLE_TITLE );
|
|
|
|
lcl_SetStyleById( pDoc,nTab, nCol,nDataStartRow, nCol,nTabEndRow,
|
|
|
|
STR_PIVOT_STYLE_RESULT );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2004-06-04 09:24:29 +00:00
|
|
|
// lcl_AttrArea( pDoc,nTab, nMemberStartCol+(SCCOL)nLevel,nRow, nTabEndCol,nRow, aItem );
|
|
|
|
lcl_SetFrame( pDoc,nTab, nMemberStartCol+(SCCOL)nLevel,nRow, nTabEndCol,nRow, 20 );
|
|
|
|
lcl_SetStyleById( pDoc,nTab, nMemberStartCol+(SCCOL)nLevel,nRow, nDataStartCol-1,nRow,
|
2000-09-18 23:16:46 +00:00
|
|
|
STR_PIVOT_STYLE_TITLE );
|
|
|
|
lcl_SetStyleById( pDoc,nTab, nDataStartCol,nRow, nTabEndCol,nRow,
|
|
|
|
STR_PIVOT_STYLE_RESULT );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-06-04 09:24:29 +00:00
|
|
|
void ScDPOutput::FieldCell( SCCOL nCol, SCROW nRow, SCTAB nTab, const String& rCaption, BOOL bFrame )
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
|
|
|
pDoc->SetString( nCol, nRow, nTab, rCaption );
|
2004-04-13 11:25:50 +00:00
|
|
|
if (bFrame)
|
|
|
|
lcl_SetFrame( pDoc,nTab, nCol,nRow, nCol,nRow, 20 );
|
2000-09-18 23:16:46 +00:00
|
|
|
|
|
|
|
// Button
|
|
|
|
pDoc->ApplyAttr( nCol, nRow, nTab, ScMergeFlagAttr(SC_MF_BUTTON) );
|
|
|
|
|
|
|
|
lcl_SetStyleById( pDoc,nTab, nCol,nRow, nCol,nRow, STR_PIVOT_STYLE_FIELDNAME );
|
|
|
|
}
|
|
|
|
|
2004-06-04 09:24:29 +00:00
|
|
|
void lcl_DoFilterButton( ScDocument* pDoc, SCCOL nCol, SCROW nRow, SCTAB nTab )
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
|
|
|
pDoc->SetString( nCol, nRow, nTab, ScGlobal::GetRscString(STR_CELL_FILTER) );
|
|
|
|
pDoc->ApplyAttr( nCol, nRow, nTab, ScMergeFlagAttr(SC_MF_BUTTON) );
|
|
|
|
}
|
|
|
|
|
|
|
|
void ScDPOutput::CalcSizes()
|
|
|
|
{
|
|
|
|
if (!bSizesValid)
|
|
|
|
{
|
|
|
|
// get column size of data from first row
|
|
|
|
//! allow different sizes (and clear following areas) ???
|
|
|
|
|
|
|
|
nRowCount = aData.getLength();
|
|
|
|
const uno::Sequence<sheet::DataResult>* pRowAry = aData.getConstArray();
|
|
|
|
nColCount = nRowCount ? ( pRowAry[0].getLength() ) : 0;
|
|
|
|
nHeaderSize = 1; // one row for field names
|
|
|
|
|
|
|
|
// calculate output positions and sizes
|
|
|
|
|
|
|
|
long nPageSize = 0; //! use page fields!
|
2004-04-13 11:25:50 +00:00
|
|
|
if ( bDoFilter || nPageFieldCount )
|
|
|
|
{
|
|
|
|
nPageSize += nPageFieldCount + 1; // plus one empty row
|
|
|
|
if ( bDoFilter )
|
|
|
|
++nPageSize; // filter button above the page fields
|
|
|
|
}
|
2000-09-18 23:16:46 +00:00
|
|
|
|
2001-03-08 13:25:49 +00:00
|
|
|
if ( aStartPos.Col() + nRowFieldCount + nColCount - 1 > MAXCOL ||
|
|
|
|
aStartPos.Row() + nPageSize + nHeaderSize + nColFieldCount + nRowCount > MAXROW )
|
|
|
|
{
|
|
|
|
bSizeOverflow = TRUE;
|
|
|
|
}
|
|
|
|
|
2000-09-18 23:16:46 +00:00
|
|
|
nTabStartCol = aStartPos.Col();
|
2004-06-04 09:24:29 +00:00
|
|
|
nTabStartRow = aStartPos.Row() + (SCROW)nPageSize; // below page fields
|
2000-09-18 23:16:46 +00:00
|
|
|
nMemberStartCol = nTabStartCol;
|
2004-06-04 09:24:29 +00:00
|
|
|
nMemberStartRow = nTabStartRow + (SCROW) nHeaderSize;
|
|
|
|
nDataStartCol = nMemberStartCol + (SCCOL)nRowFieldCount;
|
|
|
|
nDataStartRow = nMemberStartRow + (SCROW)nColFieldCount;
|
2001-10-30 16:30:44 +00:00
|
|
|
if ( nColCount > 0 )
|
2004-06-04 09:24:29 +00:00
|
|
|
nTabEndCol = nDataStartCol + (SCCOL)nColCount - 1;
|
2001-10-30 16:30:44 +00:00
|
|
|
else
|
|
|
|
nTabEndCol = nDataStartCol; // single column will remain empty
|
2004-04-13 11:25:50 +00:00
|
|
|
// if page fields are involved, include the page selection cells
|
|
|
|
if ( nPageFieldCount > 0 && nTabEndCol < nTabStartCol + 1 )
|
|
|
|
nTabEndCol = nTabStartCol + 1;
|
2001-10-30 16:30:44 +00:00
|
|
|
if ( nRowCount > 0 )
|
2004-06-04 09:24:29 +00:00
|
|
|
nTabEndRow = nDataStartRow + (SCROW)nRowCount - 1;
|
2001-10-30 16:30:44 +00:00
|
|
|
else
|
|
|
|
nTabEndRow = nDataStartRow; // single row will remain empty
|
2000-09-18 23:16:46 +00:00
|
|
|
bSizesValid = TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ScDPOutput::Output()
|
|
|
|
{
|
|
|
|
long nField;
|
2004-06-04 09:24:29 +00:00
|
|
|
SCTAB nTab = aStartPos.Tab();
|
2000-09-18 23:16:46 +00:00
|
|
|
const uno::Sequence<sheet::DataResult>* pRowAry = aData.getConstArray();
|
|
|
|
|
|
|
|
// calculate output positions and sizes
|
|
|
|
|
|
|
|
CalcSizes();
|
2001-03-08 13:25:49 +00:00
|
|
|
if ( bSizeOverflow || bResultsError ) // does output area exceed sheet limits?
|
|
|
|
return; // nothing
|
2000-09-18 23:16:46 +00:00
|
|
|
|
|
|
|
// clear whole (new) output area
|
|
|
|
//! when modifying table, clear old area
|
|
|
|
//! include IDF_OBJECTS ???
|
|
|
|
pDoc->DeleteAreaTab( aStartPos.Col(), aStartPos.Row(), nTabEndCol, nTabEndRow, nTab, IDF_ALL );
|
|
|
|
|
|
|
|
if ( bDoFilter )
|
|
|
|
lcl_DoFilterButton( pDoc, aStartPos.Col(), aStartPos.Row(), nTab );
|
|
|
|
|
2004-04-13 11:25:50 +00:00
|
|
|
// output page fields:
|
|
|
|
|
|
|
|
for (nField=0; nField<nPageFieldCount; nField++)
|
|
|
|
{
|
2004-06-04 09:24:29 +00:00
|
|
|
SCCOL nHdrCol = aStartPos.Col();
|
|
|
|
SCROW nHdrRow = aStartPos.Row() + nField + ( bDoFilter ? 1 : 0 );
|
2004-04-13 11:25:50 +00:00
|
|
|
// draw without frame for consistency with filter button:
|
|
|
|
FieldCell( nHdrCol, nHdrRow, nTab, pPageFields[nField].aCaption, FALSE );
|
2004-06-04 09:24:29 +00:00
|
|
|
SCCOL nFldCol = nHdrCol + 1;
|
2004-04-13 11:25:50 +00:00
|
|
|
|
|
|
|
String aPageValue;
|
|
|
|
if ( pPageFields[nField].aResult.getLength() == 1 )
|
|
|
|
aPageValue = pPageFields[nField].aResult[0].Caption;
|
|
|
|
else
|
|
|
|
aPageValue = String( ScResId( SCSTR_ALL ) ); //! separate string?
|
|
|
|
|
|
|
|
pDoc->SetString( nFldCol, nHdrRow, nTab, aPageValue );
|
|
|
|
|
|
|
|
lcl_SetFrame( pDoc,nTab, nFldCol,nHdrRow, nFldCol,nHdrRow, 20 );
|
|
|
|
pDoc->ApplyAttr( nFldCol, nHdrRow, nTab, ScMergeFlagAttr(SC_MF_AUTO) );
|
|
|
|
//! which style?
|
|
|
|
}
|
|
|
|
|
2000-09-18 23:16:46 +00:00
|
|
|
// data description
|
|
|
|
// (may get overwritten by first row field)
|
|
|
|
|
|
|
|
String aDesc = aDataDescription;
|
|
|
|
if ( !aDesc.Len() )
|
|
|
|
{
|
|
|
|
//! use default string ("result") ?
|
|
|
|
}
|
|
|
|
pDoc->SetString( nTabStartCol, nTabStartRow, nTab, aDesc );
|
|
|
|
|
|
|
|
// set STR_PIVOT_STYLE_INNER for whole data area (subtotals are overwritten)
|
|
|
|
|
|
|
|
if ( nDataStartRow > nTabStartRow )
|
|
|
|
lcl_SetStyleById( pDoc, nTab, nTabStartCol, nTabStartRow, nTabEndCol, nDataStartRow-1,
|
|
|
|
STR_PIVOT_STYLE_TOP );
|
|
|
|
lcl_SetStyleById( pDoc, nTab, nDataStartCol, nDataStartRow, nTabEndCol, nTabEndRow,
|
|
|
|
STR_PIVOT_STYLE_INNER );
|
|
|
|
|
|
|
|
// output column headers:
|
|
|
|
|
|
|
|
for (nField=0; nField<nColFieldCount; nField++)
|
|
|
|
{
|
2004-06-04 09:24:29 +00:00
|
|
|
SCCOL nHdrCol = nDataStartCol + (SCCOL)nField; //! check for overflow
|
2000-09-18 23:16:46 +00:00
|
|
|
FieldCell( nHdrCol, nTabStartRow, nTab, pColFields[nField].aCaption );
|
|
|
|
|
2004-06-04 09:24:29 +00:00
|
|
|
SCROW nRowPos = nMemberStartRow + (SCROW)nField; //! check for overflow
|
2000-09-18 23:16:46 +00:00
|
|
|
const uno::Sequence<sheet::MemberResult> rSequence = pColFields[nField].aResult;
|
|
|
|
const sheet::MemberResult* pArray = rSequence.getConstArray();
|
|
|
|
long nThisColCount = rSequence.getLength();
|
|
|
|
DBG_ASSERT( nThisColCount == nColCount, "count mismatch" ); //! ???
|
|
|
|
for (long nCol=0; nCol<nThisColCount; nCol++)
|
|
|
|
{
|
2004-06-04 09:24:29 +00:00
|
|
|
SCCOL nColPos = nDataStartCol + (SCCOL)nCol; //! check for overflow
|
2000-09-18 23:16:46 +00:00
|
|
|
HeaderCell( nColPos, nRowPos, nTab, pArray[nCol], TRUE, nField );
|
|
|
|
if ( ( pArray[nCol].Flags & sheet::MemberResultFlags::HASMEMBER ) &&
|
|
|
|
!( pArray[nCol].Flags & sheet::MemberResultFlags::SUBTOTAL ) )
|
|
|
|
{
|
|
|
|
if ( nField+1 < nColFieldCount )
|
|
|
|
{
|
|
|
|
long nEnd = nCol;
|
|
|
|
while ( nEnd+1 < nThisColCount && ( pArray[nEnd+1].Flags & sheet::MemberResultFlags::CONTINUE ) )
|
|
|
|
++nEnd;
|
2004-06-04 09:24:29 +00:00
|
|
|
SCCOL nEndColPos = nDataStartCol + (SCCOL)nEnd; //! check for overflow
|
2000-09-18 23:16:46 +00:00
|
|
|
lcl_SetFrame( pDoc,nTab, nColPos,nRowPos, nEndColPos,nRowPos, 20 );
|
|
|
|
lcl_SetFrame( pDoc,nTab, nColPos,nRowPos, nEndColPos,nTabEndRow, 20 );
|
|
|
|
|
|
|
|
lcl_SetStyleById( pDoc, nTab, nColPos,nRowPos, nEndColPos,nDataStartRow-1, STR_PIVOT_STYLE_CATEGORY );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
lcl_SetStyleById( pDoc, nTab, nColPos,nRowPos, nColPos,nDataStartRow-1, STR_PIVOT_STYLE_CATEGORY );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// output row headers:
|
|
|
|
|
|
|
|
for (nField=0; nField<nRowFieldCount; nField++)
|
|
|
|
{
|
2004-06-04 09:24:29 +00:00
|
|
|
SCCOL nHdrCol = nTabStartCol + (SCCOL)nField; //! check for overflow
|
|
|
|
SCROW nHdrRow = nDataStartRow - 1;
|
2000-09-18 23:16:46 +00:00
|
|
|
FieldCell( nHdrCol, nHdrRow, nTab, pRowFields[nField].aCaption );
|
|
|
|
|
2004-06-04 09:24:29 +00:00
|
|
|
SCCOL nColPos = nMemberStartCol + (SCCOL)nField; //! check for overflow
|
2000-09-18 23:16:46 +00:00
|
|
|
const uno::Sequence<sheet::MemberResult> rSequence = pRowFields[nField].aResult;
|
|
|
|
const sheet::MemberResult* pArray = rSequence.getConstArray();
|
|
|
|
long nThisRowCount = rSequence.getLength();
|
|
|
|
DBG_ASSERT( nThisRowCount == nRowCount, "count mismatch" ); //! ???
|
|
|
|
for (long nRow=0; nRow<nThisRowCount; nRow++)
|
|
|
|
{
|
2004-06-04 09:24:29 +00:00
|
|
|
SCROW nRowPos = nDataStartRow + (SCROW)nRow; //! check for overflow
|
2000-09-18 23:16:46 +00:00
|
|
|
HeaderCell( nColPos, nRowPos, nTab, pArray[nRow], FALSE, nField );
|
|
|
|
if ( ( pArray[nRow].Flags & sheet::MemberResultFlags::HASMEMBER ) &&
|
|
|
|
!( pArray[nRow].Flags & sheet::MemberResultFlags::SUBTOTAL ) )
|
|
|
|
{
|
|
|
|
if ( nField+1 < nRowFieldCount )
|
|
|
|
{
|
|
|
|
long nEnd = nRow;
|
|
|
|
while ( nEnd+1 < nThisRowCount && ( pArray[nEnd+1].Flags & sheet::MemberResultFlags::CONTINUE ) )
|
|
|
|
++nEnd;
|
2004-06-04 09:24:29 +00:00
|
|
|
SCROW nEndRowPos = nDataStartRow + (SCROW)nEnd; //! check for overflow
|
2000-09-18 23:16:46 +00:00
|
|
|
lcl_SetFrame( pDoc,nTab, nColPos,nRowPos, nColPos,nEndRowPos, 20 );
|
|
|
|
lcl_SetFrame( pDoc,nTab, nColPos,nRowPos, nTabEndCol,nEndRowPos, 20 );
|
|
|
|
|
|
|
|
lcl_SetStyleById( pDoc, nTab, nColPos,nRowPos, nDataStartCol-1,nEndRowPos, STR_PIVOT_STYLE_CATEGORY );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
lcl_SetStyleById( pDoc, nTab, nColPos,nRowPos, nDataStartCol-1,nRowPos, STR_PIVOT_STYLE_CATEGORY );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// output data results:
|
|
|
|
|
|
|
|
for (long nRow=0; nRow<nRowCount; nRow++)
|
|
|
|
{
|
2004-06-04 09:24:29 +00:00
|
|
|
SCROW nRowPos = nDataStartRow + (SCROW)nRow; //! check for overflow
|
2000-09-18 23:16:46 +00:00
|
|
|
const sheet::DataResult* pColAry = pRowAry[nRow].getConstArray();
|
|
|
|
long nThisColCount = pRowAry[nRow].getLength();
|
|
|
|
DBG_ASSERT( nThisColCount == nColCount, "count mismatch" ); //! ???
|
|
|
|
for (long nCol=0; nCol<nThisColCount; nCol++)
|
|
|
|
{
|
2004-06-04 09:24:29 +00:00
|
|
|
SCCOL nColPos = nDataStartCol + (SCCOL)nCol; //! check for overflow
|
2000-09-18 23:16:46 +00:00
|
|
|
DataCell( nColPos, nRowPos, nTab, pColAry[nCol] );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// frame around the whole table
|
|
|
|
|
|
|
|
lcl_SetFrame( pDoc,nTab, nDataStartCol,nDataStartRow, nTabEndCol,nTabEndRow, 20 );
|
|
|
|
if ( nDataStartCol > nMemberStartCol )
|
|
|
|
lcl_SetFrame( pDoc,nTab, nMemberStartCol,nDataStartRow, nDataStartCol-1,nTabEndRow, 20 );
|
|
|
|
if ( nDataStartRow > nMemberStartRow )
|
|
|
|
lcl_SetFrame( pDoc,nTab, nDataStartCol,nMemberStartRow, nTabEndCol,nDataStartRow-1, 20 );
|
|
|
|
|
|
|
|
lcl_SetFrame( pDoc,nTab, nTabStartCol,nTabStartRow, nTabEndCol,nTabEndRow, 40 );
|
|
|
|
}
|
|
|
|
|
|
|
|
ScRange ScDPOutput::GetOutputRange()
|
|
|
|
{
|
|
|
|
CalcSizes();
|
|
|
|
|
2004-06-04 09:24:29 +00:00
|
|
|
SCTAB nTab = aStartPos.Tab();
|
2000-09-18 23:16:46 +00:00
|
|
|
return ScRange( aStartPos.Col(), aStartPos.Row(), nTab, nTabEndCol, nTabEndRow, nTab);
|
|
|
|
}
|
|
|
|
|
2001-03-08 13:25:49 +00:00
|
|
|
BOOL ScDPOutput::HasError()
|
|
|
|
{
|
|
|
|
CalcSizes();
|
|
|
|
|
|
|
|
return bSizeOverflow || bResultsError;
|
|
|
|
}
|
|
|
|
|
2004-04-13 11:25:50 +00:00
|
|
|
long ScDPOutput::GetHeaderRows()
|
|
|
|
{
|
|
|
|
return nPageFieldCount + ( bDoFilter ? 1 : 0 );
|
|
|
|
}
|
|
|
|
|
2004-07-23 11:53:00 +00:00
|
|
|
void ScDPOutput::GetMemberResultNames( StrCollection& rNames, long nDimension )
|
|
|
|
{
|
|
|
|
// Return the list of all member names in a dimension's MemberResults.
|
|
|
|
// Only the dimension has to be compared because this is only used with table data,
|
|
|
|
// where each dimension occurs only once.
|
|
|
|
|
|
|
|
uno::Sequence<sheet::MemberResult> aMemberResults;
|
|
|
|
bool bFound = false;
|
|
|
|
long nField;
|
|
|
|
|
|
|
|
// look in column fields
|
|
|
|
|
|
|
|
for (nField=0; nField<nColFieldCount && !bFound; nField++)
|
|
|
|
if ( pColFields[nField].nDim == nDimension )
|
|
|
|
{
|
|
|
|
aMemberResults = pColFields[nField].aResult;
|
|
|
|
bFound = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// look in row fields
|
|
|
|
|
|
|
|
for (nField=0; nField<nRowFieldCount && !bFound; nField++)
|
|
|
|
if ( pRowFields[nField].nDim == nDimension )
|
|
|
|
{
|
|
|
|
aMemberResults = pRowFields[nField].aResult;
|
|
|
|
bFound = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// collect the member names
|
|
|
|
|
|
|
|
if ( bFound )
|
|
|
|
{
|
|
|
|
const sheet::MemberResult* pArray = aMemberResults.getConstArray();
|
|
|
|
long nResultCount = aMemberResults.getLength();
|
|
|
|
|
|
|
|
for (long nItem=0; nItem<nResultCount; nItem++)
|
|
|
|
{
|
|
|
|
if ( pArray[nItem].Flags & sheet::MemberResultFlags::HASMEMBER )
|
|
|
|
{
|
|
|
|
StrData* pNew = new StrData( pArray[nItem].Name );
|
|
|
|
if ( !rNames.Insert( pNew ) )
|
|
|
|
delete pNew;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-09-18 23:16:46 +00:00
|
|
|
//
|
|
|
|
// Methods to find specific parts of the table
|
|
|
|
//
|
|
|
|
|
|
|
|
void ScDPOutput::GetPositionData( ScDPPositionData& rData, const ScAddress& rPos )
|
|
|
|
{
|
|
|
|
//! preset rData to "invalid" ?
|
|
|
|
|
2004-06-04 09:24:29 +00:00
|
|
|
SCCOL nCol = rPos.Col();
|
|
|
|
SCROW nRow = rPos.Row();
|
|
|
|
SCTAB nTab = rPos.Tab();
|
2000-09-18 23:16:46 +00:00
|
|
|
if ( nTab != aStartPos.Tab() )
|
|
|
|
return; // wrong sheet
|
|
|
|
|
|
|
|
// calculate output positions and sizes
|
|
|
|
|
|
|
|
CalcSizes();
|
|
|
|
|
|
|
|
// test for column field
|
|
|
|
|
|
|
|
if ( nRow >= nMemberStartRow && nRow < nMemberStartRow + nColFieldCount )
|
|
|
|
{
|
|
|
|
long nField = nRow - nMemberStartRow;
|
|
|
|
const uno::Sequence<sheet::MemberResult> rSequence = pColFields[nField].aResult;
|
|
|
|
const sheet::MemberResult* pArray = rSequence.getConstArray();
|
|
|
|
long nThisColCount = rSequence.getLength();
|
|
|
|
|
|
|
|
if ( nCol >= nDataStartCol && nCol < nDataStartCol + nThisColCount )
|
|
|
|
{
|
|
|
|
long nItem = nCol - nDataStartCol;
|
|
|
|
// get origin of "continue" fields
|
|
|
|
while ( nItem > 0 && ( pArray[nItem].Flags & sheet::MemberResultFlags::CONTINUE ) )
|
|
|
|
--nItem;
|
|
|
|
rData.aMemberName = String(pArray[nItem].Name);
|
|
|
|
rData.nFlags = pArray[nItem].Flags;
|
|
|
|
rData.nDimension = pColFields[nField].nDim;
|
|
|
|
rData.nHierarchy = pColFields[nField].nHier;
|
|
|
|
rData.nLevel = pColFields[nField].nLevel;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// test for row field
|
|
|
|
|
|
|
|
if ( nCol >= nMemberStartCol && nCol < nMemberStartCol + nRowFieldCount )
|
|
|
|
{
|
|
|
|
long nField = nCol - nMemberStartCol;
|
|
|
|
const uno::Sequence<sheet::MemberResult> rSequence = pRowFields[nField].aResult;
|
|
|
|
const sheet::MemberResult* pArray = rSequence.getConstArray();
|
|
|
|
long nThisRowCount = rSequence.getLength();
|
|
|
|
|
|
|
|
if ( nRow >= nDataStartRow && nRow < nDataStartRow + nThisRowCount )
|
|
|
|
{
|
|
|
|
long nItem = nRow - nDataStartRow;
|
|
|
|
// get origin of "continue" fields
|
|
|
|
while ( nItem > 0 && ( pArray[nItem].Flags & sheet::MemberResultFlags::CONTINUE ) )
|
|
|
|
--nItem;
|
|
|
|
rData.aMemberName = String(pArray[nItem].Name);
|
|
|
|
rData.nFlags = pArray[nItem].Flags;
|
|
|
|
rData.nDimension = pRowFields[nField].nDim;
|
|
|
|
rData.nHierarchy = pRowFields[nField].nHier;
|
|
|
|
rData.nLevel = pRowFields[nField].nLevel;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOL ScDPOutput::IsFilterButton( const ScAddress& rPos )
|
|
|
|
{
|
2004-06-04 09:24:29 +00:00
|
|
|
SCCOL nCol = rPos.Col();
|
|
|
|
SCROW nRow = rPos.Row();
|
|
|
|
SCTAB nTab = rPos.Tab();
|
2000-09-18 23:16:46 +00:00
|
|
|
if ( nTab != aStartPos.Tab() || !bDoFilter )
|
|
|
|
return FALSE; // wrong sheet or no button at all
|
|
|
|
|
|
|
|
// filter button is at top left
|
|
|
|
return ( nCol == aStartPos.Col() && nRow == aStartPos.Row() );
|
|
|
|
}
|
|
|
|
|
2004-04-13 11:25:50 +00:00
|
|
|
long ScDPOutput::GetHeaderDim( const ScAddress& rPos, USHORT& rOrient )
|
2000-09-18 23:16:46 +00:00
|
|
|
{
|
2004-06-04 09:24:29 +00:00
|
|
|
SCCOL nCol = rPos.Col();
|
|
|
|
SCROW nRow = rPos.Row();
|
|
|
|
SCTAB nTab = rPos.Tab();
|
2000-09-18 23:16:46 +00:00
|
|
|
if ( nTab != aStartPos.Tab() )
|
|
|
|
return -1; // wrong sheet
|
|
|
|
|
|
|
|
// calculate output positions and sizes
|
|
|
|
|
|
|
|
CalcSizes();
|
|
|
|
|
|
|
|
// test for column header
|
|
|
|
|
|
|
|
if ( nRow == nTabStartRow && nCol >= nDataStartCol && nCol < nDataStartCol + nColFieldCount )
|
|
|
|
{
|
2004-04-13 11:25:50 +00:00
|
|
|
rOrient = sheet::DataPilotFieldOrientation_COLUMN;
|
2000-09-18 23:16:46 +00:00
|
|
|
long nField = nCol - nDataStartCol;
|
|
|
|
return pColFields[nField].nDim;
|
|
|
|
}
|
|
|
|
|
|
|
|
// test for row header
|
|
|
|
|
|
|
|
if ( nRow+1 == nDataStartRow && nCol >= nTabStartCol == nCol < nTabStartCol + nRowFieldCount )
|
|
|
|
{
|
2004-04-13 11:25:50 +00:00
|
|
|
rOrient = sheet::DataPilotFieldOrientation_ROW;
|
2000-09-18 23:16:46 +00:00
|
|
|
long nField = nCol - nTabStartCol;
|
|
|
|
return pRowFields[nField].nDim;
|
|
|
|
}
|
|
|
|
|
2004-04-13 11:25:50 +00:00
|
|
|
// test for page field
|
|
|
|
|
2004-06-04 09:24:29 +00:00
|
|
|
SCROW nPageStartRow = aStartPos.Row() + ( bDoFilter ? 1 : 0 );
|
2004-04-13 11:25:50 +00:00
|
|
|
if ( nCol == aStartPos.Col() && nRow >= nPageStartRow && nRow < nPageStartRow + nPageFieldCount )
|
|
|
|
{
|
|
|
|
rOrient = sheet::DataPilotFieldOrientation_PAGE;
|
|
|
|
long nField = nRow - nPageStartRow;
|
|
|
|
return pPageFields[nField].nDim;
|
|
|
|
}
|
|
|
|
|
2000-09-18 23:16:46 +00:00
|
|
|
//! single data field (?)
|
|
|
|
|
2004-04-13 11:25:50 +00:00
|
|
|
rOrient = sheet::DataPilotFieldOrientation_HIDDEN;
|
2000-09-18 23:16:46 +00:00
|
|
|
return -1; // invalid
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOL ScDPOutput::GetHeaderDrag( const ScAddress& rPos, BOOL bMouseLeft, BOOL bMouseTop,
|
|
|
|
long nDragDim,
|
|
|
|
Rectangle& rPosRect, USHORT& rOrient, long& rDimPos )
|
|
|
|
{
|
|
|
|
// Rectangle instead of ScRange for rPosRect to allow for negative values
|
|
|
|
|
2004-06-04 09:24:29 +00:00
|
|
|
SCCOL nCol = rPos.Col();
|
|
|
|
SCROW nRow = rPos.Row();
|
|
|
|
SCTAB nTab = rPos.Tab();
|
2000-09-18 23:16:46 +00:00
|
|
|
if ( nTab != aStartPos.Tab() )
|
|
|
|
return FALSE; // wrong sheet
|
|
|
|
|
|
|
|
// calculate output positions and sizes
|
|
|
|
|
|
|
|
CalcSizes();
|
|
|
|
|
|
|
|
// test for column header
|
|
|
|
|
|
|
|
if ( nCol >= nDataStartCol && nCol <= nTabEndCol &&
|
|
|
|
nRow + 1 >= nMemberStartRow && nRow < nMemberStartRow + nColFieldCount )
|
|
|
|
{
|
|
|
|
long nField = nRow - nMemberStartRow;
|
|
|
|
if (nField < 0)
|
|
|
|
{
|
|
|
|
nField = 0;
|
|
|
|
bMouseTop = TRUE;
|
|
|
|
}
|
|
|
|
//! find start of dimension
|
|
|
|
|
|
|
|
rPosRect = Rectangle( nDataStartCol, nMemberStartRow + nField,
|
|
|
|
nTabEndCol, nMemberStartRow + nField -1 );
|
|
|
|
|
|
|
|
BOOL bFound = FALSE; // is this within the same orientation?
|
|
|
|
BOOL bBeforeDrag = FALSE;
|
|
|
|
BOOL bAfterDrag = FALSE;
|
|
|
|
for (long nPos=0; nPos<nColFieldCount && !bFound; nPos++)
|
|
|
|
{
|
|
|
|
if (pColFields[nPos].nDim == nDragDim)
|
|
|
|
{
|
|
|
|
bFound = TRUE;
|
|
|
|
if ( nField < nPos )
|
|
|
|
bBeforeDrag = TRUE;
|
|
|
|
else if ( nField > nPos )
|
|
|
|
bAfterDrag = TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( bFound )
|
|
|
|
{
|
|
|
|
if (!bBeforeDrag)
|
|
|
|
{
|
|
|
|
++rPosRect.Bottom();
|
|
|
|
if (bAfterDrag)
|
|
|
|
++rPosRect.Top();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if ( !bMouseTop )
|
|
|
|
{
|
|
|
|
++rPosRect.Top();
|
|
|
|
++rPosRect.Bottom();
|
|
|
|
++nField;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
rOrient = sheet::DataPilotFieldOrientation_COLUMN;
|
|
|
|
rDimPos = nField; //!...
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
// test for row header
|
|
|
|
|
|
|
|
// special case if no row fields
|
|
|
|
BOOL bSpecial = ( nRow+1 >= nDataStartRow && nRow <= nTabEndRow &&
|
|
|
|
nRowFieldCount == 0 && nCol == nTabStartCol && bMouseLeft );
|
|
|
|
|
|
|
|
if ( bSpecial || ( nRow+1 >= nDataStartRow && nRow <= nTabEndRow &&
|
|
|
|
nCol + 1 >= nTabStartCol && nCol < nTabStartCol + nRowFieldCount ) )
|
|
|
|
{
|
|
|
|
long nField = nCol - nTabStartCol;
|
|
|
|
//! find start of dimension
|
|
|
|
|
|
|
|
rPosRect = Rectangle( nTabStartCol + nField, nDataStartRow - 1,
|
|
|
|
nTabStartCol + nField - 1, nTabEndRow );
|
|
|
|
|
|
|
|
BOOL bFound = FALSE; // is this within the same orientation?
|
|
|
|
BOOL bBeforeDrag = FALSE;
|
|
|
|
BOOL bAfterDrag = FALSE;
|
|
|
|
for (long nPos=0; nPos<nRowFieldCount && !bFound; nPos++)
|
|
|
|
{
|
|
|
|
if (pRowFields[nPos].nDim == nDragDim)
|
|
|
|
{
|
|
|
|
bFound = TRUE;
|
|
|
|
if ( nField < nPos )
|
|
|
|
bBeforeDrag = TRUE;
|
|
|
|
else if ( nField > nPos )
|
|
|
|
bAfterDrag = TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( bFound )
|
|
|
|
{
|
|
|
|
if (!bBeforeDrag)
|
|
|
|
{
|
|
|
|
++rPosRect.Right();
|
|
|
|
if (bAfterDrag)
|
|
|
|
++rPosRect.Left();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if ( !bMouseLeft )
|
|
|
|
{
|
|
|
|
++rPosRect.Left();
|
|
|
|
++rPosRect.Right();
|
|
|
|
++nField;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
rOrient = sheet::DataPilotFieldOrientation_ROW;
|
|
|
|
rDimPos = nField; //!...
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2004-04-13 11:25:50 +00:00
|
|
|
// test for page fields
|
|
|
|
|
2004-06-04 09:24:29 +00:00
|
|
|
SCROW nPageStartRow = aStartPos.Row() + ( bDoFilter ? 1 : 0 );
|
2004-04-13 11:25:50 +00:00
|
|
|
if ( nCol >= aStartPos.Col() && nCol <= nTabEndCol &&
|
|
|
|
nRow + 1 >= nPageStartRow && nRow < nPageStartRow + nPageFieldCount )
|
|
|
|
{
|
|
|
|
long nField = nRow - nPageStartRow;
|
|
|
|
if (nField < 0)
|
|
|
|
{
|
|
|
|
nField = 0;
|
|
|
|
bMouseTop = TRUE;
|
|
|
|
}
|
|
|
|
//! find start of dimension
|
|
|
|
|
|
|
|
rPosRect = Rectangle( aStartPos.Col(), nPageStartRow + nField,
|
|
|
|
nTabEndCol, nPageStartRow + nField - 1 );
|
|
|
|
|
|
|
|
BOOL bFound = FALSE; // is this within the same orientation?
|
|
|
|
BOOL bBeforeDrag = FALSE;
|
|
|
|
BOOL bAfterDrag = FALSE;
|
|
|
|
for (long nPos=0; nPos<nPageFieldCount && !bFound; nPos++)
|
|
|
|
{
|
|
|
|
if (pPageFields[nPos].nDim == nDragDim)
|
|
|
|
{
|
|
|
|
bFound = TRUE;
|
|
|
|
if ( nField < nPos )
|
|
|
|
bBeforeDrag = TRUE;
|
|
|
|
else if ( nField > nPos )
|
|
|
|
bAfterDrag = TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( bFound )
|
|
|
|
{
|
|
|
|
if (!bBeforeDrag)
|
|
|
|
{
|
|
|
|
++rPosRect.Bottom();
|
|
|
|
if (bAfterDrag)
|
|
|
|
++rPosRect.Top();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if ( !bMouseTop )
|
|
|
|
{
|
|
|
|
++rPosRect.Top();
|
|
|
|
++rPosRect.Bottom();
|
|
|
|
++nField;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
rOrient = sheet::DataPilotFieldOrientation_PAGE;
|
|
|
|
rDimPos = nField; //!...
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2000-09-18 23:16:46 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|