[Libreoffice-commits] core.git: include/vcl vcl/source

Libreoffice Gerrit user logerrit at kemper.freedesktop.org
Sat Sep 29 00:33:47 UTC 2018


 include/vcl/layout.hxx        |    7 +++++
 vcl/source/window/dialog.cxx  |    8 ++++++
 vcl/source/window/dlgctrl.cxx |   56 +++++++++++++++++++++---------------------
 3 files changed, 44 insertions(+), 27 deletions(-)

New commits:
commit 9ff4232c365c19c9402fce80e26ccbf739d0b82e
Author:     Jan-Marek Glogowski <glogow at fbihome.de>
AuthorDate: Wed Sep 26 14:09:59 2018 +0200
Commit:     Jan-Marek Glogowski <glogow at fbihome.de>
CommitDate: Sat Sep 29 02:33:23 2018 +0200

    Handle initial TabControl and border window
    
    ImplGetSubChildWindow has special code to handle a TabControl and
    its pages. If the function finds a TabControl as a child it'll
    return its window and then recurse into the current page.
    This currently breaks in the case where the initial parent is a
    TabControl. where the function will walk all of the tab pages.
    
    The function also ignores border windows, but not if the initial
    parent is a border window.
    
    This patch correctly handles both cases and as a bonus drops all
    the special page handling during child iteration.
    
    Change-Id: Ie8699dae8d08628b66b33e0704237b9e219874bc
    Reviewed-on: https://gerrit.libreoffice.org/61037
    Tested-by: Jenkins
    Reviewed-by: Jan-Marek Glogowski <glogow at fbihome.de>

diff --git a/include/vcl/layout.hxx b/include/vcl/layout.hxx
index 0f8818989268..22d494dfa6e2 100644
--- a/include/vcl/layout.hxx
+++ b/include/vcl/layout.hxx
@@ -769,6 +769,13 @@ public:
 //of children
 VCL_DLLPUBLIC vcl::Window* firstLogicalChildOfParent(const vcl::Window *pTopLevel);
 
+//Get last window of a pTopLevel window as
+//if any intermediate layout widgets didn't exist
+//i.e. acts like pChild = pChild->GetWindow(GetWindowType::LastChild);
+//in a flat hierarchy where dialogs only have one layer
+//of children
+VCL_DLLPUBLIC vcl::Window* lastLogicalChildOfParent(const vcl::Window *pTopLevel);
+
 //Get next window after pChild of a pTopLevel window as
 //if any intermediate layout widgets didn't exist
 //i.e. acts like pChild = pChild->GetWindow(GetWindowType::Next);
diff --git a/vcl/source/window/dialog.cxx b/vcl/source/window/dialog.cxx
index 99b1cede0a8b..f3e977e42c63 100644
--- a/vcl/source/window/dialog.cxx
+++ b/vcl/source/window/dialog.cxx
@@ -186,6 +186,14 @@ vcl::Window * firstLogicalChildOfParent(const vcl::Window *pTopLevel)
     return const_cast<vcl::Window *>(pChild);
 }
 
+vcl::Window * lastLogicalChildOfParent(const vcl::Window *pTopLevel)
+{
+    const vcl::Window *pChild = pTopLevel->GetWindow(GetWindowType::LastChild);
+    if (pChild && isContainerWindow(*pChild))
+        pChild = prevLogicalChildOfParent(pTopLevel, pChild);
+    return const_cast<vcl::Window *>(pChild);
+}
+
 void Accelerator::GenerateAutoMnemonicsOnHierarchy(vcl::Window* pWindow)
 {
     MnemonicGenerator   aMnemonicGenerator;
diff --git a/vcl/source/window/dlgctrl.cxx b/vcl/source/window/dlgctrl.cxx
index 4479291b6f24..36dcf861c566 100644
--- a/vcl/source/window/dlgctrl.cxx
+++ b/vcl/source/window/dlgctrl.cxx
@@ -94,49 +94,51 @@ static vcl::Window* ImplGetCurTabWindow(const vcl::Window* pWindow)
 
 static vcl::Window* ImplGetSubChildWindow( vcl::Window* pParent, sal_uInt16 n, sal_uInt16& nIndex )
 {
-    vcl::Window*     pTabPage = nullptr;
-    vcl::Window*     pFoundWindow = nullptr;
+    // ignore border window
+    pParent = pParent->ImplGetWindow();
+    assert(pParent == pParent->ImplGetWindow());
 
-    vcl::Window*     pWindow = firstLogicalChildOfParent(pParent);
-    vcl::Window*     pNextWindow = pWindow;
-    while ( pWindow )
+    vcl::Window* pFoundWindow = nullptr;
+    vcl::Window* pWindow = firstLogicalChildOfParent(pParent);
+    vcl::Window* pNextWindow = pWindow;
+
+    // process just the current page of a tab control
+    if (pWindow && pParent->GetType() == WindowType::TABCONTROL)
+    {
+        pWindow = ImplGetCurTabWindow(pParent);
+        pNextWindow = lastLogicalChildOfParent(pParent);
+    }
+
+    while (pWindow)
     {
         pWindow = pWindow->ImplGetWindow();
 
         // skip invisible and disabled windows
-        if ( pTabPage || isVisibleInLayout(pWindow) )
+        if (isVisibleInLayout(pWindow))
         {
-            // if the last control was a TabControl, take its TabPage
-            if ( pTabPage )
+            // return the TabControl itself, before handling its page
+            if (pWindow->GetType() == WindowType::TABCONTROL)
             {
-                pFoundWindow = ImplGetSubChildWindow( pTabPage, n, nIndex );
-                pTabPage = nullptr;
+                if (n == nIndex)
+                    return pWindow;
+                ++nIndex;
             }
+            if (pWindow->GetStyle() & (WB_DIALOGCONTROL | WB_CHILDDLGCTRL))
+                pFoundWindow = ImplGetSubChildWindow(pWindow, n, nIndex);
             else
-            {
                 pFoundWindow = pWindow;
-                // for a TabControl, remember the current TabPage for later use
-                if ( pWindow->GetType() == WindowType::TABCONTROL )
-                    pTabPage = ImplGetCurTabWindow(pWindow);
-                else if (pWindow->GetStyle() & (WB_DIALOGCONTROL | WB_CHILDDLGCTRL))
-                    pFoundWindow = ImplGetSubChildWindow( pWindow, n, nIndex );
-            }
 
-            if ( n == nIndex )
+            if (n == nIndex)
                 return pFoundWindow;
-            nIndex++;
+            ++nIndex;
         }
 
-        if ( pTabPage )
-            pWindow = pTabPage;
-        else
-        {
-            pWindow = nextLogicalChildOfParent(pParent, pNextWindow);
-            pNextWindow = pWindow;
-        }
+        pWindow = nextLogicalChildOfParent(pParent, pNextWindow);
+        pNextWindow = pWindow;
     }
 
-    nIndex--;
+    --nIndex;
+    assert(!pFoundWindow || (pFoundWindow == pFoundWindow->ImplGetWindow()));
     return pFoundWindow;
 }
 


More information about the Libreoffice-commits mailing list