1*b1cdbd2cSJim Jagielski /**************************************************************
2*b1cdbd2cSJim Jagielski  *
3*b1cdbd2cSJim Jagielski  * Licensed to the Apache Software Foundation (ASF) under one
4*b1cdbd2cSJim Jagielski  * or more contributor license agreements.  See the NOTICE file
5*b1cdbd2cSJim Jagielski  * distributed with this work for additional information
6*b1cdbd2cSJim Jagielski  * regarding copyright ownership.  The ASF licenses this file
7*b1cdbd2cSJim Jagielski  * to you under the Apache License, Version 2.0 (the
8*b1cdbd2cSJim Jagielski  * "License"); you may not use this file except in compliance
9*b1cdbd2cSJim Jagielski  * with the License.  You may obtain a copy of the License at
10*b1cdbd2cSJim Jagielski  *
11*b1cdbd2cSJim Jagielski  *   http://www.apache.org/licenses/LICENSE-2.0
12*b1cdbd2cSJim Jagielski  *
13*b1cdbd2cSJim Jagielski  * Unless required by applicable law or agreed to in writing,
14*b1cdbd2cSJim Jagielski  * software distributed under the License is distributed on an
15*b1cdbd2cSJim Jagielski  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*b1cdbd2cSJim Jagielski  * KIND, either express or implied.  See the License for the
17*b1cdbd2cSJim Jagielski  * specific language governing permissions and limitations
18*b1cdbd2cSJim Jagielski  * under the License.
19*b1cdbd2cSJim Jagielski  *
20*b1cdbd2cSJim Jagielski  *************************************************************/
21*b1cdbd2cSJim Jagielski 
22*b1cdbd2cSJim Jagielski #include "precompiled_sfx2.hxx"
23*b1cdbd2cSJim Jagielski 
24*b1cdbd2cSJim Jagielski #include "FocusManager.hxx"
25*b1cdbd2cSJim Jagielski #include "Panel.hxx"
26*b1cdbd2cSJim Jagielski #include "DeckTitleBar.hxx"
27*b1cdbd2cSJim Jagielski #include "PanelTitleBar.hxx"
28*b1cdbd2cSJim Jagielski #include "sfx2/sidebar/Tools.hxx"
29*b1cdbd2cSJim Jagielski #include "TitleBar.hxx"
30*b1cdbd2cSJim Jagielski #include <vcl/button.hxx>
31*b1cdbd2cSJim Jagielski #include <vcl/toolbox.hxx>
32*b1cdbd2cSJim Jagielski #include <toolkit/helper/vclunohelper.hxx>
33*b1cdbd2cSJim Jagielski 
34*b1cdbd2cSJim Jagielski 
35*b1cdbd2cSJim Jagielski namespace sfx2 { namespace sidebar {
36*b1cdbd2cSJim Jagielski 
FocusLocation(const PanelComponent eComponent,const sal_Int32 nIndex)37*b1cdbd2cSJim Jagielski FocusManager::FocusLocation::FocusLocation (const PanelComponent eComponent, const sal_Int32 nIndex)
38*b1cdbd2cSJim Jagielski     : meComponent(eComponent),
39*b1cdbd2cSJim Jagielski       mnIndex(nIndex)
40*b1cdbd2cSJim Jagielski {
41*b1cdbd2cSJim Jagielski }
42*b1cdbd2cSJim Jagielski 
43*b1cdbd2cSJim Jagielski 
44*b1cdbd2cSJim Jagielski 
45*b1cdbd2cSJim Jagielski 
FocusManager(const::boost::function<void (const Panel &)> & rShowPanelFunctor)46*b1cdbd2cSJim Jagielski FocusManager::FocusManager (const ::boost::function<void(const Panel&)>& rShowPanelFunctor)
47*b1cdbd2cSJim Jagielski     : mpDeckTitleBar(),
48*b1cdbd2cSJim Jagielski       maPanels(),
49*b1cdbd2cSJim Jagielski       maButtons(),
50*b1cdbd2cSJim Jagielski       maShowPanelFunctor(rShowPanelFunctor),
51*b1cdbd2cSJim Jagielski       mbObservingContentControlFocus(false),
52*b1cdbd2cSJim Jagielski       mpFirstFocusedContentControl(NULL)
53*b1cdbd2cSJim Jagielski {
54*b1cdbd2cSJim Jagielski }
55*b1cdbd2cSJim Jagielski 
56*b1cdbd2cSJim Jagielski 
57*b1cdbd2cSJim Jagielski 
58*b1cdbd2cSJim Jagielski 
~FocusManager(void)59*b1cdbd2cSJim Jagielski FocusManager::~FocusManager (void)
60*b1cdbd2cSJim Jagielski {
61*b1cdbd2cSJim Jagielski     Clear();
62*b1cdbd2cSJim Jagielski }
63*b1cdbd2cSJim Jagielski 
64*b1cdbd2cSJim Jagielski 
65*b1cdbd2cSJim Jagielski 
66*b1cdbd2cSJim Jagielski 
GrabFocus(void)67*b1cdbd2cSJim Jagielski void FocusManager::GrabFocus (void)
68*b1cdbd2cSJim Jagielski {
69*b1cdbd2cSJim Jagielski     FocusDeckTitle();
70*b1cdbd2cSJim Jagielski }
71*b1cdbd2cSJim Jagielski 
72*b1cdbd2cSJim Jagielski 
73*b1cdbd2cSJim Jagielski 
74*b1cdbd2cSJim Jagielski 
Clear(void)75*b1cdbd2cSJim Jagielski void FocusManager::Clear (void)
76*b1cdbd2cSJim Jagielski {
77*b1cdbd2cSJim Jagielski     SetDeckTitle(NULL);
78*b1cdbd2cSJim Jagielski     ClearPanels();
79*b1cdbd2cSJim Jagielski     ClearButtons();
80*b1cdbd2cSJim Jagielski }
81*b1cdbd2cSJim Jagielski 
82*b1cdbd2cSJim Jagielski 
83*b1cdbd2cSJim Jagielski 
84*b1cdbd2cSJim Jagielski 
ClearPanels(void)85*b1cdbd2cSJim Jagielski void FocusManager::ClearPanels (void)
86*b1cdbd2cSJim Jagielski {
87*b1cdbd2cSJim Jagielski     ::std::vector<Panel*> aPanels;
88*b1cdbd2cSJim Jagielski     aPanels.swap(maPanels);
89*b1cdbd2cSJim Jagielski     for (::std::vector<Panel*>::iterator iPanel(aPanels.begin()),iEnd(aPanels.end());
90*b1cdbd2cSJim Jagielski          iPanel!=iEnd;
91*b1cdbd2cSJim Jagielski         ++iPanel)
92*b1cdbd2cSJim Jagielski     {
93*b1cdbd2cSJim Jagielski         UnregisterWindow(**iPanel);
94*b1cdbd2cSJim Jagielski         if ((*iPanel)->GetTitleBar() != NULL)
95*b1cdbd2cSJim Jagielski         {
96*b1cdbd2cSJim Jagielski             UnregisterWindow(*(*iPanel)->GetTitleBar());
97*b1cdbd2cSJim Jagielski             UnregisterWindow((*iPanel)->GetTitleBar()->GetToolBox());
98*b1cdbd2cSJim Jagielski         }
99*b1cdbd2cSJim Jagielski 
100*b1cdbd2cSJim Jagielski         (*iPanel)->RemoveChildEventListener(LINK(this, FocusManager, ChildEventListener));
101*b1cdbd2cSJim Jagielski     }
102*b1cdbd2cSJim Jagielski }
103*b1cdbd2cSJim Jagielski 
104*b1cdbd2cSJim Jagielski 
105*b1cdbd2cSJim Jagielski 
106*b1cdbd2cSJim Jagielski 
ClearButtons(void)107*b1cdbd2cSJim Jagielski void FocusManager::ClearButtons (void)
108*b1cdbd2cSJim Jagielski {
109*b1cdbd2cSJim Jagielski     ::std::vector<Button*> aButtons;
110*b1cdbd2cSJim Jagielski     aButtons.swap(maButtons);
111*b1cdbd2cSJim Jagielski     for (::std::vector<Button*>::iterator iButton(aButtons.begin()),iEnd(aButtons.end());
112*b1cdbd2cSJim Jagielski          iButton!=iEnd;
113*b1cdbd2cSJim Jagielski         ++iButton)
114*b1cdbd2cSJim Jagielski     {
115*b1cdbd2cSJim Jagielski         UnregisterWindow(**iButton);
116*b1cdbd2cSJim Jagielski     }
117*b1cdbd2cSJim Jagielski }
118*b1cdbd2cSJim Jagielski 
119*b1cdbd2cSJim Jagielski 
120*b1cdbd2cSJim Jagielski 
121*b1cdbd2cSJim Jagielski 
SetDeckTitle(DeckTitleBar * pDeckTitleBar)122*b1cdbd2cSJim Jagielski void FocusManager::SetDeckTitle (DeckTitleBar* pDeckTitleBar)
123*b1cdbd2cSJim Jagielski {
124*b1cdbd2cSJim Jagielski     if (mpDeckTitleBar != NULL)
125*b1cdbd2cSJim Jagielski     {
126*b1cdbd2cSJim Jagielski         UnregisterWindow(*mpDeckTitleBar);
127*b1cdbd2cSJim Jagielski         UnregisterWindow(mpDeckTitleBar->GetToolBox());
128*b1cdbd2cSJim Jagielski     }
129*b1cdbd2cSJim Jagielski     mpDeckTitleBar = pDeckTitleBar;
130*b1cdbd2cSJim Jagielski 
131*b1cdbd2cSJim Jagielski     if (mpDeckTitleBar != NULL)
132*b1cdbd2cSJim Jagielski     {
133*b1cdbd2cSJim Jagielski         RegisterWindow(*mpDeckTitleBar);
134*b1cdbd2cSJim Jagielski         RegisterWindow(mpDeckTitleBar->GetToolBox());
135*b1cdbd2cSJim Jagielski     }
136*b1cdbd2cSJim Jagielski }
137*b1cdbd2cSJim Jagielski 
138*b1cdbd2cSJim Jagielski 
139*b1cdbd2cSJim Jagielski 
140*b1cdbd2cSJim Jagielski 
SetPanels(const SharedPanelContainer & rPanels)141*b1cdbd2cSJim Jagielski void FocusManager::SetPanels (const SharedPanelContainer& rPanels)
142*b1cdbd2cSJim Jagielski {
143*b1cdbd2cSJim Jagielski     ClearPanels();
144*b1cdbd2cSJim Jagielski     for(SharedPanelContainer::const_iterator iPanel(rPanels.begin()),iEnd(rPanels.end());
145*b1cdbd2cSJim Jagielski         iPanel!=iEnd;
146*b1cdbd2cSJim Jagielski         ++iPanel)
147*b1cdbd2cSJim Jagielski     {
148*b1cdbd2cSJim Jagielski         RegisterWindow(**iPanel);
149*b1cdbd2cSJim Jagielski         if ((*iPanel)->GetTitleBar() != NULL)
150*b1cdbd2cSJim Jagielski         {
151*b1cdbd2cSJim Jagielski             RegisterWindow(*(*iPanel)->GetTitleBar());
152*b1cdbd2cSJim Jagielski             RegisterWindow((*iPanel)->GetTitleBar()->GetToolBox());
153*b1cdbd2cSJim Jagielski         }
154*b1cdbd2cSJim Jagielski 
155*b1cdbd2cSJim Jagielski         // Register also as child event listener at the panel.
156*b1cdbd2cSJim Jagielski         (*iPanel)->AddChildEventListener(LINK(this, FocusManager, ChildEventListener));
157*b1cdbd2cSJim Jagielski 
158*b1cdbd2cSJim Jagielski         maPanels.push_back(iPanel->get());
159*b1cdbd2cSJim Jagielski     }
160*b1cdbd2cSJim Jagielski }
161*b1cdbd2cSJim Jagielski 
162*b1cdbd2cSJim Jagielski 
163*b1cdbd2cSJim Jagielski 
164*b1cdbd2cSJim Jagielski 
SetButtons(const::std::vector<Button * > & rButtons)165*b1cdbd2cSJim Jagielski void FocusManager::SetButtons (const ::std::vector<Button*>& rButtons)
166*b1cdbd2cSJim Jagielski {
167*b1cdbd2cSJim Jagielski     ClearButtons();
168*b1cdbd2cSJim Jagielski     for (::std::vector<Button*>::const_iterator iButton(rButtons.begin()),iEnd(rButtons.end());
169*b1cdbd2cSJim Jagielski          iButton!=iEnd;
170*b1cdbd2cSJim Jagielski          ++iButton)
171*b1cdbd2cSJim Jagielski     {
172*b1cdbd2cSJim Jagielski         RegisterWindow(**iButton);
173*b1cdbd2cSJim Jagielski         maButtons.push_back(*iButton);
174*b1cdbd2cSJim Jagielski     }
175*b1cdbd2cSJim Jagielski }
176*b1cdbd2cSJim Jagielski 
177*b1cdbd2cSJim Jagielski 
178*b1cdbd2cSJim Jagielski 
179*b1cdbd2cSJim Jagielski 
RegisterWindow(Window & rWindow)180*b1cdbd2cSJim Jagielski void FocusManager::RegisterWindow (Window& rWindow)
181*b1cdbd2cSJim Jagielski {
182*b1cdbd2cSJim Jagielski     rWindow.AddEventListener(LINK(this, FocusManager, WindowEventListener));
183*b1cdbd2cSJim Jagielski }
184*b1cdbd2cSJim Jagielski 
185*b1cdbd2cSJim Jagielski 
186*b1cdbd2cSJim Jagielski 
187*b1cdbd2cSJim Jagielski 
UnregisterWindow(Window & rWindow)188*b1cdbd2cSJim Jagielski void FocusManager::UnregisterWindow (Window& rWindow)
189*b1cdbd2cSJim Jagielski {
190*b1cdbd2cSJim Jagielski     rWindow.RemoveEventListener(LINK(this, FocusManager, WindowEventListener));
191*b1cdbd2cSJim Jagielski }
192*b1cdbd2cSJim Jagielski 
193*b1cdbd2cSJim Jagielski 
194*b1cdbd2cSJim Jagielski 
195*b1cdbd2cSJim Jagielski 
GetFocusLocation(const Window & rWindow) const196*b1cdbd2cSJim Jagielski FocusManager::FocusLocation FocusManager::GetFocusLocation (const Window& rWindow) const
197*b1cdbd2cSJim Jagielski {
198*b1cdbd2cSJim Jagielski     // Check the deck title.
199*b1cdbd2cSJim Jagielski     if (mpDeckTitleBar != NULL)
200*b1cdbd2cSJim Jagielski     {
201*b1cdbd2cSJim Jagielski         if (mpDeckTitleBar == &rWindow)
202*b1cdbd2cSJim Jagielski             return FocusLocation(PC_DeckTitle, -1);
203*b1cdbd2cSJim Jagielski         else if (&mpDeckTitleBar->GetToolBox() == &rWindow)
204*b1cdbd2cSJim Jagielski             return FocusLocation(PC_DeckToolBox, -1);
205*b1cdbd2cSJim Jagielski     }
206*b1cdbd2cSJim Jagielski 
207*b1cdbd2cSJim Jagielski     // Search the panels.
208*b1cdbd2cSJim Jagielski     for (sal_Int32 nIndex=0,nCount(maPanels.size()); nIndex<nCount; ++nIndex)
209*b1cdbd2cSJim Jagielski     {
210*b1cdbd2cSJim Jagielski         if (maPanels[nIndex] == &rWindow)
211*b1cdbd2cSJim Jagielski             return FocusLocation(PC_PanelContent, nIndex);
212*b1cdbd2cSJim Jagielski         TitleBar* pTitleBar = maPanels[nIndex]->GetTitleBar();
213*b1cdbd2cSJim Jagielski         if (pTitleBar == &rWindow)
214*b1cdbd2cSJim Jagielski             return FocusLocation(PC_PanelTitle, nIndex);
215*b1cdbd2cSJim Jagielski         if (pTitleBar!=NULL && &pTitleBar->GetToolBox()==&rWindow)
216*b1cdbd2cSJim Jagielski             return FocusLocation(PC_PanelToolBox, nIndex);
217*b1cdbd2cSJim Jagielski     }
218*b1cdbd2cSJim Jagielski 
219*b1cdbd2cSJim Jagielski     // Search the buttons.
220*b1cdbd2cSJim Jagielski     for (sal_Int32 nIndex=0,nCount(maButtons.size()); nIndex<nCount; ++nIndex)
221*b1cdbd2cSJim Jagielski         if (maButtons[nIndex] == &rWindow)
222*b1cdbd2cSJim Jagielski             return FocusLocation(PC_TabBar, nIndex);
223*b1cdbd2cSJim Jagielski 
224*b1cdbd2cSJim Jagielski     return FocusLocation(PC_None, -1);
225*b1cdbd2cSJim Jagielski }
226*b1cdbd2cSJim Jagielski 
227*b1cdbd2cSJim Jagielski 
228*b1cdbd2cSJim Jagielski 
229*b1cdbd2cSJim Jagielski 
IsAnyPanelFocused(void) const230*b1cdbd2cSJim Jagielski bool FocusManager::IsAnyPanelFocused (void) const
231*b1cdbd2cSJim Jagielski {
232*b1cdbd2cSJim Jagielski     for (::std::vector<Panel*>::const_iterator iPanel(maPanels.begin()),iEnd(maPanels.end());
233*b1cdbd2cSJim Jagielski          iPanel!=iEnd;
234*b1cdbd2cSJim Jagielski          ++iPanel)
235*b1cdbd2cSJim Jagielski     {
236*b1cdbd2cSJim Jagielski         if ((*iPanel)->HasFocus())
237*b1cdbd2cSJim Jagielski             return true;
238*b1cdbd2cSJim Jagielski         else if ((*iPanel)->HasChildPathFocus())
239*b1cdbd2cSJim Jagielski             return true;
240*b1cdbd2cSJim Jagielski     }
241*b1cdbd2cSJim Jagielski     return false;
242*b1cdbd2cSJim Jagielski }
243*b1cdbd2cSJim Jagielski 
244*b1cdbd2cSJim Jagielski 
245*b1cdbd2cSJim Jagielski 
246*b1cdbd2cSJim Jagielski 
IsAnyButtonFocused(void) const247*b1cdbd2cSJim Jagielski bool FocusManager::IsAnyButtonFocused (void) const
248*b1cdbd2cSJim Jagielski {
249*b1cdbd2cSJim Jagielski     for (::std::vector<Button*>::const_iterator iButton(maButtons.begin()),iEnd(maButtons.end());
250*b1cdbd2cSJim Jagielski          iButton!=iEnd;
251*b1cdbd2cSJim Jagielski          ++iButton)
252*b1cdbd2cSJim Jagielski     {
253*b1cdbd2cSJim Jagielski         if ((*iButton)->HasFocus())
254*b1cdbd2cSJim Jagielski             return true;
255*b1cdbd2cSJim Jagielski     }
256*b1cdbd2cSJim Jagielski     return false;
257*b1cdbd2cSJim Jagielski }
258*b1cdbd2cSJim Jagielski 
259*b1cdbd2cSJim Jagielski 
260*b1cdbd2cSJim Jagielski 
261*b1cdbd2cSJim Jagielski 
FocusDeckTitle(void)262*b1cdbd2cSJim Jagielski void FocusManager::FocusDeckTitle (void)
263*b1cdbd2cSJim Jagielski {
264*b1cdbd2cSJim Jagielski     if (mpDeckTitleBar != NULL)
265*b1cdbd2cSJim Jagielski     {
266*b1cdbd2cSJim Jagielski         if (IsDeckTitleVisible())
267*b1cdbd2cSJim Jagielski         {
268*b1cdbd2cSJim Jagielski             mpDeckTitleBar->GrabFocus();
269*b1cdbd2cSJim Jagielski         }
270*b1cdbd2cSJim Jagielski         else if (mpDeckTitleBar->GetToolBox().GetItemCount() > 0)
271*b1cdbd2cSJim Jagielski         {
272*b1cdbd2cSJim Jagielski             ToolBox& rToolBox = mpDeckTitleBar->GetToolBox();
273*b1cdbd2cSJim Jagielski             rToolBox.GrabFocus();
274*b1cdbd2cSJim Jagielski             rToolBox.Invalidate();
275*b1cdbd2cSJim Jagielski         }
276*b1cdbd2cSJim Jagielski         else
277*b1cdbd2cSJim Jagielski             FocusPanel(0, false);
278*b1cdbd2cSJim Jagielski     }
279*b1cdbd2cSJim Jagielski     else
280*b1cdbd2cSJim Jagielski         FocusPanel(0, false);
281*b1cdbd2cSJim Jagielski }
282*b1cdbd2cSJim Jagielski 
283*b1cdbd2cSJim Jagielski 
284*b1cdbd2cSJim Jagielski 
285*b1cdbd2cSJim Jagielski 
IsDeckTitleVisible(void) const286*b1cdbd2cSJim Jagielski bool FocusManager::IsDeckTitleVisible (void) const
287*b1cdbd2cSJim Jagielski {
288*b1cdbd2cSJim Jagielski     return mpDeckTitleBar != NULL && mpDeckTitleBar->IsVisible();
289*b1cdbd2cSJim Jagielski }
290*b1cdbd2cSJim Jagielski 
291*b1cdbd2cSJim Jagielski 
292*b1cdbd2cSJim Jagielski 
293*b1cdbd2cSJim Jagielski 
IsPanelTitleVisible(const sal_Int32 nPanelIndex) const294*b1cdbd2cSJim Jagielski bool FocusManager::IsPanelTitleVisible (const sal_Int32 nPanelIndex) const
295*b1cdbd2cSJim Jagielski {
296*b1cdbd2cSJim Jagielski     if (nPanelIndex<0 || nPanelIndex>=static_cast<sal_Int32>(maPanels.size()))
297*b1cdbd2cSJim Jagielski         return false;
298*b1cdbd2cSJim Jagielski 
299*b1cdbd2cSJim Jagielski     TitleBar* pTitleBar = maPanels[nPanelIndex]->GetTitleBar();
300*b1cdbd2cSJim Jagielski     if (pTitleBar==NULL)
301*b1cdbd2cSJim Jagielski         return false;
302*b1cdbd2cSJim Jagielski     return pTitleBar->IsVisible();
303*b1cdbd2cSJim Jagielski }
304*b1cdbd2cSJim Jagielski 
305*b1cdbd2cSJim Jagielski 
306*b1cdbd2cSJim Jagielski 
307*b1cdbd2cSJim Jagielski 
FocusPanel(const sal_Int32 nPanelIndex,const bool bFallbackToDeckTitle)308*b1cdbd2cSJim Jagielski void FocusManager::FocusPanel (
309*b1cdbd2cSJim Jagielski     const sal_Int32 nPanelIndex,
310*b1cdbd2cSJim Jagielski     const bool bFallbackToDeckTitle)
311*b1cdbd2cSJim Jagielski {
312*b1cdbd2cSJim Jagielski     if (nPanelIndex<0 || nPanelIndex>=static_cast<sal_Int32>(maPanels.size()))
313*b1cdbd2cSJim Jagielski     {
314*b1cdbd2cSJim Jagielski         if (bFallbackToDeckTitle)
315*b1cdbd2cSJim Jagielski             FocusDeckTitle();
316*b1cdbd2cSJim Jagielski         return;
317*b1cdbd2cSJim Jagielski     }
318*b1cdbd2cSJim Jagielski 
319*b1cdbd2cSJim Jagielski     Panel& rPanel (*maPanels[nPanelIndex]);
320*b1cdbd2cSJim Jagielski     TitleBar* pTitleBar = rPanel.GetTitleBar();
321*b1cdbd2cSJim Jagielski     if (pTitleBar!=NULL && pTitleBar->IsVisible())
322*b1cdbd2cSJim Jagielski     {
323*b1cdbd2cSJim Jagielski         rPanel.SetExpanded(true);
324*b1cdbd2cSJim Jagielski         pTitleBar->GrabFocus();
325*b1cdbd2cSJim Jagielski     }
326*b1cdbd2cSJim Jagielski     else if (bFallbackToDeckTitle)
327*b1cdbd2cSJim Jagielski     {
328*b1cdbd2cSJim Jagielski         // The panel title is not visible, fall back to the deck
329*b1cdbd2cSJim Jagielski         // title.
330*b1cdbd2cSJim Jagielski         // Make sure that the desk title is visible here to prevent a
331*b1cdbd2cSJim Jagielski         // loop when both the title of panel 0 and the deck title are
332*b1cdbd2cSJim Jagielski         // not present.
333*b1cdbd2cSJim Jagielski         if (IsDeckTitleVisible())
334*b1cdbd2cSJim Jagielski             FocusDeckTitle();
335*b1cdbd2cSJim Jagielski         else
336*b1cdbd2cSJim Jagielski             FocusPanelContent(nPanelIndex);
337*b1cdbd2cSJim Jagielski     }
338*b1cdbd2cSJim Jagielski     else
339*b1cdbd2cSJim Jagielski         FocusPanelContent(nPanelIndex);
340*b1cdbd2cSJim Jagielski 
341*b1cdbd2cSJim Jagielski     if (maShowPanelFunctor)
342*b1cdbd2cSJim Jagielski         maShowPanelFunctor(rPanel);
343*b1cdbd2cSJim Jagielski }
344*b1cdbd2cSJim Jagielski 
345*b1cdbd2cSJim Jagielski 
346*b1cdbd2cSJim Jagielski 
347*b1cdbd2cSJim Jagielski 
FocusPanelContent(const sal_Int32 nPanelIndex)348*b1cdbd2cSJim Jagielski void FocusManager::FocusPanelContent (const sal_Int32 nPanelIndex)
349*b1cdbd2cSJim Jagielski {
350*b1cdbd2cSJim Jagielski     Window* pWindow = VCLUnoHelper::GetWindow(maPanels[nPanelIndex]->GetElementWindow());
351*b1cdbd2cSJim Jagielski     if (pWindow != NULL)
352*b1cdbd2cSJim Jagielski     {
353*b1cdbd2cSJim Jagielski         mbObservingContentControlFocus = true;
354*b1cdbd2cSJim Jagielski         pWindow->GrabFocus();
355*b1cdbd2cSJim Jagielski         mbObservingContentControlFocus = false;
356*b1cdbd2cSJim Jagielski     }
357*b1cdbd2cSJim Jagielski }
358*b1cdbd2cSJim Jagielski 
359*b1cdbd2cSJim Jagielski 
360*b1cdbd2cSJim Jagielski 
361*b1cdbd2cSJim Jagielski 
FocusButton(const sal_Int32 nButtonIndex)362*b1cdbd2cSJim Jagielski void FocusManager::FocusButton (const sal_Int32 nButtonIndex)
363*b1cdbd2cSJim Jagielski {
364*b1cdbd2cSJim Jagielski     maButtons[nButtonIndex]->GrabFocus();
365*b1cdbd2cSJim Jagielski     maButtons[nButtonIndex]->Invalidate();
366*b1cdbd2cSJim Jagielski }
367*b1cdbd2cSJim Jagielski 
368*b1cdbd2cSJim Jagielski 
369*b1cdbd2cSJim Jagielski 
370*b1cdbd2cSJim Jagielski 
ClickButton(const sal_Int32 nButtonIndex)371*b1cdbd2cSJim Jagielski void FocusManager::ClickButton (const sal_Int32 nButtonIndex)
372*b1cdbd2cSJim Jagielski {
373*b1cdbd2cSJim Jagielski     maButtons[nButtonIndex]->Click();
374*b1cdbd2cSJim Jagielski     if (nButtonIndex > 0)
375*b1cdbd2cSJim Jagielski         if ( ! maPanels.empty())
376*b1cdbd2cSJim Jagielski             FocusPanel(0, true);
377*b1cdbd2cSJim Jagielski     maButtons[nButtonIndex]->GetParent()->Invalidate();
378*b1cdbd2cSJim Jagielski }
379*b1cdbd2cSJim Jagielski 
380*b1cdbd2cSJim Jagielski 
381*b1cdbd2cSJim Jagielski 
382*b1cdbd2cSJim Jagielski 
RemoveWindow(Window & rWindow)383*b1cdbd2cSJim Jagielski void FocusManager::RemoveWindow (Window& rWindow)
384*b1cdbd2cSJim Jagielski {
385*b1cdbd2cSJim Jagielski     ::std::vector<Panel*>::iterator iPanel (::std::find(maPanels.begin(), maPanels.end(), &rWindow));
386*b1cdbd2cSJim Jagielski     if (iPanel != maPanels.end())
387*b1cdbd2cSJim Jagielski     {
388*b1cdbd2cSJim Jagielski         UnregisterWindow(rWindow);
389*b1cdbd2cSJim Jagielski         if ((*iPanel)->GetTitleBar() != NULL)
390*b1cdbd2cSJim Jagielski         {
391*b1cdbd2cSJim Jagielski             UnregisterWindow(*(*iPanel)->GetTitleBar());
392*b1cdbd2cSJim Jagielski             UnregisterWindow((*iPanel)->GetTitleBar()->GetToolBox());
393*b1cdbd2cSJim Jagielski         }
394*b1cdbd2cSJim Jagielski         maPanels.erase(iPanel);
395*b1cdbd2cSJim Jagielski         return;
396*b1cdbd2cSJim Jagielski     }
397*b1cdbd2cSJim Jagielski 
398*b1cdbd2cSJim Jagielski     ::std::vector<Button*>::iterator iButton (::std::find(maButtons.begin(), maButtons.end(), &rWindow));
399*b1cdbd2cSJim Jagielski     if (iButton != maButtons.end())
400*b1cdbd2cSJim Jagielski     {
401*b1cdbd2cSJim Jagielski         UnregisterWindow(rWindow);
402*b1cdbd2cSJim Jagielski         maButtons.erase(iButton);
403*b1cdbd2cSJim Jagielski         return;
404*b1cdbd2cSJim Jagielski     }
405*b1cdbd2cSJim Jagielski }
406*b1cdbd2cSJim Jagielski 
407*b1cdbd2cSJim Jagielski 
408*b1cdbd2cSJim Jagielski 
409*b1cdbd2cSJim Jagielski 
MoveFocusInsidePanel(const FocusLocation aFocusLocation,const sal_Int32 nDirection)410*b1cdbd2cSJim Jagielski bool FocusManager::MoveFocusInsidePanel (
411*b1cdbd2cSJim Jagielski     const FocusLocation aFocusLocation,
412*b1cdbd2cSJim Jagielski     const sal_Int32 nDirection)
413*b1cdbd2cSJim Jagielski {
414*b1cdbd2cSJim Jagielski     const bool bHasToolBoxItem (
415*b1cdbd2cSJim Jagielski         maPanels[aFocusLocation.mnIndex]->GetTitleBar()->GetToolBox().GetItemCount() > 0);
416*b1cdbd2cSJim Jagielski     switch (aFocusLocation.meComponent)
417*b1cdbd2cSJim Jagielski     {
418*b1cdbd2cSJim Jagielski         case  PC_PanelTitle:
419*b1cdbd2cSJim Jagielski             if (nDirection > 0 && bHasToolBoxItem)
420*b1cdbd2cSJim Jagielski                 maPanels[aFocusLocation.mnIndex]->GetTitleBar()->GetToolBox().GrabFocus();
421*b1cdbd2cSJim Jagielski             else
422*b1cdbd2cSJim Jagielski                 FocusPanelContent(aFocusLocation.mnIndex);
423*b1cdbd2cSJim Jagielski             return true;
424*b1cdbd2cSJim Jagielski 
425*b1cdbd2cSJim Jagielski         case PC_PanelToolBox:
426*b1cdbd2cSJim Jagielski             if (nDirection < 0 && bHasToolBoxItem)
427*b1cdbd2cSJim Jagielski                 maPanels[aFocusLocation.mnIndex]->GetTitleBar()->GrabFocus();
428*b1cdbd2cSJim Jagielski             else
429*b1cdbd2cSJim Jagielski                 FocusPanelContent(aFocusLocation.mnIndex);
430*b1cdbd2cSJim Jagielski             return true;
431*b1cdbd2cSJim Jagielski 
432*b1cdbd2cSJim Jagielski         default:
433*b1cdbd2cSJim Jagielski             return false;
434*b1cdbd2cSJim Jagielski     }
435*b1cdbd2cSJim Jagielski }
436*b1cdbd2cSJim Jagielski 
437*b1cdbd2cSJim Jagielski 
438*b1cdbd2cSJim Jagielski 
439*b1cdbd2cSJim Jagielski 
MoveFocusInsideDeckTitle(const FocusLocation aFocusLocation,const sal_Int32 nDirection)440*b1cdbd2cSJim Jagielski bool FocusManager::MoveFocusInsideDeckTitle (
441*b1cdbd2cSJim Jagielski     const FocusLocation aFocusLocation,
442*b1cdbd2cSJim Jagielski     const sal_Int32 nDirection)
443*b1cdbd2cSJim Jagielski {
444*b1cdbd2cSJim Jagielski     // Note that when the title bar of the first (and only) panel is
445*b1cdbd2cSJim Jagielski     // not visible then the deck title takes its place and the focus
446*b1cdbd2cSJim Jagielski     // is moved between a) deck title, b) deck closer and c) content
447*b1cdbd2cSJim Jagielski     // of panel 0.
448*b1cdbd2cSJim Jagielski     const bool bHasToolBoxItem (
449*b1cdbd2cSJim Jagielski         mpDeckTitleBar->GetToolBox().GetItemCount() > 0);
450*b1cdbd2cSJim Jagielski     switch (aFocusLocation.meComponent)
451*b1cdbd2cSJim Jagielski     {
452*b1cdbd2cSJim Jagielski         case  PC_DeckTitle:
453*b1cdbd2cSJim Jagielski             if (nDirection<0 && ! IsPanelTitleVisible(0))
454*b1cdbd2cSJim Jagielski                 FocusPanelContent(0);
455*b1cdbd2cSJim Jagielski             else if (bHasToolBoxItem)
456*b1cdbd2cSJim Jagielski                 mpDeckTitleBar->GetToolBox().GrabFocus();
457*b1cdbd2cSJim Jagielski             return true;
458*b1cdbd2cSJim Jagielski 
459*b1cdbd2cSJim Jagielski         case PC_DeckToolBox:
460*b1cdbd2cSJim Jagielski             if (nDirection>0 && ! IsPanelTitleVisible(0))
461*b1cdbd2cSJim Jagielski                 FocusPanelContent(0);
462*b1cdbd2cSJim Jagielski             else
463*b1cdbd2cSJim Jagielski                 mpDeckTitleBar->GrabFocus();
464*b1cdbd2cSJim Jagielski             return true;
465*b1cdbd2cSJim Jagielski 
466*b1cdbd2cSJim Jagielski         default:
467*b1cdbd2cSJim Jagielski             return false;
468*b1cdbd2cSJim Jagielski     }
469*b1cdbd2cSJim Jagielski }
470*b1cdbd2cSJim Jagielski 
471*b1cdbd2cSJim Jagielski 
472*b1cdbd2cSJim Jagielski 
473*b1cdbd2cSJim Jagielski 
HandleKeyEvent(const KeyCode & rKeyCode,const Window & rWindow)474*b1cdbd2cSJim Jagielski void FocusManager::HandleKeyEvent (
475*b1cdbd2cSJim Jagielski     const KeyCode& rKeyCode,
476*b1cdbd2cSJim Jagielski     const Window& rWindow)
477*b1cdbd2cSJim Jagielski {
478*b1cdbd2cSJim Jagielski     const FocusLocation aLocation (GetFocusLocation(rWindow));
479*b1cdbd2cSJim Jagielski     mpLastFocusedWindow = NULL;
480*b1cdbd2cSJim Jagielski 
481*b1cdbd2cSJim Jagielski     switch (rKeyCode.GetCode())
482*b1cdbd2cSJim Jagielski     {
483*b1cdbd2cSJim Jagielski         case KEY_SPACE:
484*b1cdbd2cSJim Jagielski             switch (aLocation.meComponent)
485*b1cdbd2cSJim Jagielski             {
486*b1cdbd2cSJim Jagielski                 case PC_PanelTitle:
487*b1cdbd2cSJim Jagielski                     // Toggle panel between expanded and collapsed.
488*b1cdbd2cSJim Jagielski                     maPanels[aLocation.mnIndex]->SetExpanded( ! maPanels[aLocation.mnIndex]->IsExpanded());
489*b1cdbd2cSJim Jagielski                     break;
490*b1cdbd2cSJim Jagielski 
491*b1cdbd2cSJim Jagielski                 case PC_TabBar:
492*b1cdbd2cSJim Jagielski                     // Activate the button.
493*b1cdbd2cSJim Jagielski                     ClickButton(aLocation.mnIndex);
494*b1cdbd2cSJim Jagielski                     break;
495*b1cdbd2cSJim Jagielski 
496*b1cdbd2cSJim Jagielski                 default:
497*b1cdbd2cSJim Jagielski                     break;
498*b1cdbd2cSJim Jagielski             }
499*b1cdbd2cSJim Jagielski             return;
500*b1cdbd2cSJim Jagielski 
501*b1cdbd2cSJim Jagielski         case KEY_RETURN:
502*b1cdbd2cSJim Jagielski             switch (aLocation.meComponent)
503*b1cdbd2cSJim Jagielski             {
504*b1cdbd2cSJim Jagielski                 case PC_DeckToolBox:
505*b1cdbd2cSJim Jagielski                     FocusButton(0);
506*b1cdbd2cSJim Jagielski                     break;
507*b1cdbd2cSJim Jagielski 
508*b1cdbd2cSJim Jagielski                 case PC_PanelTitle:
509*b1cdbd2cSJim Jagielski                     // Enter the panel.
510*b1cdbd2cSJim Jagielski                     FocusPanelContent(aLocation.mnIndex);
511*b1cdbd2cSJim Jagielski                     break;
512*b1cdbd2cSJim Jagielski 
513*b1cdbd2cSJim Jagielski                 case PC_TabBar:
514*b1cdbd2cSJim Jagielski                     // Activate the button.
515*b1cdbd2cSJim Jagielski                     ClickButton(aLocation.mnIndex);
516*b1cdbd2cSJim Jagielski                     break;
517*b1cdbd2cSJim Jagielski 
518*b1cdbd2cSJim Jagielski                 default:
519*b1cdbd2cSJim Jagielski                     break;
520*b1cdbd2cSJim Jagielski             }
521*b1cdbd2cSJim Jagielski             return;
522*b1cdbd2cSJim Jagielski 
523*b1cdbd2cSJim Jagielski         case KEY_TAB:
524*b1cdbd2cSJim Jagielski         {
525*b1cdbd2cSJim Jagielski             const sal_Int32 nDirection (
526*b1cdbd2cSJim Jagielski                 rKeyCode.IsShift()
527*b1cdbd2cSJim Jagielski                     ? -1
528*b1cdbd2cSJim Jagielski                     : +1);
529*b1cdbd2cSJim Jagielski             switch (aLocation.meComponent)
530*b1cdbd2cSJim Jagielski             {
531*b1cdbd2cSJim Jagielski                 case PC_PanelTitle:
532*b1cdbd2cSJim Jagielski                 case PC_PanelToolBox:
533*b1cdbd2cSJim Jagielski                 case PC_PanelContent:
534*b1cdbd2cSJim Jagielski                     MoveFocusInsidePanel(aLocation, nDirection);
535*b1cdbd2cSJim Jagielski                     break;
536*b1cdbd2cSJim Jagielski 
537*b1cdbd2cSJim Jagielski                 case PC_DeckTitle:
538*b1cdbd2cSJim Jagielski                 case PC_DeckToolBox:
539*b1cdbd2cSJim Jagielski                     MoveFocusInsideDeckTitle(aLocation, nDirection);
540*b1cdbd2cSJim Jagielski                     break;
541*b1cdbd2cSJim Jagielski 
542*b1cdbd2cSJim Jagielski                 default:
543*b1cdbd2cSJim Jagielski                     break;
544*b1cdbd2cSJim Jagielski             }
545*b1cdbd2cSJim Jagielski             break;
546*b1cdbd2cSJim Jagielski         }
547*b1cdbd2cSJim Jagielski 
548*b1cdbd2cSJim Jagielski         case KEY_LEFT:
549*b1cdbd2cSJim Jagielski         case KEY_UP:
550*b1cdbd2cSJim Jagielski             switch (aLocation.meComponent)
551*b1cdbd2cSJim Jagielski             {
552*b1cdbd2cSJim Jagielski                 case PC_PanelTitle:
553*b1cdbd2cSJim Jagielski                 case PC_PanelToolBox:
554*b1cdbd2cSJim Jagielski                 case PC_PanelContent:
555*b1cdbd2cSJim Jagielski                     // Go to previous panel or the deck title.
556*b1cdbd2cSJim Jagielski                     if (aLocation.mnIndex > 0)
557*b1cdbd2cSJim Jagielski                         FocusPanel(aLocation.mnIndex-1, true);
558*b1cdbd2cSJim Jagielski                     else if (IsDeckTitleVisible())
559*b1cdbd2cSJim Jagielski                         FocusDeckTitle();
560*b1cdbd2cSJim Jagielski                     else
561*b1cdbd2cSJim Jagielski                         FocusButton(maButtons.size()-1);
562*b1cdbd2cSJim Jagielski                     break;
563*b1cdbd2cSJim Jagielski 
564*b1cdbd2cSJim Jagielski                 case PC_DeckTitle:
565*b1cdbd2cSJim Jagielski                 case PC_DeckToolBox:
566*b1cdbd2cSJim Jagielski                     // Focus the last button.
567*b1cdbd2cSJim Jagielski                     FocusButton(maButtons.size()-1);
568*b1cdbd2cSJim Jagielski                     break;
569*b1cdbd2cSJim Jagielski 
570*b1cdbd2cSJim Jagielski                 case PC_TabBar:
571*b1cdbd2cSJim Jagielski                     // Go to previous tab bar item.
572*b1cdbd2cSJim Jagielski                     if (aLocation.mnIndex == 0)
573*b1cdbd2cSJim Jagielski                         FocusPanel(maPanels.size()-1, true);
574*b1cdbd2cSJim Jagielski                     else
575*b1cdbd2cSJim Jagielski                         FocusButton((aLocation.mnIndex + maButtons.size() - 1) % maButtons.size());
576*b1cdbd2cSJim Jagielski                     break;
577*b1cdbd2cSJim Jagielski 
578*b1cdbd2cSJim Jagielski                 default:
579*b1cdbd2cSJim Jagielski                     break;
580*b1cdbd2cSJim Jagielski             }
581*b1cdbd2cSJim Jagielski             break;
582*b1cdbd2cSJim Jagielski 
583*b1cdbd2cSJim Jagielski         case KEY_RIGHT:
584*b1cdbd2cSJim Jagielski         case KEY_DOWN:
585*b1cdbd2cSJim Jagielski             switch(aLocation.meComponent)
586*b1cdbd2cSJim Jagielski             {
587*b1cdbd2cSJim Jagielski                 case PC_PanelTitle:
588*b1cdbd2cSJim Jagielski                 case PC_PanelToolBox:
589*b1cdbd2cSJim Jagielski                 case PC_PanelContent:
590*b1cdbd2cSJim Jagielski                     // Go to next panel.
591*b1cdbd2cSJim Jagielski                     if (aLocation.mnIndex < static_cast<sal_Int32>(maPanels.size())-1)
592*b1cdbd2cSJim Jagielski                         FocusPanel(aLocation.mnIndex+1, false);
593*b1cdbd2cSJim Jagielski                     else
594*b1cdbd2cSJim Jagielski                         FocusButton(0);
595*b1cdbd2cSJim Jagielski                     break;
596*b1cdbd2cSJim Jagielski 
597*b1cdbd2cSJim Jagielski                 case PC_DeckTitle:
598*b1cdbd2cSJim Jagielski                 case PC_DeckToolBox:
599*b1cdbd2cSJim Jagielski                     // Focus the first panel.
600*b1cdbd2cSJim Jagielski                     if (IsPanelTitleVisible(0))
601*b1cdbd2cSJim Jagielski                         FocusPanel(0, false);
602*b1cdbd2cSJim Jagielski                     else
603*b1cdbd2cSJim Jagielski                         FocusButton(0);
604*b1cdbd2cSJim Jagielski                     break;
605*b1cdbd2cSJim Jagielski 
606*b1cdbd2cSJim Jagielski                 case PC_TabBar:
607*b1cdbd2cSJim Jagielski                     // Go to next tab bar item.
608*b1cdbd2cSJim Jagielski                     if (aLocation.mnIndex < static_cast<sal_Int32>(maButtons.size())-1)
609*b1cdbd2cSJim Jagielski                         FocusButton(aLocation.mnIndex + 1);
610*b1cdbd2cSJim Jagielski                     else if (IsDeckTitleVisible())
611*b1cdbd2cSJim Jagielski                         FocusDeckTitle();
612*b1cdbd2cSJim Jagielski                     else
613*b1cdbd2cSJim Jagielski                         FocusPanel(0, true);
614*b1cdbd2cSJim Jagielski                     break;
615*b1cdbd2cSJim Jagielski 
616*b1cdbd2cSJim Jagielski                 default:
617*b1cdbd2cSJim Jagielski                     break;
618*b1cdbd2cSJim Jagielski             }
619*b1cdbd2cSJim Jagielski             break;
620*b1cdbd2cSJim Jagielski     }
621*b1cdbd2cSJim Jagielski }
622*b1cdbd2cSJim Jagielski 
623*b1cdbd2cSJim Jagielski 
624*b1cdbd2cSJim Jagielski 
625*b1cdbd2cSJim Jagielski 
IMPL_LINK(FocusManager,WindowEventListener,VclSimpleEvent *,pEvent)626*b1cdbd2cSJim Jagielski IMPL_LINK(FocusManager, WindowEventListener, VclSimpleEvent*, pEvent)
627*b1cdbd2cSJim Jagielski {
628*b1cdbd2cSJim Jagielski     if (pEvent == NULL)
629*b1cdbd2cSJim Jagielski         return 0;
630*b1cdbd2cSJim Jagielski 
631*b1cdbd2cSJim Jagielski     if ( ! pEvent->ISA(VclWindowEvent))
632*b1cdbd2cSJim Jagielski         return 0;
633*b1cdbd2cSJim Jagielski 
634*b1cdbd2cSJim Jagielski     VclWindowEvent* pWindowEvent = static_cast<VclWindowEvent*>(pEvent);
635*b1cdbd2cSJim Jagielski     Window* pSource = pWindowEvent->GetWindow();
636*b1cdbd2cSJim Jagielski     if (pSource == NULL)
637*b1cdbd2cSJim Jagielski         return 0;
638*b1cdbd2cSJim Jagielski 
639*b1cdbd2cSJim Jagielski     switch (pWindowEvent->GetId())
640*b1cdbd2cSJim Jagielski     {
641*b1cdbd2cSJim Jagielski         case VCLEVENT_WINDOW_KEYINPUT:
642*b1cdbd2cSJim Jagielski         {
643*b1cdbd2cSJim Jagielski             KeyEvent* pKeyEvent = static_cast<KeyEvent*>(pWindowEvent->GetData());
644*b1cdbd2cSJim Jagielski             HandleKeyEvent(pKeyEvent->GetKeyCode(), *pSource);
645*b1cdbd2cSJim Jagielski             return 1;
646*b1cdbd2cSJim Jagielski         }
647*b1cdbd2cSJim Jagielski 
648*b1cdbd2cSJim Jagielski         case VCLEVENT_OBJECT_DYING:
649*b1cdbd2cSJim Jagielski             RemoveWindow(*pSource);
650*b1cdbd2cSJim Jagielski             return 1;
651*b1cdbd2cSJim Jagielski 
652*b1cdbd2cSJim Jagielski         case VCLEVENT_WINDOW_GETFOCUS:
653*b1cdbd2cSJim Jagielski         case VCLEVENT_WINDOW_LOSEFOCUS:
654*b1cdbd2cSJim Jagielski             pSource->Invalidate();
655*b1cdbd2cSJim Jagielski             return 1;
656*b1cdbd2cSJim Jagielski 
657*b1cdbd2cSJim Jagielski         default:
658*b1cdbd2cSJim Jagielski             break;
659*b1cdbd2cSJim Jagielski     }
660*b1cdbd2cSJim Jagielski 
661*b1cdbd2cSJim Jagielski     return 0;
662*b1cdbd2cSJim Jagielski }
663*b1cdbd2cSJim Jagielski 
664*b1cdbd2cSJim Jagielski 
665*b1cdbd2cSJim Jagielski 
666*b1cdbd2cSJim Jagielski 
IMPL_LINK(FocusManager,ChildEventListener,VclSimpleEvent *,pEvent)667*b1cdbd2cSJim Jagielski IMPL_LINK(FocusManager, ChildEventListener, VclSimpleEvent*, pEvent)
668*b1cdbd2cSJim Jagielski {
669*b1cdbd2cSJim Jagielski     if (pEvent == NULL)
670*b1cdbd2cSJim Jagielski         return 0;
671*b1cdbd2cSJim Jagielski 
672*b1cdbd2cSJim Jagielski     if ( ! pEvent->ISA(VclWindowEvent))
673*b1cdbd2cSJim Jagielski         return 0;
674*b1cdbd2cSJim Jagielski 
675*b1cdbd2cSJim Jagielski     VclWindowEvent* pWindowEvent = static_cast<VclWindowEvent*>(pEvent);
676*b1cdbd2cSJim Jagielski     Window* pSource = pWindowEvent->GetWindow();
677*b1cdbd2cSJim Jagielski     if (pSource == NULL)
678*b1cdbd2cSJim Jagielski         return 0;
679*b1cdbd2cSJim Jagielski 
680*b1cdbd2cSJim Jagielski     switch (pWindowEvent->GetId())
681*b1cdbd2cSJim Jagielski     {
682*b1cdbd2cSJim Jagielski         case VCLEVENT_WINDOW_KEYINPUT:
683*b1cdbd2cSJim Jagielski         {
684*b1cdbd2cSJim Jagielski             KeyEvent* pKeyEvent = static_cast<KeyEvent*>(pWindowEvent->GetData());
685*b1cdbd2cSJim Jagielski 
686*b1cdbd2cSJim Jagielski             // Go up the window hierarchy to find out whether the
687*b1cdbd2cSJim Jagielski             // parent of the event source is known to us.
688*b1cdbd2cSJim Jagielski             Window* pWindow = pSource;
689*b1cdbd2cSJim Jagielski             FocusLocation aLocation (PC_None, -1);
690*b1cdbd2cSJim Jagielski             while (true)
691*b1cdbd2cSJim Jagielski             {
692*b1cdbd2cSJim Jagielski                 if (pWindow == NULL)
693*b1cdbd2cSJim Jagielski                     break;
694*b1cdbd2cSJim Jagielski                 aLocation = GetFocusLocation(*pWindow);
695*b1cdbd2cSJim Jagielski                 if (aLocation.meComponent != PC_None)
696*b1cdbd2cSJim Jagielski                     break;
697*b1cdbd2cSJim Jagielski                 pWindow = pWindow->GetParent();
698*b1cdbd2cSJim Jagielski             }
699*b1cdbd2cSJim Jagielski 
700*b1cdbd2cSJim Jagielski             if (aLocation.meComponent != PC_None)
701*b1cdbd2cSJim Jagielski             {
702*b1cdbd2cSJim Jagielski                 switch (pKeyEvent->GetKeyCode().GetCode())
703*b1cdbd2cSJim Jagielski                 {
704*b1cdbd2cSJim Jagielski                     case KEY_ESCAPE:
705*b1cdbd2cSJim Jagielski                         // Return focus back to the panel title.
706*b1cdbd2cSJim Jagielski                         FocusPanel(aLocation.mnIndex, true);
707*b1cdbd2cSJim Jagielski                         break;
708*b1cdbd2cSJim Jagielski 
709*b1cdbd2cSJim Jagielski                     case KEY_TAB:
710*b1cdbd2cSJim Jagielski                         if (mpFirstFocusedContentControl!=NULL
711*b1cdbd2cSJim Jagielski                             && mpLastFocusedWindow == mpFirstFocusedContentControl)
712*b1cdbd2cSJim Jagielski                         {
713*b1cdbd2cSJim Jagielski                             // Move focus back to panel (or deck)
714*b1cdbd2cSJim Jagielski                             // title.
715*b1cdbd2cSJim Jagielski                             FocusPanel(aLocation.mnIndex, true);
716*b1cdbd2cSJim Jagielski                         }
717*b1cdbd2cSJim Jagielski                         break;
718*b1cdbd2cSJim Jagielski 
719*b1cdbd2cSJim Jagielski                     default:
720*b1cdbd2cSJim Jagielski                         break;
721*b1cdbd2cSJim Jagielski                 }
722*b1cdbd2cSJim Jagielski             }
723*b1cdbd2cSJim Jagielski             return 1;
724*b1cdbd2cSJim Jagielski         }
725*b1cdbd2cSJim Jagielski 
726*b1cdbd2cSJim Jagielski         case VCLEVENT_WINDOW_GETFOCUS:
727*b1cdbd2cSJim Jagielski             // Keep track of focused controls in panel content.
728*b1cdbd2cSJim Jagielski             // Remember the first focused control.  When it is later
729*b1cdbd2cSJim Jagielski             // focused again due to pressing the TAB key then the
730*b1cdbd2cSJim Jagielski             // focus is moved to the panel or deck title.
731*b1cdbd2cSJim Jagielski             mpLastFocusedWindow = pSource;
732*b1cdbd2cSJim Jagielski             if (mbObservingContentControlFocus)
733*b1cdbd2cSJim Jagielski                 mpFirstFocusedContentControl = pSource;
734*b1cdbd2cSJim Jagielski             break;
735*b1cdbd2cSJim Jagielski 
736*b1cdbd2cSJim Jagielski         default:
737*b1cdbd2cSJim Jagielski             break;
738*b1cdbd2cSJim Jagielski     }
739*b1cdbd2cSJim Jagielski 
740*b1cdbd2cSJim Jagielski     return 0;
741*b1cdbd2cSJim Jagielski }
742*b1cdbd2cSJim Jagielski 
743*b1cdbd2cSJim Jagielski 
744*b1cdbd2cSJim Jagielski } } // end of namespace sfx2::sidebar
745