sc/inc/dpcache.hxx | 1 sc/inc/dpgroup.hxx | 2 sc/inc/dpobject.hxx | 19 +++ sc/qa/unit/ucalc.cxx | 4 sc/source/core/data/dpcache.cxx | 10 +- sc/source/core/data/dpdimsave.cxx | 9 + sc/source/core/data/dpgroup.cxx | 5 + sc/source/core/data/dpobject.cxx | 184 ++++++++++++++++++++++++++++++++++--- sc/source/ui/docshell/dbdocfun.cxx | 81 ++++++++++++++-- sc/source/ui/inc/dbdocfun.hxx | 16 ++- sc/source/ui/unoobj/dapiuno.cxx | 9 - sc/source/ui/view/dbfunc3.cxx | 37 ++----- 12 files changed, 311 insertions(+), 66 deletions(-)
New commits: commit 49d3e30ec975a348b7b3d82c37137eb8ff6bb52e Author: Kohei Yoshida <kohei.yosh...@gmail.com> Date: Wed Mar 14 00:31:56 2012 -0400 When changing grouping in one pivot table, update all linked tables. We need to do this now because we now store the group field data directly in the pivot cache, which is shared by all referencing tables. Also, actions involving modification of the cache is not undoable, and making it undoable would significantly increase Calc's runtime memory footprint. So, no way. diff --git a/sc/inc/dpcache.hxx b/sc/inc/dpcache.hxx index 8ece780..ea0c085 100644 --- a/sc/inc/dpcache.hxx +++ b/sc/inc/dpcache.hxx @@ -137,6 +137,7 @@ public: void ResetGroupItems(long nDim, const ScDPNumGroupInfo& rNumInfo); SCROW SetGroupItem(long nDim, const ScDPItemData& rData); void GetGroupDimMemberIds(long nDim, std::vector<SCROW>& rIds) const; + void ClearGroupFields(); SCCOL GetDimensionIndex(const rtl::OUString& sName) const; sal_uLong GetNumberFormat( long nDim ) const; diff --git a/sc/inc/dpgroup.hxx b/sc/inc/dpgroup.hxx index b81db64..987c806 100644 --- a/sc/inc/dpgroup.hxx +++ b/sc/inc/dpgroup.hxx @@ -176,6 +176,8 @@ public: ScDPGroupTableData( const ::boost::shared_ptr<ScDPTableData>& pSource, ScDocument* pDocument ); virtual ~ScDPGroupTableData(); + boost::shared_ptr<ScDPTableData> GetSourceTableData(); + void AddGroupDimension( const ScDPGroupDimension& rGroup ); void SetNumGroupDimension( long nIndex, const ScDPNumGroupDimension& rGroup ); long GetDimensionIndex( const rtl::OUString& rName ); diff --git a/sc/inc/dpobject.hxx b/sc/inc/dpobject.hxx index 5b16b59..917759d 100644 --- a/sc/inc/dpobject.hxx +++ b/sc/inc/dpobject.hxx @@ -137,6 +137,7 @@ public: void InvalidateData(); void ClearTableData(); + void ReloadGroupTableData(); void Output( const ScAddress& rPos ); ScRange GetNewOutputRange( bool& rOverflow ); @@ -286,6 +287,8 @@ public: UpdateRefMode eMode, const ScRange& r, SCsCOL nDx, SCsROW nDy, SCsTAB nDz); private: + ScDPCache* getExistingCache(const ScRange& rRange); + void updateCache(const ScRange& rRange, const ScDPDimensionSaveData* pDimData, std::set<ScDPObject*>& rRefs); bool remove(const ScDPCache* p); }; @@ -306,6 +309,8 @@ public: const ::rtl::OUString& rName, const ScRange& rRange, const ScDPDimensionSaveData* pDimData); size_t size() const; private: + ScDPCache* getExistingCache(const rtl::OUString& rName); + void updateCache( const rtl::OUString& rName, const ScRange& rRange, const ScDPDimensionSaveData* pDimData, std::set<ScDPObject*>& rRefs); @@ -346,6 +351,9 @@ public: const ScDPDimensionSaveData* pDimData); private: + ScDPCache* getExistingCache( + sal_Int32 nSdbType, const ::rtl::OUString& rDBName, const ::rtl::OUString& rCommand); + com::sun::star::uno::Reference<com::sun::star::sdbc::XRowSet> createRowSet( sal_Int32 nSdbType, const ::rtl::OUString& rDBName, const ::rtl::OUString& rCommand); @@ -359,6 +367,7 @@ public: ~ScDPCollection(); sal_uLong ReloadCache(ScDPObject* pDPObj, std::set<ScDPObject*>& rRefs); + bool ReloadGroupsInCache(ScDPObject* pDPObj, std::set<ScDPObject*>& rRefs); SC_DLLPUBLIC size_t GetCount() const; SC_DLLPUBLIC ScDPObject* operator[](size_t nIndex); diff --git a/sc/source/core/data/dpcache.cxx b/sc/source/core/data/dpcache.cxx index 6ad497e..fe262ac 100644 --- a/sc/source/core/data/dpcache.cxx +++ b/sc/source/core/data/dpcache.cxx @@ -1053,6 +1053,12 @@ struct ClearGroupItems : std::unary_function<ScDPCache::Field, void> } +void ScDPCache::ClearGroupFields() +{ + maGroupFields.clear(); + std::for_each(maFields.begin(), maFields.end(), ClearGroupItems()); +} + SCROW ScDPCache::GetOrder(long nDim, SCROW nIndex) const { OSL_ENSURE( nDim >=0 && nDim < mnColumnCount, "ScDPTableDataCache::GetOrder : out of bound" ); diff --git a/sc/source/core/data/dpgroup.cxx b/sc/source/core/data/dpgroup.cxx index 9b7720d..aca81eb 100644 --- a/sc/source/core/data/dpgroup.cxx +++ b/sc/source/core/data/dpgroup.cxx @@ -547,6 +547,11 @@ ScDPGroupTableData::~ScDPGroupTableData() delete[] pNumGroups; } +boost::shared_ptr<ScDPTableData> ScDPGroupTableData::GetSourceTableData() +{ + return pSourceData; +} + void ScDPGroupTableData::AddGroupDimension( const ScDPGroupDimension& rGroup ) { ScDPGroupDimension aNewGroup( rGroup ); diff --git a/sc/source/core/data/dpobject.cxx b/sc/source/core/data/dpobject.cxx index e5496c8..6348b7f 100644 --- a/sc/source/core/data/dpobject.cxx +++ b/sc/source/core/data/dpobject.cxx @@ -483,10 +483,6 @@ ScDPTableData* ScDPObject::GetTableData() void ScDPObject::CreateObjects() { - // if groups are involved, create a new source with the ScDPGroupTableData - if ( bSettingsChanged && pSaveData && pSaveData->GetExistingDimensionData() ) - ClearTableData(); - if (!xSource.is()) { //! cache DPSource and/or Output? @@ -551,6 +547,43 @@ void ScDPObject::ClearTableData() mpTableData.reset(); } +void ScDPObject::ReloadGroupTableData() +{ + ClearSource(); + + if (!mpTableData) + // Table data not built yet. No need to reload the group data. + return; + + if (!pSaveData) + // How could it not have the save data... but whatever. + return; + + const ScDPDimensionSaveData* pDimData = pSaveData->GetExistingDimensionData(); + if (!pDimData) + // No dimension data. Most likey it doesn't have any group dimensions. + return; + + ScDPGroupTableData* pData = dynamic_cast<ScDPGroupTableData*>(mpTableData.get()); + if (pData) + { + // This is already a group table data. Salvage the source data and + // re-create a new group data. + shared_ptr<ScDPTableData> pSource = pData->GetSourceTableData(); + shared_ptr<ScDPGroupTableData> pGroupData(new ScDPGroupTableData(pSource, pDoc)); + pDimData->WriteToData(*pGroupData); + mpTableData = pGroupData; + } + else + { + // This is a source data. Create a group data based on it. + shared_ptr<ScDPGroupTableData> pGroupData(new ScDPGroupTableData(mpTableData, pDoc)); + pDimData->WriteToData(*pGroupData); + mpTableData = pGroupData; + } + bSettingsChanged = true; +} + void ScDPObject::ClearSource() { Reference< XComponent > xObjectComp( xSource, UNO_QUERY ); @@ -2548,6 +2581,25 @@ const ScDPCache* ScDPCollection::SheetCaches::getCache(const ScRange& rRange, co return p; } +ScDPCache* ScDPCollection::SheetCaches::getExistingCache(const ScRange& rRange) +{ + RangeIndexType::iterator it = std::find(maRanges.begin(), maRanges.end(), rRange); + if (it == maRanges.end()) + // Not cached. + return NULL; + + // Already cached. + size_t nIndex = std::distance(maRanges.begin(), it); + CachesType::iterator itCache = maCaches.find(nIndex); + if (itCache == maCaches.end()) + { + OSL_FAIL("Cache pool and index pool out-of-sync !!!"); + return NULL; + } + + return itCache->second; +} + size_t ScDPCollection::SheetCaches::size() const { return maCaches.size(); @@ -2658,6 +2710,12 @@ const ScDPCache* ScDPCollection::NameCaches::getCache( return p; } +ScDPCache* ScDPCollection::NameCaches::getExistingCache(const OUString& rName) +{ + CachesType::iterator itr = maCaches.find(rName); + return itr != maCaches.end() ? itr->second : NULL; +} + size_t ScDPCollection::NameCaches::size() const { return maCaches.size(); @@ -2742,6 +2800,14 @@ const ScDPCache* ScDPCollection::DBCaches::getCache( return p; } +ScDPCache* ScDPCollection::DBCaches::getExistingCache( + sal_Int32 nSdbType, const OUString& rDBName, const OUString& rCommand) +{ + DBType aType(nSdbType, rDBName, rCommand); + CachesType::iterator itr = maCaches.find(aType); + return itr != maCaches.end() ? itr->second : NULL; +} + uno::Reference<sdbc::XRowSet> ScDPCollection::DBCaches::createRowSet( sal_Int32 nSdbType, const ::rtl::OUString& rDBName, const ::rtl::OUString& rCommand) { @@ -2966,6 +3032,94 @@ sal_uLong ScDPCollection::ReloadCache(ScDPObject* pDPObj, std::set<ScDPObject*>& return 0; } +bool ScDPCollection::ReloadGroupsInCache(ScDPObject* pDPObj, std::set<ScDPObject*>& rRefs) +{ + if (!pDPObj) + return false; + + const ScDPSaveData* pSaveData = pDPObj->GetSaveData(); + if (!pSaveData) + return false; + + // Note: Unlike reloading cache, when modifying the group dimensions the + // cache may not have all its references when this method is called. + // Therefore, we need to always call GetAllTables to get its correct + // references even when the cache exists. This may become a non-issue + // if/when we implement loading and saving of pivot caches. + + ScDPCache* pCache = NULL; + + if (pDPObj->IsSheetData()) + { + // data source is internal sheet. + const ScSheetSourceDesc* pDesc = pDPObj->GetSheetDesc(); + if (!pDesc) + return false; + + if (pDesc->HasRangeName()) + { + // cache by named range + ScDPCollection::NameCaches& rCaches = GetNameCaches(); + if (rCaches.hasCache(pDesc->GetRangeName())) + pCache = rCaches.getExistingCache(pDesc->GetRangeName()); + else + { + // Not cached yet. Cache the source dimensions. Groups will + // be added below. + pCache = const_cast<ScDPCache*>( + rCaches.getCache(pDesc->GetRangeName(), pDesc->GetSourceRange(), NULL)); + } + GetAllTables(pDesc->GetRangeName(), rRefs); + } + else + { + // cache by cell range + ScDPCollection::SheetCaches& rCaches = GetSheetCaches(); + if (rCaches.hasCache(pDesc->GetSourceRange())) + pCache = rCaches.getExistingCache(pDesc->GetSourceRange()); + else + { + // Not cached yet. Cache the source dimensions. Groups will + // be added below. + pCache = const_cast<ScDPCache*>( + rCaches.getCache(pDesc->GetSourceRange(), NULL)); + } + GetAllTables(pDesc->GetSourceRange(), rRefs); + } + } + else if (pDPObj->IsImportData()) + { + // data source is external database. + const ScImportSourceDesc* pDesc = pDPObj->GetImportSourceDesc(); + if (!pDesc) + return false; + + ScDPCollection::DBCaches& rCaches = GetDBCaches(); + if (rCaches.hasCache(pDesc->GetCommandType(), pDesc->aDBName, pDesc->aObject)) + pCache = rCaches.getExistingCache( + pDesc->GetCommandType(), pDesc->aDBName, pDesc->aObject); + else + { + // Not cached yet. Cache the source dimensions. Groups will + // be added below. + pCache = const_cast<ScDPCache*>( + rCaches.getCache(pDesc->GetCommandType(), pDesc->aDBName, pDesc->aObject, NULL)); + } + GetAllTables(pDesc->GetCommandType(), pDesc->aDBName, pDesc->aObject, rRefs); + } + + if (!pCache) + return false; + + // Clear the existing group data from the cache, and rebuild it from the + // dimension data. + pCache->ClearGroupFields(); + const ScDPDimensionSaveData* pDimData = pSaveData->GetExistingDimensionData(); + if (pDimData) + pDimData->WriteToCache(*pCache); + return true; +} + void ScDPCollection::DeleteOnTab( SCTAB nTab ) { maTables.erase_if(MatchByTable(nTab)); diff --git a/sc/source/ui/docshell/dbdocfun.cxx b/sc/source/ui/docshell/dbdocfun.cxx index d1644b4..2881e1d 100644 --- a/sc/source/ui/docshell/dbdocfun.cxx +++ b/sc/source/ui/docshell/dbdocfun.cxx @@ -51,6 +51,7 @@ #include "rangenam.hxx" #include "olinetab.hxx" #include "dpobject.hxx" +#include "dpsave.hxx" #include "dociter.hxx" // for lcl_EmptyExcept #include "cell.hxx" // for lcl_EmptyExcept #include "editable.hxx" @@ -1453,7 +1454,7 @@ bool ScDBDocFunc::DataPilotUpdate( ScDPObject* pOldObj, const ScDPObject* pNewOb return bDone; } -sal_uLong ScDBDocFunc::RefreshPivotTables(ScDPObject* pDPObj, bool bRecord, bool bApi) +sal_uLong ScDBDocFunc::RefreshPivotTables(ScDPObject* pDPObj, bool bApi) { ScDPCollection* pDPs = rDocShell.GetDocument()->GetDPCollection(); if (!pDPs) @@ -1468,12 +1469,49 @@ sal_uLong ScDBDocFunc::RefreshPivotTables(ScDPObject* pDPObj, bool bRecord, bool for (; it != itEnd; ++it) { ScDPObject* pObj = *it; - DataPilotUpdate(pObj, pObj, bRecord, bApi); + // This action is intentionally not undoable since it modifies cache. + DataPilotUpdate(pObj, pObj, false, bApi); } return 0; } +void ScDBDocFunc::RefreshPivotTableGroups(ScDPObject* pDPObj) +{ + if (!pDPObj) + return; + + ScDPCollection* pDPs = rDocShell.GetDocument()->GetDPCollection(); + if (!pDPs) + return; + + ScDPSaveData* pSaveData = pDPObj->GetSaveData(); + if (!pSaveData) + return; + + std::set<ScDPObject*> aRefs; + if (!pDPs->ReloadGroupsInCache(pDPObj, aRefs)) + return; + + // We allow pDimData being NULL. + const ScDPDimensionSaveData* pDimData = pSaveData->GetExistingDimensionData(); + std::set<ScDPObject*>::iterator it = aRefs.begin(), itEnd = aRefs.end(); + for (; it != itEnd; ++it) + { + ScDPObject* pObj = *it; + if (pObj != pDPObj) + { + pSaveData = pObj->GetSaveData(); + if (pSaveData) + pSaveData->SetDimensionData(pDimData); + } + + pObj->ReloadGroupTableData(); + // This action is intentionally not undoable since it modifies cache. + DataPilotUpdate(pObj, pObj, false, false); + } +} + //================================================================== // // database import diff --git a/sc/source/ui/inc/dbdocfun.hxx b/sc/source/ui/inc/dbdocfun.hxx index b7beda9..9658fef 100644 --- a/sc/source/ui/inc/dbdocfun.hxx +++ b/sc/source/ui/inc/dbdocfun.hxx @@ -105,7 +105,13 @@ public: * Reload the referenced pivot cache, and refresh all pivot tables that * reference the cache. */ - sal_uLong RefreshPivotTables(ScDPObject* pDPObj, bool bRecord, bool bApi); + sal_uLong RefreshPivotTables(ScDPObject* pDPObj, bool bApi); + + /** + * Refresh the group dimensions of all pivot tables referencing the same + * cache. + */ + void RefreshPivotTableGroups(ScDPObject* pDPObj); }; diff --git a/sc/source/ui/unoobj/dapiuno.cxx b/sc/source/ui/unoobj/dapiuno.cxx index 85e2495..d1d7d96 100644 --- a/sc/source/ui/unoobj/dapiuno.cxx +++ b/sc/source/ui/unoobj/dapiuno.cxx @@ -1276,7 +1276,7 @@ void SAL_CALL ScDataPilotTableObj::refresh() throw(RuntimeException) if (pDPObj) { ScDBDocFunc aFunc(*GetDocShell()); - aFunc.RefreshPivotTables(pDPObj, true, true); + aFunc.RefreshPivotTables(pDPObj, true); } } diff --git a/sc/source/ui/view/dbfunc3.cxx b/sc/source/ui/view/dbfunc3.cxx index e86d585..f6eb887 100644 --- a/sc/source/ui/view/dbfunc3.cxx +++ b/sc/source/ui/view/dbfunc3.cxx @@ -707,7 +707,7 @@ void ScDBFunc::RecalcPivotTable() // Remove existing data cache for the data that this datapilot uses, // to force re-build data cache. ScDBDocFunc aFunc(*pDocSh); - aFunc.RefreshPivotTables(pDPObj, true, false); + aFunc.RefreshPivotTables(pDPObj, false); CursorPosChanged(); // shells may be switched } @@ -1081,7 +1081,7 @@ void ScDBFunc::DateGroupDataPilot( const ScDPNumGroupInfo& rInfo, sal_Int32 nPar // apply changes ScDBDocFunc aFunc( *GetViewData()->GetDocShell() ); pDPObj->SetSaveData( aData ); - aFunc.DataPilotUpdate( pDPObj, pDPObj, true, false ); + aFunc.RefreshPivotTableGroups(pDPObj); // unmark cell selection Unmark(); @@ -1123,7 +1123,7 @@ void ScDBFunc::NumGroupDataPilot( const ScDPNumGroupInfo& rInfo ) // apply changes ScDBDocFunc aFunc( *GetViewData()->GetDocShell() ); pDPObj->SetSaveData( aData ); - aFunc.DataPilotUpdate( pDPObj, pDPObj, true, false ); + aFunc.RefreshPivotTableGroups(pDPObj); // unmark cell selection Unmark(); @@ -1264,7 +1264,7 @@ void ScDBFunc::GroupDataPilot() // apply changes ScDBDocFunc aFunc( *GetViewData()->GetDocShell() ); pDPObj->SetSaveData( aData ); - aFunc.DataPilotUpdate( pDPObj, pDPObj, true, false ); + aFunc.RefreshPivotTableGroups(pDPObj); // unmark cell selection Unmark(); @@ -1288,8 +1288,11 @@ void ScDBFunc::UngroupDataPilot() OUString aDimName = pDPObj->GetDimName( nSelectDimension, bIsDataLayout ); ScDPSaveData aData( *pDPObj->GetSaveData() ); - ScDPDimensionSaveData* pDimData = aData.GetDimensionData(); // created if not there - //! test first if DimensionData exists? + if (!aData.GetExistingDimensionData()) + // There is nothing to ungroup. + return; + + ScDPDimensionSaveData* pDimData = aData.GetDimensionData(); bool bApply = false; @@ -1343,7 +1346,7 @@ void ScDBFunc::UngroupDataPilot() // apply changes ScDBDocFunc aFunc( *GetViewData()->GetDocShell() ); pDPObj->SetSaveData( aData ); - aFunc.DataPilotUpdate( pDPObj, pDPObj, true, false ); + aFunc.RefreshPivotTableGroups(pDPObj); // unmark cell selection Unmark(); commit 6aeed3c93bb8c123154bbe47702080c9c1176f39 Author: Kohei Yoshida <kohei.yosh...@gmail.com> Date: Tue Mar 13 16:30:49 2012 -0400 Re-added ClearSource() which will only clear the source. Nothing else. diff --git a/sc/inc/dpobject.hxx b/sc/inc/dpobject.hxx index 5f5496e..5b16b59 100644 --- a/sc/inc/dpobject.hxx +++ b/sc/inc/dpobject.hxx @@ -114,8 +114,11 @@ private: SC_DLLPRIVATE ScDPTableData* GetTableData(); SC_DLLPRIVATE void CreateObjects(); SC_DLLPRIVATE void CreateOutput(); - - bool FillLabelDataForDimension(const com::sun::star::uno::Reference<com::sun::star::container::XIndexAccess>& xDims, sal_Int32 nDim, ScDPLabelData& rLabelData); + SC_DLLPRIVATE void ClearSource(); + SC_DLLPRIVATE bool FillLabelDataForDimension( + const com::sun::star::uno::Reference< + com::sun::star::container::XIndexAccess>& xDims, + sal_Int32 nDim, ScDPLabelData& rLabelData); public: ScDPObject(ScDocument* pD); diff --git a/sc/source/core/data/dpobject.cxx b/sc/source/core/data/dpobject.cxx index 31afb26..e5496c8 100644 --- a/sc/source/core/data/dpobject.cxx +++ b/sc/source/core/data/dpobject.cxx @@ -544,8 +544,17 @@ void ScDPObject::InvalidateData() void ScDPObject::ClearTableData() { + ClearSource(); + + if (mpTableData) + mpTableData->GetCacheTable().getCache()->RemoveReference(this); + mpTableData.reset(); +} + +void ScDPObject::ClearSource() +{ Reference< XComponent > xObjectComp( xSource, UNO_QUERY ); - if ( xObjectComp.is() ) + if (xObjectComp.is()) { try { @@ -557,9 +566,6 @@ void ScDPObject::ClearTableData() } } xSource = NULL; - if (mpTableData) - mpTableData->GetCacheTable().getCache()->RemoveReference(this); - mpTableData.reset(); } ScRange ScDPObject::GetNewOutputRange( bool& rOverflow ) diff --git a/sc/source/ui/view/dbfunc3.cxx b/sc/source/ui/view/dbfunc3.cxx index 7cbd71c..e86d585 100644 --- a/sc/source/ui/view/dbfunc3.cxx +++ b/sc/source/ui/view/dbfunc3.cxx @@ -1150,7 +1150,7 @@ void ScDBFunc::GroupDataPilot() ScDPDimensionSaveData* pDimData = aData.GetDimensionData(); // created if not there // find original base - String aBaseDimName( aDimName ); + rtl::OUString aBaseDimName = aDimName; const ScDPSaveGroupDimension* pBaseGroupDim = pDimData->GetNamedGroupDim( aDimName ); if ( pBaseGroupDim ) { commit 49cb939de712163c90f3e989c846a68d5ae86ee2 Author: Kohei Yoshida <kohei.yosh...@gmail.com> Date: Tue Mar 13 16:07:16 2012 -0400 Rename ClearSource() to ClearTableData(). diff --git a/sc/inc/dpobject.hxx b/sc/inc/dpobject.hxx index 5f3963d..5f5496e 100644 --- a/sc/inc/dpobject.hxx +++ b/sc/inc/dpobject.hxx @@ -133,8 +133,7 @@ public: void SetAllowMove(bool bSet); void InvalidateData(); - void ClearSource(); - + void ClearTableData(); void Output( const ScAddress& rPos ); ScRange GetNewOutputRange( bool& rOverflow ); diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx index 0079758..cf1526f 100644 --- a/sc/qa/unit/ucalc.cxx +++ b/sc/qa/unit/ucalc.cxx @@ -1358,7 +1358,7 @@ void Test::testPivotTable() pDPs->InsertNewTable(pDPObj2); aOutRange = pDPObj2->GetOutRange(); - pDPObj2->ClearSource(); + pDPObj2->ClearTableData(); pDPObj2->Output(aOutRange.aStart); { // Expected output table content. 0 = empty cell @@ -1394,7 +1394,7 @@ void Test::testPivotTable() CPPUNIT_ASSERT_MESSAGE("Reloading a cache shouldn't remove any cache.", pDPs->GetSheetCaches().size() == 1); - pDPObj2->ClearSource(); + pDPObj2->ClearTableData(); pDPObj2->Output(aOutRange.aStart); { diff --git a/sc/source/core/data/dpcache.cxx b/sc/source/core/data/dpcache.cxx index 0281a54..6ad497e 100644 --- a/sc/source/core/data/dpcache.cxx +++ b/sc/source/core/data/dpcache.cxx @@ -242,7 +242,7 @@ struct ClearObjectSource : std::unary_function<ScDPObject*, void> { void operator() (ScDPObject* p) const { - p->ClearSource(); + p->ClearTableData(); } }; diff --git a/sc/source/core/data/dpobject.cxx b/sc/source/core/data/dpobject.cxx index 3b192b5..31afb26 100644 --- a/sc/source/core/data/dpobject.cxx +++ b/sc/source/core/data/dpobject.cxx @@ -213,7 +213,7 @@ ScDPObject::~ScDPObject() delete pSheetDesc; delete pImpDesc; delete pServDesc; - ClearSource(); + ClearTableData(); } void ScDPObject::EnableGetPivotData(bool b) @@ -282,7 +282,7 @@ void ScDPObject::SetSheetDesc(const ScSheetSourceDesc& rDesc) aParam.bHasHeader = true; pSheetDesc->SetQueryParam(aParam); - ClearSource(); // new source must be created + ClearTableData(); // new source must be created } void ScDPObject::SetImportDesc(const ScImportSourceDesc& rDesc) @@ -296,7 +296,7 @@ void ScDPObject::SetImportDesc(const ScImportSourceDesc& rDesc) delete pImpDesc; pImpDesc = new ScImportSourceDesc(rDesc); - ClearSource(); // new source must be created + ClearTableData(); // new source must be created } void ScDPObject::SetServiceData(const ScDPServiceDesc& rDesc) @@ -310,7 +310,7 @@ void ScDPObject::SetServiceData(const ScDPServiceDesc& rDesc) delete pServDesc; pServDesc = new ScDPServiceDesc(rDesc); - ClearSource(); // new source must be created + ClearTableData(); // new source must be created } void ScDPObject::WriteSourceDataTo( ScDPObject& rDest ) const @@ -485,7 +485,7 @@ void ScDPObject::CreateObjects() { // if groups are involved, create a new source with the ScDPGroupTableData if ( bSettingsChanged && pSaveData && pSaveData->GetExistingDimensionData() ) - ClearSource(); + ClearTableData(); if (!xSource.is()) { @@ -542,7 +542,7 @@ void ScDPObject::InvalidateData() bSettingsChanged = true; } -void ScDPObject::ClearSource() +void ScDPObject::ClearTableData() { Reference< XComponent > xObjectComp( xSource, UNO_QUERY ); if ( xObjectComp.is() ) diff --git a/sc/source/ui/docshell/dbdocfun.cxx b/sc/source/ui/docshell/dbdocfun.cxx index e560741..d1644b4 100644 --- a/sc/source/ui/docshell/dbdocfun.cxx +++ b/sc/source/ui/docshell/dbdocfun.cxx @@ -1324,7 +1324,7 @@ bool ScDBDocFunc::DataPilotUpdate( ScDPObject* pOldObj, const ScDPObject* pNewOb // (and re-read column entry collections) // so all changes take effect if ( pNewObj == pOldObj && pDestObj->IsImportData() ) - pDestObj->ClearSource(); + pDestObj->ClearTableData(); pDestObj->InvalidateData(); // before getting the new output area commit b4af9a6a902bef4d4f6dc4e550097ef8b6254abd Author: Kohei Yoshida <kohei.yosh...@gmail.com> Date: Tue Mar 13 14:33:21 2012 -0400 Let's just do the whole thing in the new method. diff --git a/sc/source/ui/docshell/dbdocfun.cxx b/sc/source/ui/docshell/dbdocfun.cxx index 3a5e0fd..e560741 100644 --- a/sc/source/ui/docshell/dbdocfun.cxx +++ b/sc/source/ui/docshell/dbdocfun.cxx @@ -61,6 +61,8 @@ #include "queryentry.hxx" #include "markdata.hxx" +#include <set> + using namespace ::com::sun::star; // ----------------------------------------------------------------- @@ -1451,14 +1453,25 @@ bool ScDBDocFunc::DataPilotUpdate( ScDPObject* pOldObj, const ScDPObject* pNewOb return bDone; } -void ScDBDocFunc::RefreshPivotTables(std::set<ScDPObject*>& rRefs, bool bRecord, bool bApi) +sal_uLong ScDBDocFunc::RefreshPivotTables(ScDPObject* pDPObj, bool bRecord, bool bApi) { - std::set<ScDPObject*>::iterator it = rRefs.begin(), itEnd = rRefs.end(); + ScDPCollection* pDPs = rDocShell.GetDocument()->GetDPCollection(); + if (!pDPs) + return 0; + + std::set<ScDPObject*> aRefs; + sal_uLong nErrId = pDPs->ReloadCache(pDPObj, aRefs); + if (nErrId) + return nErrId; + + std::set<ScDPObject*>::iterator it = aRefs.begin(), itEnd = aRefs.end(); for (; it != itEnd; ++it) { ScDPObject* pObj = *it; DataPilotUpdate(pObj, pObj, bRecord, bApi); } + + return 0; } //================================================================== diff --git a/sc/source/ui/inc/dbdocfun.hxx b/sc/source/ui/inc/dbdocfun.hxx index 79956e5..b7beda9 100644 --- a/sc/source/ui/inc/dbdocfun.hxx +++ b/sc/source/ui/inc/dbdocfun.hxx @@ -33,8 +33,6 @@ #include <tools/solar.h> #include <com/sun/star/uno/Sequence.hxx> -#include <set> - class String; struct ScImportParam; @@ -104,12 +102,10 @@ public: bool bRecord, bool bApi, bool bAllowMove = false ); /** - * Refresh multiple pivot tables that reference the same pivot cache. - * Before calling this method, the caller must take care of reloading the - * cache and providing the correct pivot table objects referencing the - * cache. + * Reload the referenced pivot cache, and refresh all pivot tables that + * reference the cache. */ - void RefreshPivotTables(std::set<ScDPObject*>& rRefs, bool bRecord, bool bApi); + sal_uLong RefreshPivotTables(ScDPObject* pDPObj, bool bRecord, bool bApi); }; diff --git a/sc/source/ui/unoobj/dapiuno.cxx b/sc/source/ui/unoobj/dapiuno.cxx index dbc3f50..85e2495 100644 --- a/sc/source/ui/unoobj/dapiuno.cxx +++ b/sc/source/ui/unoobj/dapiuno.cxx @@ -1276,9 +1276,7 @@ void SAL_CALL ScDataPilotTableObj::refresh() throw(RuntimeException) if (pDPObj) { ScDBDocFunc aFunc(*GetDocShell()); - std::set<ScDPObject*> aRefs; - GetDocShell()->GetDocument()->GetDPCollection()->ReloadCache(pDPObj, aRefs); - aFunc.RefreshPivotTables(aRefs, true, true); + aFunc.RefreshPivotTables(pDPObj, true, true); } } diff --git a/sc/source/ui/view/dbfunc3.cxx b/sc/source/ui/view/dbfunc3.cxx index 08f3f3d..7cbd71c 100644 --- a/sc/source/ui/view/dbfunc3.cxx +++ b/sc/source/ui/view/dbfunc3.cxx @@ -699,24 +699,15 @@ void ScDBFunc::RecalcPivotTable() ScDocShell* pDocSh = GetViewData()->GetDocShell(); ScDocument* pDoc = GetViewData()->GetDocument(); - ScDPCollection* pDPs = pDoc->GetDPCollection(); ScDPObject* pDPObj = pDoc->GetDPAtCursor( GetViewData()->GetCurX(), GetViewData()->GetCurY(), GetViewData()->GetTabNo() ); - if (pDPs && pDPObj) + if (pDPObj) { // Remove existing data cache for the data that this datapilot uses, // to force re-build data cache. - std::set<ScDPObject*> aRefs; - sal_uLong nErrId = pDPs->ReloadCache(pDPObj, aRefs); - if (nErrId) - { - ErrorMessage(nErrId); - return; - } - - ScDBDocFunc aFunc( *pDocSh ); - aFunc.RefreshPivotTables(aRefs, true, false); + ScDBDocFunc aFunc(*pDocSh); + aFunc.RefreshPivotTables(pDPObj, true, false); CursorPosChanged(); // shells may be switched } commit 9be40516455eef80d7c121455c08da41b27373bf Author: Kohei Yoshida <kohei.yosh...@gmail.com> Date: Tue Mar 13 11:57:08 2012 -0400 Dedicated method for refreshing multiple linked pivot tables. diff --git a/sc/source/ui/docshell/dbdocfun.cxx b/sc/source/ui/docshell/dbdocfun.cxx index 145f457..3a5e0fd 100644 --- a/sc/source/ui/docshell/dbdocfun.cxx +++ b/sc/source/ui/docshell/dbdocfun.cxx @@ -1451,6 +1451,16 @@ bool ScDBDocFunc::DataPilotUpdate( ScDPObject* pOldObj, const ScDPObject* pNewOb return bDone; } +void ScDBDocFunc::RefreshPivotTables(std::set<ScDPObject*>& rRefs, bool bRecord, bool bApi) +{ + std::set<ScDPObject*>::iterator it = rRefs.begin(), itEnd = rRefs.end(); + for (; it != itEnd; ++it) + { + ScDPObject* pObj = *it; + DataPilotUpdate(pObj, pObj, bRecord, bApi); + } +} + //================================================================== // // database import diff --git a/sc/source/ui/inc/dbdocfun.hxx b/sc/source/ui/inc/dbdocfun.hxx index 35ad848..79956e5 100644 --- a/sc/source/ui/inc/dbdocfun.hxx +++ b/sc/source/ui/inc/dbdocfun.hxx @@ -33,6 +33,8 @@ #include <tools/solar.h> #include <com/sun/star/uno/Sequence.hxx> +#include <set> + class String; struct ScImportParam; @@ -100,6 +102,14 @@ public: bool DataPilotUpdate( ScDPObject* pOldObj, const ScDPObject* pNewObj, bool bRecord, bool bApi, bool bAllowMove = false ); + + /** + * Refresh multiple pivot tables that reference the same pivot cache. + * Before calling this method, the caller must take care of reloading the + * cache and providing the correct pivot table objects referencing the + * cache. + */ + void RefreshPivotTables(std::set<ScDPObject*>& rRefs, bool bRecord, bool bApi); }; diff --git a/sc/source/ui/unoobj/dapiuno.cxx b/sc/source/ui/unoobj/dapiuno.cxx index 9ff4cb9..dbc3f50 100644 --- a/sc/source/ui/unoobj/dapiuno.cxx +++ b/sc/source/ui/unoobj/dapiuno.cxx @@ -1278,12 +1278,7 @@ void SAL_CALL ScDataPilotTableObj::refresh() throw(RuntimeException) ScDBDocFunc aFunc(*GetDocShell()); std::set<ScDPObject*> aRefs; GetDocShell()->GetDocument()->GetDPCollection()->ReloadCache(pDPObj, aRefs); - std::set<ScDPObject*>::iterator it = aRefs.begin(), itEnd = aRefs.end(); - for (; it != itEnd; ++it) - { - ScDPObject* pObj = *it; - aFunc.DataPilotUpdate(pObj, pObj, true, true); - } + aFunc.RefreshPivotTables(aRefs, true, true); } } diff --git a/sc/source/ui/view/dbfunc3.cxx b/sc/source/ui/view/dbfunc3.cxx index 41cebf1..08f3f3d 100644 --- a/sc/source/ui/view/dbfunc3.cxx +++ b/sc/source/ui/view/dbfunc3.cxx @@ -716,12 +716,7 @@ void ScDBFunc::RecalcPivotTable() } ScDBDocFunc aFunc( *pDocSh ); - std::set<ScDPObject*>::iterator it = aRefs.begin(), itEnd = aRefs.end(); - for (; it != itEnd; ++it) - { - ScDPObject* pObj = *it; - aFunc.DataPilotUpdate(pObj, pObj, true, false); - } + aFunc.RefreshPivotTables(aRefs, true, false); CursorPosChanged(); // shells may be switched } commit c18dc2e2047f07fb13ec5890db4dbd4357cfa7ce Author: Kohei Yoshida <kohei.yosh...@gmail.com> Date: Tue Mar 13 11:41:20 2012 -0400 Use bool. diff --git a/sc/source/ui/docshell/dbdocfun.cxx b/sc/source/ui/docshell/dbdocfun.cxx index 3266abe..145f457 100644 --- a/sc/source/ui/docshell/dbdocfun.cxx +++ b/sc/source/ui/docshell/dbdocfun.cxx @@ -1192,14 +1192,14 @@ sal_Bool lcl_EmptyExcept( ScDocument* pDoc, const ScRange& rRange, const ScRange return sal_True; // nothing found - empty } -sal_Bool ScDBDocFunc::DataPilotUpdate( ScDPObject* pOldObj, const ScDPObject* pNewObj, - sal_Bool bRecord, sal_Bool bApi, sal_Bool bAllowMove ) +bool ScDBDocFunc::DataPilotUpdate( ScDPObject* pOldObj, const ScDPObject* pNewObj, + bool bRecord, bool bApi, bool bAllowMove ) { ScDocShellModificator aModificator( rDocShell ); WaitObject aWait( rDocShell.GetActiveDialogParent() ); - sal_Bool bDone = false; - sal_Bool bUndoSelf = false; + bool bDone = false; + bool bUndoSelf = false; sal_uInt16 nErrId = 0; ScDocument* pOldUndoDoc = NULL; @@ -1265,7 +1265,7 @@ sal_Bool ScDBDocFunc::DataPilotUpdate( ScDPObject* pOldObj, const ScDPObject* pN rDocShell.PostPaintGridAll(); //! only necessary parts rDocShell.PostPaint(aRange, PAINT_GRID); - bDone = sal_True; + bDone = true; } else if ( pNewObj ) { @@ -1352,7 +1352,7 @@ sal_Bool ScDBDocFunc::DataPilotUpdate( ScDPObject* pOldObj, const ScDPObject* pN { // like with STR_PROTECTIONERR, use undo to reverse everything OSL_ENSURE( bRecord, "DataPilotUpdate: can't undo" ); - bUndoSelf = sal_True; + bUndoSelf = true; nErrId = STR_PIVOT_ERROR; } else @@ -1374,7 +1374,7 @@ sal_Bool ScDBDocFunc::DataPilotUpdate( ScDPObject* pOldObj, const ScDPObject* pN // test if new output area is empty except for old area if ( !bApi ) { - sal_Bool bEmpty; + bool bEmpty; if ( pOldObj ) // OutRange of pOldObj (pDestObj) is still old area bEmpty = lcl_EmptyExcept( pDoc, aNewOut, pOldObj->GetOutRange() ); else @@ -1390,7 +1390,7 @@ sal_Bool ScDBDocFunc::DataPilotUpdate( ScDPObject* pOldObj, const ScDPObject* pN { //! like above (not editable), use undo to reverse everything OSL_ENSURE( bRecord, "DataPilotUpdate: can't undo" ); - bUndoSelf = sal_True; + bUndoSelf = true; } } } @@ -1406,7 +1406,7 @@ sal_Bool ScDBDocFunc::DataPilotUpdate( ScDPObject* pOldObj, const ScDPObject* pN pDestObj->Output( aNewOut.aStart ); rDocShell.PostPaintGridAll(); //! only necessary parts - bDone = sal_True; + bDone = true; } } // else nothing (no old, no new) diff --git a/sc/source/ui/inc/dbdocfun.hxx b/sc/source/ui/inc/dbdocfun.hxx index 83996cc..35ad848 100644 --- a/sc/source/ui/inc/dbdocfun.hxx +++ b/sc/source/ui/inc/dbdocfun.hxx @@ -98,8 +98,8 @@ public: bool RepeatDB( const ::rtl::OUString& rDBName, bool bRecord, bool bApi, bool bIsUnnamed=false, SCTAB aTab = 0); - sal_Bool DataPilotUpdate( ScDPObject* pOldObj, const ScDPObject* pNewObj, - sal_Bool bRecord, sal_Bool bApi, sal_Bool bAllowMove = false ); + bool DataPilotUpdate( ScDPObject* pOldObj, const ScDPObject* pNewObj, + bool bRecord, bool bApi, bool bAllowMove = false ); }; commit 599c06acb2d8bfc986eaac061aa4b7e2a5bab3c6 Author: Kohei Yoshida <kohei.yosh...@gmail.com> Date: Tue Mar 13 10:37:46 2012 -0400 Check the return value for negative index, to prevent crash. Also, use at(index) when unsure about boundary condition. That makes it easier to detect where illegal memory access is being done. diff --git a/sc/source/core/data/dpcache.cxx b/sc/source/core/data/dpcache.cxx index a4705b4..0281a54 100644 --- a/sc/source/core/data/dpcache.cxx +++ b/sc/source/core/data/dpcache.cxx @@ -807,7 +807,7 @@ SCROW ScDPCache::GetRowCount() const const ScDPCache::DataListType& ScDPCache::GetDimMemberValues(SCCOL nDim) const { OSL_ENSURE( nDim>=0 && nDim < mnColumnCount ," nDim < mnColumnCount "); - return maFields[nDim].maItems; + return maFields.at(nDim).maItems; } sal_uLong ScDPCache::GetNumberFormat( long nDim ) const diff --git a/sc/source/core/data/dpdimsave.cxx b/sc/source/core/data/dpdimsave.cxx index 9d02594..8cf8d39 100644 --- a/sc/source/core/data/dpdimsave.cxx +++ b/sc/source/core/data/dpdimsave.cxx @@ -395,12 +395,15 @@ void ScDPSaveGroupDimension::AddToData( ScDPGroupTableData& rData ) const void ScDPSaveGroupDimension::AddToCache(ScDPCache& rCache) const { + long nSourceDim = rCache.GetDimensionIndex(aSourceDim); + if (nSourceDim < 0) + return; + long nDim = rCache.AppendGroupField(); SvNumberFormatter* pFormatter = rCache.GetDoc()->GetFormatTable(); if (nDatePart) { - long nSourceDim = rCache.GetDimensionIndex(aSourceDim); fillDateGroupDimension(rCache, aDateInfo, nSourceDim, nDim, nDatePart, pFormatter); return; } @@ -416,7 +419,6 @@ void ScDPSaveGroupDimension::AddToCache(ScDPCache& rCache) const } } - long nSourceDim = rCache.GetDimensionIndex(aSourceDim); const ScDPCache::DataListType& rItems = rCache.GetDimMemberValues(nSourceDim); { ScDPCache::DataListType::const_iterator it = rItems.begin(), itEnd = rItems.end(); @@ -466,6 +468,9 @@ void ScDPSaveNumGroupDimension::AddToData( ScDPGroupTableData& rData ) const void ScDPSaveNumGroupDimension::AddToCache(ScDPCache& rCache) const { long nDim = rCache.GetDimensionIndex(aDimensionName); + if (nDim < 0) + return; + if (aDateInfo.mbEnable) { // Date grouping _______________________________________________ Libreoffice-commits mailing list Libreoffice-commits@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits