[Libreoffice-commits] .: 2 commits - sc/source

Libreoffice Gerrit user logerrit at kemper.freedesktop.org
Fri Jan 11 09:52:05 PST 2013


 sc/source/ui/docshell/dbdocfun.cxx |  146 +++++++++++++++++++++++++++++++++++--
 sc/source/ui/inc/dbdocfun.hxx      |    2 
 sc/source/ui/view/dbfunc3.cxx      |    2 
 sc/source/ui/view/gridwin2.cxx     |    2 
 4 files changed, 146 insertions(+), 6 deletions(-)

New commits:
commit d99abd61a9091426bfccd871d6a8f036d5f49479
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Fri Jan 11 12:51:13 2013 -0500

    Let's not return here to prevent memory leak.
    
    There are several heap objects that are deleted at the end of the
    method.  Returning prematurely would leak those objects.
    
    Change-Id: If70cb3c9c02e47229d10b30f1542f7b25534d593

diff --git a/sc/source/ui/docshell/dbdocfun.cxx b/sc/source/ui/docshell/dbdocfun.cxx
index 403ecd3..d0e3ebb 100644
--- a/sc/source/ui/docshell/dbdocfun.cxx
+++ b/sc/source/ui/docshell/dbdocfun.cxx
@@ -1320,8 +1320,7 @@ bool ScDBDocFunc::DataPilotUpdate( ScDPObject* pOldObj, const ScDPObject* pNewOb
             if ( pDestObj )
             {
                 pDestObj->ReloadGroupTableData();
-                if (!pDestObj->SyncAllDimensionMembers())
-                    return false;
+                pDestObj->SyncAllDimensionMembers();
                 pDestObj->InvalidateData();             // before getting the new output area
 
                 //  make sure the table has a name (not set by dialog)
commit feef29286f0a7c6abd512a07fce9ef48327e0a78
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Fri Jan 11 12:12:09 2013 -0500

    Create a self-update variant of DataPilotUpdate().
    
    DataPilotUpdate() is getting more and more complicated, with so many
    branches.  Since self-updating a pivot table object is common, let's
    create a variant just for that.  This variant has much less branching.
    
    Change-Id: I75b0512258a09961ef13516d8d9bc8a2939287e1

diff --git a/sc/source/ui/docshell/dbdocfun.cxx b/sc/source/ui/docshell/dbdocfun.cxx
index 3b1db2f..403ecd3 100644
--- a/sc/source/ui/docshell/dbdocfun.cxx
+++ b/sc/source/ui/docshell/dbdocfun.cxx
@@ -50,6 +50,7 @@
 #include "progress.hxx"
 
 #include <set>
+#include <memory>
 
 using namespace ::com::sun::star;
 
@@ -1448,6 +1449,144 @@ bool ScDBDocFunc::DataPilotUpdate( ScDPObject* pOldObj, const ScDPObject* pNewOb
     return bDone;
 }
 
+bool ScDBDocFunc::UpdatePivotTable(ScDPObject& rDPObj, bool bRecord, bool bApi)
+{
+    ScDocShellModificator aModificator( rDocShell );
+    WaitObject aWait( rDocShell.GetActiveDialogParent() );
+
+    std::auto_ptr<ScDocument> pOldUndoDoc;
+    std::auto_ptr<ScDocument> pNewUndoDoc;
+
+    ScDPObject aUndoDPObj(rDPObj); // For undo or revert on failure.
+
+    ScDocument* pDoc = rDocShell.GetDocument();
+    if (bRecord && !pDoc->IsUndoEnabled())
+        bRecord = false;
+
+    if (!rDocShell.IsEditable() || pDoc->GetChangeTrack())
+    {
+        //  not recorded -> disallow
+        //! different error messages?
+        if (!bApi)
+            rDocShell.ErrorMessage(STR_PROTECTIONERR);
+
+        return false;
+    }
+
+    {
+        ScEditableTester aTester(pDoc, rDPObj.GetOutRange());
+        if (!aTester.IsEditable())
+        {
+            if (!bApi)
+                rDocShell.ErrorMessage(aTester.GetMessageId());
+
+            return false;
+        }
+    }
+
+    if (bRecord)
+    {
+        ScRange aRange = rDPObj.GetOutRange();
+        SCTAB nTab = aRange.aStart.Tab();
+        pOldUndoDoc.reset(new ScDocument(SCDOCMODE_UNDO));
+        pOldUndoDoc->InitUndo( pDoc, nTab, nTab );
+        pDoc->CopyToDocument(aRange, IDF_ALL, false, pOldUndoDoc.get());
+    }
+
+    rDPObj.SetAllowMove(false);
+    rDPObj.ReloadGroupTableData();
+    if (!rDPObj.SyncAllDimensionMembers())
+        return false;
+
+    rDPObj.InvalidateData();             // before getting the new output area
+
+    //  make sure the table has a name (not set by dialog)
+    if (rDPObj.GetName().isEmpty())
+        rDPObj.SetName( pDoc->GetDPCollection()->CreateNewName() );
+
+    bool bOverflow = false;
+    ScRange aNewOut = rDPObj.GetNewOutputRange(bOverflow);
+
+    //! test for overlap with other data pilot tables
+    const ScSheetSourceDesc* pSheetDesc = rDPObj.GetSheetDesc();
+    if (pSheetDesc && pSheetDesc->GetSourceRange().Intersects(aNewOut))
+    {
+        ScRange aOldRange = rDPObj.GetOutRange();
+        SCsROW nDiff = aOldRange.aStart.Row()-aNewOut.aStart.Row();
+        aNewOut.aStart.SetRow( aOldRange.aStart.Row() );
+        aNewOut.aEnd.SetRow( aNewOut.aEnd.Row()+nDiff );
+        if (!ValidRow(aNewOut.aStart.Row()) || !ValidRow(aNewOut.aEnd.Row()))
+            bOverflow = true;
+    }
+
+    if (bOverflow)
+    {
+        //  like with STR_PROTECTIONERR, use undo to reverse everything
+        OSL_ENSURE( bRecord, "DataPilotUpdate: can't undo" );
+
+        if (!bApi)
+            rDocShell.ErrorMessage(STR_PIVOT_ERROR);
+
+        rDPObj = aUndoDPObj;
+        return false;
+    }
+
+    {
+        ScEditableTester aTester(pDoc, aNewOut);
+        if (!aTester.IsEditable())
+        {
+            //  destination area isn't editable
+            //! reverse everything done so far, don't proceed
+
+            if (!bApi)
+                rDocShell.ErrorMessage(aTester.GetMessageId());
+
+            rDPObj = aUndoDPObj;
+            return false;
+        }
+    }
+
+    //  test if new output area is empty except for old area
+    if (!bApi)
+    {
+        if (!lcl_EmptyExcept(pDoc, aNewOut, rDPObj.GetOutRange()))
+        {
+            QueryBox aBox( rDocShell.GetActiveDialogParent(), WinBits(WB_YES_NO | WB_DEF_YES),
+                             ScGlobal::GetRscString(STR_PIVOT_NOTEMPTY) );
+            if (aBox.Execute() == RET_NO)
+            {
+                rDPObj = aUndoDPObj;
+                return false;
+            }
+        }
+    }
+
+    if (bRecord)
+    {
+        SCTAB nTab = aNewOut.aStart.Tab();
+        pNewUndoDoc.reset(new ScDocument(SCDOCMODE_UNDO));
+        pNewUndoDoc->InitUndo( pDoc, nTab, nTab );
+        pDoc->CopyToDocument(aNewOut, IDF_ALL, false, pNewUndoDoc.get());
+    }
+
+    rDPObj.Output(aNewOut.aStart);
+    rDocShell.PostPaintGridAll();           //! only necessary parts
+
+    if (bRecord)
+    {
+        std::auto_ptr<SfxUndoAction> pAction(
+            new ScUndoDataPilot(
+                &rDocShell, pOldUndoDoc.release(), pNewUndoDoc.release(), &aUndoDPObj, &rDPObj, false));
+
+        rDocShell.GetUndoManager()->AddUndoAction(pAction.release());
+    }
+
+    // notify API objects
+    pDoc->BroadcastUno( ScDataPilotModifiedHint(rDPObj.GetName()) );
+    aModificator.SetDocumentModified();
+    return true;
+}
+
 sal_uLong ScDBDocFunc::RefreshPivotTables(ScDPObject* pDPObj, bool bApi)
 {
     ScDPCollection* pDPs = rDocShell.GetDocument()->GetDPCollection();
@@ -1465,7 +1604,7 @@ sal_uLong ScDBDocFunc::RefreshPivotTables(ScDPObject* pDPObj, bool bApi)
         ScDPObject* pObj = *it;
 
         // This action is intentionally not undoable since it modifies cache.
-        DataPilotUpdate(pObj, pObj, false, bApi);
+        UpdatePivotTable(*pObj, false, bApi);
     }
 
     return 0;
@@ -1502,7 +1641,7 @@ void ScDBDocFunc::RefreshPivotTableGroups(ScDPObject* pDPObj)
         }
 
         // This action is intentionally not undoable since it modifies cache.
-        DataPilotUpdate(pObj, pObj, false, false);
+        UpdatePivotTable(*pObj, false, false);
     }
 }
 
