diff options
author | Jan Holesovsky <kendy@collabora.com> | 2018-01-15 19:56:52 +0100 |
---|---|---|
committer | Michael Meeks <michael.meeks@collabora.com> | 2018-01-15 23:10:37 +0100 |
commit | 1a156644e27a380daed217707a9cff9319f70a49 (patch) | |
tree | 8355bfa07c7c6357b8f1aa5ec5eda4937479bf93 /vcl | |
parent | f2e3d8d34b3d3993d46e38c660a60cdfc7950090 (diff) |
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@libreoffice.org>
Reviewed-by: Michael Meeks <michael.meeks@collabora.com>
Diffstat (limited to 'vcl')
-rw-r--r-- | vcl/inc/svdata.hxx | 2 | ||||
-rw-r--r-- | vcl/source/app/svmain.cxx | 2 | ||||
-rw-r--r-- | vcl/source/uitest/uitest.cxx | 4 | ||||
-rw-r--r-- | vcl/source/window/dialog.cxx | 95 | ||||
-rw-r--r-- | vcl/source/window/winproc.cxx | 6 |
5 files changed, 45 insertions, 64 deletions
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(); } |