summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan-Marek Glogowski <glogow@fbihome.de>2018-09-26 14:09:59 +0200
committerJan-Marek Glogowski <glogow@fbihome.de>2018-09-29 01:22:05 +0200
commit0e75a2d4c9d7704f49d0600632cf92aed5b00734 (patch)
tree6c46356cf20722d3aa01ed386f72ab39f8eb0f87
parent43ace67cee8d9429ae1f9437eb0b51238f3dbda7 (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.hxx7
-rw-r--r--vcl/source/window/dialog.cxx8
-rw-r--r--vcl/source/window/dlgctrl.cxx56
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;
}