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 <ke...@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 <c...@libreoffice.org>
    Reviewed-by: Michael Meeks <michael.me...@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();
             }
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to