[Libreoffice-commits] .: 7 commits - sc/inc sc/qa sc/source

Kohei Yoshida kohei at kemper.freedesktop.org
Tue Mar 13 21:35:15 PDT 2012


 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.yoshida at 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.yoshida at 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.yoshida at 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.yoshida at 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.yoshida at 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.yoshida at 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.yoshida at 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


More information about the Libreoffice-commits mailing list