summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/sfx2/tabdlg.hxx1
-rw-r--r--include/vcl/abstdlg.hxx18
-rw-r--r--include/vcl/dialog.hxx17
-rw-r--r--sc/source/ui/attrdlg/scdlgfact.hxx5
-rw-r--r--sc/source/ui/view/tabvwsha.cxx34
-rw-r--r--sfx2/source/control/request.cxx17
-rw-r--r--sfx2/source/dialog/tabdlg.cxx37
-rw-r--r--vcl/source/window/abstdlg.cxx6
-rw-r--r--vcl/source/window/dialog.cxx100
-rw-r--r--vcl/source/window/window.cxx5
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