summaryrefslogtreecommitdiff
path: root/vcl
diff options
context:
space:
mode:
authorJan Holesovsky <kendy@collabora.com>2018-01-12 11:57:22 +0000
committerAndras Timar <andras.timar@collabora.com>2018-03-21 12:11:50 +0100
commitde70c261103da079a8cf54c818aa1e6d6085202c (patch)
tree1fcdeabcc2d313c1933c05f7016b61672482a566 /vcl
parenta1d6bb723907c0c5e0b1753f2e95724d16c67133 (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. 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> (cherry picked from commit c40dfabd56ade10fe35690dc9810955c2e99e2c0) Change-Id: Idb2c1ec790e38f582438471a0419a56cdcf1439d
Diffstat (limited to 'vcl')
-rw-r--r--vcl/source/window/abstdlg.cxx6
-rw-r--r--vcl/source/window/dialog.cxx100
-rw-r--r--vcl/source/window/window.cxx5
3 files changed, 78 insertions, 33 deletions
diff --git a/vcl/source/window/abstdlg.cxx b/vcl/source/window/abstdlg.cxx
index 807e75ead2d0..8ce6fd4221d6 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 5be7d2a01ed5..3d43c7750fd2 100644
--- a/vcl/source/window/dialog.cxx
+++ b/vcl/source/window/dialog.cxx
@@ -37,6 +37,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>
@@ -342,7 +343,7 @@ struct DialogImpl
{
long mnResult;
bool mbStartedModal;
- Link<Dialog&,void> maEndDialogHdl;
+ VclAbstractDialog::AsyncContext maEndCtx;
DialogImpl() : mnResult( -1 ), mbStartedModal( false ) {}
};
@@ -351,6 +352,7 @@ void Dialog::ImplInitDialogData()
{
mpWindowImpl->mbDialog = true;
mpPrevExecuteDlg = nullptr;
+ mpNextExecuteDlg = nullptr;
mbInExecute = false;
mbInClose = false;
mbModalMode = false;
@@ -584,7 +586,9 @@ Dialog::~Dialog()
void Dialog::dispose()
{
mpDialogImpl.reset();
+ RemoveFromDlgList();
mpPrevExecuteDlg.clear();
+ mpNextExecuteDlg.clear();
mpActionArea.clear();
mpContentArea.clear();
@@ -781,7 +785,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(): "
@@ -827,6 +833,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
@@ -842,7 +850,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();
@@ -854,6 +864,13 @@ bool Dialog::ImplStartExecuteModal()
Show(true, showFlags);
pSVData->maAppData.mnModalMode++;
+
+ 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;
}
@@ -914,21 +931,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 )
@@ -950,7 +957,8 @@ short Dialog::Execute()
long nRet = mpDialogImpl->mnResult;
mpDialogImpl->mnResult = -1;
- return (short)nRet;
+
+ return static_cast<short>(nRet);
#else
@@ -965,11 +973,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 )
@@ -979,24 +1020,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() )
)
@@ -1005,6 +1036,7 @@ void Dialog::EndDialog( long nResult )
}
}
mpPrevExecuteDlg = nullptr;
+ mpNextExecuteDlg = nullptr;
Hide();
if ( GetParent() )
@@ -1018,16 +1050,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 20e7fde45c66..3aff52f67573 100644
--- a/vcl/source/window/window.cxx
+++ b/vcl/source/window/window.cxx
@@ -2494,6 +2494,8 @@ bool Window::IsCallHandlersOnInputDisabled() const
void Window::EnableInput( bool bEnable, bool bChild )
{
+ if (!mpWindowImpl)
+ return;
bool bNotify = (bEnable != mpWindowImpl->mbInputDisabled);
if ( mpWindowImpl->mpBorderWindow )
@@ -2557,6 +2559,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