diff options
-rw-r--r-- | include/sfx2/tabdlg.hxx | 1 | ||||
-rw-r--r-- | include/vcl/abstdlg.hxx | 18 | ||||
-rw-r--r-- | include/vcl/dialog.hxx | 17 | ||||
-rw-r--r-- | sc/source/ui/attrdlg/scdlgfact.hxx | 5 | ||||
-rw-r--r-- | sc/source/ui/view/tabvwsha.cxx | 34 | ||||
-rw-r--r-- | sfx2/source/control/request.cxx | 17 | ||||
-rw-r--r-- | sfx2/source/dialog/tabdlg.cxx | 37 | ||||
-rw-r--r-- | vcl/source/window/abstdlg.cxx | 6 | ||||
-rw-r--r-- | vcl/source/window/dialog.cxx | 100 | ||||
-rw-r--r-- | vcl/source/window/window.cxx | 5 |
10 files changed, 179 insertions, 61 deletions
diff --git a/include/sfx2/tabdlg.hxx b/include/sfx2/tabdlg.hxx index 06f99318c3c0..409b15196307 100644 --- a/include/sfx2/tabdlg.hxx +++ b/include/sfx2/tabdlg.hxx @@ -190,6 +190,7 @@ public: short Execute() override; void StartExecuteModal( const Link<Dialog&,void>& rEndDialogHdl ) override; + bool StartExecuteAsync( VclAbstractDialog::AsyncContext &rCtx ) override; void Start(); const SfxItemSet* GetExampleSet() const { return m_pExampleSet; } diff --git a/include/vcl/abstdlg.hxx b/include/vcl/abstdlg.hxx index 40f75ed293b6..87336e0d5a5f 100644 --- a/include/vcl/abstdlg.hxx +++ b/include/vcl/abstdlg.hxx @@ -25,6 +25,7 @@ #include <vcl/vclptr.hxx> #include <vcl/vclreferencebase.hxx> #include <vector> +#include <functional> namespace vcl { class Window; } class Dialog; @@ -42,6 +43,23 @@ protected: public: virtual short Execute() = 0; + struct AsyncContext { + VclPtr<VclReferenceBase> mxOwner; + std::function<void(sal_Int32)> maEndDialogFn; + bool isSet() { return !!maEndDialogFn; } + }; + + bool StartExecuteAsync(const std::function<void(sal_Int32)> &rEndDialogFn, VclPtr<VclReferenceBase> xOwner) + { + AsyncContext aCtx; + aCtx.mxOwner = xOwner; + aCtx.maEndDialogFn = rEndDialogFn; + return StartExecuteAsync(aCtx); + } + + /// Commence execution of a modal dialog. + virtual bool StartExecuteAsync(AsyncContext &); + // Screenshot interface virtual std::vector<OString> getAllPageUIXMLDescriptions() const; virtual bool selectPageByUIXMLDescription(const OString& rUIXMLDescription); diff --git a/include/vcl/dialog.hxx b/include/vcl/dialog.hxx index 3da4ec0cb59a..6dea53f47058 100644 --- a/include/vcl/dialog.hxx +++ b/include/vcl/dialog.hxx @@ -26,6 +26,7 @@ #include <vcl/syswin.hxx> #include <vcl/vclptr.hxx> #include <vcl/IDialogRenderable.hxx> +#include <vcl/abstdlg.hxx> struct DialogImpl; class VclBox; @@ -45,6 +46,7 @@ public: private: VclPtr<Dialog> mpPrevExecuteDlg; + VclPtr<Dialog> mpNextExecuteDlg; std::unique_ptr<DialogImpl> mpDialogImpl; long mnMousePositioned; bool mbInExecute; @@ -57,6 +59,7 @@ private: VclPtr<VclButtonBox> mpActionArea; VclPtr<VclBox> mpContentArea; + SAL_DLLPRIVATE void RemoveFromDlgList(); SAL_DLLPRIVATE void ImplInitDialogData(); SAL_DLLPRIVATE void ImplInitSettings(); SAL_DLLPRIVATE VclPtr<vcl::Window> AddBorderWindow(vcl::Window* pParent, WinBits nBits); @@ -138,6 +141,20 @@ private: void ImplSetModalInputMode(bool bModal); public: + // FIXME: Need to remove old StartExecuteModal in favour of this one. + /// Returns true of the dialog successfully starts + bool StartExecuteAsync(const std::function<void(sal_Int32)> &rEndDialogFn, + VclPtr<VclReferenceBase> xOwner = VclPtr<VclReferenceBase>()) + { + VclAbstractDialog::AsyncContext aCtx; + aCtx.mxOwner = xOwner; + aCtx.maEndDialogFn = rEndDialogFn; + return StartExecuteAsync(aCtx); + } + + /// Commence execution of a modal dialog, disposes owner on failure + virtual bool StartExecuteAsync(VclAbstractDialog::AsyncContext &rCtx); + // Dialog::Execute replacement API diff --git a/sc/source/ui/attrdlg/scdlgfact.hxx b/sc/source/ui/attrdlg/scdlgfact.hxx index 5684f1245825..a1a3806f059c 100644 --- a/sc/source/ui/attrdlg/scdlgfact.hxx +++ b/sc/source/ui/attrdlg/scdlgfact.hxx @@ -65,6 +65,7 @@ public: \ {} \ virtual ~Class() override; \ virtual short Execute() override ; \ + virtual bool StartExecuteAsync(VclAbstractDialog::AsyncContext &rCtx) override; \ std::vector<OString> getAllPageUIXMLDescriptions() const override; \ bool selectPageByUIXMLDescription(const OString& rUIXMLDescription) override; \ virtual Bitmap createScreenshot() const override; \ @@ -78,6 +79,10 @@ short Class::Execute() \ { \ return pDlg->Execute(); \ } \ +bool Class::StartExecuteAsync(VclAbstractDialog::AsyncContext &rCtx)\ +{ \ + return pDlg->StartExecuteAsync( rCtx ); \ +} \ std::vector<OString> Class::getAllPageUIXMLDescriptions() const \ { \ return pDlg->getAllPageUIXMLDescriptions(); \ diff --git a/sc/source/ui/view/tabvwsha.cxx b/sc/source/ui/view/tabvwsha.cxx index 8b04b067818e..649e4cde46c3 100644 --- a/sc/source/ui/view/tabvwsha.cxx +++ b/sc/source/ui/view/tabvwsha.cxx @@ -478,8 +478,8 @@ void ScTabViewShell::ExecuteCellFormatDlg(SfxRequest& rReq, const OString &rName const ScPatternAttr* pOldAttrs = GetSelectionPattern(); - std::unique_ptr<SfxItemSet> pOldSet(new SfxItemSet(pOldAttrs->GetItemSet())); - std::unique_ptr<SvxNumberInfoItem> pNumberInfoItem; + std::shared_ptr<SfxItemSet> pOldSet(new SfxItemSet(pOldAttrs->GetItemSet())); + std::shared_ptr<SvxNumberInfoItem> pNumberInfoItem; pOldSet->MergeRange(SID_ATTR_BORDER_STYLES, SID_ATTR_BORDER_DEFAULT_WIDTH); @@ -536,28 +536,30 @@ void ScTabViewShell::ExecuteCellFormatDlg(SfxRequest& rReq, const OString &rName ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create(); OSL_ENSURE(pFact, "ScAbstractFactory create fail!"); - ScopedVclPtr<SfxAbstractTabDialog> pDlg(pFact->CreateScAttrDlg(GetDialogParent(), pOldSet.get())); + VclPtr<SfxAbstractTabDialog> pDlg(pFact->CreateScAttrDlg(GetDialogParent(), pOldSet.get())); if (!rName.isEmpty()) pDlg->SetCurPageId(rName); - short nResult = pDlg->Execute(); - bInFormatDialog = false; - if ( nResult == RET_OK ) - { - const SfxItemSet* pOutSet = pDlg->GetOutputItemSet(); + std::shared_ptr<SfxRequest> pRequest(new SfxRequest(rReq)); + pDlg->StartExecuteAsync([=](sal_Int32 nResult){ + bInFormatDialog = false; - const SfxPoolItem* pItem=nullptr; - if(pOutSet->GetItemState(SID_ATTR_NUMBERFORMAT_INFO,true,&pItem)==SfxItemState::SET) - { + if ( nResult == RET_OK ) + { + const SfxItemSet* pOutSet = pDlg->GetOutputItemSet(); - UpdateNumberFormatter(static_cast<const SvxNumberInfoItem&>(*pItem)); - } + const SfxPoolItem* pItem=nullptr; + if(pOutSet->GetItemState(SID_ATTR_NUMBERFORMAT_INFO,true,&pItem)==SfxItemState::SET) + { + UpdateNumberFormatter(static_cast<const SvxNumberInfoItem&>(*pItem)); + } - ApplyAttributes(pOutSet, pOldSet.get()); + ApplyAttributes(pOutSet, pOldSet.get()); - rReq.Done( *pOutSet ); - } + pRequest->Done(pOutSet); + } + }, pDlg); } bool ScTabViewShell::IsRefInputMode() const diff --git a/sfx2/source/control/request.cxx b/sfx2/source/control/request.cxx index 2bd37d439613..d7e6e6af1346 100644 --- a/sfx2/source/control/request.cxx +++ b/sfx2/source/control/request.cxx @@ -155,6 +155,23 @@ SfxRequest::SfxRequest pImpl->SetPool( pArgs->GetPool() ); else pImpl->SetPool( rOrig.pImpl->pPool ); + + // setup macro recording if it was in the original SfxRequest + if (rOrig.pImpl->pViewFrame && rOrig.pImpl->xRecorder.is()) + { + nSlot = rOrig.nSlot; + pImpl->pViewFrame = rOrig.pImpl->pViewFrame; + if (pImpl->pViewFrame->GetDispatcher()->GetShellAndSlot_Impl(nSlot, &pImpl->pShell, &pImpl->pSlot, true, true)) + { + pImpl->SetPool( &pImpl->pShell->GetPool() ); + pImpl->xRecorder = SfxRequest::GetMacroRecorder(pImpl->pViewFrame); + pImpl->aTarget = pImpl->pShell->GetName(); + } + else + { + SAL_WARN("sfx", "Recording unsupported slot: " << pImpl->pPool->GetSlotId(nSlot)); + } + } } diff --git a/sfx2/source/dialog/tabdlg.cxx b/sfx2/source/dialog/tabdlg.cxx index ff154a9bc2bb..dea1658092fe 100644 --- a/sfx2/source/dialog/tabdlg.cxx +++ b/sfx2/source/dialog/tabdlg.cxx @@ -518,22 +518,19 @@ short SfxTabDialog::Execute() return RET_CANCEL; Start_Impl(); - SfxViewShell* pViewShell = SfxViewShell::Current(); - if (comphelper::LibreOfficeKit::isActive() && pViewShell && !GetLOKNotifier()) - { - SetLOKNotifier(pViewShell); - const Size aSize = GetOptimalSize(); - std::vector<vcl::LOKPayloadItem> aItems; - aItems.emplace_back("type", "dialog"); - aItems.emplace_back("size", aSize.toString()); - if (!GetText().isEmpty()) - aItems.emplace_back("title", GetText().toUtf8()); - pViewShell->notifyWindow(GetLOKWindowId(), "created", aItems); - } - return TabDialog::Execute(); } +bool SfxTabDialog::StartExecuteAsync( VclAbstractDialog::AsyncContext &rCtx ) +{ + if ( !m_pTabCtrl->GetPageCount() ) + { + rCtx.mxOwner.disposeAndClear(); + return false; + } + Start_Impl(); + return TabDialog::StartExecuteAsync( rCtx ); +} void SfxTabDialog::StartExecuteModal( const Link<Dialog&,void>& rEndDialogHdl ) { @@ -590,6 +587,20 @@ void SfxTabDialog::Start_Impl() m_pTabCtrl->SetCurPageId( nActPage ); ActivatePageHdl( m_pTabCtrl ); + + SfxViewShell* pViewShell = SfxViewShell::Current(); + + if (comphelper::LibreOfficeKit::isActive() && pViewShell && !GetLOKNotifier()) + { + SetLOKNotifier(pViewShell); + const Size aSize = GetOptimalSize(); + std::vector<vcl::LOKPayloadItem> aItems; + aItems.emplace_back("type", "dialog"); + aItems.emplace_back("size", aSize.toString()); + if (!GetText().isEmpty()) + aItems.emplace_back("title", GetText().toUtf8()); + pViewShell->notifyWindow(GetLOKWindowId(), "created", aItems); + } } void SfxTabDialog::AddTabPage( sal_uInt16 nId, const OUString &rRiderText ) diff --git a/vcl/source/window/abstdlg.cxx b/vcl/source/window/abstdlg.cxx index aa2c971b5bbd..267df9e097ad 100644 --- a/vcl/source/window/abstdlg.cxx +++ b/vcl/source/window/abstdlg.cxx @@ -58,6 +58,12 @@ VclAbstractDialog::~VclAbstractDialog() { } +bool VclAbstractDialog::StartExecuteAsync(AsyncContext &) +{ + assert(false); + return false; +} + std::vector<OString> VclAbstractDialog::getAllPageUIXMLDescriptions() const { // default has no pages diff --git a/vcl/source/window/dialog.cxx b/vcl/source/window/dialog.cxx index abd858860758..b2f97bdcd081 100644 --- a/vcl/source/window/dialog.cxx +++ b/vcl/source/window/dialog.cxx @@ -36,6 +36,7 @@ #include <rtl/strbuf.hxx> #include <sal/log.hxx> +#include <vcl/abstdlg.hxx> #include <vcl/builder.hxx> #include <vcl/layout.hxx> #include <vcl/svapp.hxx> @@ -341,7 +342,7 @@ struct DialogImpl { long mnResult; bool mbStartedModal; - Link<Dialog&,void> maEndDialogHdl; + VclAbstractDialog::AsyncContext maEndCtx; DialogImpl() : mnResult( -1 ), mbStartedModal( false ) {} }; @@ -350,6 +351,7 @@ void Dialog::ImplInitDialogData() { mpWindowImpl->mbDialog = true; mpPrevExecuteDlg = nullptr; + mpNextExecuteDlg = nullptr; mbInExecute = false; mbInClose = false; mbModalMode = false; @@ -583,7 +585,9 @@ Dialog::~Dialog() void Dialog::dispose() { mpDialogImpl.reset(); + RemoveFromDlgList(); mpPrevExecuteDlg.clear(); + mpNextExecuteDlg.clear(); mpActionArea.clear(); mpContentArea.clear(); @@ -780,7 +784,9 @@ bool Dialog::Close() bool Dialog::ImplStartExecuteModal() { - if ( mbInExecute ) + setDeferredProperties(); + + if ( mbInExecute || mpDialogImpl->maEndCtx.isSet() ) { #ifdef DBG_UTIL SAL_WARN( "vcl", "Dialog::StartExecuteModal() is called in Dialog::StartExecuteModal(): " @@ -826,6 +832,8 @@ bool Dialog::ImplStartExecuteModal() // link all dialogs which are being executed mpPrevExecuteDlg = pSVData->maWinData.mpLastExecuteDlg; + if (mpPrevExecuteDlg) + mpPrevExecuteDlg->mpNextExecuteDlg = this; pSVData->maWinData.mpLastExecuteDlg = this; // stop capturing, in order to have control over the dialog @@ -841,7 +849,9 @@ bool Dialog::ImplStartExecuteModal() GetParent()->CompatNotify( aNEvt ); } mbInExecute = true; - SetModalInputMode(true); + // no real modality in LibreOfficeKit + if (!comphelper::LibreOfficeKit::isActive()) + SetModalInputMode(true); // FIXME: no layouting, workaround some clipping issues ImplAdjustNWFSizes(); @@ -849,6 +859,15 @@ bool Dialog::ImplStartExecuteModal() Show(); pSVData->maAppData.mnModalMode++; + + css::uno::Reference< css::uno::XComponentContext > xContext( + comphelper::getProcessComponentContext() ); + css::uno::Reference<css::frame::XGlobalEventBroadcaster> xEventBroadcaster(css::frame::theGlobalEventBroadcaster::get(xContext), css::uno::UNO_QUERY_THROW); + css::document::DocumentEvent aObject; + aObject.EventName = "DialogExecute"; + xEventBroadcaster->documentEventOccured(aObject); + UITestLogger::getInstance().log("DialogExecute"); + return true; } @@ -909,21 +928,11 @@ Bitmap Dialog::createScreenshot() short Dialog::Execute() { #if HAVE_FEATURE_DESKTOP - - setDeferredProperties(); + VclPtr<vcl::Window> xWindow = this; if ( !ImplStartExecuteModal() ) return 0; - VclPtr<vcl::Window> xWindow = this; - - css::uno::Reference< css::uno::XComponentContext > xContext( - comphelper::getProcessComponentContext() ); - css::uno::Reference<css::frame::XGlobalEventBroadcaster> xEventBroadcaster(css::frame::theGlobalEventBroadcaster::get(xContext), css::uno::UNO_QUERY_THROW); - css::document::DocumentEvent aObject; - aObject.EventName = "DialogExecute"; - xEventBroadcaster->documentEventOccured(aObject); - UITestLogger::getInstance().log("DialogExecute"); // Yield util EndDialog is called or dialog gets destroyed // (the latter should not happen, but better safe than sorry while ( !xWindow->IsDisposed() && mbInExecute ) @@ -945,6 +954,7 @@ short Dialog::Execute() long nRet = mpDialogImpl->mnResult; mpDialogImpl->mnResult = -1; + return static_cast<short>(nRet); #else @@ -960,11 +970,44 @@ short Dialog::Execute() // virtual void Dialog::StartExecuteModal( const Link<Dialog&,void>& rEndDialogHdl ) { + VclAbstractDialog::AsyncContext aCtx; + VclPtr<Dialog> ref(this); + aCtx.maEndDialogFn = [ref,rEndDialogHdl](sal_Int32){ rEndDialogHdl.Call(*ref.get()); }; + StartExecuteAsync(aCtx); +} + +// virtual +bool Dialog::StartExecuteAsync( VclAbstractDialog::AsyncContext &rCtx ) +{ if ( !ImplStartExecuteModal() ) - return; + { + rCtx.mxOwner.disposeAndClear(); + return false; + } - mpDialogImpl->maEndDialogHdl = rEndDialogHdl; + mpDialogImpl->maEndCtx = rCtx; mpDialogImpl->mbStartedModal = true; + + return true; +} + +void Dialog::RemoveFromDlgList() +{ + // remove dialog from the list of dialogs which are being executed + ImplSVData* pSVData = ImplGetSVData(); + if (pSVData->maWinData.mpLastExecuteDlg == this) + { + if (mpPrevExecuteDlg) + pSVData->maWinData.mpLastExecuteDlg = mpPrevExecuteDlg; + else + pSVData->maWinData.mpLastExecuteDlg = mpNextExecuteDlg; + } + if (mpPrevExecuteDlg) + mpPrevExecuteDlg->mpNextExecuteDlg = mpNextExecuteDlg; + if (mpNextExecuteDlg) + mpNextExecuteDlg->mpPrevExecuteDlg = mpPrevExecuteDlg; + mpPrevExecuteDlg.clear(); + mpNextExecuteDlg.clear(); } void Dialog::EndDialog( long nResult ) @@ -974,24 +1017,14 @@ void Dialog::EndDialog( long nResult ) SetModalInputMode(false); - // remove dialog from the list of dialogs which are being executed - ImplSVData* pSVData = ImplGetSVData(); - Dialog* pExeDlg = pSVData->maWinData.mpLastExecuteDlg; - while ( pExeDlg ) - { - if ( pExeDlg == this ) - { - pSVData->maWinData.mpLastExecuteDlg = mpPrevExecuteDlg; - break; - } - pExeDlg = pExeDlg->mpPrevExecuteDlg; - } + RemoveFromDlgList(); + // set focus to previous modal dialogue if it is modal for // the same frame parent (or NULL) if( mpPrevExecuteDlg ) { vcl::Window* pFrameParent = ImplGetFrameWindow()->ImplGetParent(); - vcl::Window* pPrevFrameParent = mpPrevExecuteDlg->ImplGetFrameWindow()->ImplGetParent(); + vcl::Window* pPrevFrameParent = mpPrevExecuteDlg->ImplGetFrameWindow()? mpPrevExecuteDlg->ImplGetFrameWindow()->ImplGetParent(): nullptr; if( ( !pFrameParent && !pPrevFrameParent ) || ( pFrameParent && pPrevFrameParent && pFrameParent->ImplGetFrame() == pPrevFrameParent->ImplGetFrame() ) ) @@ -1000,6 +1033,7 @@ void Dialog::EndDialog( long nResult ) } } mpPrevExecuteDlg = nullptr; + mpNextExecuteDlg = nullptr; Hide(); if ( GetParent() ) @@ -1013,16 +1047,18 @@ void Dialog::EndDialog( long nResult ) if ( mpDialogImpl->mbStartedModal ) { ImplEndExecuteModal(); - if (mpDialogImpl->maEndDialogHdl.IsSet()) + if (mpDialogImpl->maEndCtx.isSet()) { - mpDialogImpl->maEndDialogHdl.Call( *this ); - mpDialogImpl->maEndDialogHdl = Link<Dialog&,void>(); + mpDialogImpl->maEndCtx.maEndDialogFn(nResult); + mpDialogImpl->maEndCtx.maEndDialogFn = nullptr; } mpDialogImpl->mbStartedModal = false; mpDialogImpl->mnResult = -1; } mbInExecute = false; + // Destroy ourselves (if we have a context with VclPtr owner) + mpDialogImpl->maEndCtx.mxOwner.disposeAndClear(); } long Dialog::GetResult() const diff --git a/vcl/source/window/window.cxx b/vcl/source/window/window.cxx index 3dc940ecb00e..36dad81c68cb 100644 --- a/vcl/source/window/window.cxx +++ b/vcl/source/window/window.cxx @@ -2479,6 +2479,8 @@ bool Window::IsCallHandlersOnInputDisabled() const void Window::EnableInput( bool bEnable, bool bChild ) { + if (!mpWindowImpl) + return; bool bNotify = (bEnable != mpWindowImpl->mbInputDisabled); if ( mpWindowImpl->mpBorderWindow ) @@ -2542,6 +2544,9 @@ void Window::EnableInput( bool bEnable, bool bChild ) void Window::EnableInput( bool bEnable, const vcl::Window* pExcludeWindow ) { + if (!mpWindowImpl) + return; + EnableInput( bEnable ); // pExecuteWindow is the first Overlap-Frame --> if this |