summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Holesovsky <kendy@collabora.com>2018-01-12 11:57:22 +0000
committerJan Holesovsky <kendy@collabora.com>2018-01-15 17:44:42 +0100
commitc40dfabd56ade10fe35690dc9810955c2e99e2c0 (patch)
tree0ae297ec41e2a1a5e4e078180c18320a83823a89
parent5942140c5149065ffb5adf9d33b21aeceeabf957 (diff)
lokdialog: Allow closing the Format Cell dialogs in any order.
Includes also lots of infrastructural changes, making the conversion of the rest of the dialogs much easier. StartExecuteAsync should be used in-place of StartExecuteModal and the latter removed from the code-base incrementally. More common code from Dialog::Execute should be moved to ImplStartExecuteModal in a next step, as this is used more widely. Change-Id: Idb2c1ec790e38f582438471a0419a56cdcf1439d Reviewed-on: https://gerrit.libreoffice.org/47722 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Jan Holesovsky <kendy@collabora.com> Tested-by: Jan Holesovsky <kendy@collabora.com>
-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