diff options
Diffstat (limited to 'sc/source/core')
-rw-r--r-- | sc/source/core/data/attarray.cxx | 3 | ||||
-rw-r--r-- | sc/source/core/data/column2.cxx | 14 | ||||
-rw-r--r-- | sc/source/core/data/documen8.cxx | 10 | ||||
-rw-r--r-- | sc/source/core/data/document.cxx | 26 | ||||
-rw-r--r-- | sc/source/core/data/dpgroup.cxx | 4 | ||||
-rw-r--r-- | sc/source/core/data/dpobject.cxx | 329 | ||||
-rw-r--r-- | sc/source/core/data/dpoutput.cxx | 104 | ||||
-rw-r--r-- | sc/source/core/data/dpoutputgeometry.cxx | 217 | ||||
-rw-r--r-- | sc/source/core/data/dpsave.cxx | 327 | ||||
-rw-r--r-- | sc/source/core/data/dptabres.cxx | 94 | ||||
-rw-r--r-- | sc/source/core/data/dptabsrc.cxx | 129 | ||||
-rw-r--r-- | sc/source/core/data/fillinfo.cxx | 8 | ||||
-rw-r--r-- | sc/source/core/data/global2.cxx | 47 | ||||
-rw-r--r-- | sc/source/core/data/makefile.mk | 2 | ||||
-rw-r--r-- | sc/source/core/data/pivot2.cxx | 25 | ||||
-rw-r--r-- | sc/source/core/data/table2.cxx | 8 |
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 { |