diff options
author | Jan-Marek Glogowski <glogow@fbihome.de> | 2018-09-26 14:09:59 +0200 |
---|---|---|
committer | Jan-Marek Glogowski <glogow@fbihome.de> | 2018-09-29 01:22:05 +0200 |
commit | 0e75a2d4c9d7704f49d0600632cf92aed5b00734 (patch) | |
tree | 6c46356cf20722d3aa01ed386f72ab39f8eb0f87 | |
parent | 43ace67cee8d9429ae1f9437eb0b51238f3dbda7 (diff) |
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
-rw-r--r-- | include/vcl/layout.hxx | 7 | ||||
-rw-r--r-- | vcl/source/window/dialog.cxx | 8 | ||||
-rw-r--r-- | vcl/source/window/dlgctrl.cxx | 56 |
3 files changed, 44 insertions, 27 deletions
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; } |