summaryrefslogtreecommitdiff
path: root/sc/source/core
diff options
context:
space:
mode:
Diffstat (limited to 'sc/source/core')
-rw-r--r--sc/source/core/data/attarray.cxx3
-rw-r--r--sc/source/core/data/column2.cxx14
-rw-r--r--sc/source/core/data/documen8.cxx10
-rw-r--r--sc/source/core/data/document.cxx26
-rw-r--r--sc/source/core/data/dpgroup.cxx4
-rw-r--r--sc/source/core/data/dpobject.cxx329
-rw-r--r--sc/source/core/data/dpoutput.cxx104
-rw-r--r--sc/source/core/data/dpoutputgeometry.cxx217
-rw-r--r--sc/source/core/data/dpsave.cxx327
-rw-r--r--sc/source/core/data/dptabres.cxx94
-rw-r--r--sc/source/core/data/dptabsrc.cxx129
-rw-r--r--sc/source/core/data/fillinfo.cxx8
-rw-r--r--sc/source/core/data/global2.cxx47
-rw-r--r--sc/source/core/data/makefile.mk2
-rw-r--r--sc/source/core/data/pivot2.cxx25
-rw-r--r--sc/source/core/data/table2.cxx8
16 files changed, 1052 insertions, 295 deletions
diff --git a/sc/source/core/data/attarray.cxx b/sc/source/core/data/attarray.cxx
index 590f278901d6..a4875ba4d1e3 100644
--- a/sc/source/core/data/attarray.cxx
+++ b/sc/source/core/data/attarray.cxx
@@ -2117,7 +2117,8 @@ void ScAttrArray::InsertRow( SCROW nStartRow, SCSIZE nSize )
}
// Don't duplicate the merge flags in the inserted row.
- RemoveFlags( nStartRow, nStartRow+nSize-1, SC_MF_ALL );
+ // #i108488# SC_MF_SCENARIO has to be allowed.
+ RemoveFlags( nStartRow, nStartRow+nSize-1, SC_MF_HOR | SC_MF_VER | SC_MF_AUTO | SC_MF_BUTTON );
}
diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx
index 4205c0f59dcc..3da3d3810f0b 100644
--- a/sc/source/core/data/column2.cxx
+++ b/sc/source/core/data/column2.cxx
@@ -1376,13 +1376,13 @@ SCSIZE ScColumn::GetEmptyLinesInBlock( SCROW nStartRow, SCROW nEndRow, ScDirecti
return nLines;
}
-//UNUSED2009-05 SCROW ScColumn::GetFirstDataPos() const
-//UNUSED2009-05 {
-//UNUSED2009-05 if (nCount)
-//UNUSED2009-05 return pItems[0].nRow;
-//UNUSED2009-05 else
-//UNUSED2009-05 return 0;
-//UNUSED2009-05 }
+SCROW ScColumn::GetFirstDataPos() const
+{
+ if (nCount)
+ return pItems[0].nRow;
+ else
+ return 0;
+}
SCROW ScColumn::GetLastDataPos() const
{
diff --git a/sc/source/core/data/documen8.cxx b/sc/source/core/data/documen8.cxx
index 2b0b3821dcc2..18370d2f5a0f 100644
--- a/sc/source/core/data/documen8.cxx
+++ b/sc/source/core/data/documen8.cxx
@@ -96,6 +96,7 @@
#include "globstr.hrc"
#include "sc.hrc"
#include "charthelper.hxx"
+#include "dpobject.hxx"
#define GET_SCALEVALUE(set,id) ((const SfxUInt16Item&)(set.Get( id ))).GetValue()
@@ -700,8 +701,13 @@ BOOL ScDocument::OnlineSpellInRange( const ScRange& rSpellRange, ScAddress& rSpe
// skip everything left of rSpellPos:
while ( pCell && nRow == rSpellPos.Row() && nCol < rSpellPos.Col() )
pCell = aIter.GetNext( nCol, nRow );
- while ( pCell )
+
+ for (; pCell; pCell = aIter.GetNext(nCol, nRow))
{
+ if (pDPCollection && pDPCollection->HasDPTable(nCol, nRow, nTab))
+ // Don't spell check within datapilot table.
+ continue;
+
CellType eType = pCell->GetCellType();
if ( eType == CELLTYPE_STRING || eType == CELLTYPE_EDIT )
{
@@ -786,8 +792,6 @@ BOOL ScDocument::OnlineSpellInRange( const ScRange& rSpellRange, ScAddress& rSpe
if ( ++nCellCount >= SPELL_MAXCELLS ) // seen enough cells?
break;
-
- pCell = aIter.GetNext( nCol, nRow );
}
if ( pCell )
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index 4dd3f34e3f0d..f8fa2bc46c9b 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -639,6 +639,32 @@ BOOL ScDocument::GetTableArea( SCTAB nTab, SCCOL& rEndCol, SCROW& rEndRow ) cons
return FALSE;
}
+bool ScDocument::ShrinkToDataArea(SCTAB nTab, SCCOL& rStartCol, SCROW& rStartRow, SCCOL& rEndCol, SCROW& rEndRow) const
+{
+ if (!ValidTab(nTab) || !pTab[nTab])
+ return false;
+
+ SCCOL nCol1, nCol2;
+ SCROW nRow1, nRow2;
+ pTab[nTab]->GetFirstDataPos(nCol1, nRow1);
+ pTab[nTab]->GetLastDataPos(nCol2, nRow2);
+
+ if (nCol1 > nCol2 || nRow1 > nRow2)
+ // invalid range.
+ return false;
+
+ // Make sure the area only shrinks, and doesn't grow.
+ if (rStartCol < nCol1)
+ rStartCol = nCol1;
+ if (nCol2 < rEndCol)
+ rEndCol = nCol2;
+ if (rStartRow < nRow1)
+ rStartRow = nRow1;
+ if (nRow2 < rEndRow)
+ rEndRow = nRow2;
+
+ return true; // success!
+}
// zusammenhaengender Bereich
diff --git a/sc/source/core/data/dpgroup.cxx b/sc/source/core/data/dpgroup.cxx
index 09f32b4ba1b1..29284b20e4bb 100644
--- a/sc/source/core/data/dpgroup.cxx
+++ b/sc/source/core/data/dpgroup.cxx
@@ -70,6 +70,7 @@ using ::rtl::OUStringHash;
using ::std::vector;
using ::std::hash_set;
using ::std::hash_map;
+using ::boost::shared_ptr;
#define D_TIMEFACTOR 86400.0
@@ -977,7 +978,7 @@ String lcl_GetNumGroupForValue( double fValue, const ScDPNumGroupInfo& rInfo, bo
return lcl_GetNumGroupName( fGroupStart, rInfo, bHasNonInteger, cDecSeparator, pFormatter );
}
-ScDPGroupTableData::ScDPGroupTableData( ScDPTableData* pSource, ScDocument* pDocument ) :
+ScDPGroupTableData::ScDPGroupTableData( const shared_ptr<ScDPTableData>& pSource, ScDocument* pDocument ) :
ScDPTableData(pDocument),
pSourceData( pSource ),
pDoc( pDocument )
@@ -992,7 +993,6 @@ ScDPGroupTableData::ScDPGroupTableData( ScDPTableData* pSource, ScDocument* pDoc
ScDPGroupTableData::~ScDPGroupTableData()
{
delete[] pNumGroups;
- delete pSourceData;
}
void ScDPGroupTableData::AddGroupDimension( const ScDPGroupDimension& rGroup )
diff --git a/sc/source/core/data/dpobject.cxx b/sc/source/core/data/dpobject.cxx
index ad9795d11c4d..295ed78159b3 100644
--- a/sc/source/core/data/dpobject.cxx
+++ b/sc/source/core/data/dpobject.cxx
@@ -75,9 +75,11 @@
#include <svl/zforlist.hxx> // IsNumberFormat
#include <vector>
+#include <stdio.h>
using namespace com::sun::star;
using ::std::vector;
+using ::boost::shared_ptr;
using ::com::sun::star::uno::Sequence;
using ::com::sun::star::uno::Reference;
using ::com::sun::star::uno::UNO_QUERY;
@@ -162,11 +164,14 @@ ScDPObject::ScDPObject( ScDocument* pD ) :
pSheetDesc( NULL ),
pImpDesc( NULL ),
pServDesc( NULL ),
+ mpTableData(static_cast<ScDPTableData*>(NULL)),
pOutput( NULL ),
bSettingsChanged( FALSE ),
bAlive( FALSE ),
+ mnAutoFormatIndex( 65535 ),
bAllowMove( FALSE ),
- nHeaderRows( 0 )
+ nHeaderRows( 0 ),
+ mbHeaderLayout(false)
{
}
@@ -180,11 +185,14 @@ ScDPObject::ScDPObject(const ScDPObject& r) :
pSheetDesc( NULL ),
pImpDesc( NULL ),
pServDesc( NULL ),
+ mpTableData(static_cast<ScDPTableData*>(NULL)),
pOutput( NULL ),
bSettingsChanged( FALSE ),
bAlive( FALSE ),
+ mnAutoFormatIndex( r.mnAutoFormatIndex ),
bAllowMove( FALSE ),
- nHeaderRows( r.nHeaderRows )
+ nHeaderRows( r.nHeaderRows ),
+ mbHeaderLayout( r.mbHeaderLayout )
{
if (r.pSaveData)
pSaveData = new ScDPSaveData(*r.pSaveData);
@@ -232,6 +240,26 @@ void ScDPObject::SetSaveData(const ScDPSaveData& rData)
InvalidateData(); // re-init source from SaveData
}
+void ScDPObject::SetAutoFormatIndex(const sal_uInt16 nIndex)
+{
+ mnAutoFormatIndex = nIndex;
+}
+
+sal_uInt16 ScDPObject::GetAutoFormatIndex() const
+{
+ return mnAutoFormatIndex;
+}
+
+void ScDPObject::SetHeaderLayout (bool bUseGrid)
+{
+ mbHeaderLayout = bUseGrid;
+}
+
+bool ScDPObject::GetHeaderLayout() const
+{
+ return mbHeaderLayout;
+}
+
void ScDPObject::SetOutRange(const ScRange& rRange)
{
aOutRange = rRange;
@@ -325,6 +353,22 @@ void ScDPObject::SetTag(const String& rNew)
aTableTag = rNew;
}
+bool ScDPObject::IsDataDescriptionCell(const ScAddress& rPos)
+{
+ if (!pSaveData)
+ return false;
+
+ long nDataDimCount = pSaveData->GetDataDimensionCount();
+ if (nDataDimCount != 1)
+ // There has to be exactly one data dimension for the description to
+ // appear at top-left corner.
+ return false;
+
+ CreateOutput();
+ ScRange aTabRange = pOutput->GetOutputRange(sheet::DataPilotOutputRangeType::TABLE);
+ return (rPos == aTabRange.aStart);
+}
+
uno::Reference<sheet::XDimensionsSupplier> ScDPObject::GetSource()
{
CreateObjects();
@@ -338,6 +382,7 @@ void ScDPObject::CreateOutput()
{
BOOL bFilterButton = IsSheetData() && pSaveData && pSaveData->GetFilterButton();
pOutput = new ScDPOutput( pDoc, xSource, aOutRange.aStart, bFilterButton );
+ pOutput->SetHeaderLayout ( mbHeaderLayout );
long nOldRows = nHeaderRows;
nHeaderRows = pOutput->GetHeaderRows();
@@ -365,11 +410,43 @@ void ScDPObject::CreateOutput()
}
}
+ScDPTableData* ScDPObject::GetTableData()
+{
+ if (!mpTableData)
+ {
+ if ( pImpDesc )
+ {
+ // database data
+ mpTableData.reset(new ScDatabaseDPData(pDoc, *pImpDesc));
+ }
+ else
+ {
+ // cell data
+ if (!pSheetDesc)
+ {
+ DBG_ERROR("no source descriptor");
+ pSheetDesc = new ScSheetSourceDesc; // dummy defaults
+ }
+ mpTableData.reset(new ScSheetDPData(pDoc, *pSheetDesc));
+ }
+
+ // grouping (for cell or database data)
+ if ( pSaveData && pSaveData->GetExistingDimensionData() )
+ {
+ shared_ptr<ScDPGroupTableData> pGroupData(new ScDPGroupTableData(mpTableData, pDoc));
+ pSaveData->GetExistingDimensionData()->WriteToData(*pGroupData);
+ mpTableData = pGroupData;
+ }
+ }
+
+ return mpTableData.get();
+}
+
void ScDPObject::CreateObjects()
{
// if groups are involved, create a new source with the ScDPGroupTableData
if ( bSettingsChanged && pSaveData && pSaveData->GetExistingDimensionData() )
- xSource = NULL;
+ InvalidateSource();
if (!xSource.is())
{
@@ -387,33 +464,9 @@ void ScDPObject::CreateObjects()
if ( !xSource.is() ) // database or sheet data, or error in CreateSource
{
DBG_ASSERT( !pServDesc, "DPSource could not be created" );
-
- ScDPTableData* pData = NULL;
- if ( pImpDesc )
- {
- // database data
- pData = new ScDatabaseDPData( pDoc, *pImpDesc );
- }
- else
- {
- // cell data
- if (!pSheetDesc)
- {
- DBG_ERROR("no source descriptor");
- pSheetDesc = new ScSheetSourceDesc; // dummy defaults
- }
- pData = new ScSheetDPData( pDoc, *pSheetDesc );
- }
-
- // grouping (for cell or database data)
- if ( pSaveData && pSaveData->GetExistingDimensionData() )
- {
- ScDPGroupTableData* pGroupData = new ScDPGroupTableData( pData, pDoc );
- pSaveData->GetExistingDimensionData()->WriteToData( *pGroupData );
- pData = pGroupData;
- }
-
- xSource = new ScDPSource( pData );
+ ScDPTableData* pData = GetTableData();
+ ScDPSource* pSource = new ScDPSource( pData );
+ xSource = pSource;
}
if (pSaveData)
@@ -450,6 +503,7 @@ void ScDPObject::InvalidateData()
void ScDPObject::InvalidateSource()
{
xSource = NULL;
+ mpTableData.reset();
}
ScRange ScDPObject::GetNewOutputRange( BOOL& rOverflow )
@@ -484,6 +538,9 @@ void ScDPObject::Output( const ScAddress& rPos )
// aOutRange is always the range that was last output to the document
aOutRange = pOutput->GetOutputRange();
+ const ScAddress& s = aOutRange.aStart;
+ const ScAddress& e = aOutRange.aEnd;
+ pDoc->ApplyFlagsTab(s.Col(), s.Row(), e.Col(), e.Row(), s.Tab(), SC_MF_DP_TABLE);
}
const ScRange ScDPObject::GetOutputRangeByType( sal_Int32 nType )
@@ -533,6 +590,63 @@ void ScDPObject::RefreshAfterLoad()
nHeaderRows = 0; // nothing found, no drop-down lists
}
+void ScDPObject::BuildAllDimensionMembers()
+{
+ if (!pSaveData)
+ return;
+
+ pSaveData->BuildAllDimensionMembers(GetTableData());
+}
+
+bool ScDPObject::GetMemberNames( sal_Int32 nDim, Sequence<OUString>& rNames )
+{
+ vector<ScDPLabelData::Member> aMembers;
+ if (!GetMembers(nDim, GetUsedHierarchy(nDim), aMembers))
+ return false;
+
+ size_t n = aMembers.size();
+ rNames.realloc(n);
+ for (size_t i = 0; i < n; ++i)
+ rNames[i] = aMembers[i].maName;
+
+ return true;
+}
+
+bool ScDPObject::GetMembers( sal_Int32 nDim, sal_Int32 nHier, vector<ScDPLabelData::Member>& rMembers )
+{
+ Reference< container::XNameAccess > xMembersNA;
+ if (!GetMembersNA( nDim, nHier, xMembersNA ))
+ return false;
+
+ Reference<container::XIndexAccess> xMembersIA( new ScNameToIndexAccess(xMembersNA) );
+ sal_Int32 nCount = xMembersIA->getCount();
+ vector<ScDPLabelData::Member> aMembers;
+ aMembers.reserve(nCount);
+
+ for (sal_Int32 i = 0; i < nCount; ++i)
+ {
+ Reference<container::XNamed> xMember(xMembersIA->getByIndex(i), UNO_QUERY);
+ ScDPLabelData::Member aMem;
+
+ if (xMember.is())
+ aMem.maName = xMember->getName();
+
+ Reference<beans::XPropertySet> xMemProp(xMember, UNO_QUERY);
+ if (xMemProp.is())
+ {
+ aMem.mbVisible = ScUnoHelpFunctions::GetBoolProperty(xMemProp, OUString::createFromAscii(SC_UNO_ISVISIBL));
+ aMem.mbShowDetails = ScUnoHelpFunctions::GetBoolProperty(xMemProp, OUString::createFromAscii(SC_UNO_SHOWDETA));
+
+ aMem.maLayoutName = ScUnoHelpFunctions::GetStringProperty(
+ xMemProp, OUString::createFromAscii(SC_UNO_LAYOUTNAME), OUString());
+ }
+
+ aMembers.push_back(aMem);
+ }
+ rMembers.swap(aMembers);
+ return true;
+}
+
void ScDPObject::UpdateReference( UpdateRefMode eUpdateRefMode,
const ScRange& rRange, SCsCOL nDx, SCsROW nDy, SCsTAB nDz )
{
@@ -655,23 +769,33 @@ void ScDPObject::GetDrillDownData(const ScAddress& rPos, Sequence< Sequence<Any>
rTableData = xDrillDownData->getDrillDownData(filters);
}
-BOOL ScDPObject::IsDimNameInUse( const String& rName ) const
+bool ScDPObject::IsDimNameInUse(const OUString& rName) const
{
- if ( xSource.is() )
+ if (!xSource.is())
+ return false;
+
+ Reference<container::XNameAccess> xDims = xSource->getDimensions();
+ Sequence<OUString> aDimNames = xDims->getElementNames();
+ sal_Int32 n = aDimNames.getLength();
+ for (sal_Int32 i = 0; i < n; ++i)
{
- uno::Reference<container::XNameAccess> xDimsName = xSource->getDimensions();
- if ( xDimsName.is() )
+ const OUString& rDimName = aDimNames[i];
+ if (rDimName.equalsIgnoreAsciiCase(rName))
+ return true;
+
+ Reference<beans::XPropertySet> xPropSet(xDims->getByName(rDimName), UNO_QUERY);
+ if (!xPropSet.is())
+ continue;
+
+ Any any = xPropSet->getPropertyValue(OUString::createFromAscii(SC_UNO_LAYOUTNAME));
+ OUString aLayoutName;
+ if (any >>= aLayoutName)
{
- rtl::OUString aCompare( rName );
- uno::Sequence<rtl::OUString> aNames = xDimsName->getElementNames();
- long nCount = aNames.getLength();
- const rtl::OUString* pArr = aNames.getConstArray();
- for (long nPos=0; nPos<nCount; nPos++)
- if ( pArr[nPos] == aCompare ) //! ignore case
- return TRUE;
+ if (aLayoutName.equalsIgnoreAsciiCase(rName))
+ return true;
}
}
- return FALSE; // not found
+ return false;
}
String ScDPObject::GetDimName( long nDim, BOOL& rIsDataLayout )
@@ -1732,7 +1856,7 @@ BOOL ScDPObject::FillOldParam(ScPivotParam& rParam, BOOL bForFile) const
return TRUE;
}
-void lcl_FillLabelData( LabelData& rData, const uno::Reference< beans::XPropertySet >& xDimProp )
+void lcl_FillLabelData( ScDPLabelData& rData, const uno::Reference< beans::XPropertySet >& xDimProp )
{
uno::Reference<sheet::XHierarchiesSupplier> xDimSupp( xDimProp, uno::UNO_QUERY );
if ( xDimProp.is() && xDimSupp.is() )
@@ -1778,6 +1902,8 @@ void lcl_FillLabelData( LabelData& rData, const uno::Reference< beans::XProperty
BOOL ScDPObject::FillLabelData(ScPivotParam& rParam)
{
+ rParam.maLabelArray.clear();
+
((ScDPObject*)this)->CreateObjects();
uno::Reference<container::XNameAccess> xDimsName = xSource->getDimensions();
@@ -1788,8 +1914,6 @@ BOOL ScDPObject::FillLabelData(ScPivotParam& rParam)
if (!nDimCount)
return FALSE;
- SCSIZE nOutCount = 0;
- LabelData** aLabelArr = new LabelData*[nDimCount];
for (long nDim=0; nDim < nDimCount; nDim++)
{
String aFieldName;
@@ -1819,29 +1943,24 @@ BOOL ScDPObject::FillLabelData(ScPivotParam& rParam)
{
}
+ OUString aLayoutName = ScUnoHelpFunctions::GetStringProperty(
+ xDimProp, OUString::createFromAscii(SC_UNO_LAYOUTNAME), OUString());
+
if ( aFieldName.Len() && !bData && !bDuplicated )
{
SCsCOL nCol = static_cast< SCsCOL >( nDim ); //! ???
bool bIsValue = true; //! check
- aLabelArr[nOutCount] = new LabelData( aFieldName, nCol, bIsValue );
-
- LabelData& rLabelData = *aLabelArr[nOutCount];
- GetHierarchies( nDim, rLabelData.maHiers );
- GetMembers( nDim, rLabelData.maMembers, &rLabelData.maVisible, &rLabelData.maShowDet );
- lcl_FillLabelData( rLabelData, xDimProp );
-
- ++nOutCount;
+ ScDPLabelDataRef pNewLabel(new ScDPLabelData(aFieldName, nCol, bIsValue));
+ pNewLabel->maLayoutName = aLayoutName;
+ GetHierarchies(nDim, pNewLabel->maHiers);
+ GetMembers(nDim, GetUsedHierarchy(nDim), pNewLabel->maMembers);
+ lcl_FillLabelData(*pNewLabel, xDimProp);
+ rParam.maLabelArray.push_back(pNewLabel);
}
}
}
- rParam.SetLabelData( aLabelArr, nOutCount );
-
- for (SCSIZE i=0; i<nOutCount; i++)
- delete aLabelArr[i];
- delete[] aLabelArr;
-
return TRUE;
}
@@ -1890,14 +2009,6 @@ BOOL ScDPObject::GetMembersNA( sal_Int32 nDim, uno::Reference< container::XNameA
return GetMembersNA( nDim, GetUsedHierarchy( nDim ), xMembers );
}
-BOOL ScDPObject::GetMembers( sal_Int32 nDim,
- uno::Sequence< rtl::OUString >& rMembers,
- uno::Sequence< sal_Bool >* pVisible,
- uno::Sequence< sal_Bool >* pShowDet )
-{
- return GetMembers( nDim, GetUsedHierarchy( nDim ), rMembers, pVisible, pShowDet );
-}
-
BOOL ScDPObject::GetMembersNA( sal_Int32 nDim, sal_Int32 nHier, uno::Reference< container::XNameAccess >& xMembers )
{
BOOL bRet = FALSE;
@@ -1933,55 +2044,6 @@ BOOL ScDPObject::GetMembersNA( sal_Int32 nDim, sal_Int32 nHier, uno::Reference<
return bRet;
}
-BOOL ScDPObject::GetMembers( sal_Int32 nDim, sal_Int32 nHier,
- uno::Sequence< rtl::OUString >& rMembers,
- uno::Sequence< sal_Bool >* pVisible,
- uno::Sequence< sal_Bool >* pShowDet )
-{
- BOOL bRet = FALSE;
- uno::Reference< container::XNameAccess > xMembersNA;
- if( GetMembersNA( nDim, nHier, xMembersNA ) )
- {
- uno::Reference< container::XIndexAccess > xMembersIA( new ScNameToIndexAccess( xMembersNA ) );
- sal_Int32 nCount = xMembersIA->getCount();
- rMembers.realloc( nCount );
- if( pVisible )
- pVisible->realloc( nCount );
- if( pShowDet )
- pShowDet->realloc( nCount );
-
- rtl::OUString* pAry = rMembers.getArray();
- for( sal_Int32 nItem = 0; nItem < nCount; ++nItem )
- {
- uno::Reference< container::XNamed > xMember( xMembersIA->getByIndex( nItem ), uno::UNO_QUERY );
- if( xMember.is() )
- pAry[ nItem ] = xMember->getName();
- if( pVisible || pShowDet )
- {
- uno::Reference< beans::XPropertySet > xMemProp( xMember, uno::UNO_QUERY );
- if( pVisible )
- {
- sal_Bool bVis = sal_True;
- if( xMemProp.is() )
- bVis = ScUnoHelpFunctions::GetBoolProperty( xMemProp,
- rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_ISVISIBL ) ) );
- (*pVisible)[ nItem ] = bVis;
- }
- if( pShowDet )
- {
- sal_Bool bShow = sal_True;
- if( xMemProp.is() )
- bShow = ScUnoHelpFunctions::GetBoolProperty( xMemProp,
- rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_SHOWDETA ) ) );
- (*pShowDet)[ nItem ] = bShow;
- }
- }
- }
- bRet = TRUE;
- }
- return bRet;
-}
-
//------------------------------------------------------------------------
// convert old pivot tables into new datapilot tables
@@ -2376,7 +2438,7 @@ void ScDPCollection::WriteRefsTo( ScDPCollection& r ) const
ScDPObject* pDestObj = new ScDPObject( *pSourceObj );
pDestObj->SetAlive(TRUE);
- if ( !r.Insert(pDestObj) )
+ if ( !r.InsertNewTable(pDestObj) )
{
DBG_ERROR("cannot insert DPObject");
DELETEZ( pDestObj );
@@ -2411,6 +2473,39 @@ ScSimpleSharedString& ScDPCollection::GetSharedString()
return maSharedString;
}
+void ScDPCollection::FreeTable(ScDPObject* pDPObj)
+{
+ const ScRange& rOutRange = pDPObj->GetOutRange();
+ const ScAddress& s = rOutRange.aStart;
+ const ScAddress& e = rOutRange.aEnd;
+ pDoc->RemoveFlagsTab(s.Col(), s.Row(), e.Col(), e.Row(), s.Tab(), SC_MF_DP_TABLE);
+ Free(pDPObj);
+}
+
+bool ScDPCollection::InsertNewTable(ScDPObject* pDPObj)
+{
+ bool bSuccess = Insert(pDPObj);
+ if (bSuccess)
+ {
+ const ScRange& rOutRange = pDPObj->GetOutRange();
+ const ScAddress& s = rOutRange.aStart;
+ const ScAddress& e = rOutRange.aEnd;
+ pDoc->ApplyFlagsTab(s.Col(), s.Row(), e.Col(), e.Row(), s.Tab(), SC_MF_DP_TABLE);
+ }
+ return bSuccess;
+}
+
+bool ScDPCollection::HasDPTable(SCCOL nCol, SCROW nRow, SCTAB nTab) const
+{
+ const ScMergeFlagAttr* pMergeAttr = static_cast<const ScMergeFlagAttr*>(
+ pDoc->GetAttr(nCol, nRow, nTab, ATTR_MERGE_FLAG));
+
+ if (!pMergeAttr)
+ return false;
+
+ return pMergeAttr->HasDPTable();
+}
+
ScDPCacheCell* ScDPCollection::getCacheCellFromPool(const ScDPCacheCell& rCell)
{
ScDPCacheCell aCell(rCell);
diff --git a/sc/source/core/data/dpoutput.cxx b/sc/source/core/data/dpoutput.cxx
index d1fad68f16a2..10dcbfa8238e 100644
--- a/sc/source/core/data/dpoutput.cxx
+++ b/sc/source/core/data/dpoutput.cxx
@@ -81,6 +81,7 @@
using namespace com::sun::star;
using ::std::vector;
+using ::com::sun::star::beans::XPropertySet;
using ::com::sun::star::uno::Sequence;
using ::com::sun::star::uno::UNO_QUERY;
using ::com::sun::star::uno::Reference;
@@ -98,7 +99,6 @@ using ::rtl::OUString;
#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"
#define DP_PROP_FILTER "Filter"
@@ -119,9 +119,15 @@ struct ScDPOutLevelData
long nLevel;
long nDimPos;
uno::Sequence<sheet::MemberResult> aResult;
- String aCaption;
+ String maName; /// Name is the internal field name.
+ String aCaption; /// Caption is the name visible in the output table.
+ bool mbHasHiddenMember;
- ScDPOutLevelData() { nDim = nHier = nLevel = nDimPos = -1; }
+ ScDPOutLevelData()
+ {
+ nDim = nHier = nLevel = nDimPos = -1;
+ mbHasHiddenMember = false;
+ }
BOOL operator<(const ScDPOutLevelData& r) const
{ return nDimPos<r.nDimPos || ( nDimPos==r.nDimPos && nHier<r.nHier ) ||
@@ -370,13 +376,15 @@ ScDPOutput::ScDPOutput( ScDocument* pD, const uno::Reference<sheet::XDimensionsS
aStartPos( rPos ),
bDoFilter( bFilter ),
bResultsError( FALSE ),
+ mbHasDataLayout(false),
pColNumFmt( NULL ),
pRowNumFmt( NULL ),
nColFmtCount( 0 ),
nRowFmtCount( 0 ),
nSingleNumFmt( 0 ),
bSizesValid( FALSE ),
- bSizeOverflow( FALSE )
+ bSizeOverflow( FALSE ),
+ mbHeaderLayout( false )
{
nTabStartCol = nMemberStartCol = nDataStartCol = nTabEndCol = 0;
nTabStartRow = nMemberStartRow = nDataStartRow = nTabEndRow = 0;
@@ -413,6 +421,8 @@ ScDPOutput::ScDPOutput( ScDocument* pD, const uno::Reference<sheet::XDimensionsS
BOOL bIsDataLayout = ScUnoHelpFunctions::GetBoolProperty(
xDimProp,
rtl::OUString::createFromAscii(DP_PROP_ISDATALAYOUT) );
+ bool bHasHiddenMember = ScUnoHelpFunctions::GetBoolProperty(
+ xDimProp, OUString::createFromAscii(SC_UNO_HAS_HIDDEN_MEMBER));
if ( eDimOrient != sheet::DataPilotFieldOrientation_HIDDEN )
{
@@ -443,7 +453,17 @@ ScDPOutput::ScDPOutput( ScDocument* pD, const uno::Reference<sheet::XDimensionsS
xLevel, uno::UNO_QUERY );
if ( xLevNam.is() && xLevRes.is() )
{
- String aCaption = String(xLevNam->getName()); //! Caption...
+ String aName = xLevNam->getName();
+ OUString aCaption = aName; // Caption equals the field name by default.
+ Reference<XPropertySet> xPropSet(xLevel, UNO_QUERY);
+ if (xPropSet.is())
+ {
+ Any any = xPropSet->getPropertyValue(
+ OUString::createFromAscii(SC_UNO_LAYOUTNAME));
+ any >>= aCaption;
+ }
+
+ bool bRowFieldHasMember = false;
switch ( eDimOrient )
{
case sheet::DataPilotFieldOrientation_COLUMN:
@@ -452,7 +472,9 @@ ScDPOutput::ScDPOutput( ScDocument* pD, const uno::Reference<sheet::XDimensionsS
pColFields[nColFieldCount].nLevel = nLev;
pColFields[nColFieldCount].nDimPos = nDimPos;
pColFields[nColFieldCount].aResult = xLevRes->getResults();
+ pColFields[nColFieldCount].maName = aName;
pColFields[nColFieldCount].aCaption= aCaption;
+ pColFields[nColFieldCount].mbHasHiddenMember = bHasHiddenMember;
if (!lcl_MemberEmpty(pColFields[nColFieldCount].aResult))
++nColFieldCount;
break;
@@ -462,9 +484,14 @@ ScDPOutput::ScDPOutput( ScDocument* pD, const uno::Reference<sheet::XDimensionsS
pRowFields[nRowFieldCount].nLevel = nLev;
pRowFields[nRowFieldCount].nDimPos = nDimPos;
pRowFields[nRowFieldCount].aResult = xLevRes->getResults();
+ pRowFields[nRowFieldCount].maName = aName;
pRowFields[nRowFieldCount].aCaption= aCaption;
+ pRowFields[nRowFieldCount].mbHasHiddenMember = bHasHiddenMember;
if (!lcl_MemberEmpty(pRowFields[nRowFieldCount].aResult))
+ {
++nRowFieldCount;
+ bRowFieldHasMember = true;
+ }
break;
case sheet::DataPilotFieldOrientation_PAGE:
pPageFields[nPageFieldCount].nDim = nDim;
@@ -472,7 +499,9 @@ ScDPOutput::ScDPOutput( ScDocument* pD, const uno::Reference<sheet::XDimensionsS
pPageFields[nPageFieldCount].nLevel = nLev;
pPageFields[nPageFieldCount].nDimPos = nDimPos;
pPageFields[nPageFieldCount].aResult = lcl_GetSelectedPageAsResult(xDimProp);
+ pPageFields[nPageFieldCount].maName = aName;
pPageFields[nPageFieldCount].aCaption= aCaption;
+ pPageFields[nPageFieldCount].mbHasHiddenMember = bHasHiddenMember;
// no check on results for page fields
++nPageFieldCount;
break;
@@ -485,6 +514,9 @@ ScDPOutput::ScDPOutput( ScDocument* pD, const uno::Reference<sheet::XDimensionsS
// get number formats from data dimensions
if ( bIsDataLayout )
{
+ if (bRowFieldHasMember)
+ mbHasDataLayout = true;
+
DBG_ASSERT( nLevCount == 1, "data layout: multiple levels?" );
if ( eDimOrient == sheet::DataPilotFieldOrientation_COLUMN )
lcl_FillNumberFormats( pColNumFmt, nColFmtCount, xLevRes, xDims );
@@ -528,7 +560,7 @@ ScDPOutput::ScDPOutput( ScDocument* pD, const uno::Reference<sheet::XDimensionsS
try
{
uno::Any aAny = xSrcProp->getPropertyValue(
- rtl::OUString::createFromAscii(DP_PROP_DATADESCR) );
+ rtl::OUString::createFromAscii(SC_UNO_DATADESC) );
rtl::OUString aUStr;
aAny >>= aUStr;
aDataDescription = String( aUStr );
@@ -605,9 +637,16 @@ void ScDPOutput::HeaderCell( SCCOL nCol, SCROW nRow, SCTAB nTab,
const sheet::MemberResult& rData, BOOL bColHeader, long nLevel )
{
long nFlags = rData.Flags;
+
+ rtl::OUStringBuffer aCaptionBuf;
+ if (!(nFlags & sheet::MemberResultFlags::NUMERIC))
+ // This caption is not a number. Make sure it won't get parsed as one.
+ aCaptionBuf.append(sal_Unicode('\''));
+ aCaptionBuf.append(rData.Caption);
+
if ( nFlags & sheet::MemberResultFlags::HASMEMBER )
{
- pDoc->SetString( nCol, nRow, nTab, rData.Caption );
+ pDoc->SetString( nCol, nRow, nTab, aCaptionBuf.makeStringAndClear() );
}
else
{
@@ -638,14 +677,20 @@ void ScDPOutput::HeaderCell( SCCOL nCol, SCROW nRow, SCTAB nTab,
}
}
-void ScDPOutput::FieldCell( SCCOL nCol, SCROW nRow, SCTAB nTab, const String& rCaption, BOOL bFrame )
+void ScDPOutput::FieldCell( SCCOL nCol, SCROW nRow, SCTAB nTab, const String& rCaption,
+ bool bInTable, bool bPopup, bool bHasHiddenMember )
{
pDoc->SetString( nCol, nRow, nTab, rCaption );
- if (bFrame)
+ if (bInTable)
lcl_SetFrame( pDoc,nTab, nCol,nRow, nCol,nRow, 20 );
// Button
- pDoc->ApplyAttr( nCol, nRow, nTab, ScMergeFlagAttr(SC_MF_BUTTON) );
+ sal_uInt16 nMergeFlag = SC_MF_BUTTON;
+ if (bPopup)
+ nMergeFlag |= SC_MF_BUTTON_POPUP;
+ if (bHasHiddenMember)
+ nMergeFlag |= SC_MF_HIDDEN_MEMBER;
+ pDoc->ApplyFlagsTab(nCol, nRow, nCol, nRow, nTab, nMergeFlag);
lcl_SetStyleById( pDoc,nTab, nCol,nRow, nCol,nRow, STR_PIVOT_STYLE_FIELDNAME );
}
@@ -653,7 +698,7 @@ void ScDPOutput::FieldCell( SCCOL nCol, SCROW nRow, SCTAB nTab, const String& rC
void lcl_DoFilterButton( ScDocument* pDoc, SCCOL nCol, SCROW nRow, SCTAB nTab )
{
pDoc->SetString( nCol, nRow, nTab, ScGlobal::GetRscString(STR_CELL_FILTER) );
- pDoc->ApplyAttr( nCol, nRow, nTab, ScMergeFlagAttr(SC_MF_BUTTON) );
+ pDoc->ApplyFlagsTab(nCol, nRow, nCol, nRow, nTab, SC_MF_BUTTON);
}
void ScDPOutput::CalcSizes()
@@ -666,7 +711,11 @@ void ScDPOutput::CalcSizes()
nRowCount = aData.getLength();
const uno::Sequence<sheet::DataResult>* pRowAry = aData.getConstArray();
nColCount = nRowCount ? ( pRowAry[0].getLength() ) : 0;
- nHeaderSize = 1; // one row for field names
+
+ nHeaderSize = 1;
+ if (GetHeaderLayout() && nColFieldCount == 0)
+ // Insert an extra header row only when there is no column field.
+ nHeaderSize = 2;
// calculate output positions and sizes
@@ -775,7 +824,7 @@ void ScDPOutput::Output()
SCCOL nHdrCol = aStartPos.Col();
SCROW nHdrRow = aStartPos.Row() + nField + ( bDoFilter ? 1 : 0 );
// draw without frame for consistency with filter button:
- FieldCell( nHdrCol, nHdrRow, nTab, pPageFields[nField].aCaption, FALSE );
+ FieldCell( nHdrCol, nHdrRow, nTab, pPageFields[nField].aCaption, false, false, pPageFields[nField].mbHasHiddenMember );
SCCOL nFldCol = nHdrCol + 1;
String aPageValue;
@@ -814,7 +863,7 @@ void ScDPOutput::Output()
for (nField=0; nField<nColFieldCount; nField++)
{
SCCOL nHdrCol = nDataStartCol + (SCCOL)nField; //! check for overflow
- FieldCell( nHdrCol, nTabStartRow, nTab, pColFields[nField].aCaption );
+ FieldCell( nHdrCol, nTabStartRow, nTab, pColFields[nField].aCaption, true, true, pColFields[nField].mbHasHiddenMember );
SCROW nRowPos = nMemberStartRow + (SCROW)nField; //! check for overflow
const uno::Sequence<sheet::MemberResult> rSequence = pColFields[nField].aResult;
@@ -849,9 +898,12 @@ void ScDPOutput::Output()
for (nField=0; nField<nRowFieldCount; nField++)
{
+ bool bDataLayout = mbHasDataLayout && (nField == nRowFieldCount-1);
+
SCCOL nHdrCol = nTabStartCol + (SCCOL)nField; //! check for overflow
SCROW nHdrRow = nDataStartRow - 1;
- FieldCell( nHdrCol, nHdrRow, nTab, pRowFields[nField].aCaption );
+ FieldCell( nHdrCol, nHdrRow, nTab, pRowFields[nField].aCaption, true, !bDataLayout,
+ pRowFields[nField].mbHasHiddenMember );
SCCOL nColPos = nMemberStartCol + (SCCOL)nField; //! check for overflow
const uno::Sequence<sheet::MemberResult> rSequence = pRowFields[nField].aResult;
@@ -993,6 +1045,16 @@ void ScDPOutput::GetMemberResultNames( ScStrCollection& rNames, long nDimension
}
}
+void ScDPOutput::SetHeaderLayout(bool bUseGrid)
+{
+ mbHeaderLayout = bUseGrid;
+ bSizesValid = false;
+}
+
+bool ScDPOutput::GetHeaderLayout() const
+{
+ return mbHeaderLayout;
+}
void ScDPOutput::GetPositionData(const ScAddress& rPos, DataPilotTablePositionData& rPosData)
{
@@ -1146,7 +1208,7 @@ bool ScDPOutput::GetDataResultPositionData(vector<sheet::DataPilotFieldFilter>&
for (SCCOL nColField = 0; nColField < nColFieldCount && bFilterByCol; ++nColField)
{
sheet::DataPilotFieldFilter filter;
- filter.FieldName = pColFields[nColField].aCaption;
+ filter.FieldName = pColFields[nColField].maName;
const uno::Sequence<sheet::MemberResult> rSequence = pColFields[nColField].aResult;
const sheet::MemberResult* pArray = rSequence.getConstArray();
@@ -1163,10 +1225,15 @@ bool ScDPOutput::GetDataResultPositionData(vector<sheet::DataPilotFieldFilter>&
}
// row fields
+ bool bDataLayoutExists = (nDataFieldCount > 1);
for (SCROW nRowField = 0; nRowField < nRowFieldCount && bFilterByRow; ++nRowField)
{
+ if (bDataLayoutExists && nRowField == nRowFieldCount - 1)
+ // There is no sense including the data layout field for filtering.
+ continue;
+
sheet::DataPilotFieldFilter filter;
- filter.FieldName = pRowFields[nRowField].aCaption;
+ filter.FieldName = pRowFields[nRowField].maName;
const uno::Sequence<sheet::MemberResult> rSequence = pRowFields[nRowField].aResult;
const sheet::MemberResult* pArray = rSequence.getConstArray();
@@ -1198,8 +1265,7 @@ bool lcl_IsNamedDataField( const ScDPGetPivotDataField& rTarget, const String& r
bool lcl_IsNamedCategoryField( const ScDPGetPivotDataField& rFilter, const ScDPOutLevelData& rField )
{
- //! name from source instead of caption?
- return ScGlobal::GetpTransliteration()->isEqual( rFilter.maFieldName, rField.aCaption );
+ return ScGlobal::GetpTransliteration()->isEqual( rFilter.maFieldName, rField.maName );
}
bool lcl_IsCondition( const sheet::MemberResult& rResultEntry, const ScDPGetPivotDataField& rFilter )
diff --git a/sc/source/core/data/dpoutputgeometry.cxx b/sc/source/core/data/dpoutputgeometry.cxx
new file mode 100644
index 000000000000..9eace100c137
--- /dev/null
+++ b/sc/source/core/data/dpoutputgeometry.cxx
@@ -0,0 +1,217 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: xmldpimp.cxx,v $
+ * $Revision: 1.27.134.1 $
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "dpoutputgeometry.hxx"
+#include "address.hxx"
+
+#include <vector>
+
+using ::std::vector;
+
+ScDPOutputGeometry::ScDPOutputGeometry(const ScRange& rOutRange, bool bShowFilter, ImportType eImportType) :
+ maOutRange(rOutRange),
+ mnRowFields(0),
+ mnColumnFields(0),
+ mnPageFields(0),
+ mnDataFields(0),
+ meImportType(eImportType),
+ mbShowFilter(bShowFilter)
+{
+}
+
+ScDPOutputGeometry::~ScDPOutputGeometry()
+{
+}
+
+void ScDPOutputGeometry::setRowFieldCount(sal_uInt32 nCount)
+{
+ mnRowFields = nCount;
+}
+
+void ScDPOutputGeometry::setColumnFieldCount(sal_uInt32 nCount)
+{
+ mnColumnFields = nCount;
+}
+
+void ScDPOutputGeometry::setPageFieldCount(sal_uInt32 nCount)
+{
+ mnPageFields = nCount;
+}
+
+void ScDPOutputGeometry::setDataFieldCount(sal_uInt32 nCount)
+{
+ mnDataFields = nCount;
+}
+
+void ScDPOutputGeometry::getColumnFieldPositions(vector<ScAddress>& rAddrs) const
+{
+ vector<ScAddress> aAddrs;
+ if (!mnColumnFields)
+ {
+ rAddrs.swap(aAddrs);
+ return;
+ }
+
+ bool bDataLayout = mnDataFields > 1;
+
+ SCROW nCurRow = maOutRange.aStart.Row();
+
+ if (mnPageFields)
+ {
+ SCROW nRowStart = maOutRange.aStart.Row() + mbShowFilter;
+ SCROW nRowEnd = nRowStart + static_cast<SCCOL>(mnPageFields-1);
+ nCurRow = nRowEnd + 2;
+ }
+ else if (mbShowFilter)
+ nCurRow += 2;
+
+ SCROW nRow = nCurRow;
+ SCTAB nTab = maOutRange.aStart.Tab();
+ SCCOL nColStart = static_cast<SCCOL>(maOutRange.aStart.Col() + mnRowFields + (bDataLayout ? 1 : 0));
+ SCCOL nColEnd = nColStart + static_cast<SCCOL>(mnColumnFields-1);
+
+ for (SCCOL nCol = nColStart; nCol <= nColEnd; ++nCol)
+ aAddrs.push_back(ScAddress(nCol, nRow, nTab));
+ rAddrs.swap(aAddrs);
+}
+
+void ScDPOutputGeometry::getRowFieldPositions(vector<ScAddress>& rAddrs) const
+{
+ vector<ScAddress> aAddrs;
+ if (!mnRowFields)
+ {
+ rAddrs.swap(aAddrs);
+ return;
+ }
+
+ SCROW nRow = getRowFieldHeaderRow();
+ SCTAB nTab = maOutRange.aStart.Tab();
+ SCCOL nColStart = maOutRange.aStart.Col();
+ SCCOL nColEnd = nColStart + static_cast<SCCOL>(mnRowFields-1);
+
+ for (SCCOL nCol = nColStart; nCol <= nColEnd; ++nCol)
+ aAddrs.push_back(ScAddress(nCol, nRow, nTab));
+ rAddrs.swap(aAddrs);
+}
+
+void ScDPOutputGeometry::getPageFieldPositions(vector<ScAddress>& rAddrs) const
+{
+ vector<ScAddress> aAddrs;
+ if (!mnPageFields)
+ {
+ rAddrs.swap(aAddrs);
+ return;
+ }
+
+ SCTAB nTab = maOutRange.aStart.Tab();
+ SCCOL nCol = maOutRange.aStart.Col();
+
+ SCROW nRowStart = maOutRange.aStart.Row() + mbShowFilter;
+ SCROW nRowEnd = nRowStart + static_cast<SCCOL>(mnPageFields-1);
+
+ for (SCROW nRow = nRowStart; nRow <= nRowEnd; ++nRow)
+ aAddrs.push_back(ScAddress(nCol, nRow, nTab));
+ rAddrs.swap(aAddrs);
+}
+
+SCROW ScDPOutputGeometry::getRowFieldHeaderRow() const
+{
+ SCROW nCurRow = maOutRange.aStart.Row();
+
+ if (mnPageFields)
+ {
+ SCROW nRowStart = maOutRange.aStart.Row() + mbShowFilter;
+ SCROW nRowEnd = nRowStart + static_cast<SCCOL>(mnPageFields-1);
+ nCurRow = nRowEnd + 2;
+ }
+ else if (mbShowFilter)
+ nCurRow += 2;
+
+ if (mnColumnFields)
+ nCurRow += static_cast<SCROW>(mnColumnFields);
+ else if (mnRowFields)
+ ++nCurRow;
+
+ return nCurRow;
+}
+
+ScDPOutputGeometry::FieldType ScDPOutputGeometry::getFieldButtonType(const ScAddress& rPos) const
+{
+ // We will ignore the table position for now.
+
+ bool bExtraTitleRow = (mnColumnFields == 0 && meImportType == ScDPOutputGeometry::XLS);
+ bool bDataLayout = mnDataFields > 1;
+
+ SCROW nCurRow = maOutRange.aStart.Row();
+
+ if (mnPageFields)
+ {
+ SCCOL nCol = maOutRange.aStart.Col();
+ SCROW nRowStart = maOutRange.aStart.Row() + mbShowFilter;
+ SCROW nRowEnd = nRowStart + static_cast<SCCOL>(mnPageFields-1);
+ if (rPos.Col() == nCol && nRowStart <= rPos.Row() && rPos.Row() <= nRowEnd)
+ return Page;
+
+ nCurRow = nRowEnd + 2;
+ }
+ else if (mbShowFilter)
+ nCurRow += 2;
+
+ if (mnColumnFields)
+ {
+ SCROW nRow = nCurRow;
+ SCCOL nColStart = static_cast<SCCOL>(maOutRange.aStart.Col() + mnRowFields + (bDataLayout ? 1 : 0));
+ SCCOL nColEnd = nColStart + static_cast<SCCOL>(mnColumnFields-1);
+ if (rPos.Row() == nRow && nColStart <= rPos.Col() && rPos.Col() <= nColEnd)
+ return Column;
+
+ nCurRow += static_cast<SCROW>(mnColumnFields);
+ }
+
+ if (bExtraTitleRow)
+ ++nCurRow;
+
+ if (mnRowFields)
+ {
+ SCCOL nColStart = maOutRange.aStart.Col();
+ SCCOL nColEnd = nColStart + static_cast<SCCOL>(mnRowFields-1);
+ if (rPos.Row() == nCurRow && nColStart <= rPos.Col() && rPos.Col() <= nColEnd)
+ return Row;
+ }
+
+ return None;
+}
diff --git a/sc/source/core/data/dpsave.cxx b/sc/source/core/data/dpsave.cxx
index 62798076afb9..e66bd8dfe705 100644
--- a/sc/source/core/data/dpsave.cxx
+++ b/sc/source/core/data/dpsave.cxx
@@ -58,7 +58,15 @@
#include <com/sun/star/container/XNamed.hpp>
#include <com/sun/star/util/XCloneable.hpp>
+#include <hash_map>
+
using namespace com::sun::star;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Any;
+using ::rtl::OUString;
+using ::rtl::OUStringHash;
+using ::std::hash_map;
+using ::std::auto_ptr;
// -----------------------------------------------------------------------
@@ -99,6 +107,7 @@ void lcl_SetBoolProperty( const uno::Reference<beans::XPropertySet>& xProp,
ScDPSaveMember::ScDPSaveMember(const String& rName) :
aName( rName ),
+ mpLayoutName(NULL),
nVisibleMode( SC_DPSAVEMODE_DONTKNOW ),
nShowDetailsMode( SC_DPSAVEMODE_DONTKNOW )
{
@@ -106,9 +115,12 @@ ScDPSaveMember::ScDPSaveMember(const String& rName) :
ScDPSaveMember::ScDPSaveMember(const ScDPSaveMember& r) :
aName( r.aName ),
+ mpLayoutName(NULL),
nVisibleMode( r.nVisibleMode ),
nShowDetailsMode( r.nShowDetailsMode )
{
+ if (r.mpLayoutName.get())
+ mpLayoutName.reset(new OUString(*r.mpLayoutName));
}
ScDPSaveMember::~ScDPSaveMember()
@@ -153,12 +165,23 @@ void ScDPSaveMember::SetName( const String& rNew )
aName = rNew;
}
-void ScDPSaveMember::WriteToSource( const uno::Reference<uno::XInterface>& xMember, sal_Int32 nPosition )
+void ScDPSaveMember::SetLayoutName( const OUString& rName )
{
- // nothing to do?
- if ( nVisibleMode == SC_DPSAVEMODE_DONTKNOW && nShowDetailsMode == SC_DPSAVEMODE_DONTKNOW && nPosition < 0 )
- return;
+ mpLayoutName.reset(new OUString(rName));
+}
+
+const OUString* ScDPSaveMember::GetLayoutName() const
+{
+ return mpLayoutName.get();
+}
+
+void ScDPSaveMember::RemoveLayoutName()
+{
+ mpLayoutName.reset(NULL);
+}
+void ScDPSaveMember::WriteToSource( const uno::Reference<uno::XInterface>& xMember, sal_Int32 nPosition )
+{
uno::Reference<beans::XPropertySet> xMembProp( xMember, uno::UNO_QUERY );
DBG_ASSERT( xMembProp.is(), "no properties at member" );
if ( xMembProp.is() )
@@ -173,17 +196,11 @@ void ScDPSaveMember::WriteToSource( const uno::Reference<uno::XInterface>& xMemb
lcl_SetBoolProperty( xMembProp,
rtl::OUString::createFromAscii(DP_PROP_SHOWDETAILS), (BOOL)nShowDetailsMode );
+ if (mpLayoutName.get())
+ ScUnoHelpFunctions::SetOptionalPropertyValue(xMembProp, SC_UNO_LAYOUTNAME, *mpLayoutName);
+
if ( nPosition >= 0 )
- {
- try
- {
- xMembProp->setPropertyValue( rtl::OUString::createFromAscii(DP_PROP_POSITION), uno::Any(nPosition) );
- }
- catch ( uno::Exception& )
- {
- // position is optional - exception must be ignored
- }
- }
+ ScUnoHelpFunctions::SetOptionalPropertyValue(xMembProp, DP_PROP_POSITION, nPosition);
}
}
@@ -191,8 +208,9 @@ void ScDPSaveMember::WriteToSource( const uno::Reference<uno::XInterface>& xMemb
ScDPSaveDimension::ScDPSaveDimension(const String& rName, BOOL bDataLayout) :
aName( rName ),
- pLayoutName( NULL ),
pSelectedPage( NULL ),
+ mpLayoutName(NULL),
+ mpSubtotalName(NULL),
bIsDataLayout( bDataLayout ),
bDupFlag( FALSE ),
nOrientation( sheet::DataPilotFieldOrientation_HIDDEN ),
@@ -211,6 +229,8 @@ ScDPSaveDimension::ScDPSaveDimension(const String& rName, BOOL bDataLayout) :
ScDPSaveDimension::ScDPSaveDimension(const ScDPSaveDimension& r) :
aName( r.aName ),
+ mpLayoutName(NULL),
+ mpSubtotalName(NULL),
bIsDataLayout( r.bIsDataLayout ),
bDupFlag( r.bDupFlag ),
nOrientation( r.nOrientation ),
@@ -251,14 +271,14 @@ ScDPSaveDimension::ScDPSaveDimension(const ScDPSaveDimension& r) :
pLayoutInfo = new sheet::DataPilotFieldLayoutInfo( *(r.pLayoutInfo) );
else
pLayoutInfo = NULL;
- if (r.pLayoutName)
- pLayoutName = new String( *(r.pLayoutName) );
- else
- pLayoutName = NULL;
if (r.pSelectedPage)
pSelectedPage = new String( *(r.pSelectedPage) );
else
pSelectedPage = NULL;
+ if (r.mpLayoutName.get())
+ mpLayoutName.reset(new OUString(*r.mpLayoutName));
+ if (r.mpSubtotalName.get())
+ mpSubtotalName.reset(new OUString(*r.mpSubtotalName));
}
ScDPSaveDimension::~ScDPSaveDimension()
@@ -269,7 +289,6 @@ ScDPSaveDimension::~ScDPSaveDimension()
delete pSortInfo;
delete pAutoShowInfo;
delete pLayoutInfo;
- delete pLayoutName;
delete pSelectedPage;
delete [] pSubTotalFuncs;
}
@@ -370,25 +389,45 @@ void ScDPSaveDimension::SetUsedHierarchy(long nNew)
nUsedHierarchy = nNew;
}
-BOOL ScDPSaveDimension::HasLayoutName() const
+void ScDPSaveDimension::SetSubtotalName(const OUString& rName)
{
- return ( pLayoutName != NULL );
+ mpSubtotalName.reset(new OUString(rName));
}
-void ScDPSaveDimension::SetLayoutName(const String* pName)
+const OUString* ScDPSaveDimension::GetSubtotalName() const
{
- delete pLayoutName;
- if (pName)
- pLayoutName = new String( *pName );
- else
- pLayoutName = NULL;
+ return mpSubtotalName.get();
+}
+
+bool ScDPSaveDimension::IsMemberNameInUse(const OUString& rName) const
+{
+ MemberList::const_iterator itr = maMemberList.begin(), itrEnd = maMemberList.end();
+ for (; itr != itrEnd; ++itr)
+ {
+ const ScDPSaveMember* pMem = *itr;
+ if (rName.equalsIgnoreAsciiCase(pMem->GetName()))
+ return true;
+
+ const OUString* pLayoutName = pMem->GetLayoutName();
+ if (pLayoutName && rName.equalsIgnoreAsciiCase(*pLayoutName))
+ return true;
+ }
+ return false;
+}
+
+void ScDPSaveDimension::SetLayoutName(const OUString& rName)
+{
+ mpLayoutName.reset(new OUString(rName));
+}
+
+const OUString* ScDPSaveDimension::GetLayoutName() const
+{
+ return mpLayoutName.get();
}
-const String& ScDPSaveDimension::GetLayoutName() const
+void ScDPSaveDimension::RemoveLayoutName()
{
- if (pLayoutName)
- return *pLayoutName;
- return aName;
+ mpLayoutName.reset(NULL);
}
void ScDPSaveDimension::SetReferenceValue(const sheet::DataPilotFieldReference* pNew)
@@ -520,15 +559,15 @@ void ScDPSaveDimension::WriteToSource( const uno::Reference<uno::XInterface>& xD
aFilter = uno::Sequence<sheet::TableFilterField>( &aField, 1 );
}
// else keep empty sequence
- try
- {
- aAny <<= aFilter;
- xDimProp->setPropertyValue( rtl::OUString::createFromAscii(DP_PROP_FILTER), aAny );
- }
- catch ( beans::UnknownPropertyException& )
- {
- // recent addition - allow source to not handle it (no error)
- }
+
+ ScUnoHelpFunctions::SetOptionalPropertyValue(xDimProp, DP_PROP_FILTER, aFilter);
+ if (mpLayoutName.get())
+ ScUnoHelpFunctions::SetOptionalPropertyValue(xDimProp, SC_UNO_LAYOUTNAME, *mpLayoutName);
+
+ const OUString* pSubTotalName = GetSubtotalName();
+ if (pSubTotalName)
+ // Custom subtotal name, with '?' being replaced by the visible field name later.
+ ScUnoHelpFunctions::SetOptionalPropertyValue(xDimProp, SC_UNO_FIELD_SUBTOTALNAME, *pSubTotalName);
}
// Level loop outside of maMemberList loop
@@ -546,6 +585,8 @@ void ScDPSaveDimension::WriteToSource( const uno::Reference<uno::XInterface>& xD
nHierCount = xHiers->getCount();
}
+ sal_Bool bHasHiddenMember = false;
+
for (long nHier=0; nHier<nHierCount; nHier++)
{
uno::Reference<uno::XInterface> xHierarchy = ScUnoHelpFunctions::AnyToInterface( xHiers->getByIndex(nHier) );
@@ -585,41 +626,13 @@ void ScDPSaveDimension::WriteToSource( const uno::Reference<uno::XInterface>& xD
rtl::OUString::createFromAscii(DP_PROP_SHOWEMPTY), (BOOL)nShowEmptyMode );
if ( pSortInfo )
- {
- aAny <<= *pSortInfo;
- try
- {
- xLevProp->setPropertyValue( rtl::OUString::createFromAscii(SC_UNO_SORTING), aAny );
- }
- catch ( beans::UnknownPropertyException& )
- {
- // recent addition - allow source to not handle it (no error)
- }
- }
+ ScUnoHelpFunctions::SetOptionalPropertyValue(xLevProp, SC_UNO_SORTING, *pSortInfo);
+
if ( pAutoShowInfo )
- {
- aAny <<= *pAutoShowInfo;
- try
- {
- xLevProp->setPropertyValue( rtl::OUString::createFromAscii(SC_UNO_AUTOSHOW), aAny );
- }
- catch ( beans::UnknownPropertyException& )
- {
- // recent addition - allow source to not handle it (no error)
- }
- }
+ ScUnoHelpFunctions::SetOptionalPropertyValue(xLevProp, SC_UNO_AUTOSHOW, *pAutoShowInfo);
+
if ( pLayoutInfo )
- {
- aAny <<= *pLayoutInfo;
- try
- {
- xLevProp->setPropertyValue( rtl::OUString::createFromAscii(SC_UNO_LAYOUT), aAny );
- }
- catch ( beans::UnknownPropertyException& )
- {
- // recent addition - allow source to not handle it (no error)
- }
- }
+ ScUnoHelpFunctions::SetOptionalPropertyValue(xLevProp, SC_UNO_LAYOUT, *pLayoutInfo);
// exceptions are caught at ScDPSaveData::WriteToSource
}
@@ -638,12 +651,15 @@ void ScDPSaveDimension::WriteToSource( const uno::Reference<uno::XInterface>& xD
for (MemberList::const_iterator i=maMemberList.begin(); i != maMemberList.end() ; i++)
{
- rtl::OUString aMemberName = (*i)->GetName();
+ ScDPSaveMember* pMember = *i;
+ if (!pMember->GetIsVisible())
+ bHasHiddenMember = true;
+ rtl::OUString aMemberName = pMember->GetName();
if ( xMembers->hasByName( aMemberName ) )
{
uno::Reference<uno::XInterface> xMemberInt = ScUnoHelpFunctions::AnyToInterface(
xMembers->getByName( aMemberName ) );
- (*i)->WriteToSource( xMemberInt, nPosition );
+ pMember->WriteToSource( xMemberInt, nPosition );
if ( nPosition >= 0 )
++nPosition; // increase if initialized
@@ -655,6 +671,35 @@ void ScDPSaveDimension::WriteToSource( const uno::Reference<uno::XInterface>& xD
}
}
}
+
+ if (xDimProp.is())
+ ScUnoHelpFunctions::SetOptionalPropertyValue(xDimProp, SC_UNO_HAS_HIDDEN_MEMBER, bHasHiddenMember);
+}
+
+void ScDPSaveDimension::UpdateMemberVisibility(const hash_map<OUString, bool, OUStringHash>& rData)
+{
+ typedef hash_map<OUString, bool, OUStringHash> DataMap;
+ MemberList::iterator itrMem = maMemberList.begin(), itrMemEnd = maMemberList.end();
+ for (; itrMem != itrMemEnd; ++itrMem)
+ {
+ ScDPSaveMember* pMem = *itrMem;
+ const String& rMemName = pMem->GetName();
+ DataMap::const_iterator itr = rData.find(rMemName);
+ if (itr != rData.end())
+ pMem->SetIsVisible(itr->second);
+ }
+}
+
+bool ScDPSaveDimension::HasInvisibleMember() const
+{
+ MemberList::const_iterator itrMem = maMemberList.begin(), itrMemEnd = maMemberList.end();
+ for (; itrMem != itrMemEnd; ++itrMem)
+ {
+ const ScDPSaveMember* pMem = *itrMem;
+ if (!pMem->GetIsVisible())
+ return true;
+ }
+ return false;
}
// -----------------------------------------------------------------------
@@ -666,7 +711,9 @@ ScDPSaveData::ScDPSaveData() :
nIgnoreEmptyMode( SC_DPSAVEMODE_DONTKNOW ),
nRepeatEmptyMode( SC_DPSAVEMODE_DONTKNOW ),
bFilterButton( TRUE ),
- bDrillDown( TRUE )
+ bDrillDown( TRUE ),
+ mbDimensionMembersBuilt(false),
+ mpGrandTotalName(NULL)
{
}
@@ -676,7 +723,9 @@ ScDPSaveData::ScDPSaveData(const ScDPSaveData& r) :
nIgnoreEmptyMode( r.nIgnoreEmptyMode ),
nRepeatEmptyMode( r.nRepeatEmptyMode ),
bFilterButton( r.bFilterButton ),
- bDrillDown( r.bDrillDown )
+ bDrillDown( r.bDrillDown ),
+ mbDimensionMembersBuilt(r.mbDimensionMembersBuilt),
+ mpGrandTotalName(NULL)
{
if ( r.pDimensionData )
pDimensionData = new ScDPDimensionSaveData( *r.pDimensionData );
@@ -689,6 +738,9 @@ ScDPSaveData::ScDPSaveData(const ScDPSaveData& r) :
ScDPSaveDimension* pNew = new ScDPSaveDimension( *(ScDPSaveDimension*)r.aDimList.GetObject(i) );
aDimList.Insert( pNew, LIST_APPEND );
}
+
+ if (r.mpGrandTotalName.get())
+ mpGrandTotalName.reset(new OUString(*r.mpGrandTotalName));
}
ScDPSaveData& ScDPSaveData::operator= ( const ScDPSaveData& r )
@@ -707,6 +759,7 @@ ScDPSaveData& ScDPSaveData::operator= ( const ScDPSaveData& r )
nRepeatEmptyMode = r.nRepeatEmptyMode;
bFilterButton = r.bFilterButton;
bDrillDown = r.bDrillDown;
+ mbDimensionMembersBuilt = r.mbDimensionMembersBuilt;
// remove old dimensions
@@ -725,6 +778,9 @@ ScDPSaveData& ScDPSaveData::operator= ( const ScDPSaveData& r )
new ScDPSaveDimension( *(ScDPSaveDimension*)r.aDimList.GetObject(i) );
aDimList.Insert( pNew, LIST_APPEND );
}
+
+ if (r.mpGrandTotalName.get())
+ mpGrandTotalName.reset(new OUString(*r.mpGrandTotalName));
}
return *this;
}
@@ -736,7 +792,8 @@ BOOL ScDPSaveData::operator== ( const ScDPSaveData& r ) const
nIgnoreEmptyMode != r.nIgnoreEmptyMode ||
nRepeatEmptyMode != r.nRepeatEmptyMode ||
bFilterButton != r.bFilterButton ||
- bDrillDown != r.bDrillDown )
+ bDrillDown != r.bDrillDown ||
+ mbDimensionMembersBuilt != r.mbDimensionMembersBuilt)
return FALSE;
if ( pDimensionData || r.pDimensionData )
@@ -752,6 +809,16 @@ BOOL ScDPSaveData::operator== ( const ScDPSaveData& r ) const
*(ScDPSaveDimension*)r.aDimList.GetObject(i) ) )
return FALSE;
+ if (mpGrandTotalName.get())
+ {
+ if (!r.mpGrandTotalName.get())
+ return false;
+ if (!mpGrandTotalName->equals(*r.mpGrandTotalName))
+ return false;
+ }
+ else if (r.mpGrandTotalName.get())
+ return false;
+
return TRUE;
}
@@ -765,6 +832,16 @@ ScDPSaveData::~ScDPSaveData()
delete pDimensionData;
}
+void ScDPSaveData::SetGrandTotalName(const OUString& rName)
+{
+ mpGrandTotalName.reset(new OUString(rName));
+}
+
+const OUString* ScDPSaveData::GetGrandTotalName() const
+{
+ return mpGrandTotalName.get();
+}
+
ScDPSaveDimension* ScDPSaveData::GetDimensionByName(const String& rName)
{
long nCount = aDimList.Count();
@@ -779,7 +856,7 @@ ScDPSaveDimension* ScDPSaveData::GetDimensionByName(const String& rName)
return pNew;
}
-ScDPSaveDimension* ScDPSaveData::GetExistingDimensionByName(const String& rName)
+ScDPSaveDimension* ScDPSaveData::GetExistingDimensionByName(const String& rName) const
{
long nCount = aDimList.Count();
for (long i=0; i<nCount; i++)
@@ -807,16 +884,25 @@ ScDPSaveDimension* ScDPSaveData::GetNewDimensionByName(const String& rName)
ScDPSaveDimension* ScDPSaveData::GetDataLayoutDimension()
{
- ULONG nCount = aDimList.Count();
- for (ULONG i=0; i<nCount; i++)
+ ScDPSaveDimension* pDim = GetExistingDataLayoutDimension();
+ if (pDim)
+ return pDim;
+
+ ScDPSaveDimension* pNew = new ScDPSaveDimension( String(), TRUE );
+ aDimList.Insert( pNew, LIST_APPEND );
+ return pNew;
+}
+
+ScDPSaveDimension* ScDPSaveData::GetExistingDataLayoutDimension() const
+{
+ long nCount = aDimList.Count();
+ for (long i=0; i<nCount; i++)
{
ScDPSaveDimension* pDim = (ScDPSaveDimension*)aDimList.GetObject(i);
if ( pDim->IsDataLayout() )
return pDim;
}
- ScDPSaveDimension* pNew = new ScDPSaveDimension( String(), TRUE );
- aDimList.Insert( pNew, LIST_APPEND );
- return pNew;
+ return NULL;
}
ScDPSaveDimension* ScDPSaveData::DuplicateDimension(const String& rName)
@@ -870,6 +956,18 @@ ScDPSaveDimension* ScDPSaveData::GetInnermostDimension(USHORT nOrientation)
return pInner; // the last matching one
}
+ScDPSaveDimension* ScDPSaveData::GetFirstDimension(sheet::DataPilotFieldOrientation eOrientation)
+{
+ long nCount = aDimList.Count();
+ for (long i = 0; i < nCount; ++i)
+ {
+ ScDPSaveDimension* pDim = static_cast<ScDPSaveDimension*>(aDimList.GetObject(i));
+ if (pDim->GetOrientation() == eOrientation && !pDim->IsDataLayout())
+ return pDim;
+ }
+ return NULL;
+}
+
long ScDPSaveData::GetDataDimensionCount() const
{
long nDataCount = 0;
@@ -982,6 +1080,10 @@ void ScDPSaveData::WriteToSource( const uno::Reference<sheet::XDimensionsSupplie
{
// no error
}
+
+ const OUString* pGrandTotalName = GetGrandTotalName();
+ if (pGrandTotalName)
+ ScUnoHelpFunctions::SetOptionalPropertyValue(xSourceProp, SC_UNO_GRANDTOTAL_NAME, *pGrandTotalName);
}
// exceptions in the other calls are errors
@@ -1100,3 +1202,58 @@ void ScDPSaveData::SetDimensionData( const ScDPDimensionSaveData* pNew )
pDimensionData = NULL;
}
+void ScDPSaveData::BuildAllDimensionMembers(ScDPTableData* pData)
+{
+ if (mbDimensionMembersBuilt)
+ return;
+
+ // First, build a dimension name-to-index map.
+ typedef hash_map<OUString, long, ::rtl::OUStringHash> NameIndexMap;
+ NameIndexMap aMap;
+ long nColCount = pData->GetColumnCount();
+ for (long i = 0; i < nColCount; ++i)
+ aMap.insert( NameIndexMap::value_type(pData->getDimensionName(i), i));
+
+ NameIndexMap::const_iterator itrEnd = aMap.end();
+
+ sal_uInt32 n = aDimList.Count();
+ for (sal_uInt32 i = 0; i < n; ++i)
+ {
+ ScDPSaveDimension* pDim = static_cast<ScDPSaveDimension*>(aDimList.GetObject(i));
+ const String& rDimName = pDim->GetName();
+ if (!rDimName.Len())
+ // empty dimension name. It must be data layout.
+ continue;
+
+ NameIndexMap::const_iterator itr = aMap.find(rDimName);
+ if (itr == itrEnd)
+ // dimension name not in the data. This should never happen!
+ continue;
+
+ long nDimIndex = itr->second;
+ const TypedScStrCollection& rMembers = pData->GetColumnEntries(nDimIndex);
+ sal_uInt16 nMemberCount = rMembers.GetCount();
+ for (sal_uInt16 j = 0; j < nMemberCount; ++j)
+ {
+ const String& rMemName = rMembers[j]->GetString();
+ if (pDim->GetExistingMemberByName(rMemName))
+ // this member instance already exists. nothing to do.
+ continue;
+
+ auto_ptr<ScDPSaveMember> pNewMember(new ScDPSaveMember(rMemName));
+ pNewMember->SetIsVisible(true);
+ pDim->AddMember(pNewMember.release());
+ }
+ }
+
+ mbDimensionMembersBuilt = true;
+}
+
+bool ScDPSaveData::HasInvisibleMember(const OUString& rDimName) const
+{
+ ScDPSaveDimension* pDim = GetExistingDimensionByName(rDimName);
+ if (!pDim)
+ return false;
+
+ return pDim->HasInvisibleMember();
+}
diff --git a/sc/source/core/data/dptabres.cxx b/sc/source/core/data/dptabres.cxx
index 398d4d1c7e01..e548db56d7ff 100644
--- a/sc/source/core/data/dptabres.cxx
+++ b/sc/source/core/data/dptabres.cxx
@@ -67,6 +67,7 @@ using ::std::vector;
using ::std::pair;
using ::std::hash_map;
using ::com::sun::star::uno::Sequence;
+using ::rtl::OUString;
// -----------------------------------------------------------------------
@@ -825,11 +826,11 @@ USHORT ScDPResultData::GetMeasureRefOrient(long nMeasure) const
return pMeasRefOrient[nMeasure];
}
-String ScDPResultData::GetMeasureString(long nMeasure, BOOL bForce, ScSubTotalFunc eForceFunc) const
+String ScDPResultData::GetMeasureString(long nMeasure, BOOL bForce, ScSubTotalFunc eForceFunc, bool& rbTotalResult) const
{
// with bForce==TRUE, return function instead of "result" for single measure
// with eForceFunc != SUBTOTAL_FUNC_NONE, always use eForceFunc
-
+ rbTotalResult = false;
if ( nMeasure < 0 || ( nMeasCount == 1 && !bForce && eForceFunc == SUBTOTAL_FUNC_NONE ) )
{
// for user-specified subtotal function with all measures,
@@ -837,12 +838,19 @@ String ScDPResultData::GetMeasureString(long nMeasure, BOOL bForce, ScSubTotalFu
if ( eForceFunc != SUBTOTAL_FUNC_NONE )
return ScGlobal::GetRscString(nFuncStrIds[eForceFunc]);
+ rbTotalResult = true;
return ScGlobal::GetRscString(STR_TABLE_ERGEBNIS);
}
else
{
DBG_ASSERT( pMeasNames && nMeasure < nMeasCount, "bumm" );
-
+ ScDPDimension* pDataDim = pSource->GetDataDimension(nMeasure);
+ if (pDataDim)
+ {
+ const OUString* pLayoutName = pDataDim->GetLayoutName();
+ if (pLayoutName)
+ return *pLayoutName;
+ }
String aRet;
ScSubTotalFunc eFunc = ( eForceFunc == SUBTOTAL_FUNC_NONE ) ?
GetMeasureFunction(nMeasure) : eForceFunc;
@@ -896,6 +904,11 @@ BOOL ScDPResultData::HasCommonElement( const ScDPItemData& rFirstData, long nFir
return pSource->GetData()->HasCommonElement( rFirstData, nFirstIndex, rSecondData, nSecondIndex );
}
+const ScDPSource* ScDPResultData::GetSource() const
+{
+ return pSource;
+}
+
// -----------------------------------------------------------------------
@@ -1172,6 +1185,33 @@ void ScDPResultMember::ProcessData( const vector<ScDPItemData>& aChildMembers, c
}
}
+/**
+ * Parse subtotal string and replace all occurrences of '?' with the caption
+ * string. Do ensure that escaped characters are not translated.
+ */
+static String lcl_parseSubtotalName(const String& rSubStr, const String& rCaption)
+{
+ String aNewStr;
+ xub_StrLen n = rSubStr.Len();
+ bool bEscaped = false;
+ for (xub_StrLen i = 0; i < n; ++i)
+ {
+ sal_Unicode c = rSubStr.GetChar(i);
+ if (!bEscaped && c == sal_Unicode('\\'))
+ {
+ bEscaped = true;
+ continue;
+ }
+
+ if (!bEscaped && c == sal_Unicode('?'))
+ aNewStr.Append(rCaption);
+ else
+ aNewStr.Append(c);
+ bEscaped = false;
+ }
+ return aNewStr;
+}
+
void ScDPResultMember::FillMemberResults( uno::Sequence<sheet::MemberResult>* pSequences,
long& rPos, long nMeasure, BOOL bRoot,
const String* pMemberName,
@@ -1204,17 +1244,25 @@ void ScDPResultMember::FillMemberResults( uno::Sequence<sheet::MemberResult>* pS
}
String aCaption = aName;
+ if (pMemberDesc)
+ {
+ const OUString* pLayoutName = pMemberDesc->GetLayoutName();
+ if (pLayoutName)
+ {
+ aCaption = *pLayoutName;
+ bIsNumeric = false; // layout name is always non-numeric.
+ }
+ }
+
if ( pMemberCaption ) // use pMemberCaption if != NULL
aCaption = *pMemberCaption;
if (!aCaption.Len())
aCaption = ScGlobal::GetRscString(STR_EMPTYDATA);
- if ( !bIsNumeric )
- {
- // add a "'" character so a string isn't parsed as value in the output cell
- //! have a separate bit in Flags (MemberResultFlags) instead?
- aCaption.Insert( (sal_Unicode) '\'', 0 );
- }
+ if (bIsNumeric)
+ pArray[rPos].Flags |= sheet::MemberResultFlags::NUMERIC;
+ else
+ pArray[rPos].Flags &= ~sheet::MemberResultFlags::NUMERIC;
if ( nSize && !bRoot ) // root is overwritten by first dimension
{
@@ -1277,9 +1325,30 @@ void ScDPResultMember::FillMemberResults( uno::Sequence<sheet::MemberResult>* pS
if (bHasChild)
eForce = lcl_GetForceFunc( pParentLevel, nUserPos );
- String aSubStr = aName; //! caption?
+ bool bTotalResult = false;
+ String aSubStr = aCaption;
aSubStr += ' ';
- aSubStr += pResultData->GetMeasureString(nMemberMeasure, FALSE, eForce);
+ aSubStr += pResultData->GetMeasureString(nMemberMeasure, FALSE, eForce, bTotalResult);
+
+ if (bTotalResult)
+ {
+ if (pMemberDesc)
+ {
+ // single data field layout.
+ const OUString* pSubtotalName = pParentDim->GetSubtotalName();
+ if (pSubtotalName)
+ aSubStr = lcl_parseSubtotalName(*pSubtotalName, aCaption);
+ pArray[rPos].Flags &= ~sheet::MemberResultFlags::GRANDTOTAL;
+ }
+ else
+ {
+ // root member - subtotal (grand total?) for multi-data field layout.
+ const rtl::OUString* pGrandTotalName = pResultData->GetSource()->GetGrandTotalName();
+ if (pGrandTotalName)
+ aSubStr = *pGrandTotalName;
+ pArray[rPos].Flags |= sheet::MemberResultFlags::GRANDTOTAL;
+ }
+ }
pArray[rPos].Name = rtl::OUString(aName);
pArray[rPos].Caption = rtl::OUString(aSubStr);
@@ -2796,8 +2865,9 @@ void ScDPResultDimension::FillMemberResults( uno::Sequence<sheet::MemberResult>*
// in data layout dimension, use first member with different measures/names
if ( bIsDataLayout )
{
+ bool bTotalResult = false;
String aMbrName = pResultData->GetMeasureDimensionName( nSorted );
- String aMbrCapt = pResultData->GetMeasureString( nSorted, FALSE, SUBTOTAL_FUNC_NONE );
+ String aMbrCapt = pResultData->GetMeasureString( nSorted, FALSE, SUBTOTAL_FUNC_NONE, bTotalResult );
maMemberArray[0]->FillMemberResults( pSequences, nPos, nSorted, FALSE, &aMbrName, &aMbrCapt );
}
else if ( pMember->IsVisible() )
diff --git a/sc/source/core/data/dptabsrc.cxx b/sc/source/core/data/dptabsrc.cxx
index e123e74a20e6..2a091c8b45b5 100644
--- a/sc/source/core/data/dptabsrc.cxx
+++ b/sc/source/core/data/dptabsrc.cxx
@@ -85,6 +85,7 @@ using ::com::sun::star::uno::Reference;
using ::com::sun::star::uno::Sequence;
using ::com::sun::star::uno::Any;
using ::com::sun::star::sheet::DataPilotFieldAutoShowInfo;
+using ::rtl::OUString;
// -----------------------------------------------------------------------
@@ -141,15 +142,14 @@ ScDPSource::ScDPSource( ScDPTableData* pD ) :
pRowResRoot( NULL ),
pColResults( NULL ),
pRowResults( NULL ),
- bResultOverflow( FALSE )
+ bResultOverflow( FALSE ),
+ mpGrandTotalName(NULL)
{
pData->SetEmptyFlags( bIgnoreEmptyRows, bRepeatIfEmpty );
}
ScDPSource::~ScDPSource()
{
- delete pData; // ScDPTableData is not ref-counted
-
if (pDimensions)
pDimensions->release(); // ref-counted
@@ -163,6 +163,16 @@ ScDPSource::~ScDPSource()
delete pResData;
}
+void ScDPSource::SetGrandTotalName(const ::rtl::OUString& rName)
+{
+ mpGrandTotalName.reset(new ::rtl::OUString(rName));
+}
+
+const ::rtl::OUString* ScDPSource::GetGrandTotalName() const
+{
+ return mpGrandTotalName.get();
+}
+
USHORT ScDPSource::GetOrientation(long nColumn)
{
long i;
@@ -186,16 +196,21 @@ long ScDPSource::GetDataDimensionCount()
return nDataDimCount;
}
+ScDPDimension* ScDPSource::GetDataDimension(long nIndex)
+{
+ if (nIndex < 0 || nIndex >= nDataDimCount)
+ return NULL;
+
+ long nDimIndex = nDataDims[nIndex];
+ return GetDimensionsObject()->getByIndex(nDimIndex);
+}
+
String ScDPSource::GetDataDimName( long nIndex )
{
String aRet;
- if ( nIndex >= 0 && nIndex < nDataDimCount )
- {
- long nDimIndex = nDataDims[nIndex];
- ScDPDimension* pDim = GetDimensionsObject()->getByIndex(nDimIndex);
- if (pDim)
- aRet = String( pDim->getName() );
- }
+ ScDPDimension* pDim = GetDataDimension(nIndex);
+ if (pDim)
+ aRet = String(pDim->getName());
return aRet;
}
@@ -488,7 +503,10 @@ String ScDPSource::getDataDescription()
String aRet;
if ( pResData->GetMeasureCount() == 1 )
- aRet = pResData->GetMeasureString( 0, TRUE, SUBTOTAL_FUNC_NONE );
+ {
+ bool bTotalResult = false;
+ aRet = pResData->GetMeasureString( 0, TRUE, SUBTOTAL_FUNC_NONE, bTotalResult );
+ }
// empty for more than one measure
@@ -1132,6 +1150,7 @@ uno::Reference<beans::XPropertySetInfo> SAL_CALL ScDPSource::getPropertySetInfo(
throw(uno::RuntimeException)
{
ScUnoGuard aGuard;
+ using beans::PropertyAttribute::READONLY;
static SfxItemPropertyMapEntry aDPSourceMap_Impl[] =
{
@@ -1140,6 +1159,10 @@ uno::Reference<beans::XPropertySetInfo> SAL_CALL ScDPSource::getPropertySetInfo(
{MAP_CHAR_LEN(SC_UNO_IGNOREEM), 0, &getBooleanCppuType(), 0, 0 }, // for sheet data only
{MAP_CHAR_LEN(SC_UNO_REPEATIF), 0, &getBooleanCppuType(), 0, 0 }, // for sheet data only
{MAP_CHAR_LEN(SC_UNO_ROWGRAND), 0, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_ROWFIELDCOUNT), 0, &getCppuType(static_cast<sal_Int32*>(0)), READONLY, 0 },
+ {MAP_CHAR_LEN(SC_UNO_COLUMNFIELDCOUNT), 0, &getCppuType(static_cast<sal_Int32*>(0)), READONLY, 0 },
+ {MAP_CHAR_LEN(SC_UNO_DATAFIELDCOUNT), 0, &getCppuType(static_cast<sal_Int32*>(0)), READONLY, 0 },
+ {MAP_CHAR_LEN(SC_UNO_GRANDTOTAL_NAME), 0, &getCppuType(static_cast<OUString*>(0)), 0, 0 },
{0,0,0,0,0,0}
};
static uno::Reference<beans::XPropertySetInfo> aRef =
@@ -1161,6 +1184,12 @@ void SAL_CALL ScDPSource::setPropertyValue( const rtl::OUString& aPropertyName,
setIgnoreEmptyRows( lcl_GetBoolFromAny( aValue ) );
else if ( aNameStr.EqualsAscii( SC_UNO_REPEATIF ) )
setRepeatIfEmpty( lcl_GetBoolFromAny( aValue ) );
+ else if (aNameStr.EqualsAscii(SC_UNO_GRANDTOTAL_NAME))
+ {
+ OUString aName;
+ if (aValue >>= aName)
+ mpGrandTotalName.reset(new OUString(aName));
+ }
else
{
DBG_ERROR("unknown property");
@@ -1190,6 +1219,11 @@ uno::Any SAL_CALL ScDPSource::getPropertyValue( const rtl::OUString& aPropertyNa
aRet <<= static_cast<sal_Int32>(nColDimCount);
else if ( aNameStr.EqualsAscii( SC_UNO_DATAFIELDCOUNT ) ) // read-only
aRet <<= static_cast<sal_Int32>(nDataDimCount);
+ else if (aNameStr.EqualsAscii(SC_UNO_GRANDTOTAL_NAME))
+ {
+ if (mpGrandTotalName.get())
+ aRet <<= *mpGrandTotalName;
+ }
else
{
DBG_ERROR("unknown property");
@@ -1337,9 +1371,12 @@ ScDPDimension::ScDPDimension( ScDPSource* pSrc, long nD ) :
pHierarchies( NULL ),
nUsedHier( 0 ),
nFunction( SUBTOTAL_FUNC_SUM ), // sum is default
+ mpLayoutName(NULL),
+ mpSubtotalName(NULL),
nSourceDim( -1 ),
bHasSelectedPage( FALSE ),
- pSelectedData( NULL )
+ pSelectedData( NULL ),
+ mbHasHiddenMember(false)
{
//! hold pSource
}
@@ -1364,6 +1401,16 @@ ScDPHierarchies* ScDPDimension::GetHierarchiesObject()
return pHierarchies;
}
+const rtl::OUString* ScDPDimension::GetLayoutName() const
+{
+ return mpLayoutName.get();
+}
+
+const rtl::OUString* ScDPDimension::GetSubtotalName() const
+{
+ return mpSubtotalName.get();
+}
+
uno::Reference<container::XNameAccess> SAL_CALL ScDPDimension::getHierarchies()
throw(uno::RuntimeException)
{
@@ -1523,6 +1570,9 @@ uno::Reference<beans::XPropertySetInfo> SAL_CALL ScDPDimension::getPropertySetIn
{MAP_CHAR_LEN(SC_UNO_POSITION), 0, &getCppuType((sal_Int32*)0), 0, 0 },
{MAP_CHAR_LEN(SC_UNO_REFVALUE), 0, &getCppuType((sheet::DataPilotFieldReference*)0), 0, 0 },
{MAP_CHAR_LEN(SC_UNO_USEDHIER), 0, &getCppuType((sal_Int32*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_LAYOUTNAME), 0, &getCppuType(static_cast<rtl::OUString*>(0)), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_FIELD_SUBTOTALNAME), 0, &getCppuType(static_cast<rtl::OUString*>(0)), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_HAS_HIDDEN_MEMBER), 0, &getBooleanCppuType(), 0, 0 },
{0,0,0,0,0,0}
};
static uno::Reference<beans::XPropertySetInfo> aRef =
@@ -1593,6 +1643,20 @@ void SAL_CALL ScDPDimension::setPropertyValue( const rtl::OUString& aPropertyNam
}
DELETEZ( pSelectedData ); // invalid after changing aSelectedPage
}
+ else if (aNameStr.EqualsAscii(SC_UNO_LAYOUTNAME))
+ {
+ OUString aTmpName;
+ if (aValue >>= aTmpName)
+ mpLayoutName.reset(new OUString(aTmpName));
+ }
+ else if (aNameStr.EqualsAscii(SC_UNO_FIELD_SUBTOTALNAME))
+ {
+ OUString aTmpName;
+ if (aValue >>= aTmpName)
+ mpSubtotalName.reset(new OUString(aTmpName));
+ }
+ else if (aNameStr.EqualsAscii(SC_UNO_HAS_HIDDEN_MEMBER))
+ aValue >>= mbHasHiddenMember;
else
{
DBG_ERROR("unknown property");
@@ -1652,6 +1716,12 @@ uno::Any SAL_CALL ScDPDimension::getPropertyValue( const rtl::OUString& aPropert
else
aRet <<= uno::Sequence<sheet::TableFilterField>(0);
}
+ else if (aNameStr.EqualsAscii(SC_UNO_LAYOUTNAME))
+ aRet <<= mpLayoutName.get() ? *mpLayoutName : OUString::createFromAscii("");
+ else if (aNameStr.EqualsAscii(SC_UNO_FIELD_SUBTOTALNAME))
+ aRet <<= mpSubtotalName.get() ? *mpSubtotalName : OUString::createFromAscii("");
+ else if (aNameStr.EqualsAscii(SC_UNO_HAS_HIDDEN_MEMBER))
+ aRet <<= mbHasHiddenMember;
else
{
DBG_ERROR("unknown property");
@@ -2155,7 +2225,11 @@ uno::Sequence<sheet::MemberResult> SAL_CALL ScDPLevel::getResults() throw(uno::R
return aRet;
}
- return pSource->GetData()->getDimensionName( nSrcDim ); // (original) dimension name
+ ScDPDimension* pDim = pSource->GetDimensionsObject()->getByIndex(nSrcDim);
+ if (!pDim)
+ return rtl::OUString();
+
+ return pDim->getName();
}
void SAL_CALL ScDPLevel::setName( const ::rtl::OUString& /* rNewName */ ) throw(uno::RuntimeException)
@@ -2258,6 +2332,20 @@ uno::Any SAL_CALL ScDPLevel::getPropertyValue( const rtl::OUString& aPropertyNam
aRet <<= aAutoShowInfo;
else if ( aNameStr.EqualsAscii( SC_UNO_LAYOUT ) )
aRet <<= aLayoutInfo;
+ else if (aNameStr.EqualsAscii(SC_UNO_LAYOUTNAME))
+ {
+ // read only property
+ long nSrcDim = pSource->GetSourceDim(nDim);
+ ScDPDimension* pDim = pSource->GetDimensionsObject()->getByIndex(nSrcDim);
+ if (!pDim)
+ return aRet;
+
+ const OUString* pLayoutName = pDim->GetLayoutName();
+ if (!pLayoutName)
+ return aRet;
+
+ aRet <<= *pLayoutName;
+ }
else
{
DBG_ERROR("unknown property");
@@ -2550,6 +2638,7 @@ ScDPMember::ScDPMember( ScDPSource* pSrc, long nD, long nH, long nL,
nHier( nH ),
nLev( nL ),
maData( rN, fV, bHV ),
+ mpLayoutName(NULL),
nPosition( -1 ),
bVisible( TRUE ),
bShowDet( TRUE )
@@ -2610,6 +2699,11 @@ void ScDPMember::FillItemData( ScDPItemData& rData ) const
rData = maData;
}
+const OUString* ScDPMember::GetLayoutName() const
+{
+ return mpLayoutName.get();
+}
+
String ScDPMember::GetNameStr() const
{
return maData.aString;
@@ -2669,6 +2763,7 @@ uno::Reference<beans::XPropertySetInfo> SAL_CALL ScDPMember::getPropertySetInfo(
{MAP_CHAR_LEN(SC_UNO_ISVISIBL), 0, &getBooleanCppuType(), 0, 0 },
{MAP_CHAR_LEN(SC_UNO_POSITION), 0, &getCppuType((sal_Int32*)0), 0, 0 },
{MAP_CHAR_LEN(SC_UNO_SHOWDETA), 0, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_LAYOUTNAME), 0, &getCppuType(static_cast<rtl::OUString*>(0)), 0, 0 },
{0,0,0,0,0,0}
};
static uno::Reference<beans::XPropertySetInfo> aRef =
@@ -2692,6 +2787,12 @@ void SAL_CALL ScDPMember::setPropertyValue( const rtl::OUString& aPropertyName,
if (aValue >>= nInt)
setPosition( nInt );
}
+ else if (aNameStr.EqualsAscii(SC_UNO_LAYOUTNAME))
+ {
+ rtl::OUString aName;
+ if (aValue >>= aName)
+ mpLayoutName.reset(new rtl::OUString(aName));
+ }
else
{
DBG_ERROR("unknown property");
@@ -2711,6 +2812,8 @@ uno::Any SAL_CALL ScDPMember::getPropertyValue( const rtl::OUString& aPropertyNa
lcl_SetBoolInAny( aRet, getShowDetails() );
else if ( aNameStr.EqualsAscii( SC_UNO_POSITION ) )
aRet <<= (sal_Int32) getPosition();
+ else if (aNameStr.EqualsAscii(SC_UNO_LAYOUTNAME))
+ aRet <<= mpLayoutName.get() ? *mpLayoutName : rtl::OUString();
else
{
DBG_ERROR("unknown property");
diff --git a/sc/source/core/data/fillinfo.cxx b/sc/source/core/data/fillinfo.cxx
index c8eba91d2cc1..ac4cb9908a3f 100644
--- a/sc/source/core/data/fillinfo.cxx
+++ b/sc/source/core/data/fillinfo.cxx
@@ -332,6 +332,8 @@ void ScDocument::FillInfo( ScTableInfo& rTabInfo, SCCOL nX1, SCROW nY1, SCCOL nX
pInfo->bVOverlapped = FALSE;
pInfo->bAutoFilter = FALSE;
pInfo->bPushButton = FALSE;
+ pInfo->bPopupButton = false;
+ pInfo->bFilterActive = false;
pInfo->nRotateDir = SC_ROTDIR_NONE;
pInfo->bPrinted = FALSE; // view-intern
@@ -458,6 +460,8 @@ void ScDocument::FillInfo( ScTableInfo& rTabInfo, SCCOL nX1, SCROW nY1, SCCOL nX
BOOL bAutoFilter = ((nOverlap & SC_MF_AUTO) != 0);
BOOL bPushButton = ((nOverlap & SC_MF_BUTTON) != 0);
BOOL bScenario = ((nOverlap & SC_MF_SCENARIO) != 0);
+ bool bPopupButton = ((nOverlap & SC_MF_BUTTON_POPUP) != 0);
+ bool bFilterActive = ((nOverlap & SC_MF_HIDDEN_MEMBER) != 0);
if (bMerged||bHOverlapped||bVOverlapped)
bAnyMerged = TRUE; // intern
@@ -498,6 +502,8 @@ void ScDocument::FillInfo( ScTableInfo& rTabInfo, SCCOL nX1, SCROW nY1, SCCOL nX
pInfo->bVOverlapped = bVOverlapped;
pInfo->bAutoFilter = bAutoFilter;
pInfo->bPushButton = bPushButton;
+ pInfo->bPopupButton = bPopupButton;
+ pInfo->bFilterActive = bFilterActive;
pInfo->pLinesAttr = pLinesAttr;
pInfo->mpTLBRLine = pTLBRLine;
pInfo->mpBLTRLine = pBLTRLine;
@@ -512,7 +518,7 @@ void ScDocument::FillInfo( ScTableInfo& rTabInfo, SCCOL nX1, SCROW nY1, SCCOL nX
nCurRow >= aEmbedRange.aStart.Row() &&
nCurRow <= aEmbedRange.aEnd.Row();
- if (bPushButton || bScenario)
+ if (bScenario)
{
pInfo->pBackground = ScGlobal::GetButtonBrushItem();
pThisRowInfo->bEmptyBack = FALSE;
diff --git a/sc/source/core/data/global2.cxx b/sc/source/core/data/global2.cxx
index e6f8523a3c42..ffeb6cc0684c 100644
--- a/sc/source/core/data/global2.cxx
+++ b/sc/source/core/data/global2.cxx
@@ -56,6 +56,7 @@
#include "sc.hrc"
#include "globstr.hrc"
+using ::std::vector;
// -----------------------------------------------------------------------
@@ -817,7 +818,6 @@ bool PivotField::operator==( const PivotField& r ) const
ScPivotParam::ScPivotParam()
: nCol(0), nRow(0), nTab(0),
- ppLabelArr( NULL ), nLabels(0),
nPageCount(0), nColCount(0), nRowCount(0), nDataCount(0),
bIgnoreEmptyRows(FALSE), bDetectCategories(FALSE),
bMakeTotalCol(TRUE), bMakeTotalRow(TRUE)
@@ -828,23 +828,22 @@ ScPivotParam::ScPivotParam()
ScPivotParam::ScPivotParam( const ScPivotParam& r )
: nCol( r.nCol ), nRow( r.nRow ), nTab( r.nTab ),
- ppLabelArr( NULL ), nLabels(0),
nPageCount(0), nColCount(0), nRowCount(0), nDataCount(0),
bIgnoreEmptyRows(r.bIgnoreEmptyRows),
bDetectCategories(r.bDetectCategories),
bMakeTotalCol(r.bMakeTotalCol),
bMakeTotalRow(r.bMakeTotalRow)
{
- SetLabelData ( r.ppLabelArr, r.nLabels );
SetPivotArrays ( r.aPageArr, r.aColArr, r.aRowArr, r.aDataArr,
r.nPageCount, r.nColCount, r.nRowCount, r.nDataCount );
+
+ SetLabelData(r.maLabelArray);
}
//------------------------------------------------------------------------
__EXPORT ScPivotParam::~ScPivotParam()
{
- ClearLabelData();
}
//------------------------------------------------------------------------
@@ -860,22 +859,6 @@ __EXPORT ScPivotParam::~ScPivotParam()
//UNUSED2009-05 ClearPivotArrays();
//UNUSED2009-05 }
-//------------------------------------------------------------------------
-
-void __EXPORT ScPivotParam::ClearLabelData()
-{
- if ( (nLabels > 0) && ppLabelArr )
- {
- for ( SCSIZE i=0; i<nLabels; i++ )
- delete ppLabelArr[i];
- delete [] ppLabelArr;
- ppLabelArr = NULL;
- nLabels = 0;
- }
-}
-
-//------------------------------------------------------------------------
-
void __EXPORT ScPivotParam::ClearPivotArrays()
{
memset( aPageArr, 0, PIVOT_MAXPAGEFIELD * sizeof(PivotField) );
@@ -888,20 +871,17 @@ void __EXPORT ScPivotParam::ClearPivotArrays()
nDataCount = 0;
}
-//------------------------------------------------------------------------
-
-void __EXPORT ScPivotParam::SetLabelData( LabelData** pLabArr,
- SCSIZE nLab )
+void ScPivotParam::SetLabelData(const vector<ScDPLabelDataRef>& r)
{
- ClearLabelData();
-
- if ( (nLab > 0) && pLabArr )
+ vector<ScDPLabelDataRef> aNewArray;
+ aNewArray.reserve(r.size());
+ for (vector<ScDPLabelDataRef>::const_iterator itr = r.begin(), itrEnd = r.end();
+ itr != itrEnd; ++itr)
{
- nLabels = (nLab>MAX_LABELS) ? MAX_LABELS : nLab;
- ppLabelArr = new LabelData*[nLabels];
- for ( SCSIZE i=0; i<nLabels; i++ )
- ppLabelArr[i] = new LabelData( *(pLabArr[i]) );
+ ScDPLabelDataRef p(new ScDPLabelData(**itr));
+ aNewArray.push_back(p);
}
+ maLabelArray.swap(aNewArray);
}
//------------------------------------------------------------------------
@@ -943,10 +923,9 @@ ScPivotParam& __EXPORT ScPivotParam::operator=( const ScPivotParam& r )
bMakeTotalCol = r.bMakeTotalCol;
bMakeTotalRow = r.bMakeTotalRow;
- SetLabelData ( r.ppLabelArr, r.nLabels );
SetPivotArrays ( r.aPageArr, r.aColArr, r.aRowArr, r.aDataArr,
r.nPageCount, r.nColCount, r.nRowCount, r.nDataCount );
-
+ SetLabelData(r.maLabelArray);
return *this;
}
@@ -961,7 +940,7 @@ BOOL __EXPORT ScPivotParam::operator==( const ScPivotParam& r ) const
&& (bDetectCategories == r.bDetectCategories)
&& (bMakeTotalCol == r.bMakeTotalCol)
&& (bMakeTotalRow == r.bMakeTotalRow)
- && (nLabels == r.nLabels)
+ && (maLabelArray.size() == r.maLabelArray.size())
&& (nPageCount == r.nPageCount)
&& (nColCount == r.nColCount)
&& (nRowCount == r.nRowCount)
diff --git a/sc/source/core/data/makefile.mk b/sc/source/core/data/makefile.mk
index d2c700c5f95d..ecd3aad07c0b 100644
--- a/sc/source/core/data/makefile.mk
+++ b/sc/source/core/data/makefile.mk
@@ -79,6 +79,7 @@ SLOFILES = \
$(SLO)$/dpgroup.obj \
$(SLO)$/dpobject.obj \
$(SLO)$/dpoutput.obj \
+ $(SLO)$/dpoutputgeometry.obj \
$(SLO)$/dpsave.obj \
$(SLO)$/dpsdbtab.obj \
$(SLO)$/dpshttab.obj \
@@ -142,6 +143,7 @@ EXCEPTIONSFILES= \
$(SLO)$/dpsdbtab.obj \
$(SLO)$/dpobject.obj \
$(SLO)$/dpoutput.obj \
+ $(SLO)$/dpoutputgeometry.obj \
$(SLO)$/dpsave.obj \
$(SLO)$/dbdocutl.obj \
$(SLO)$/dptabsrc.obj \
diff --git a/sc/source/core/data/pivot2.cxx b/sc/source/core/data/pivot2.cxx
index e12df0cda6e5..951a656d841d 100644
--- a/sc/source/core/data/pivot2.cxx
+++ b/sc/source/core/data/pivot2.cxx
@@ -61,11 +61,26 @@
#include "stlsheet.hxx"
using ::com::sun::star::sheet::DataPilotFieldReference;
+using ::rtl::OUString;
// STATIC DATA -----------------------------------------------------------
// ============================================================================
-LabelData::LabelData( const String& rName, short nCol, bool bIsValue ) :
+ScDPLabelData::Member::Member() :
+ mbVisible(true),
+ mbShowDetails(true)
+{
+}
+
+OUString ScDPLabelData::Member::getDisplayName() const
+{
+ if (maLayoutName.getLength())
+ return maLayoutName;
+
+ return maName;
+}
+
+ScDPLabelData::ScDPLabelData( const String& rName, short nCol, bool bIsValue ) :
maName( rName ),
mnCol( nCol ),
mnFuncMask( PIVOT_FUNC_NONE ),
@@ -75,6 +90,14 @@ LabelData::LabelData( const String& rName, short nCol, bool bIsValue ) :
{
}
+OUString ScDPLabelData::getDisplayName() const
+{
+ if (maLayoutName.getLength())
+ return maLayoutName;
+
+ return maName;
+}
+
// ============================================================================
ScDPFuncData::ScDPFuncData( short nCol, USHORT nFuncMask ) :
diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx
index 31f9c18e3d3a..4d0eaf76a976 100644
--- a/sc/source/core/data/table2.cxx
+++ b/sc/source/core/data/table2.cxx
@@ -972,6 +972,14 @@ ScBaseCell* ScTable::GetCell( SCCOL nCol, SCROW nRow ) const
return NULL;
}
+void ScTable::GetFirstDataPos(SCCOL& rCol, SCROW& rRow) const
+{
+ rCol = 0;
+ rRow = 0;
+ while (aCol[rCol].IsEmptyData() && rCol < MAXCOL)
+ ++rCol;
+ rRow = aCol[rCol].GetFirstDataPos();
+}
void ScTable::GetLastDataPos(SCCOL& rCol, SCROW& rRow) const
{