165908a7eSAndre Fischer /**************************************************************
265908a7eSAndre Fischer  *
365908a7eSAndre Fischer  * Licensed to the Apache Software Foundation (ASF) under one
465908a7eSAndre Fischer  * or more contributor license agreements.  See the NOTICE file
565908a7eSAndre Fischer  * distributed with this work for additional information
665908a7eSAndre Fischer  * regarding copyright ownership.  The ASF licenses this file
765908a7eSAndre Fischer  * to you under the Apache License, Version 2.0 (the
865908a7eSAndre Fischer  * "License"); you may not use this file except in compliance
965908a7eSAndre Fischer  * with the License.  You may obtain a copy of the License at
1065908a7eSAndre Fischer  *
1165908a7eSAndre Fischer  *   http://www.apache.org/licenses/LICENSE-2.0
1265908a7eSAndre Fischer  *
1365908a7eSAndre Fischer  * Unless required by applicable law or agreed to in writing,
1465908a7eSAndre Fischer  * software distributed under the License is distributed on an
1565908a7eSAndre Fischer  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1665908a7eSAndre Fischer  * KIND, either express or implied.  See the License for the
1765908a7eSAndre Fischer  * specific language governing permissions and limitations
1865908a7eSAndre Fischer  * under the License.
1965908a7eSAndre Fischer  *
2065908a7eSAndre Fischer  *************************************************************/
2165908a7eSAndre Fischer 
2265908a7eSAndre Fischer #include "precompiled_sfx2.hxx"
2365908a7eSAndre Fischer 
2465908a7eSAndre Fischer #include "FocusManager.hxx"
2565908a7eSAndre Fischer #include "Panel.hxx"
2652d13b84SAndre Fischer #include "DeckTitleBar.hxx"
278a1a651aSAndre Fischer #include "PanelTitleBar.hxx"
28f35c6d02SAndre Fischer #include "sfx2/sidebar/Tools.hxx"
2965908a7eSAndre Fischer #include "TitleBar.hxx"
3065908a7eSAndre Fischer #include <vcl/button.hxx>
3165908a7eSAndre Fischer #include <vcl/toolbox.hxx>
3265908a7eSAndre Fischer #include <toolkit/helper/vclunohelper.hxx>
3365908a7eSAndre Fischer 
3465908a7eSAndre Fischer 
3565908a7eSAndre Fischer namespace sfx2 { namespace sidebar {
3665908a7eSAndre Fischer 
FocusLocation(const PanelComponent eComponent,const sal_Int32 nIndex)3752d13b84SAndre Fischer FocusManager::FocusLocation::FocusLocation (const PanelComponent eComponent, const sal_Int32 nIndex)
3852d13b84SAndre Fischer     : meComponent(eComponent),
3952d13b84SAndre Fischer       mnIndex(nIndex)
4065908a7eSAndre Fischer {
4165908a7eSAndre Fischer }
4265908a7eSAndre Fischer 
4365908a7eSAndre Fischer 
4452d13b84SAndre Fischer 
4552d13b84SAndre Fischer 
FocusManager(const::boost::function<void (const Panel &)> & rShowPanelFunctor)4652d13b84SAndre Fischer FocusManager::FocusManager (const ::boost::function<void(const Panel&)>& rShowPanelFunctor)
4752d13b84SAndre Fischer     : mpDeckTitleBar(),
4852d13b84SAndre Fischer       maPanels(),
4965908a7eSAndre Fischer       maButtons(),
50*441705dbSAndre Fischer       maShowPanelFunctor(rShowPanelFunctor),
51*441705dbSAndre Fischer       mbObservingContentControlFocus(false),
52*441705dbSAndre Fischer       mpFirstFocusedContentControl(NULL)
5365908a7eSAndre Fischer {
5465908a7eSAndre Fischer }
5565908a7eSAndre Fischer 
5665908a7eSAndre Fischer 
5765908a7eSAndre Fischer 
5865908a7eSAndre Fischer 
~FocusManager(void)5965908a7eSAndre Fischer FocusManager::~FocusManager (void)
6065908a7eSAndre Fischer {
6165908a7eSAndre Fischer     Clear();
6265908a7eSAndre Fischer }
6365908a7eSAndre Fischer 
6465908a7eSAndre Fischer 
6565908a7eSAndre Fischer 
6665908a7eSAndre Fischer 
GrabFocus(void)6765908a7eSAndre Fischer void FocusManager::GrabFocus (void)
6865908a7eSAndre Fischer {
6952d13b84SAndre Fischer     FocusDeckTitle();
7065908a7eSAndre Fischer }
7165908a7eSAndre Fischer 
7265908a7eSAndre Fischer 
7365908a7eSAndre Fischer 
7465908a7eSAndre Fischer 
Clear(void)7565908a7eSAndre Fischer void FocusManager::Clear (void)
7665908a7eSAndre Fischer {
7752d13b84SAndre Fischer     SetDeckTitle(NULL);
7865908a7eSAndre Fischer     ClearPanels();
7965908a7eSAndre Fischer     ClearButtons();
8065908a7eSAndre Fischer }
8165908a7eSAndre Fischer 
8265908a7eSAndre Fischer 
8365908a7eSAndre Fischer 
8452d13b84SAndre Fischer 
ClearPanels(void)8565908a7eSAndre Fischer void FocusManager::ClearPanels (void)
8665908a7eSAndre Fischer {
8765908a7eSAndre Fischer     ::std::vector<Panel*> aPanels;
8865908a7eSAndre Fischer     aPanels.swap(maPanels);
8965908a7eSAndre Fischer     for (::std::vector<Panel*>::iterator iPanel(aPanels.begin()),iEnd(aPanels.end());
9065908a7eSAndre Fischer          iPanel!=iEnd;
9165908a7eSAndre Fischer         ++iPanel)
9265908a7eSAndre Fischer     {
9365908a7eSAndre Fischer         UnregisterWindow(**iPanel);
9465908a7eSAndre Fischer         if ((*iPanel)->GetTitleBar() != NULL)
9565908a7eSAndre Fischer         {
9665908a7eSAndre Fischer             UnregisterWindow(*(*iPanel)->GetTitleBar());
9765908a7eSAndre Fischer             UnregisterWindow((*iPanel)->GetTitleBar()->GetToolBox());
9865908a7eSAndre Fischer         }
9952d13b84SAndre Fischer 
10052d13b84SAndre Fischer         (*iPanel)->RemoveChildEventListener(LINK(this, FocusManager, ChildEventListener));
10165908a7eSAndre Fischer     }
10265908a7eSAndre Fischer }
10365908a7eSAndre Fischer 
10465908a7eSAndre Fischer 
10565908a7eSAndre Fischer 
10665908a7eSAndre Fischer 
ClearButtons(void)10765908a7eSAndre Fischer void FocusManager::ClearButtons (void)
10865908a7eSAndre Fischer {
109611a5f08SAndre Fischer     ::std::vector<Button*> aButtons;
110611a5f08SAndre Fischer     aButtons.swap(maButtons);
111611a5f08SAndre Fischer     for (::std::vector<Button*>::iterator iButton(aButtons.begin()),iEnd(aButtons.end());
11265908a7eSAndre Fischer          iButton!=iEnd;
11365908a7eSAndre Fischer         ++iButton)
11465908a7eSAndre Fischer     {
11565908a7eSAndre Fischer         UnregisterWindow(**iButton);
11665908a7eSAndre Fischer     }
11765908a7eSAndre Fischer }
11865908a7eSAndre Fischer 
11965908a7eSAndre Fischer 
12065908a7eSAndre Fischer 
12165908a7eSAndre Fischer 
SetDeckTitle(DeckTitleBar * pDeckTitleBar)12252d13b84SAndre Fischer void FocusManager::SetDeckTitle (DeckTitleBar* pDeckTitleBar)
12352d13b84SAndre Fischer {
12452d13b84SAndre Fischer     if (mpDeckTitleBar != NULL)
12552d13b84SAndre Fischer     {
12652d13b84SAndre Fischer         UnregisterWindow(*mpDeckTitleBar);
12752d13b84SAndre Fischer         UnregisterWindow(mpDeckTitleBar->GetToolBox());
12852d13b84SAndre Fischer     }
12952d13b84SAndre Fischer     mpDeckTitleBar = pDeckTitleBar;
13052d13b84SAndre Fischer 
13152d13b84SAndre Fischer     if (mpDeckTitleBar != NULL)
13252d13b84SAndre Fischer     {
13352d13b84SAndre Fischer         RegisterWindow(*mpDeckTitleBar);
13452d13b84SAndre Fischer         RegisterWindow(mpDeckTitleBar->GetToolBox());
13552d13b84SAndre Fischer     }
13652d13b84SAndre Fischer }
13752d13b84SAndre Fischer 
13852d13b84SAndre Fischer 
13952d13b84SAndre Fischer 
14052d13b84SAndre Fischer 
SetPanels(const SharedPanelContainer & rPanels)14165908a7eSAndre Fischer void FocusManager::SetPanels (const SharedPanelContainer& rPanels)
14265908a7eSAndre Fischer {
14365908a7eSAndre Fischer     ClearPanels();
14465908a7eSAndre Fischer     for(SharedPanelContainer::const_iterator iPanel(rPanels.begin()),iEnd(rPanels.end());
14565908a7eSAndre Fischer         iPanel!=iEnd;
14665908a7eSAndre Fischer         ++iPanel)
14765908a7eSAndre Fischer     {
14865908a7eSAndre Fischer         RegisterWindow(**iPanel);
14965908a7eSAndre Fischer         if ((*iPanel)->GetTitleBar() != NULL)
15065908a7eSAndre Fischer         {
15165908a7eSAndre Fischer             RegisterWindow(*(*iPanel)->GetTitleBar());
15265908a7eSAndre Fischer             RegisterWindow((*iPanel)->GetTitleBar()->GetToolBox());
15365908a7eSAndre Fischer         }
15452d13b84SAndre Fischer 
15552d13b84SAndre Fischer         // Register also as child event listener at the panel.
15652d13b84SAndre Fischer         (*iPanel)->AddChildEventListener(LINK(this, FocusManager, ChildEventListener));
15752d13b84SAndre Fischer 
15865908a7eSAndre Fischer         maPanels.push_back(iPanel->get());
15965908a7eSAndre Fischer     }
16065908a7eSAndre Fischer }
16165908a7eSAndre Fischer 
16265908a7eSAndre Fischer 
16365908a7eSAndre Fischer 
16465908a7eSAndre Fischer 
SetButtons(const::std::vector<Button * > & rButtons)16565908a7eSAndre Fischer void FocusManager::SetButtons (const ::std::vector<Button*>& rButtons)
16665908a7eSAndre Fischer {
16765908a7eSAndre Fischer     ClearButtons();
16865908a7eSAndre Fischer     for (::std::vector<Button*>::const_iterator iButton(rButtons.begin()),iEnd(rButtons.end());
16965908a7eSAndre Fischer          iButton!=iEnd;
17065908a7eSAndre Fischer          ++iButton)
17165908a7eSAndre Fischer     {
17265908a7eSAndre Fischer         RegisterWindow(**iButton);
17365908a7eSAndre Fischer         maButtons.push_back(*iButton);
17465908a7eSAndre Fischer     }
17565908a7eSAndre Fischer }
17665908a7eSAndre Fischer 
17765908a7eSAndre Fischer 
17865908a7eSAndre Fischer 
17965908a7eSAndre Fischer 
RegisterWindow(Window & rWindow)18065908a7eSAndre Fischer void FocusManager::RegisterWindow (Window& rWindow)
18165908a7eSAndre Fischer {
18265908a7eSAndre Fischer     rWindow.AddEventListener(LINK(this, FocusManager, WindowEventListener));
18365908a7eSAndre Fischer }
18465908a7eSAndre Fischer 
18565908a7eSAndre Fischer 
18665908a7eSAndre Fischer 
18765908a7eSAndre Fischer 
UnregisterWindow(Window & rWindow)18865908a7eSAndre Fischer void FocusManager::UnregisterWindow (Window& rWindow)
18965908a7eSAndre Fischer {
19065908a7eSAndre Fischer     rWindow.RemoveEventListener(LINK(this, FocusManager, WindowEventListener));
19165908a7eSAndre Fischer }
19265908a7eSAndre Fischer 
19365908a7eSAndre Fischer 
19465908a7eSAndre Fischer 
19565908a7eSAndre Fischer 
GetFocusLocation(const Window & rWindow) const19652d13b84SAndre Fischer FocusManager::FocusLocation FocusManager::GetFocusLocation (const Window& rWindow) const
19765908a7eSAndre Fischer {
19852d13b84SAndre Fischer     // Check the deck title.
19952d13b84SAndre Fischer     if (mpDeckTitleBar != NULL)
200edc7f530SAndre Fischer     {
20152d13b84SAndre Fischer         if (mpDeckTitleBar == &rWindow)
20252d13b84SAndre Fischer             return FocusLocation(PC_DeckTitle, -1);
20352d13b84SAndre Fischer         else if (&mpDeckTitleBar->GetToolBox() == &rWindow)
20452d13b84SAndre Fischer             return FocusLocation(PC_DeckToolBox, -1);
205edc7f530SAndre Fischer     }
206edc7f530SAndre Fischer 
20752d13b84SAndre Fischer     // Search the panels.
20865908a7eSAndre Fischer     for (sal_Int32 nIndex=0,nCount(maPanels.size()); nIndex<nCount; ++nIndex)
20965908a7eSAndre Fischer     {
21065908a7eSAndre Fischer         if (maPanels[nIndex] == &rWindow)
21152d13b84SAndre Fischer             return FocusLocation(PC_PanelContent, nIndex);
21265908a7eSAndre Fischer         TitleBar* pTitleBar = maPanels[nIndex]->GetTitleBar();
21365908a7eSAndre Fischer         if (pTitleBar == &rWindow)
21452d13b84SAndre Fischer             return FocusLocation(PC_PanelTitle, nIndex);
21565908a7eSAndre Fischer         if (pTitleBar!=NULL && &pTitleBar->GetToolBox()==&rWindow)
21652d13b84SAndre Fischer             return FocusLocation(PC_PanelToolBox, nIndex);
21765908a7eSAndre Fischer     }
21865908a7eSAndre Fischer 
21952d13b84SAndre Fischer     // Search the buttons.
22065908a7eSAndre Fischer     for (sal_Int32 nIndex=0,nCount(maButtons.size()); nIndex<nCount; ++nIndex)
22165908a7eSAndre Fischer         if (maButtons[nIndex] == &rWindow)
22252d13b84SAndre Fischer             return FocusLocation(PC_TabBar, nIndex);
22352d13b84SAndre Fischer 
22452d13b84SAndre Fischer     return FocusLocation(PC_None, -1);
22565908a7eSAndre Fischer }
22652d13b84SAndre Fischer 
22765908a7eSAndre Fischer 
22865908a7eSAndre Fischer 
22965908a7eSAndre Fischer 
IsAnyPanelFocused(void) const23065908a7eSAndre Fischer bool FocusManager::IsAnyPanelFocused (void) const
23165908a7eSAndre Fischer {
23265908a7eSAndre Fischer     for (::std::vector<Panel*>::const_iterator iPanel(maPanels.begin()),iEnd(maPanels.end());
23365908a7eSAndre Fischer          iPanel!=iEnd;
23465908a7eSAndre Fischer          ++iPanel)
23565908a7eSAndre Fischer     {
23665908a7eSAndre Fischer         if ((*iPanel)->HasFocus())
23765908a7eSAndre Fischer             return true;
23865908a7eSAndre Fischer         else if ((*iPanel)->HasChildPathFocus())
23965908a7eSAndre Fischer             return true;
24065908a7eSAndre Fischer     }
24165908a7eSAndre Fischer     return false;
24265908a7eSAndre Fischer }
24365908a7eSAndre Fischer 
24465908a7eSAndre Fischer 
24565908a7eSAndre Fischer 
24665908a7eSAndre Fischer 
IsAnyButtonFocused(void) const24765908a7eSAndre Fischer bool FocusManager::IsAnyButtonFocused (void) const
24865908a7eSAndre Fischer {
24965908a7eSAndre Fischer     for (::std::vector<Button*>::const_iterator iButton(maButtons.begin()),iEnd(maButtons.end());
25065908a7eSAndre Fischer          iButton!=iEnd;
25165908a7eSAndre Fischer          ++iButton)
25265908a7eSAndre Fischer     {
25365908a7eSAndre Fischer         if ((*iButton)->HasFocus())
25465908a7eSAndre Fischer             return true;
25565908a7eSAndre Fischer     }
25665908a7eSAndre Fischer     return false;
25765908a7eSAndre Fischer }
25865908a7eSAndre Fischer 
25965908a7eSAndre Fischer 
26065908a7eSAndre Fischer 
26165908a7eSAndre Fischer 
FocusDeckTitle(void)26252d13b84SAndre Fischer void FocusManager::FocusDeckTitle (void)
26352d13b84SAndre Fischer {
264*441705dbSAndre Fischer     if (mpDeckTitleBar != NULL)
26552d13b84SAndre Fischer     {
266*441705dbSAndre Fischer         if (IsDeckTitleVisible())
267*441705dbSAndre Fischer         {
268*441705dbSAndre Fischer             mpDeckTitleBar->GrabFocus();
269*441705dbSAndre Fischer         }
270*441705dbSAndre Fischer         else if (mpDeckTitleBar->GetToolBox().GetItemCount() > 0)
27152d13b84SAndre Fischer         {
272*441705dbSAndre Fischer             ToolBox& rToolBox = mpDeckTitleBar->GetToolBox();
27352d13b84SAndre Fischer             rToolBox.GrabFocus();
27452d13b84SAndre Fischer             rToolBox.Invalidate();
27552d13b84SAndre Fischer         }
276*441705dbSAndre Fischer         else
277*441705dbSAndre Fischer             FocusPanel(0, false);
27852d13b84SAndre Fischer     }
27952d13b84SAndre Fischer     else
280*441705dbSAndre Fischer         FocusPanel(0, false);
28152d13b84SAndre Fischer }
28252d13b84SAndre Fischer 
28352d13b84SAndre Fischer 
28452d13b84SAndre Fischer 
28552d13b84SAndre Fischer 
IsDeckTitleVisible(void) const28652d13b84SAndre Fischer bool FocusManager::IsDeckTitleVisible (void) const
28752d13b84SAndre Fischer {
28852d13b84SAndre Fischer     return mpDeckTitleBar != NULL && mpDeckTitleBar->IsVisible();
28952d13b84SAndre Fischer }
29052d13b84SAndre Fischer 
29152d13b84SAndre Fischer 
29252d13b84SAndre Fischer 
29352d13b84SAndre Fischer 
IsPanelTitleVisible(const sal_Int32 nPanelIndex) const294*441705dbSAndre Fischer bool FocusManager::IsPanelTitleVisible (const sal_Int32 nPanelIndex) const
295*441705dbSAndre Fischer {
296*441705dbSAndre Fischer     if (nPanelIndex<0 || nPanelIndex>=static_cast<sal_Int32>(maPanels.size()))
297*441705dbSAndre Fischer         return false;
298*441705dbSAndre Fischer 
299*441705dbSAndre Fischer     TitleBar* pTitleBar = maPanels[nPanelIndex]->GetTitleBar();
300*441705dbSAndre Fischer     if (pTitleBar==NULL)
301*441705dbSAndre Fischer         return false;
302*441705dbSAndre Fischer     return pTitleBar->IsVisible();
303*441705dbSAndre Fischer }
304*441705dbSAndre Fischer 
305*441705dbSAndre Fischer 
306*441705dbSAndre Fischer 
307*441705dbSAndre Fischer 
FocusPanel(const sal_Int32 nPanelIndex,const bool bFallbackToDeckTitle)308*441705dbSAndre Fischer void FocusManager::FocusPanel (
309*441705dbSAndre Fischer     const sal_Int32 nPanelIndex,
310*441705dbSAndre Fischer     const bool bFallbackToDeckTitle)
31165908a7eSAndre Fischer {
3120f2fd489SPavel Janík     if (nPanelIndex<0 || nPanelIndex>=static_cast<sal_Int32>(maPanels.size()))
313*441705dbSAndre Fischer     {
314*441705dbSAndre Fischer         if (bFallbackToDeckTitle)
315*441705dbSAndre Fischer             FocusDeckTitle();
316611a5f08SAndre Fischer         return;
317*441705dbSAndre Fischer     }
318*441705dbSAndre Fischer 
31965908a7eSAndre Fischer     Panel& rPanel (*maPanels[nPanelIndex]);
32065908a7eSAndre Fischer     TitleBar* pTitleBar = rPanel.GetTitleBar();
32165908a7eSAndre Fischer     if (pTitleBar!=NULL && pTitleBar->IsVisible())
32265908a7eSAndre Fischer     {
32365908a7eSAndre Fischer         rPanel.SetExpanded(true);
32465908a7eSAndre Fischer         pTitleBar->GrabFocus();
32565908a7eSAndre Fischer     }
326*441705dbSAndre Fischer     else if (bFallbackToDeckTitle)
327*441705dbSAndre Fischer     {
328*441705dbSAndre Fischer         // The panel title is not visible, fall back to the deck
329*441705dbSAndre Fischer         // title.
330*441705dbSAndre Fischer         // Make sure that the desk title is visible here to prevent a
331*441705dbSAndre Fischer         // loop when both the title of panel 0 and the deck title are
332*441705dbSAndre Fischer         // not present.
333*441705dbSAndre Fischer         if (IsDeckTitleVisible())
334*441705dbSAndre Fischer             FocusDeckTitle();
335*441705dbSAndre Fischer         else
336*441705dbSAndre Fischer             FocusPanelContent(nPanelIndex);
337*441705dbSAndre Fischer     }
33865908a7eSAndre Fischer     else
33965908a7eSAndre Fischer         FocusPanelContent(nPanelIndex);
340*441705dbSAndre Fischer 
34152d13b84SAndre Fischer     if (maShowPanelFunctor)
34252d13b84SAndre Fischer         maShowPanelFunctor(rPanel);
34365908a7eSAndre Fischer }
34465908a7eSAndre Fischer 
34565908a7eSAndre Fischer 
34665908a7eSAndre Fischer 
34765908a7eSAndre Fischer 
FocusPanelContent(const sal_Int32 nPanelIndex)34865908a7eSAndre Fischer void FocusManager::FocusPanelContent (const sal_Int32 nPanelIndex)
34965908a7eSAndre Fischer {
35065908a7eSAndre Fischer     Window* pWindow = VCLUnoHelper::GetWindow(maPanels[nPanelIndex]->GetElementWindow());
35165908a7eSAndre Fischer     if (pWindow != NULL)
352*441705dbSAndre Fischer     {
353*441705dbSAndre Fischer         mbObservingContentControlFocus = true;
35465908a7eSAndre Fischer         pWindow->GrabFocus();
355*441705dbSAndre Fischer         mbObservingContentControlFocus = false;
356*441705dbSAndre Fischer     }
35765908a7eSAndre Fischer }
35865908a7eSAndre Fischer 
35965908a7eSAndre Fischer 
36065908a7eSAndre Fischer 
36165908a7eSAndre Fischer 
FocusButton(const sal_Int32 nButtonIndex)36265908a7eSAndre Fischer void FocusManager::FocusButton (const sal_Int32 nButtonIndex)
36365908a7eSAndre Fischer {
36465908a7eSAndre Fischer     maButtons[nButtonIndex]->GrabFocus();
36565908a7eSAndre Fischer     maButtons[nButtonIndex]->Invalidate();
36665908a7eSAndre Fischer }
36765908a7eSAndre Fischer 
36865908a7eSAndre Fischer 
36965908a7eSAndre Fischer 
37065908a7eSAndre Fischer 
ClickButton(const sal_Int32 nButtonIndex)37165908a7eSAndre Fischer void FocusManager::ClickButton (const sal_Int32 nButtonIndex)
37265908a7eSAndre Fischer {
37365908a7eSAndre Fischer     maButtons[nButtonIndex]->Click();
37465908a7eSAndre Fischer     if (nButtonIndex > 0)
37565908a7eSAndre Fischer         if ( ! maPanels.empty())
376*441705dbSAndre Fischer             FocusPanel(0, true);
37765908a7eSAndre Fischer     maButtons[nButtonIndex]->GetParent()->Invalidate();
37865908a7eSAndre Fischer }
37965908a7eSAndre Fischer 
38065908a7eSAndre Fischer 
38165908a7eSAndre Fischer 
38265908a7eSAndre Fischer 
RemoveWindow(Window & rWindow)38365908a7eSAndre Fischer void FocusManager::RemoveWindow (Window& rWindow)
38465908a7eSAndre Fischer {
38565908a7eSAndre Fischer     ::std::vector<Panel*>::iterator iPanel (::std::find(maPanels.begin(), maPanels.end(), &rWindow));
38665908a7eSAndre Fischer     if (iPanel != maPanels.end())
38765908a7eSAndre Fischer     {
38865908a7eSAndre Fischer         UnregisterWindow(rWindow);
38965908a7eSAndre Fischer         if ((*iPanel)->GetTitleBar() != NULL)
39065908a7eSAndre Fischer         {
39165908a7eSAndre Fischer             UnregisterWindow(*(*iPanel)->GetTitleBar());
39265908a7eSAndre Fischer             UnregisterWindow((*iPanel)->GetTitleBar()->GetToolBox());
39365908a7eSAndre Fischer         }
39465908a7eSAndre Fischer         maPanels.erase(iPanel);
39565908a7eSAndre Fischer         return;
39665908a7eSAndre Fischer     }
39765908a7eSAndre Fischer 
39865908a7eSAndre Fischer     ::std::vector<Button*>::iterator iButton (::std::find(maButtons.begin(), maButtons.end(), &rWindow));
39965908a7eSAndre Fischer     if (iButton != maButtons.end())
40065908a7eSAndre Fischer     {
40165908a7eSAndre Fischer         UnregisterWindow(rWindow);
40265908a7eSAndre Fischer         maButtons.erase(iButton);
40365908a7eSAndre Fischer         return;
40465908a7eSAndre Fischer     }
40565908a7eSAndre Fischer }
40665908a7eSAndre Fischer 
40765908a7eSAndre Fischer 
40865908a7eSAndre Fischer 
40965908a7eSAndre Fischer 
MoveFocusInsidePanel(const FocusLocation aFocusLocation,const sal_Int32 nDirection)41065908a7eSAndre Fischer bool FocusManager::MoveFocusInsidePanel (
41152d13b84SAndre Fischer     const FocusLocation aFocusLocation,
41265908a7eSAndre Fischer     const sal_Int32 nDirection)
41365908a7eSAndre Fischer {
41452d13b84SAndre Fischer     const bool bHasToolBoxItem (
41552d13b84SAndre Fischer         maPanels[aFocusLocation.mnIndex]->GetTitleBar()->GetToolBox().GetItemCount() > 0);
41652d13b84SAndre Fischer     switch (aFocusLocation.meComponent)
41765908a7eSAndre Fischer     {
41852d13b84SAndre Fischer         case  PC_PanelTitle:
41952d13b84SAndre Fischer             if (nDirection > 0 && bHasToolBoxItem)
42052d13b84SAndre Fischer                 maPanels[aFocusLocation.mnIndex]->GetTitleBar()->GetToolBox().GrabFocus();
42165908a7eSAndre Fischer             else
42252d13b84SAndre Fischer                 FocusPanelContent(aFocusLocation.mnIndex);
42365908a7eSAndre Fischer             return true;
42465908a7eSAndre Fischer 
42552d13b84SAndre Fischer         case PC_PanelToolBox:
42652d13b84SAndre Fischer             if (nDirection < 0 && bHasToolBoxItem)
42752d13b84SAndre Fischer                 maPanels[aFocusLocation.mnIndex]->GetTitleBar()->GrabFocus();
42865908a7eSAndre Fischer             else
42952d13b84SAndre Fischer                 FocusPanelContent(aFocusLocation.mnIndex);
43065908a7eSAndre Fischer             return true;
43165908a7eSAndre Fischer 
43265908a7eSAndre Fischer         default:
43365908a7eSAndre Fischer             return false;
43465908a7eSAndre Fischer     }
43565908a7eSAndre Fischer }
43665908a7eSAndre Fischer 
43765908a7eSAndre Fischer 
43865908a7eSAndre Fischer 
43965908a7eSAndre Fischer 
MoveFocusInsideDeckTitle(const FocusLocation aFocusLocation,const sal_Int32 nDirection)440*441705dbSAndre Fischer bool FocusManager::MoveFocusInsideDeckTitle (
441*441705dbSAndre Fischer     const FocusLocation aFocusLocation,
442*441705dbSAndre Fischer     const sal_Int32 nDirection)
443*441705dbSAndre Fischer {
444*441705dbSAndre Fischer     // Note that when the title bar of the first (and only) panel is
445*441705dbSAndre Fischer     // not visible then the deck title takes its place and the focus
446*441705dbSAndre Fischer     // is moved between a) deck title, b) deck closer and c) content
447*441705dbSAndre Fischer     // of panel 0.
448*441705dbSAndre Fischer     const bool bHasToolBoxItem (
449*441705dbSAndre Fischer         mpDeckTitleBar->GetToolBox().GetItemCount() > 0);
450*441705dbSAndre Fischer     switch (aFocusLocation.meComponent)
451*441705dbSAndre Fischer     {
452*441705dbSAndre Fischer         case  PC_DeckTitle:
453*441705dbSAndre Fischer             if (nDirection<0 && ! IsPanelTitleVisible(0))
454*441705dbSAndre Fischer                 FocusPanelContent(0);
455*441705dbSAndre Fischer             else if (bHasToolBoxItem)
456*441705dbSAndre Fischer                 mpDeckTitleBar->GetToolBox().GrabFocus();
457*441705dbSAndre Fischer             return true;
458*441705dbSAndre Fischer 
459*441705dbSAndre Fischer         case PC_DeckToolBox:
460*441705dbSAndre Fischer             if (nDirection>0 && ! IsPanelTitleVisible(0))
461*441705dbSAndre Fischer                 FocusPanelContent(0);
462*441705dbSAndre Fischer             else
463*441705dbSAndre Fischer                 mpDeckTitleBar->GrabFocus();
464*441705dbSAndre Fischer             return true;
465*441705dbSAndre Fischer 
466*441705dbSAndre Fischer         default:
467*441705dbSAndre Fischer             return false;
468*441705dbSAndre Fischer     }
469*441705dbSAndre Fischer }
470*441705dbSAndre Fischer 
471*441705dbSAndre Fischer 
472*441705dbSAndre Fischer 
473*441705dbSAndre Fischer 
HandleKeyEvent(const KeyCode & rKeyCode,const Window & rWindow)47465908a7eSAndre Fischer void FocusManager::HandleKeyEvent (
47565908a7eSAndre Fischer     const KeyCode& rKeyCode,
47665908a7eSAndre Fischer     const Window& rWindow)
47765908a7eSAndre Fischer {
47852d13b84SAndre Fischer     const FocusLocation aLocation (GetFocusLocation(rWindow));
479*441705dbSAndre Fischer     mpLastFocusedWindow = NULL;
480*441705dbSAndre Fischer 
48165908a7eSAndre Fischer     switch (rKeyCode.GetCode())
48265908a7eSAndre Fischer     {
48365908a7eSAndre Fischer         case KEY_SPACE:
48452d13b84SAndre Fischer             switch (aLocation.meComponent)
48565908a7eSAndre Fischer             {
48652d13b84SAndre Fischer                 case PC_PanelTitle:
48752d13b84SAndre Fischer                     // Toggle panel between expanded and collapsed.
48852d13b84SAndre Fischer                     maPanels[aLocation.mnIndex]->SetExpanded( ! maPanels[aLocation.mnIndex]->IsExpanded());
48952d13b84SAndre Fischer                     break;
49052d13b84SAndre Fischer 
49152d13b84SAndre Fischer                 case PC_TabBar:
49252d13b84SAndre Fischer                     // Activate the button.
49352d13b84SAndre Fischer                     ClickButton(aLocation.mnIndex);
49452d13b84SAndre Fischer                     break;
49552d13b84SAndre Fischer 
49652d13b84SAndre Fischer                 default:
49752d13b84SAndre Fischer                     break;
49865908a7eSAndre Fischer             }
49965908a7eSAndre Fischer             return;
50065908a7eSAndre Fischer 
50165908a7eSAndre Fischer         case KEY_RETURN:
50252d13b84SAndre Fischer             switch (aLocation.meComponent)
50365908a7eSAndre Fischer             {
50452d13b84SAndre Fischer                 case PC_DeckToolBox:
50552d13b84SAndre Fischer                     FocusButton(0);
50652d13b84SAndre Fischer                     break;
50752d13b84SAndre Fischer 
50852d13b84SAndre Fischer                 case PC_PanelTitle:
50965908a7eSAndre Fischer                     // Enter the panel.
51052d13b84SAndre Fischer                     FocusPanelContent(aLocation.mnIndex);
51152d13b84SAndre Fischer                     break;
51252d13b84SAndre Fischer 
51352d13b84SAndre Fischer                 case PC_TabBar:
51452d13b84SAndre Fischer                     // Activate the button.
51552d13b84SAndre Fischer                     ClickButton(aLocation.mnIndex);
51652d13b84SAndre Fischer                     break;
51752d13b84SAndre Fischer 
51852d13b84SAndre Fischer                 default:
51952d13b84SAndre Fischer                     break;
52065908a7eSAndre Fischer             }
52165908a7eSAndre Fischer             return;
52265908a7eSAndre Fischer 
52365908a7eSAndre Fischer         case KEY_TAB:
524*441705dbSAndre Fischer         {
525*441705dbSAndre Fischer             const sal_Int32 nDirection (
526*441705dbSAndre Fischer                 rKeyCode.IsShift()
527*441705dbSAndre Fischer                     ? -1
528*441705dbSAndre Fischer                     : +1);
52952d13b84SAndre Fischer             switch (aLocation.meComponent)
53065908a7eSAndre Fischer             {
53152d13b84SAndre Fischer                 case PC_PanelTitle:
53252d13b84SAndre Fischer                 case PC_PanelToolBox:
53352d13b84SAndre Fischer                 case PC_PanelContent:
534*441705dbSAndre Fischer                     MoveFocusInsidePanel(aLocation, nDirection);
53552d13b84SAndre Fischer                     break;
53652d13b84SAndre Fischer 
537*441705dbSAndre Fischer                 case PC_DeckTitle:
538*441705dbSAndre Fischer                 case PC_DeckToolBox:
539*441705dbSAndre Fischer                     MoveFocusInsideDeckTitle(aLocation, nDirection);
540*441705dbSAndre Fischer                     break;
541*441705dbSAndre Fischer 
54252d13b84SAndre Fischer                 default:
54352d13b84SAndre Fischer                     break;
54465908a7eSAndre Fischer             }
54565908a7eSAndre Fischer             break;
546*441705dbSAndre Fischer         }
547*441705dbSAndre Fischer 
54865908a7eSAndre Fischer         case KEY_LEFT:
54965908a7eSAndre Fischer         case KEY_UP:
55052d13b84SAndre Fischer             switch (aLocation.meComponent)
55165908a7eSAndre Fischer             {
55252d13b84SAndre Fischer                 case PC_PanelTitle:
55352d13b84SAndre Fischer                 case PC_PanelToolBox:
55452d13b84SAndre Fischer                 case PC_PanelContent:
55552d13b84SAndre Fischer                     // Go to previous panel or the deck title.
55652d13b84SAndre Fischer                     if (aLocation.mnIndex > 0)
557*441705dbSAndre Fischer                         FocusPanel(aLocation.mnIndex-1, true);
55852d13b84SAndre Fischer                     else if (IsDeckTitleVisible())
55952d13b84SAndre Fischer                         FocusDeckTitle();
56052d13b84SAndre Fischer                     else
56152d13b84SAndre Fischer                         FocusButton(maButtons.size()-1);
56252d13b84SAndre Fischer                     break;
56352d13b84SAndre Fischer 
56452d13b84SAndre Fischer                 case PC_DeckTitle:
56552d13b84SAndre Fischer                 case PC_DeckToolBox:
56652d13b84SAndre Fischer                     // Focus the last button.
56752d13b84SAndre Fischer                     FocusButton(maButtons.size()-1);
56852d13b84SAndre Fischer                     break;
56952d13b84SAndre Fischer 
57052d13b84SAndre Fischer                 case PC_TabBar:
57152d13b84SAndre Fischer                     // Go to previous tab bar item.
57252d13b84SAndre Fischer                     if (aLocation.mnIndex == 0)
573*441705dbSAndre Fischer                         FocusPanel(maPanels.size()-1, true);
57452d13b84SAndre Fischer                     else
57552d13b84SAndre Fischer                         FocusButton((aLocation.mnIndex + maButtons.size() - 1) % maButtons.size());
57652d13b84SAndre Fischer                     break;
57752d13b84SAndre Fischer 
57852d13b84SAndre Fischer                 default:
57952d13b84SAndre Fischer                     break;
58065908a7eSAndre Fischer             }
58165908a7eSAndre Fischer             break;
58265908a7eSAndre Fischer 
58365908a7eSAndre Fischer         case KEY_RIGHT:
58465908a7eSAndre Fischer         case KEY_DOWN:
58552d13b84SAndre Fischer             switch(aLocation.meComponent)
58665908a7eSAndre Fischer             {
58752d13b84SAndre Fischer                 case PC_PanelTitle:
58852d13b84SAndre Fischer                 case PC_PanelToolBox:
58952d13b84SAndre Fischer                 case PC_PanelContent:
59052d13b84SAndre Fischer                     // Go to next panel.
5910f2fd489SPavel Janík                     if (aLocation.mnIndex < static_cast<sal_Int32>(maPanels.size())-1)
592*441705dbSAndre Fischer                         FocusPanel(aLocation.mnIndex+1, false);
59352d13b84SAndre Fischer                     else
59452d13b84SAndre Fischer                         FocusButton(0);
59552d13b84SAndre Fischer                     break;
59652d13b84SAndre Fischer 
59752d13b84SAndre Fischer                 case PC_DeckTitle:
59852d13b84SAndre Fischer                 case PC_DeckToolBox:
59952d13b84SAndre Fischer                     // Focus the first panel.
600*441705dbSAndre Fischer                     if (IsPanelTitleVisible(0))
601*441705dbSAndre Fischer                         FocusPanel(0, false);
602*441705dbSAndre Fischer                     else
603*441705dbSAndre Fischer                         FocusButton(0);
60452d13b84SAndre Fischer                     break;
60552d13b84SAndre Fischer 
60652d13b84SAndre Fischer                 case PC_TabBar:
60752d13b84SAndre Fischer                     // Go to next tab bar item.
6080f2fd489SPavel Janík                     if (aLocation.mnIndex < static_cast<sal_Int32>(maButtons.size())-1)
60952d13b84SAndre Fischer                         FocusButton(aLocation.mnIndex + 1);
61052d13b84SAndre Fischer                     else if (IsDeckTitleVisible())
61152d13b84SAndre Fischer                         FocusDeckTitle();
61252d13b84SAndre Fischer                     else
613*441705dbSAndre Fischer                         FocusPanel(0, true);
61452d13b84SAndre Fischer                     break;
61552d13b84SAndre Fischer 
61652d13b84SAndre Fischer                 default:
61752d13b84SAndre Fischer                     break;
61865908a7eSAndre Fischer             }
61965908a7eSAndre Fischer             break;
62065908a7eSAndre Fischer     }
62165908a7eSAndre Fischer }
62265908a7eSAndre Fischer 
62365908a7eSAndre Fischer 
62465908a7eSAndre Fischer 
62565908a7eSAndre Fischer 
IMPL_LINK(FocusManager,WindowEventListener,VclSimpleEvent *,pEvent)62652d13b84SAndre Fischer IMPL_LINK(FocusManager, WindowEventListener, VclSimpleEvent*, pEvent)
62765908a7eSAndre Fischer {
62852d13b84SAndre Fischer     if (pEvent == NULL)
62952d13b84SAndre Fischer         return 0;
63052d13b84SAndre Fischer 
63152d13b84SAndre Fischer     if ( ! pEvent->ISA(VclWindowEvent))
63252d13b84SAndre Fischer         return 0;
63352d13b84SAndre Fischer 
63452d13b84SAndre Fischer     VclWindowEvent* pWindowEvent = static_cast<VclWindowEvent*>(pEvent);
63552d13b84SAndre Fischer     Window* pSource = pWindowEvent->GetWindow();
63652d13b84SAndre Fischer     if (pSource == NULL)
63752d13b84SAndre Fischer         return 0;
63852d13b84SAndre Fischer 
63952d13b84SAndre Fischer     switch (pWindowEvent->GetId())
64065908a7eSAndre Fischer     {
64165908a7eSAndre Fischer         case VCLEVENT_WINDOW_KEYINPUT:
64265908a7eSAndre Fischer         {
64352d13b84SAndre Fischer             KeyEvent* pKeyEvent = static_cast<KeyEvent*>(pWindowEvent->GetData());
64452d13b84SAndre Fischer             HandleKeyEvent(pKeyEvent->GetKeyCode(), *pSource);
64552d13b84SAndre Fischer             return 1;
64665908a7eSAndre Fischer         }
64752d13b84SAndre Fischer 
64852d13b84SAndre Fischer         case VCLEVENT_OBJECT_DYING:
64952d13b84SAndre Fischer             RemoveWindow(*pSource);
65052d13b84SAndre Fischer             return 1;
65152d13b84SAndre Fischer 
65252d13b84SAndre Fischer         case VCLEVENT_WINDOW_GETFOCUS:
65352d13b84SAndre Fischer         case VCLEVENT_WINDOW_LOSEFOCUS:
65452d13b84SAndre Fischer             pSource->Invalidate();
655a1fa6b52SAndre Fischer             return 1;
656a1fa6b52SAndre Fischer 
657a1fa6b52SAndre Fischer         default:
658a1fa6b52SAndre Fischer             break;
65965908a7eSAndre Fischer     }
66052d13b84SAndre Fischer 
66152d13b84SAndre Fischer     return 0;
66265908a7eSAndre Fischer }
66365908a7eSAndre Fischer 
66465908a7eSAndre Fischer 
66565908a7eSAndre Fischer 
66665908a7eSAndre Fischer 
IMPL_LINK(FocusManager,ChildEventListener,VclSimpleEvent *,pEvent)66752d13b84SAndre Fischer IMPL_LINK(FocusManager, ChildEventListener, VclSimpleEvent*, pEvent)
66865908a7eSAndre Fischer {
66965908a7eSAndre Fischer     if (pEvent == NULL)
67065908a7eSAndre Fischer         return 0;
67165908a7eSAndre Fischer 
67265908a7eSAndre Fischer     if ( ! pEvent->ISA(VclWindowEvent))
67365908a7eSAndre Fischer         return 0;
67465908a7eSAndre Fischer 
67565908a7eSAndre Fischer     VclWindowEvent* pWindowEvent = static_cast<VclWindowEvent*>(pEvent);
67665908a7eSAndre Fischer     Window* pSource = pWindowEvent->GetWindow();
67765908a7eSAndre Fischer     if (pSource == NULL)
67865908a7eSAndre Fischer         return 0;
67965908a7eSAndre Fischer 
68052d13b84SAndre Fischer     switch (pWindowEvent->GetId())
68152d13b84SAndre Fischer     {
68252d13b84SAndre Fischer         case VCLEVENT_WINDOW_KEYINPUT:
68365908a7eSAndre Fischer         {
68452d13b84SAndre Fischer             KeyEvent* pKeyEvent = static_cast<KeyEvent*>(pWindowEvent->GetData());
68552d13b84SAndre Fischer 
686*441705dbSAndre Fischer             // Go up the window hierarchy to find out whether the
687*441705dbSAndre Fischer             // parent of the event source is known to us.
68852d13b84SAndre Fischer             Window* pWindow = pSource;
68952d13b84SAndre Fischer             FocusLocation aLocation (PC_None, -1);
69052d13b84SAndre Fischer             while (true)
69165908a7eSAndre Fischer             {
69252d13b84SAndre Fischer                 if (pWindow == NULL)
69352d13b84SAndre Fischer                     break;
69452d13b84SAndre Fischer                 aLocation = GetFocusLocation(*pWindow);
69552d13b84SAndre Fischer                 if (aLocation.meComponent != PC_None)
69652d13b84SAndre Fischer                     break;
69752d13b84SAndre Fischer                 pWindow = pWindow->GetParent();
69865908a7eSAndre Fischer             }
69952d13b84SAndre Fischer 
70052d13b84SAndre Fischer             if (aLocation.meComponent != PC_None)
70152d13b84SAndre Fischer             {
70252d13b84SAndre Fischer                 switch (pKeyEvent->GetKeyCode().GetCode())
70352d13b84SAndre Fischer                 {
70452d13b84SAndre Fischer                     case KEY_ESCAPE:
70552d13b84SAndre Fischer                         // Return focus back to the panel title.
706*441705dbSAndre Fischer                         FocusPanel(aLocation.mnIndex, true);
707*441705dbSAndre Fischer                         break;
708*441705dbSAndre Fischer 
709*441705dbSAndre Fischer                     case KEY_TAB:
710*441705dbSAndre Fischer                         if (mpFirstFocusedContentControl!=NULL
711*441705dbSAndre Fischer                             && mpLastFocusedWindow == mpFirstFocusedContentControl)
712*441705dbSAndre Fischer                         {
713*441705dbSAndre Fischer                             // Move focus back to panel (or deck)
714*441705dbSAndre Fischer                             // title.
715*441705dbSAndre Fischer                             FocusPanel(aLocation.mnIndex, true);
716*441705dbSAndre Fischer                         }
71752d13b84SAndre Fischer                         break;
71865908a7eSAndre Fischer 
71952d13b84SAndre Fischer                     default:
72052d13b84SAndre Fischer                         break;
72152d13b84SAndre Fischer                 }
72252d13b84SAndre Fischer             }
723a1fa6b52SAndre Fischer             return 1;
72465908a7eSAndre Fischer         }
72565908a7eSAndre Fischer 
726*441705dbSAndre Fischer         case VCLEVENT_WINDOW_GETFOCUS:
727*441705dbSAndre Fischer             // Keep track of focused controls in panel content.
728*441705dbSAndre Fischer             // Remember the first focused control.  When it is later
729*441705dbSAndre Fischer             // focused again due to pressing the TAB key then the
730*441705dbSAndre Fischer             // focus is moved to the panel or deck title.
731*441705dbSAndre Fischer             mpLastFocusedWindow = pSource;
732*441705dbSAndre Fischer             if (mbObservingContentControlFocus)
733*441705dbSAndre Fischer                 mpFirstFocusedContentControl = pSource;
734*441705dbSAndre Fischer             break;
735*441705dbSAndre Fischer 
73652d13b84SAndre Fischer         default:
73752d13b84SAndre Fischer             break;
73852d13b84SAndre Fischer     }
73952d13b84SAndre Fischer 
740a1fa6b52SAndre Fischer     return 0;
74152d13b84SAndre Fischer }
74265908a7eSAndre Fischer 
74365908a7eSAndre Fischer 
74465908a7eSAndre Fischer } } // end of namespace sfx2::sidebar
745