diff --git a/sc/source/ui/inc/dbdocfun.hxx b/sc/source/ui/inc/dbdocfun.hxx
index 3cf2242..c302d5c 100644
--- a/sc/source/ui/inc/dbdocfun.hxx
+++ b/sc/source/ui/inc/dbdocfun.hxx
@@ -92,6 +92,8 @@ public:
     bool DataPilotUpdate( ScDPObject* pOldObj, const ScDPObject* pNewObj,
                           bool bRecord, bool bApi, bool bAllowMove = false );
 
+    bool UpdatePivotTable(ScDPObject& rDPObj, bool bRecord, bool bApi);
+
     /**
      * Reload the referenced pivot cache, and refresh all pivot tables that
      * reference the cache.
diff --git a/sc/source/ui/view/dbfunc3.cxx b/sc/source/ui/view/dbfunc3.cxx
index 84754c2..ff768cf 100644
--- a/sc/source/ui/view/dbfunc3.cxx
+++ b/sc/source/ui/view/dbfunc3.cxx
@@ -1596,7 +1596,7 @@ void ScDBFunc::DataPilotInput( const ScAddress& rPos, const rtl::OUString& rStri
         // apply changes
         ScDBDocFunc aFunc( *GetViewData()->GetDocShell() );
         pDPObj->SetSaveData( aData );
-        aFunc.DataPilotUpdate( pDPObj, pDPObj, true, false );
+        aFunc.UpdatePivotTable(*pDPObj, true, false);
     }
     else
     {
diff --git a/sc/source/ui/view/gridwin2.cxx b/sc/source/ui/view/gridwin2.cxx
index 3ec36a2..94ed3e7 100644
--- a/sc/source/ui/view/gridwin2.cxx
+++ b/sc/source/ui/view/gridwin2.cxx
@@ -591,7 +591,7 @@ void ScGridWindow::UpdateDPFromFieldPopupMenu()
     pDim->UpdateMemberVisibility(aResult);
 
     ScDBDocFunc aFunc(*pViewData->GetDocShell());
-    aFunc.DataPilotUpdate(pDPObj, pDPObj, true, false);
+    aFunc.UpdatePivotTable(*pDPObj, true, false);
 }
 
 void ScGridWindow::UpdateVisibleRange()


More information about the Libreoffice-commits mailing list