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