Skip to content

Commit

Permalink
Make Pivot table data source dialog async
Browse files Browse the repository at this point in the history
Change-Id: I573038935e31c5393293197c1a9706110a970837
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/106848
Tested-by: Jenkins
Reviewed-by: Szymon Kłos <[email protected]>
  • Loading branch information
eszkadev committed Nov 30, 2020
1 parent 73c0218 commit 244a447
Show file tree
Hide file tree
Showing 3 changed files with 132 additions and 111 deletions.
7 changes: 6 additions & 1 deletion sc/source/ui/attrdlg/scdlgfact.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,11 @@ short AbstractScDataPilotSourceTypeDlg_Impl::Execute()
return m_xDlg->run();
}

bool AbstractScDataPilotSourceTypeDlg_Impl::StartExecuteAsync(AsyncContext &rCtx)
{
return weld::DialogController::runAsync(m_xDlg, rCtx.maEndDialogFn);
}

short AbstractScDataPilotServiceDlg_Impl::Execute()
{
return m_xDlg->run();
Expand Down Expand Up @@ -988,7 +993,7 @@ VclPtr<AbstractScDataPilotDatabaseDlg> ScAbstractDialogFactory_Impl::CreateScDat
VclPtr<AbstractScDataPilotSourceTypeDlg> ScAbstractDialogFactory_Impl::CreateScDataPilotSourceTypeDlg(
weld::Window* pParent, bool bEnableExternal)
{
return VclPtr<AbstractScDataPilotSourceTypeDlg_Impl>::Create(std::make_unique<ScDataPilotSourceTypeDlg>(pParent, bEnableExternal));
return VclPtr<AbstractScDataPilotSourceTypeDlg_Impl>::Create(std::make_shared<ScDataPilotSourceTypeDlg>(pParent, bEnableExternal));
}

VclPtr<AbstractScDataPilotServiceDlg> ScAbstractDialogFactory_Impl::CreateScDataPilotServiceDlg(weld::Window* pParent,
Expand Down
5 changes: 3 additions & 2 deletions sc/source/ui/attrdlg/scdlgfact.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -180,13 +180,14 @@ public:

class AbstractScDataPilotSourceTypeDlg_Impl :public AbstractScDataPilotSourceTypeDlg
{
std::unique_ptr<ScDataPilotSourceTypeDlg> m_xDlg;
std::shared_ptr<ScDataPilotSourceTypeDlg> m_xDlg;
public:
explicit AbstractScDataPilotSourceTypeDlg_Impl(std::unique_ptr<ScDataPilotSourceTypeDlg> p)
explicit AbstractScDataPilotSourceTypeDlg_Impl(std::shared_ptr<ScDataPilotSourceTypeDlg> p)
: m_xDlg(std::move(p))
{
}
virtual short Execute() override;
virtual bool StartExecuteAsync(AsyncContext &) override;
virtual bool IsDatabase() const override;
virtual bool IsExternal() const override;
virtual bool IsNamedRange() const override;
Expand Down
231 changes: 123 additions & 108 deletions sc/source/ui/view/cellsh1.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -2845,6 +2845,23 @@ bool isDPSourceValid(const ScDPObject& rDPObj)
return true;
}

void RunPivotLayoutDialog(ScModule* pScMod,
ScTabViewShell* pTabViewShell,
std::unique_ptr<ScDPObject>& pNewDPObject)
{
bool bHadNewDPObject = pNewDPObject != nullptr;
pTabViewShell->SetDialogDPObject( std::move(pNewDPObject) );
if ( bHadNewDPObject )
{
// start layout dialog

sal_uInt16 nId = ScPivotLayoutWrapper::GetChildWindowId();
SfxViewFrame* pViewFrm = pTabViewShell->GetViewFrame();
SfxChildWindow* pWnd = pViewFrm->GetChildWindow( nId );
pScMod->SetRefDialog( nId, pWnd == nullptr );
}
}

}

void ScCellShell::ExecuteDataPilotDialog()
Expand All @@ -2854,21 +2871,21 @@ void ScCellShell::ExecuteDataPilotDialog()
ScViewData* pData = GetViewData();
ScDocument& rDoc = pData->GetDocument();

std::unique_ptr<ScDPObject> pNewDPObject;

// ScPivot is no longer used...
ScDPObject* pDPObj = rDoc.GetDPAtCursor(
pData->GetCurX(), pData->GetCurY(),
pData->GetTabNo() );
if ( pDPObj ) // on an existing table?
{
std::unique_ptr<ScDPObject> pNewDPObject;

if (isDPSourceValid(*pDPObj))
pNewDPObject.reset(new ScDPObject(*pDPObj));

RunPivotLayoutDialog(pScMod, pTabViewShell, pNewDPObject);
}
else // create new table
{
const char* pSrcErrorId = nullptr;

// select database range or data
pTabViewShell->GetDBData( true, SC_DB_OLD );
ScMarkData& rMark = GetViewData()->GetMarkData();
Expand All @@ -2885,7 +2902,7 @@ void ScCellShell::ExecuteDataPilotDialog()

ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();

ScopedVclPtr<AbstractScDataPilotSourceTypeDlg> pTypeDlg(
VclPtr<AbstractScDataPilotSourceTypeDlg> pTypeDlg(
pFact->CreateScDataPilotSourceTypeDlg(
pTabViewShell->GetFrameWeld(), bEnableExt));

Expand All @@ -2898,129 +2915,127 @@ void ScCellShell::ExecuteDataPilotDialog()
pTypeDlg->AppendNamedRange(itr->second->GetName());
}

if ( pTypeDlg->Execute() == RET_OK )
{
if ( pTypeDlg->IsExternal() )
{
std::vector<OUString> aSources = ScDPObject::GetRegisteredSources();
ScopedVclPtr<AbstractScDataPilotServiceDlg> pServDlg(
pFact->CreateScDataPilotServiceDlg(
pTabViewShell->GetFrameWeld(), aSources));
pTypeDlg->StartExecuteAsync([this, pTypeDlg, pTabViewShell,
pScMod, pFact, &rDoc, &rMark, &aDestPos](int nResult) {
const char* pSrcErrorId = nullptr;
std::unique_ptr<ScDPObject> pNewDPObject;

if ( pServDlg->Execute() == RET_OK )
{
ScDPServiceDesc aServDesc(
pServDlg->GetServiceName(),
pServDlg->GetParSource(),
pServDlg->GetParName(),
pServDlg->GetParUser(),
pServDlg->GetParPass() );
pNewDPObject.reset(new ScDPObject(&rDoc));
pNewDPObject->SetServiceData( aServDesc );
}
}
else if ( pTypeDlg->IsDatabase() )
if (nResult == RET_OK )
{
assert(pFact && "ScAbstractFactory create fail!");
ScopedVclPtr<AbstractScDataPilotDatabaseDlg> pDataDlg(
pFact->CreateScDataPilotDatabaseDlg(pTabViewShell->GetFrameWeld()));
assert(pDataDlg && "Dialog create fail!");
if ( pDataDlg->Execute() == RET_OK )
if ( pTypeDlg->IsExternal() )
{
ScImportSourceDesc aImpDesc(&rDoc);
pDataDlg->GetValues( aImpDesc );
pNewDPObject.reset(new ScDPObject(&rDoc));
pNewDPObject->SetImportDesc( aImpDesc );
}
}
else if (pTypeDlg->IsNamedRange())
{
OUString aName = pTypeDlg->GetSelectedNamedRange();
ScSheetSourceDesc aShtDesc(&rDoc);
aShtDesc.SetRangeName(aName);
pSrcErrorId = aShtDesc.CheckSourceRange();
if (!pSrcErrorId)
{
pNewDPObject.reset(new ScDPObject(&rDoc));
pNewDPObject->SetSheetDesc(aShtDesc);
std::vector<OUString> aSources = ScDPObject::GetRegisteredSources();
ScopedVclPtr<AbstractScDataPilotServiceDlg> pServDlg(
pFact->CreateScDataPilotServiceDlg(
pTabViewShell->GetFrameWeld(), aSources));

if ( pServDlg->Execute() == RET_OK )
{
ScDPServiceDesc aServDesc(
pServDlg->GetServiceName(),
pServDlg->GetParSource(),
pServDlg->GetParName(),
pServDlg->GetParUser(),
pServDlg->GetParPass() );
pNewDPObject.reset(new ScDPObject(&rDoc));
pNewDPObject->SetServiceData( aServDesc );
}
}
}
else // selection
{
//! use database ranges (select before type dialog?)
ScRange aRange;
ScMarkType eType = GetViewData()->GetSimpleArea(aRange);
if ( (eType & SC_MARK_SIMPLE) == SC_MARK_SIMPLE )
else if ( pTypeDlg->IsDatabase() )
{
// Shrink the range to the data area.
SCCOL nStartCol = aRange.aStart.Col(), nEndCol = aRange.aEnd.Col();
SCROW nStartRow = aRange.aStart.Row(), nEndRow = aRange.aEnd.Row();
if (rDoc.ShrinkToDataArea(aRange.aStart.Tab(), nStartCol, nStartRow, nEndCol, nEndRow))
assert(pFact && "ScAbstractFactory create fail!");
ScopedVclPtr<AbstractScDataPilotDatabaseDlg> pDataDlg(
pFact->CreateScDataPilotDatabaseDlg(pTabViewShell->GetFrameWeld()));
assert(pDataDlg && "Dialog create fail!");
if ( pDataDlg->Execute() == RET_OK )
{
aRange.aStart.SetCol(nStartCol);
aRange.aStart.SetRow(nStartRow);
aRange.aEnd.SetCol(nEndCol);
aRange.aEnd.SetRow(nEndRow);
rMark.SetMarkArea(aRange);
pTabViewShell->MarkRange(aRange);
ScImportSourceDesc aImpDesc(&rDoc);
pDataDlg->GetValues( aImpDesc );
pNewDPObject.reset(new ScDPObject(&rDoc));
pNewDPObject->SetImportDesc( aImpDesc );
}

bool bOK = true;
if ( rDoc.HasSubTotalCells( aRange ) )
}
else if (pTypeDlg->IsNamedRange())
{
OUString aName = pTypeDlg->GetSelectedNamedRange();
ScSheetSourceDesc aShtDesc(&rDoc);
aShtDesc.SetRangeName(aName);
pSrcErrorId = aShtDesc.CheckSourceRange();
if (!pSrcErrorId)
{
// confirm selection if it contains SubTotal cells
std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(pTabViewShell->GetFrameWeld(),
VclMessageType::Question, VclButtonsType::YesNo,
ScResId(STR_DATAPILOT_SUBTOTAL)));
xQueryBox->set_default_response(RET_YES);
if (xQueryBox->run() == RET_NO)
bOK = false;
pNewDPObject.reset(new ScDPObject(&rDoc));
pNewDPObject->SetSheetDesc(aShtDesc);
}
if (bOK)
}
else // selection
{
//! use database ranges (select before type dialog?)
ScRange aRange;
ScMarkType eType = GetViewData()->GetSimpleArea(aRange);
if ( (eType & SC_MARK_SIMPLE) == SC_MARK_SIMPLE )
{
ScSheetSourceDesc aShtDesc(&rDoc);
aShtDesc.SetSourceRange(aRange);
pSrcErrorId = aShtDesc.CheckSourceRange();
if (!pSrcErrorId)
// Shrink the range to the data area.
SCCOL nStartCol = aRange.aStart.Col(), nEndCol = aRange.aEnd.Col();
SCROW nStartRow = aRange.aStart.Row(), nEndRow = aRange.aEnd.Row();
if (rDoc.ShrinkToDataArea(aRange.aStart.Tab(), nStartCol, nStartRow, nEndCol, nEndRow))
{
pNewDPObject.reset(new ScDPObject(&rDoc));
pNewDPObject->SetSheetDesc( aShtDesc );
aRange.aStart.SetCol(nStartCol);
aRange.aStart.SetRow(nStartRow);
aRange.aEnd.SetCol(nEndCol);
aRange.aEnd.SetRow(nEndRow);
rMark.SetMarkArea(aRange);
pTabViewShell->MarkRange(aRange);
}

// output below source data
if ( aRange.aEnd.Row()+2 <= rDoc.MaxRow() - 4 )
aDestPos = ScAddress( aRange.aStart.Col(),
aRange.aEnd.Row()+2,
aRange.aStart.Tab() );
bool bOK = true;
if ( rDoc.HasSubTotalCells( aRange ) )
{
// confirm selection if it contains SubTotal cells
std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(pTabViewShell->GetFrameWeld(),
VclMessageType::Question, VclButtonsType::YesNo,
ScResId(STR_DATAPILOT_SUBTOTAL)));
xQueryBox->set_default_response(RET_YES);
if (xQueryBox->run() == RET_NO)
bOK = false;
}
if (bOK)
{
ScSheetSourceDesc aShtDesc(&rDoc);
aShtDesc.SetSourceRange(aRange);
pSrcErrorId = aShtDesc.CheckSourceRange();
if (!pSrcErrorId)
{
pNewDPObject.reset(new ScDPObject(&rDoc));
pNewDPObject->SetSheetDesc( aShtDesc );
}

// output below source data
if ( aRange.aEnd.Row()+2 <= rDoc.MaxRow() - 4 )
aDestPos = ScAddress( aRange.aStart.Col(),
aRange.aEnd.Row()+2,
aRange.aStart.Tab() );
}
}
}
}
}

if (pSrcErrorId)
{
// Error occurred during data creation. Launch an error and bail out.
std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(pTabViewShell->GetFrameWeld(),
VclMessageType::Info, VclButtonsType::Ok,
ScResId(pSrcErrorId)));
xInfoBox->run();
return;
}
if (pSrcErrorId)
{
// Error occurred during data creation. Launch an error and bail out.
std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(pTabViewShell->GetFrameWeld(),
VclMessageType::Info, VclButtonsType::Ok,
ScResId(pSrcErrorId)));
xInfoBox->run();
return;
}

if ( pNewDPObject )
pNewDPObject->SetOutRange( aDestPos );
}
if ( pNewDPObject )
pNewDPObject->SetOutRange( aDestPos );

bool bHadNewDPObject = pNewDPObject != nullptr;
pTabViewShell->SetDialogDPObject( std::move(pNewDPObject) );
if ( bHadNewDPObject )
{
// start layout dialog
pTypeDlg->disposeOnce();

sal_uInt16 nId = ScPivotLayoutWrapper::GetChildWindowId();
SfxViewFrame* pViewFrm = pTabViewShell->GetViewFrame();
SfxChildWindow* pWnd = pViewFrm->GetChildWindow( nId );
pScMod->SetRefDialog( nId, pWnd == nullptr );
RunPivotLayoutDialog(pScMod, pTabViewShell, pNewDPObject);
});
}
}

Expand Down

0 comments on commit 244a447

Please sign in to comment.