[Libreoffice-commits] core.git: include/vcl vcl/inc vcl/source
Jan Holesovsky
kendy at collabora.com
Mon Jan 15 22:10:57 UTC 2018
include/vcl/dialog.hxx | 4 -
vcl/inc/svdata.hxx | 2
vcl/source/app/svmain.cxx | 2
vcl/source/uitest/uitest.cxx | 4 -
vcl/source/window/dialog.cxx | 95 ++++++++++++++++--------------------------
vcl/source/window/winproc.cxx | 6 +-
6 files changed, 46 insertions(+), 67 deletions(-)
New commits:
commit 1a156644e27a380daed217707a9cff9319f70a49
Author: Jan Holesovsky <kendy at collabora.com>
Date: Mon Jan 15 19:56:52 2018 +0100
vcl: No need for a double-linked list of dialogs in Execute().
Instead use a simple vector.
Change-Id: I50652468cf06ba681d5caccb74a52b32c6c507a0
Reviewed-on: https://gerrit.libreoffice.org/47910
Tested-by: Jenkins <ci at libreoffice.org>
Reviewed-by: Michael Meeks <michael.meeks at collabora.com>
diff --git a/include/vcl/dialog.hxx b/include/vcl/dialog.hxx
index 6dea53f47058..7fe00ba1c8c3 100644
--- a/include/vcl/dialog.hxx
+++ b/include/vcl/dialog.hxx
@@ -45,9 +45,7 @@ public:
};
private:
- VclPtr<Dialog> mpPrevExecuteDlg;
- VclPtr<Dialog> mpNextExecuteDlg;
- std::unique_ptr<DialogImpl> mpDialogImpl;
+ std::unique_ptr<DialogImpl> mpDialogImpl;
long mnMousePositioned;
bool mbInExecute;
bool mbInClose;
diff --git a/vcl/inc/svdata.hxx b/vcl/inc/svdata.hxx
index c88f8a4ce356..7949de3c0861 100644
--- a/vcl/inc/svdata.hxx
+++ b/vcl/inc/svdata.hxx
@@ -204,7 +204,7 @@ struct ImplSVWinData
VclPtr<vcl::Window> mpCaptureWin; // window, that has the mouse capture
VclPtr<vcl::Window> mpLastDeacWin; // Window, that need a deactivate (FloatingWindow-Handling)
VclPtr<FloatingWindow> mpFirstFloat; // First FloatingWindow in PopupMode
- VclPtr<Dialog> mpLastExecuteDlg; // First Dialog that is in Execute
+ std::vector<VclPtr<Dialog>> mpExecuteDialogs; ///< Stack of dialogs that are Execute()'d - the last one is the top most one.
VclPtr<vcl::Window> mpExtTextInputWin; // Window, which is in ExtTextInput
VclPtr<vcl::Window> mpTrackWin; // window, that is in tracking mode
AutoTimer* mpTrackTimer = nullptr; // tracking timer
diff --git a/vcl/source/app/svmain.cxx b/vcl/source/app/svmain.cxx
index 10d65ad2802c..500eb3060c19 100644
--- a/vcl/source/app/svmain.cxx
+++ b/vcl/source/app/svmain.cxx
@@ -606,7 +606,7 @@ void DeInitVCL()
pSVData->maWinData.mpCaptureWin = nullptr;
pSVData->maWinData.mpLastDeacWin = nullptr;
pSVData->maWinData.mpFirstFloat = nullptr;
- pSVData->maWinData.mpLastExecuteDlg = nullptr;
+ pSVData->maWinData.mpExecuteDialogs.clear();
pSVData->maWinData.mpExtTextInputWin = nullptr;
pSVData->maWinData.mpTrackWin = nullptr;
pSVData->maWinData.mpAutoScrollWin = nullptr;
diff --git a/vcl/source/uitest/uitest.cxx b/vcl/source/uitest/uitest.cxx
index 3234108ca7ed..658b8cf75a82 100644
--- a/vcl/source/uitest/uitest.cxx
+++ b/vcl/source/uitest/uitest.cxx
@@ -38,9 +38,9 @@ std::unique_ptr<UIObject> UITest::getFocusTopWindow()
ImplSVData* pSVData = ImplGetSVData();
ImplSVWinData& rWinData = pSVData->maWinData;
- if (rWinData.mpLastExecuteDlg)
+ if (!rWinData.mpExecuteDialogs.empty())
{
- return rWinData.mpLastExecuteDlg->GetUITestFactory()(rWinData.mpLastExecuteDlg);
+ return rWinData.mpExecuteDialogs.back()->GetUITestFactory()(rWinData.mpExecuteDialogs.back());
}
return rWinData.mpFirstFrame->GetUITestFactory()(rWinData.mpFirstFrame);
diff --git a/vcl/source/window/dialog.cxx b/vcl/source/window/dialog.cxx
index b2f97bdcd081..972b6671f0ed 100644
--- a/vcl/source/window/dialog.cxx
+++ b/vcl/source/window/dialog.cxx
@@ -350,8 +350,6 @@ struct DialogImpl
void Dialog::ImplInitDialogData()
{
mpWindowImpl->mbDialog = true;
- mpPrevExecuteDlg = nullptr;
- mpNextExecuteDlg = nullptr;
mbInExecute = false;
mbInClose = false;
mbModalMode = false;
@@ -373,19 +371,17 @@ vcl::Window* Dialog::GetDefaultParent(WinBits nStyle)
if (pParent && (!pParent->IsInputEnabled() || pParent->IsInModalMode()))
{
ImplSVData* pSVData = ImplGetSVData();
- Dialog* pExeDlg = pSVData->maWinData.mpLastExecuteDlg;
- while (pExeDlg)
+ auto& rExecuteDialogs = pSVData->maWinData.mpExecuteDialogs;
+ for (auto it = rExecuteDialogs.rbegin(); it != rExecuteDialogs.rend(); ++it)
{
// only if visible and enabled
- if (pParent->ImplGetFirstOverlapWindow()->IsWindowOrChild(pExeDlg, true) &&
- pExeDlg->IsReallyVisible() &&
- pExeDlg->IsEnabled() && pExeDlg->IsInputEnabled() && !pExeDlg->IsInModalMode())
+ if (pParent->ImplGetFirstOverlapWindow()->IsWindowOrChild(*it, true) &&
+ (*it)->IsReallyVisible() &&
+ (*it)->IsEnabled() && (*it)->IsInputEnabled() && !(*it)->IsInModalMode())
{
- pParent = pExeDlg;
+ pParent = it->get();
break;
}
-
- pExeDlg = pExeDlg->mpPrevExecuteDlg;
}
}
@@ -586,8 +582,6 @@ void Dialog::dispose()
{
mpDialogImpl.reset();
RemoveFromDlgList();
- mpPrevExecuteDlg.clear();
- mpNextExecuteDlg.clear();
mpActionArea.clear();
mpContentArea.clear();
@@ -831,10 +825,7 @@ bool Dialog::ImplStartExecuteModal()
ImplSVData* pSVData = ImplGetSVData();
// link all dialogs which are being executed
- mpPrevExecuteDlg = pSVData->maWinData.mpLastExecuteDlg;
- if (mpPrevExecuteDlg)
- mpPrevExecuteDlg->mpNextExecuteDlg = this;
- pSVData->maWinData.mpLastExecuteDlg = this;
+ pSVData->maWinData.mpExecuteDialogs.push_back(this);
// stop capturing, in order to have control over the dialog
if ( pSVData->maWinData.mpTrackWin )
@@ -993,21 +984,11 @@ bool Dialog::StartExecuteAsync( VclAbstractDialog::AsyncContext &rCtx )
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();
+ auto& rExecuteDialogs = pSVData->maWinData.mpExecuteDialogs;
+
+ // remove dialog from the list of dialogs which are being executed
+ rExecuteDialogs.erase(std::remove_if(rExecuteDialogs.begin(), rExecuteDialogs.end(), [=](VclPtr<Dialog>& dialog){ return dialog.get() == this; }), rExecuteDialogs.end());
}
void Dialog::EndDialog( long nResult )
@@ -1021,19 +1002,20 @@ void Dialog::EndDialog( long nResult )
// set focus to previous modal dialogue if it is modal for
// the same frame parent (or NULL)
- if( mpPrevExecuteDlg )
+ ImplSVData* pSVData = ImplGetSVData();
+ if (!pSVData->maWinData.mpExecuteDialogs.empty())
{
+ VclPtr<Dialog> pPrevious = pSVData->maWinData.mpExecuteDialogs.back();
+
vcl::Window* pFrameParent = ImplGetFrameWindow()->ImplGetParent();
- vcl::Window* pPrevFrameParent = mpPrevExecuteDlg->ImplGetFrameWindow()? mpPrevExecuteDlg->ImplGetFrameWindow()->ImplGetParent(): nullptr;
+ vcl::Window* pPrevFrameParent = pPrevious->ImplGetFrameWindow()? pPrevious->ImplGetFrameWindow()->ImplGetParent(): nullptr;
if( ( !pFrameParent && !pPrevFrameParent ) ||
( pFrameParent && pPrevFrameParent && pFrameParent->ImplGetFrame() == pPrevFrameParent->ImplGetFrame() )
)
{
- mpPrevExecuteDlg->GrabFocus();
+ pPrevious->GrabFocus();
}
}
- mpPrevExecuteDlg = nullptr;
- mpNextExecuteDlg = nullptr;
Hide();
if ( GetParent() )
@@ -1069,17 +1051,15 @@ long Dialog::GetResult() const
void Dialog::EndAllDialogs( vcl::Window const * pParent )
{
ImplSVData* pSVData = ImplGetSVData();
- Dialog* pTempModDialog;
- Dialog* pModDialog = pSVData->maWinData.mpLastExecuteDlg;
- while (pModDialog)
+ auto& rExecuteDialogs = pSVData->maWinData.mpExecuteDialogs;
+
+ for (auto it = rExecuteDialogs.rbegin(); it != rExecuteDialogs.rend(); ++it)
{
- pTempModDialog = pModDialog->mpPrevExecuteDlg;
- if(!pParent || pParent->IsWindowOrChild(pModDialog,true))
+ if (!pParent || pParent->IsWindowOrChild(*it, true))
{
- pModDialog->EndDialog();
- pModDialog->PostUserEvent( Link<void*,void>() );
+ (*it)->EndDialog();
+ (*it)->PostUserEvent(Link<void*, void>());
}
- pModDialog = pTempModDialog;
}
}
@@ -1097,14 +1077,21 @@ void Dialog::ImplSetModalInputMode( bool bModal )
if ( bModal == mbModalMode )
return;
+ // previously Execute()'d dialog - the one below the top-most one
+ VclPtr<Dialog> pPrevious;
+ ImplSVData* pSVData = ImplGetSVData();
+ auto& rExecuteDialogs = pSVData->maWinData.mpExecuteDialogs;
+ if (rExecuteDialogs.size() > 1)
+ pPrevious = rExecuteDialogs[rExecuteDialogs.size() - 2];
+
mbModalMode = bModal;
if ( bModal )
{
// Disable the prev Modal Dialog, because our dialog must close at first,
// before the other dialog can be closed (because the other dialog
// is on stack since our dialog returns)
- if ( mpPrevExecuteDlg && !mpPrevExecuteDlg->IsWindowOrChild( this, true ) )
- mpPrevExecuteDlg->EnableInput( false, this );
+ if (pPrevious && !pPrevious->IsWindowOrChild(this, true))
+ pPrevious->EnableInput(false, this);
// determine next overlap dialog parent
vcl::Window* pParent = GetParent();
@@ -1128,24 +1115,18 @@ void Dialog::ImplSetModalInputMode( bool bModal )
}
// Enable the prev Modal Dialog
- if ( mpPrevExecuteDlg && !mpPrevExecuteDlg->IsWindowOrChild( this, true ) )
+ if (pPrevious && !pPrevious->IsWindowOrChild(this, true))
{
- mpPrevExecuteDlg->EnableInput( true, this );
+ pPrevious->EnableInput(true, this);
+
// ensure continued modality of prev dialog
// do not change modality counter
// #i119994# need find the last modal dialog before reactive it
- Dialog * pPrevModalDlg = mpPrevExecuteDlg;
-
- while( pPrevModalDlg && !pPrevModalDlg->IsModalInputMode() )
- pPrevModalDlg = pPrevModalDlg->mpPrevExecuteDlg;
-
- if( pPrevModalDlg &&
- ( pPrevModalDlg == mpPrevExecuteDlg.get()
- || !pPrevModalDlg->IsWindowOrChild( this, true ) ) )
+ if (pPrevious->IsModalInputMode() || !pPrevious->IsWindowOrChild(this, true))
{
- mpPrevExecuteDlg->ImplSetModalInputMode( false );
- mpPrevExecuteDlg->ImplSetModalInputMode( true );
+ pPrevious->ImplSetModalInputMode(false);
+ pPrevious->ImplSetModalInputMode(true);
}
}
}
diff --git a/vcl/source/window/winproc.cxx b/vcl/source/window/winproc.cxx
index 5c7ce150c5e4..66233e765941 100644
--- a/vcl/source/window/winproc.cxx
+++ b/vcl/source/window/winproc.cxx
@@ -1733,9 +1733,9 @@ IMPL_LINK_NOARG(vcl::Window, ImplAsyncFocusHdl, void*, void)
{
ImplSVData* pSVData = ImplGetSVData();
vcl::Window* pTopLevelWindow = ImplGetWindowImpl()->mpFrameData->mpFocusWin->ImplGetFirstOverlapWindow();
- if ( ( ! pTopLevelWindow->IsInputEnabled() || pTopLevelWindow->IsInModalMode() )
- && pSVData->maWinData.mpLastExecuteDlg )
- pSVData->maWinData.mpLastExecuteDlg->ToTop( ToTopFlags::RestoreWhenMin | ToTopFlags::GrabFocusOnly);
+
+ if ((!pTopLevelWindow->IsInputEnabled() || pTopLevelWindow->IsInModalMode()) && !pSVData->maWinData.mpExecuteDialogs.empty())
+ pSVData->maWinData.mpExecuteDialogs.back()->ToTop(ToTopFlags::RestoreWhenMin | ToTopFlags::GrabFocusOnly);
else
pTopLevelWindow->GrabFocus();
}
More information about the Libreoffice-commits
mailing list