summaryrefslogtreecommitdiff
path: root/sc
diff options
context:
space:
mode:
authorKohei Yoshida <kohei.yoshida@gmail.com>2013-01-11 12:12:09 -0500
committerKohei Yoshida <kohei.yoshida@gmail.com>2013-01-11 12:53:22 -0500
commitfeef29286f0a7c6abd512a07fce9ef48327e0a78 (patch)
treefa8d667cfed7c86583062f37a20f02f907866c82 /sc
parentac56d9373a66378a04048993ed5aec65cf39f149 (diff)
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
Diffstat (limited to 'sc')
-rw-r--r--sc/source/ui/docshell/dbdocfun.cxx143
-rw-r--r--sc/source/ui/inc/dbdocfun.hxx2
-rw-r--r--sc/source/ui/view/dbfunc3.cxx2
-rw-r--r--sc/source/ui/view/gridwin2.cxx2
4 files changed, 145 insertions, 4 deletions
diff --git a/sc/source/ui/docshell/dbdocfun.cxx b/sc/source/ui/docshell/dbdocfun.cxx
index 3b1db2f05e7a..403ecd3a94df 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 3cf22427a90e..c302d5c532ce 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 84754c2c94cc..ff768cf501eb 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 3ec36a25cef9..94ed3e7b23c1 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()