[Libreoffice-commits] core.git: Branch 'feature/sidebar' - sfx2/source svx/source

Andre Fischer af at apache.org
Fri May 10 06:46:52 PDT 2013


 sfx2/source/sidebar/Deck.cxx                       |   33 +
 sfx2/source/sidebar/Deck.hxx                       |    6 
 sfx2/source/sidebar/FocusManager.cxx               |  450 +++++++++++----------
 sfx2/source/sidebar/FocusManager.hxx               |   63 ++
 sfx2/source/sidebar/Panel.cxx                      |    4 
 sfx2/source/sidebar/SidebarController.cxx          |   13 
 sfx2/source/sidebar/SidebarController.hxx          |    6 
 sfx2/source/sidebar/SidebarDockingWindow.cxx       |   25 -
 sfx2/source/sidebar/SidebarDockingWindow.hxx       |    1 
 sfx2/source/sidebar/SidebarToolBox.cxx             |   17 
 sfx2/source/sidebar/SidebarToolBox.hxx             |    1 
 sfx2/source/sidebar/TitleBar.cxx                   |   12 
 sfx2/source/sidebar/TitleBar.hxx                   |    1 
 svx/source/sidebar/paragraph/ParaPropertyPanel.cxx |   16 
 svx/source/sidebar/paragraph/ParaPropertyPanel.hxx |   12 
 svx/source/sidebar/text/TextPropertyPanel.cxx      |   16 
 svx/source/sidebar/text/TextPropertyPanel.hxx      |    8 
 17 files changed, 420 insertions(+), 264 deletions(-)

New commits:
commit e604df6d147e636a4c51d0ca1e8f416d4ffa2260
Author: Andre Fischer <af at apache.org>
Date:   Mon May 6 13:12:20 2013 +0000

    Resolves: #i122230# Fixed focus traveling in the sidebar
    
    (cherry picked from commit bab3ddce4b3d5330835494f54b68406335821b76)
    
    Conflicts:
    	sfx2/source/sidebar/FocusManager.cxx
    
    Change-Id: I8853a92da3c4fe41a0110c630cc6af556ffc2ce4

diff --git a/sfx2/source/sidebar/Deck.cxx b/sfx2/source/sidebar/Deck.cxx
index 91929f8..ad3751c 100644
--- a/sfx2/source/sidebar/Deck.cxx
+++ b/sfx2/source/sidebar/Deck.cxx
@@ -260,6 +260,39 @@ void Deck::RequestLayout (void)
 
 
 
+void Deck::ShowPanel (const Panel& rPanel)
+{
+    if (mpVerticalScrollBar && mpVerticalScrollBar->IsVisible())
+    {
+        // Get vertical extent of the panel.
+        sal_Int32 nPanelTop (rPanel.GetPosPixel().Y());
+        const sal_Int32 nPanelBottom (nPanelTop + rPanel.GetSizePixel().Height() - 1);
+        // Add the title bar into the extent.
+        if (rPanel.GetTitleBar() != NULL && rPanel.GetTitleBar()->IsVisible())
+            nPanelTop = rPanel.GetTitleBar()->GetPosPixel().Y();
+
+
+        // Determine what the new thumb position should be like.
+        // When the whole panel does not fit then make its top visible
+        // and it off at the bottom.
+        sal_Int32 nNewThumbPos (mpVerticalScrollBar->GetThumbPos());
+        if (nPanelBottom >= nNewThumbPos+mpVerticalScrollBar->GetVisibleSize())
+            nNewThumbPos = nPanelBottom - mpVerticalScrollBar->GetVisibleSize();
+        if (nPanelTop < nNewThumbPos)
+            nNewThumbPos = nPanelTop;
+
+        mpVerticalScrollBar->SetThumbPos(nNewThumbPos);
+        mpScrollContainer->SetPosPixel(
+            Point(
+                mpScrollContainer->GetPosPixel().X(),
+                -nNewThumbPos));
+
+    }
+}
+
+
+
+
 const char* GetWindowClassification (const Window* pWindow)
 {
     const String& rsName (pWindow->GetText());
diff --git a/sfx2/source/sidebar/Deck.hxx b/sfx2/source/sidebar/Deck.hxx
index 07cdaec..e3c3b6f 100644
--- a/sfx2/source/sidebar/Deck.hxx
+++ b/sfx2/source/sidebar/Deck.hxx
@@ -61,6 +61,12 @@ public:
     void RequestLayout (void);
     ::Window* GetPanelParentWindow (void);
 
+    /** Try to make the panel completely visible.
+        When the whole panel does not fit then make its top visible
+        and it off at the bottom.
+    */
+    void ShowPanel (const Panel& rPanel);
+
     virtual void Paint (const Rectangle& rUpdateArea);
     virtual void DataChanged (const DataChangedEvent& rEvent);
 
diff --git a/sfx2/source/sidebar/FocusManager.cxx b/sfx2/source/sidebar/FocusManager.cxx
index f213a8c..b3c83d3 100644
--- a/sfx2/source/sidebar/FocusManager.cxx
+++ b/sfx2/source/sidebar/FocusManager.cxx
@@ -18,6 +18,7 @@
 
 #include "FocusManager.hxx"
 #include "Panel.hxx"
+#include "DeckTitleBar.hxx"
 #include "sfx2/sidebar/Tools.hxx"
 #include "TitleBar.hxx"
 #include <vcl/button.hxx>
@@ -27,36 +28,20 @@
 
 namespace sfx2 { namespace sidebar {
 
-namespace
+FocusManager::FocusLocation::FocusLocation (const PanelComponent eComponent, const sal_Int32 nIndex)
+    : meComponent(eComponent),
+      mnIndex(nIndex)
 {
-    enum PanelComponent
-    {
-        PC_TitleBar,
-        PC_ToolBox,
-        PC_Content,
-        PC_None
-    };
-
-    PanelComponent GetFocusedComponent (const Panel& rPanel)
-    {
-        if (rPanel.HasFocus())
-            return PC_Content;
-        else if (rPanel.GetTitleBar() != NULL)
-        {
-            if (rPanel.GetTitleBar()->HasFocus())
-                return PC_TitleBar;
-            else if (rPanel.GetTitleBar()->GetToolBox().HasFocus())
-                return PC_ToolBox;
-        }
-        return PC_None;
-    }
 }
 
 
-FocusManager::FocusManager (void)
-    : maPanels(),
+
+
+FocusManager::FocusManager (const ::boost::function<void(const Panel&)>& rShowPanelFunctor)
+    : mpDeckTitleBar(),
+      maPanels(),
       maButtons(),
-      mpTopLevelWindow(NULL)
+      maShowPanelFunctor(rShowPanelFunctor)
 {
 }
 
@@ -73,8 +58,7 @@ FocusManager::~FocusManager (void)
 
 void FocusManager::GrabFocus (void)
 {
-    if ( ! maPanels.empty())
-        FocusPanel(0);
+    FocusDeckTitle();
 }
 
 
@@ -82,16 +66,16 @@ void FocusManager::GrabFocus (void)
 
 void FocusManager::Clear (void)
 {
+    SetDeckTitle(NULL);
     ClearPanels();
     ClearButtons();
 }
 
 
 
+
 void FocusManager::ClearPanels (void)
 {
-    SetTopLevelWindow(NULL);
-
     ::std::vector<Panel*> aPanels;
     aPanels.swap(maPanels);
     for (::std::vector<Panel*>::iterator iPanel(aPanels.begin()),iEnd(aPanels.end());
@@ -104,6 +88,8 @@ void FocusManager::ClearPanels (void)
             UnregisterWindow(*(*iPanel)->GetTitleBar());
             UnregisterWindow((*iPanel)->GetTitleBar()->GetToolBox());
         }
+
+        (*iPanel)->RemoveChildEventListener(LINK(this, FocusManager, ChildEventListener));
     }
 }
 
@@ -124,6 +110,25 @@ void FocusManager::ClearButtons (void)
 
 
 
+void FocusManager::SetDeckTitle (DeckTitleBar* pDeckTitleBar)
+{
+    if (mpDeckTitleBar != NULL)
+    {
+        UnregisterWindow(*mpDeckTitleBar);
+        UnregisterWindow(mpDeckTitleBar->GetToolBox());
+    }
+    mpDeckTitleBar = pDeckTitleBar;
+
+    if (mpDeckTitleBar != NULL)
+    {
+        RegisterWindow(*mpDeckTitleBar);
+        RegisterWindow(mpDeckTitleBar->GetToolBox());
+    }
+}
+
+
+
+
 void FocusManager::SetPanels (const SharedPanelContainer& rPanels)
 {
     ClearPanels();
@@ -137,10 +142,12 @@ void FocusManager::SetPanels (const SharedPanelContainer& rPanels)
             RegisterWindow(*(*iPanel)->GetTitleBar());
             RegisterWindow((*iPanel)->GetTitleBar()->GetToolBox());
         }
+
+        // Register also as child event listener at the panel.
+        (*iPanel)->AddChildEventListener(LINK(this, FocusManager, ChildEventListener));
+
         maPanels.push_back(iPanel->get());
     }
-
-    RegisterTopLevelListener();
 }
 
 
@@ -177,66 +184,35 @@ void FocusManager::UnregisterWindow (Window& rWindow)
 
 
 
-void FocusManager::RegisterTopLevelListener (void)
-{
-    if (maPanels.empty())
-        return;
-    Window* pWindow = maPanels.front();
-    while (pWindow != NULL && pWindow->GetParent()!=NULL)
-    {
-        pWindow = pWindow->GetParent();
-    }
-    SetTopLevelWindow(pWindow);
-}
-
-
-
-
-void FocusManager::SetTopLevelWindow (Window* pWindow)
+FocusManager::FocusLocation FocusManager::GetFocusLocation (const Window& rWindow) const
 {
-    if (mpTopLevelWindow != pWindow)
+    // Check the deck title.
+    if (mpDeckTitleBar != NULL)
     {
-        if (mpTopLevelWindow != NULL)
-        {
-            UnregisterWindow(*mpTopLevelWindow);
-            mpTopLevelWindow->RemoveChildEventListener(LINK(this, FocusManager, WindowEventListener));
-        }
-        mpTopLevelWindow = pWindow;
-        if (mpTopLevelWindow != NULL)
-        {
-            RegisterWindow(*mpTopLevelWindow);
-            mpTopLevelWindow->AddChildEventListener(LINK(this, FocusManager, WindowEventListener));
-        }
+        if (mpDeckTitleBar == &rWindow)
+            return FocusLocation(PC_DeckTitle, -1);
+        else if (&mpDeckTitleBar->GetToolBox() == &rWindow)
+            return FocusLocation(PC_DeckToolBox, -1);
     }
-}
-
-
 
-
-sal_Int32 FocusManager::GetPanelIndex (const Window& rWindow) const
-{
+    // Search the panels.
     for (sal_Int32 nIndex=0,nCount(maPanels.size()); nIndex<nCount; ++nIndex)
     {
         if (maPanels[nIndex] == &rWindow)
-            return nIndex;
+            return FocusLocation(PC_PanelContent, nIndex);
         TitleBar* pTitleBar = maPanels[nIndex]->GetTitleBar();
         if (pTitleBar == &rWindow)
-            return nIndex;
+            return FocusLocation(PC_PanelTitle, nIndex);
         if (pTitleBar!=NULL && &pTitleBar->GetToolBox()==&rWindow)
-            return nIndex;
+            return FocusLocation(PC_PanelToolBox, nIndex);
     }
-    return -1;
-}
-
-
 
-
-sal_Int32 FocusManager::GetButtonIndex (const Window& rWindow) const
-{
+    // Search the buttons.
     for (sal_Int32 nIndex=0,nCount(maButtons.size()); nIndex<nCount; ++nIndex)
         if (maButtons[nIndex] == &rWindow)
-            return nIndex;
-    return -1;
+            return FocusLocation(PC_TabBar, nIndex);
+
+    return FocusLocation(PC_None, -1);
 }
 
 
@@ -274,6 +250,32 @@ bool FocusManager::IsAnyButtonFocused (void) const
 
 
 
+void FocusManager::FocusDeckTitle (void)
+{
+    if (IsDeckTitleVisible())
+    {
+        ToolBox& rToolBox = mpDeckTitleBar->GetToolBox();
+        if (rToolBox.GetItemCount() > 0)
+        {
+            rToolBox.GrabFocus();
+            rToolBox.Invalidate();
+        }
+    }
+    else
+        FocusPanel(0);
+}
+
+
+
+
+bool FocusManager::IsDeckTitleVisible (void) const
+{
+    return mpDeckTitleBar != NULL && mpDeckTitleBar->IsVisible();
+}
+
+
+
+
 void FocusManager::FocusPanel (const sal_Int32 nPanelIndex)
 {
     Panel& rPanel (*maPanels[nPanelIndex]);
@@ -285,6 +287,8 @@ void FocusManager::FocusPanel (const sal_Int32 nPanelIndex)
     }
     else
         FocusPanelContent(nPanelIndex);
+    if (maShowPanelFunctor)
+        maShowPanelFunctor(rPanel);
 }
 
 
@@ -349,24 +353,25 @@ void FocusManager::RemoveWindow (Window& rWindow)
 
 
 bool FocusManager::MoveFocusInsidePanel (
-    const sal_Int32 nPanelIndex,
+    const FocusLocation aFocusLocation,
     const sal_Int32 nDirection)
 {
-    Panel& rPanel (*maPanels[nPanelIndex]);
-    switch (GetFocusedComponent(rPanel))
+    const bool bHasToolBoxItem (
+        maPanels[aFocusLocation.mnIndex]->GetTitleBar()->GetToolBox().GetItemCount() > 0);
+    switch (aFocusLocation.meComponent)
     {
-        case  PC_TitleBar:
-            if (nDirection > 0)
-                rPanel.GetTitleBar()->GetToolBox().GrabFocus();
+        case  PC_PanelTitle:
+            if (nDirection > 0 && bHasToolBoxItem)
+                maPanels[aFocusLocation.mnIndex]->GetTitleBar()->GetToolBox().GrabFocus();
             else
-                FocusPanelContent(nPanelIndex);
+                FocusPanelContent(aFocusLocation.mnIndex);
             return true;
 
-        case PC_ToolBox:
-            if (nDirection > 0)
-                FocusPanelContent(nPanelIndex);
+        case PC_PanelToolBox:
+            if (nDirection < 0 && bHasToolBoxItem)
+                maPanels[aFocusLocation.mnIndex]->GetTitleBar()->GrabFocus();
             else
-                rPanel.GetTitleBar()->GrabFocus();
+                FocusPanelContent(aFocusLocation.mnIndex);
             return true;
 
         default:
@@ -377,119 +382,138 @@ bool FocusManager::MoveFocusInsidePanel (
 
 
 
-long FocusManager::NotifyDockingWindowEvent (const KeyEvent& rKeyEvent)
-{
-    switch(rKeyEvent.GetKeyCode().GetCode())
-    {
-        case KEY_F6:
-            if (rKeyEvent.GetKeyCode().IsShift())
-            {
-                if (IsAnyButtonFocused())
-                {
-                    FocusPanel(0);
-                    return 1;
-                }
-            }
-            else
-            {
-                if (IsAnyPanelFocused())
-                {
-                    FocusButton(0);
-                    return 1;
-                }
-            }
-            break;
-    }
-    return 0;
-}
-
-
-
-
 void FocusManager::HandleKeyEvent (
     const KeyCode& rKeyCode,
     const Window& rWindow)
 {
-    if (rKeyCode.GetModifier() != 0)
-        return;
-
-    const sal_Int32 nPanelIndex (GetPanelIndex(rWindow));
-    sal_Int32 nButtonIndex (nPanelIndex==-1 ? GetButtonIndex(rWindow) : -1);
+    const FocusLocation aLocation (GetFocusLocation(rWindow));
 
     switch (rKeyCode.GetCode())
     {
-        case KEY_F6:
-            if (nPanelIndex >= 0)
-                FocusButton(0);
-            else
-                return;
-            break;
-
         case KEY_SPACE:
-            if (nPanelIndex >= 0)
-            {
-                if (GetFocusedComponent(*maPanels[nPanelIndex]) == PC_TitleBar)
-                {
-                    // Toggle the expansion state.
-                    maPanels[nPanelIndex]->SetExpanded( ! maPanels[nPanelIndex]->IsExpanded());
-                }
-            }
-            else if (nButtonIndex >= 0)
+            switch (aLocation.meComponent)
             {
-                // Activate the button.
-                ClickButton(nButtonIndex);
+                case PC_PanelTitle:
+                    // Toggle panel between expanded and collapsed.
+                    maPanels[aLocation.mnIndex]->SetExpanded( ! maPanels[aLocation.mnIndex]->IsExpanded());
+                    break;
+
+                case PC_TabBar:
+                    // Activate the button.
+                    ClickButton(aLocation.mnIndex);
+                    break;
+
+                default:
+                    break;
             }
             return;
 
         case KEY_RETURN:
-            if (nPanelIndex >= 0)
+            switch (aLocation.meComponent)
             {
-                if (GetFocusedComponent(*maPanels[nPanelIndex]) == PC_TitleBar)
-                {
+                case PC_DeckToolBox:
+                    FocusButton(0);
+                    break;
+
+                case PC_PanelTitle:
                     // Enter the panel.
-                    FocusPanelContent(nPanelIndex);
-                }
-            }
-            else if (nButtonIndex >= 0)
-            {
-                // Activate the button.
-                ClickButton(nButtonIndex);
+                    FocusPanelContent(aLocation.mnIndex);
+                    break;
+
+                case PC_TabBar:
+                    // Activate the button.
+                    ClickButton(aLocation.mnIndex);
+                    break;
+
+                default:
+                    break;
             }
             return;
 
         case KEY_TAB:
-            if (nPanelIndex >= 0)
+            switch (aLocation.meComponent)
             {
-                if (rKeyCode.IsShift())
-                    MoveFocusInsidePanel(nPanelIndex, -1);
-                else
-                    MoveFocusInsidePanel(nPanelIndex, +1);
+                case PC_PanelTitle:
+                case PC_PanelToolBox:
+                case PC_PanelContent:
+                    if (rKeyCode.IsShift())
+                        MoveFocusInsidePanel(aLocation, -1);
+                    else
+                        MoveFocusInsidePanel(aLocation, +1);
+                    break;
+
+                default:
+                    break;
             }
             break;
 
         case KEY_LEFT:
         case KEY_UP:
-            // Go to previous element in focus ring.
-            if (nPanelIndex >= 0)
-            {
-                FocusPanel((nPanelIndex + maPanels.size() - 1) % maPanels.size());
-            }
-            else if (nButtonIndex >= 0)
+            switch (aLocation.meComponent)
             {
-                FocusButton((nButtonIndex + maButtons.size() - 1) % maButtons.size());
+                case PC_PanelTitle:
+                case PC_PanelToolBox:
+                case PC_PanelContent:
+                    // Go to previous panel or the deck title.
+                    if (aLocation.mnIndex > 0)
+                        FocusPanel(aLocation.mnIndex-1);
+                    else if (IsDeckTitleVisible())
+                        FocusDeckTitle();
+                    else
+                        FocusButton(maButtons.size()-1);
+                    break;
+
+                case PC_DeckTitle:
+                case PC_DeckToolBox:
+                    // Focus the last button.
+                    FocusButton(maButtons.size()-1);
+                    break;
+
+                case PC_TabBar:
+                    // Go to previous tab bar item.
+                    if (aLocation.mnIndex == 0)
+                        FocusPanel(maPanels.size()-1);
+                    else
+                        FocusButton((aLocation.mnIndex + maButtons.size() - 1) % maButtons.size());
+                    break;
+
+                default:
+                    break;
             }
             break;
 
         case KEY_RIGHT:
         case KEY_DOWN:
-            // Go to next element in focus ring.
-            if (nPanelIndex >= 0)
-            {
-                FocusPanel((nPanelIndex + 1) % maPanels.size());
-            }
-            else if (nButtonIndex >= 0)
+            switch(aLocation.meComponent)
             {
-                FocusButton((nButtonIndex + 1) % maButtons.size());
+                case PC_PanelTitle:
+                case PC_PanelToolBox:
+                case PC_PanelContent:
+                    // Go to next panel.
+                    if (aLocation.mnIndex < static_cast<sal_Int32>(maPanels.size())-1)
+                        FocusPanel(aLocation.mnIndex+1);
+                    else
+                        FocusButton(0);
+                    break;
+
+                case PC_DeckTitle:
+                case PC_DeckToolBox:
+                    // Focus the first panel.
+                    FocusPanel(0);
+                    break;
+
+                case PC_TabBar:
+                    // Go to next tab bar item.
+                    if (aLocation.mnIndex < static_cast<sal_Int32>(maButtons.size())-1)
+                        FocusButton(aLocation.mnIndex + 1);
+                    else if (IsDeckTitleVisible())
+                        FocusDeckTitle();
+                    else
+                        FocusPanel(0);
+                    break;
+
+                default:
+                    break;
             }
             break;
     }
@@ -498,27 +522,44 @@ void FocusManager::HandleKeyEvent (
 
 
 
-void FocusManager::HandleTopLevelEvent (VclWindowEvent& rEvent)
+IMPL_LINK(FocusManager, WindowEventListener, VclSimpleEvent*, pEvent)
 {
-    switch (rEvent.GetId())
+    if (pEvent == NULL)
+        return 0;
+
+    if ( ! pEvent->ISA(VclWindowEvent))
+        return 0;
+
+    VclWindowEvent* pWindowEvent = static_cast<VclWindowEvent*>(pEvent);
+    Window* pSource = pWindowEvent->GetWindow();
+    if (pSource == NULL)
+        return 0;
+
+    switch (pWindowEvent->GetId())
     {
         case VCLEVENT_WINDOW_KEYINPUT:
         {
-            KeyEvent* pKeyEvent = static_cast<KeyEvent*>(rEvent.GetData());
-            switch (pKeyEvent->GetKeyCode().GetCode())
-            {
-                case KEY_F6:
-                    OSL_TRACE("");
-                    break;
-            }
+            KeyEvent* pKeyEvent = static_cast<KeyEvent*>(pWindowEvent->GetData());
+            HandleKeyEvent(pKeyEvent->GetKeyCode(), *pSource);
+            return 1;
         }
+
+        case VCLEVENT_OBJECT_DYING:
+            RemoveWindow(*pSource);
+            return 1;
+
+        case VCLEVENT_WINDOW_GETFOCUS:
+        case VCLEVENT_WINDOW_LOSEFOCUS:
+            pSource->Invalidate();
     }
+
+    return 0;
 }
 
 
 
 
-IMPL_LINK(FocusManager, WindowEventListener, VclSimpleEvent*, pEvent)
+IMPL_LINK(FocusManager, ChildEventListener, VclSimpleEvent*, pEvent)
 {
     if (pEvent == NULL)
         return 0;
@@ -531,29 +572,48 @@ IMPL_LINK(FocusManager, WindowEventListener, VclSimpleEvent*, pEvent)
     if (pSource == NULL)
         return 0;
 
-    if (pSource == mpTopLevelWindow)
-        HandleTopLevelEvent(*pWindowEvent);
-    else
-        switch (pWindowEvent->GetId())
+    switch (pWindowEvent->GetId())
+    {
+        case VCLEVENT_WINDOW_KEYINPUT:
         {
-            case VCLEVENT_WINDOW_KEYINPUT:
+            KeyEvent* pKeyEvent = static_cast<KeyEvent*>(pWindowEvent->GetData());
+
+            // Go up the window hierarchy to find the parent of the
+            // event source which is known to us.
+            Window* pWindow = pSource;
+            FocusLocation aLocation (PC_None, -1);
+            while (true)
             {
-                KeyEvent* pKeyEvent = static_cast<KeyEvent*>(pWindowEvent->GetData());
-                HandleKeyEvent(pKeyEvent->GetKeyCode(), *pSource);
-                return 1;
+                if (pWindow == NULL)
+                    break;
+                aLocation = GetFocusLocation(*pWindow);
+                if (aLocation.meComponent != PC_None)
+                    break;
+                pWindow = pWindow->GetParent();
             }
 
-            case VCLEVENT_OBJECT_DYING:
-                RemoveWindow(*pSource);
-                return 1;
+            if (aLocation.meComponent != PC_None)
+            {
+                switch (pKeyEvent->GetKeyCode().GetCode())
+                {
+                    case KEY_ESCAPE:
+                        // Return focus back to the panel title.
+                        FocusPanel(aLocation.mnIndex);
+                        break;
 
-            case VCLEVENT_WINDOW_GETFOCUS:
-            case VCLEVENT_WINDOW_LOSEFOCUS:
-                pSource->Invalidate();
+                    default:
+                        break;
+                }
+            }
+            break;
         }
-    return 0;
-}
 
+        default:
+            break;
+    }
+
+    return 1;
+}
 
 
 } } // end of namespace sfx2::sidebar
diff --git a/sfx2/source/sidebar/FocusManager.hxx b/sfx2/source/sidebar/FocusManager.hxx
index f811f5e..c06642f 100644
--- a/sfx2/source/sidebar/FocusManager.hxx
+++ b/sfx2/source/sidebar/FocusManager.hxx
@@ -25,17 +25,32 @@ class Button;
 class KeyCode;
 class VclSimpleEvent;
 
+
 namespace sfx2 { namespace sidebar {
 
+class DeckTitleBar;
+
 /** Concentrate all focus handling in this class.
-    There are two rings of windows that accept the input focus: panels
-    and tab bar buttons.
-    Arrow keys move the focus between them.  Tab moves focus between rings.
+
+    There is one ring of windows that accept the input focus which are
+    cycled through with the arrow keys:
+    - the closer in the deck title (present only when docked)
+    - the panel title bars
+    - the tab bar items
+
+    When the focus is in a panel title then focus travels over
+    - the panel title
+    - the panel closer
+    - the panel content
+
+    Once the focus is in the panel content then focus cycles through
+    all controls inside the panel but not back to the title bar of
+    the panel.  Escape places the focus back in the panel title.
 */
 class FocusManager
 {
 public:
-    FocusManager (void);
+    FocusManager (const ::boost::function<void(const Panel&)>& rShowPanelFunctor);
     ~FocusManager (void);
 
     /** Forget all panels and buttons.  Remove all window listeners.
@@ -48,22 +63,38 @@ public:
     */
     void GrabFocus (void);
 
-    /** Handle the key event that was sent to the docking window.
-    */
-    long NotifyDockingWindowEvent (const KeyEvent& rKeyEvent);
-
+    void SetDeckTitle (DeckTitleBar* pDeckTitleBar);
     void SetPanels (const SharedPanelContainer& rPanels);
-
     void SetButtons (const ::std::vector<Button*>& rButtons);
 
 private:
+    DeckTitleBar* mpDeckTitleBar;
     ::std::vector<Panel*> maPanels;
     ::std::vector<Button*> maButtons;
-    Window* mpTopLevelWindow;
+    const ::boost::function<void(const Panel&)> maShowPanelFunctor;
+
+    enum PanelComponent
+    {
+        PC_DeckTitle,
+        PC_DeckToolBox,
+        PC_PanelTitle,
+        PC_PanelToolBox,
+        PC_PanelContent,
+        PC_TabBar,
+        PC_None
+    };
+    class FocusLocation
+    {
+    public:
+        PanelComponent meComponent;
+        sal_Int32 mnIndex;
+        FocusLocation (const PanelComponent eComponent, const sal_Int32 nIndex);
+    };
 
     /** Listen for key events for panels and buttons.
     */
     DECL_LINK(WindowEventListener, VclSimpleEvent*);
+    DECL_LINK(ChildEventListener, VclSimpleEvent*);
 
     void ClearPanels (void);
     void ClearButtons (void);
@@ -73,17 +104,17 @@ private:
     */
     void RegisterWindow (Window& rWindow);
     void UnregisterWindow (Window& rWindow);
-    void RegisterTopLevelListener (void);
 
     /** Remove the window from the panel or the button container.
     */
     void RemoveWindow (Window& rWindow);
 
-    sal_Int32 GetPanelIndex (const Window& rWindow) const;
-    sal_Int32 GetButtonIndex (const Window& rWindow) const;
     bool IsAnyPanelFocused (void) const;
     bool IsAnyButtonFocused (void) const;
 
+    void FocusDeckTitle (void);
+    bool IsDeckTitleVisible (void) const;
+
     /** Set the focus to the title bar of the panel or, if the the
         title bar is not visible, directly to the panel.
     */
@@ -92,15 +123,15 @@ private:
     void FocusButton (const sal_Int32 nButtonIndex);
     void ClickButton (const sal_Int32 nButtonIndex);
     bool MoveFocusInsidePanel (
-        const sal_Int32 nPanelIndex,
+        const FocusLocation aLocation,
         const sal_Int32 nDirection);
 
     void HandleKeyEvent (
         const KeyCode& rKeyCode,
         const Window& rWindow);
 
-    void SetTopLevelWindow (Window* pWindow);
-    void HandleTopLevelEvent (VclWindowEvent& rEvent);
+    FocusLocation GetFocusLocation (const Window& rWindow) const;
+
 };
 
 } } // end of namespace sfx2::sidebar
diff --git a/sfx2/source/sidebar/Panel.cxx b/sfx2/source/sidebar/Panel.cxx
index b5bfcf2..59eeb05 100644
--- a/sfx2/source/sidebar/Panel.cxx
+++ b/sfx2/source/sidebar/Panel.cxx
@@ -47,7 +47,7 @@ namespace sfx2 { namespace sidebar {
 Panel::Panel (
     const PanelDescriptor& rPanelDescriptor,
     Window* pParentWindow,
-    const ::boost::function<void(void)>& rDeckLayoutTrigger )
+    const ::boost::function<void(void)>& rDeckLayoutTrigger)
     : Window(pParentWindow),
       msPanelId(rPanelDescriptor.msId),
       mpTitleBar(new PanelTitleBar(
@@ -63,7 +63,6 @@ Panel::Panel (
     SetBackground(Theme::GetPaint(Theme::Paint_PanelBackground).GetWallpaper());
 
 #ifdef DEBUG
-    OSL_TRACE("creating Panel at %x", this);
     SetText(A2S("Panel"));
 #endif
 }
@@ -73,7 +72,6 @@ Panel::Panel (
 
 Panel::~Panel (void)
 {
-    OSL_TRACE("destroying Panel at %x", this);
     Dispose();
 }
 
diff --git a/sfx2/source/sidebar/SidebarController.cxx b/sfx2/source/sidebar/SidebarController.cxx
index 6f4c95e..0cbaea7b 100644
--- a/sfx2/source/sidebar/SidebarController.cxx
+++ b/sfx2/source/sidebar/SidebarController.cxx
@@ -100,13 +100,16 @@ SidebarController::SidebarController (
               ::boost::bind(&SidebarController::ShowPopupMenu, this, _1,_2,_3))),
       mxFrame(rxFrame),
       maCurrentContext(OUString(), OUString()),
+      maRequestedContext(),
       msCurrentDeckId(A2S("PropertyDeck")),
+      msCurrentDeckTitle(),
       maPropertyChangeForwarder(::boost::bind(&SidebarController::BroadcastPropertyChange, this)),
       maContextChangeUpdate(::boost::bind(&SidebarController::UpdateConfigurations, this)),
       mbIsDeckRequestedOpen(),
       mbIsDeckOpen(),
       mbCanDeckBeOpened(true),
       mnSavedSidebarWidth(pParentWindow->GetSizePixel().Width()),
+      maFocusManager(::boost::bind(&SidebarController::ShowPanel, this, _1)),
       mxReadOnlyModeDispatch(),
       mbIsDocumentReadOnly(false),
       mpSplitWindow(NULL),
@@ -603,6 +606,7 @@ void SidebarController::SwitchToDeck (
 
     // Tell the focus manager about the new panels and tab bar
     // buttons.
+    maFocusManager.SetDeckTitle(mpCurrentDeck->GetTitleBar());
     maFocusManager.SetPanels(aNewPanels);
     mpTabBar->UpdateFocusManager(maFocusManager);
     UpdateTitleBarIcons();
@@ -1154,4 +1158,13 @@ void SidebarController::UpdateTitleBarIcons (void)
 }
 
 
+
+
+void SidebarController::ShowPanel (const Panel& rPanel)
+{
+    if (mpCurrentDeck)
+        mpCurrentDeck->ShowPanel(rPanel);
+}
+
+
 } } // end of namespace sfx2::sidebar
diff --git a/sfx2/source/sidebar/SidebarController.hxx b/sfx2/source/sidebar/SidebarController.hxx
index ec93b06..7ba4092 100644
--- a/sfx2/source/sidebar/SidebarController.hxx
+++ b/sfx2/source/sidebar/SidebarController.hxx
@@ -206,6 +206,12 @@ private:
     void ProcessNewWidth (const sal_Int32 nNewWidth);
     void UpdateCloseIndicator (const bool bIsIndicatorVisible);
 
+    /** Typically called when a panel is focused via keyboard.
+        Tries to scroll the deck up or down to make the given panel
+        completely visible.
+    */
+    void ShowPanel (const Panel& rPanel);
+
     virtual void SAL_CALL disposing (void);
 };
 
diff --git a/sfx2/source/sidebar/SidebarDockingWindow.cxx b/sfx2/source/sidebar/SidebarDockingWindow.cxx
index 1e01bb7..f991c7a5 100644
--- a/sfx2/source/sidebar/SidebarDockingWindow.cxx
+++ b/sfx2/source/sidebar/SidebarDockingWindow.cxx
@@ -78,31 +78,6 @@ void SidebarDockingWindow::GetFocus()
 
 
 
-long SidebarDockingWindow::PreNotify (NotifyEvent& rEvent)
-{
-    switch (rEvent.GetType())
-    {
-        case EVENT_KEYINPUT:
-        {
-            const KeyEvent* pKeyEvent = rEvent.GetKeyEvent();
-            if (pKeyEvent != NULL)
-                return mpSidebarController->GetFocusManager().NotifyDockingWindowEvent(*pKeyEvent);
-            else
-                break;
-        }
-
-        case EVENT_GETFOCUS:
-            OSL_TRACE("");
-            break;
-
-    }
-
-    return SfxDockingWindow::PreNotify(rEvent);
-}
-
-
-
-
 SfxChildWindow* SidebarDockingWindow::GetChildWindow (void)
 {
     return GetChildWindow_Impl();
diff --git a/sfx2/source/sidebar/SidebarDockingWindow.hxx b/sfx2/source/sidebar/SidebarDockingWindow.hxx
index 700ffde..2125212 100644
--- a/sfx2/source/sidebar/SidebarDockingWindow.hxx
+++ b/sfx2/source/sidebar/SidebarDockingWindow.hxx
@@ -48,7 +48,6 @@ public:
 protected:
     // Window overridables
     virtual void GetFocus (void);
-    virtual long PreNotify (NotifyEvent& rEvent);
 
 private:
     ::rtl::Reference<sfx2::sidebar::SidebarController> mpSidebarController;
diff --git a/sfx2/source/sidebar/SidebarToolBox.cxx b/sfx2/source/sidebar/SidebarToolBox.cxx
index 6992afb..bf07a30 100644
--- a/sfx2/source/sidebar/SidebarToolBox.cxx
+++ b/sfx2/source/sidebar/SidebarToolBox.cxx
@@ -150,4 +150,21 @@ void SidebarToolBox::setPosSizePixel (
 
 
 
+
+long SidebarToolBox::Notify (NotifyEvent& rEvent)
+{
+    if (rEvent.GetType() == EVENT_KEYINPUT)
+    {
+        if (rEvent.GetKeyEvent()->GetKeyCode().GetCode() == KEY_TAB)
+        {
+            // Special handling for transferring handling of KEY_TAB
+            // that becomes necessary because of our parent that is
+            // not the dialog but a background control.
+            return DockingWindow::Notify(rEvent);
+        }
+    }
+    return ToolBox::Notify(rEvent);
+}
+
+
 } } // end of namespace sfx2::sidebar
diff --git a/sfx2/source/sidebar/SidebarToolBox.hxx b/sfx2/source/sidebar/SidebarToolBox.hxx
index 125839a..f76de46 100644
--- a/sfx2/source/sidebar/SidebarToolBox.hxx
+++ b/sfx2/source/sidebar/SidebarToolBox.hxx
@@ -40,6 +40,7 @@ public:
         long nWidth,
         long nHeight,
         sal_uInt16 nFlags);
+    virtual long Notify (NotifyEvent& rEvent);
 
 private:
     bool mbParentIsBorder;
diff --git a/sfx2/source/sidebar/TitleBar.cxx b/sfx2/source/sidebar/TitleBar.cxx
index 6f73636..76bf7d7 100644
--- a/sfx2/source/sidebar/TitleBar.cxx
+++ b/sfx2/source/sidebar/TitleBar.cxx
@@ -134,6 +134,14 @@ ToolBox& TitleBar::GetToolBox (void)
 
 
 
+const ToolBox& TitleBar::GetToolBox (void) const
+{
+    return maToolBox;
+}
+
+
+
+
 void TitleBar::HandleToolBoxItemClick (const sal_uInt16 nItemIndex)
 {
     (void)nItemIndex;
@@ -182,6 +190,10 @@ void TitleBar::PaintFocus (const Rectangle& rFocusBox)
 {
     Push(PUSH_FONT | PUSH_TEXTCOLOR | PUSH_LINECOLOR | PUSH_FILLCOLOR);
 
+    Font aFont(GetFont());
+    aFont.SetWeight(WEIGHT_BOLD);
+    SetFont(aFont);
+
     const Rectangle aTextBox (
         GetTextRect(
             rFocusBox,
diff --git a/sfx2/source/sidebar/TitleBar.hxx b/sfx2/source/sidebar/TitleBar.hxx
index e0e3772..c16cfbc 100644
--- a/sfx2/source/sidebar/TitleBar.hxx
+++ b/sfx2/source/sidebar/TitleBar.hxx
@@ -49,6 +49,7 @@ public:
         sal_uInt16 nFlags = WINDOW_POSSIZE_ALL);
 
     ToolBox& GetToolBox (void);
+    const ToolBox& GetToolBox (void) const;
 
 protected:
     ToolBox maToolBox;
diff --git a/svx/source/sidebar/paragraph/ParaPropertyPanel.cxx b/svx/source/sidebar/paragraph/ParaPropertyPanel.cxx
index 2dbedb5..f4391e6 100644
--- a/svx/source/sidebar/paragraph/ParaPropertyPanel.cxx
+++ b/svx/source/sidebar/paragraph/ParaPropertyPanel.cxx
@@ -1548,18 +1548,22 @@ ParaPropertyPanel::ParaPropertyPanel(Window* pParent,
       maFTUL (new FixedText(this, SVX_RES(FT_SPACING))),
       maTbxUL_IncDecBackground(ControlFactory::CreateToolBoxBackground(this)),
       maTbxUL_IncDec (ControlFactory::CreateToolBox(maTbxUL_IncDecBackground.get(),SVX_RES(TBX_UL_INC_DEC))),
-      maTopDist (new SvxRelativeField(this, SVX_RES(MF_ABOVE_PARASPACING))),
-      maBottomDist (new SvxRelativeField(this, SVX_RES(MF_BELOW_PARASPACING))),
-      maLineSPTbxBackground(ControlFactory::CreateToolBoxBackground(this)),
-      maLineSPTbx (ControlFactory::CreateToolBox(maLineSPTbxBackground.get(),SVX_RES(TBX_LINESP))),
       maFTIndent (new FixedText(this, SVX_RES(FT_INDENT))),
       maTbxIndent_IncDecBackground(ControlFactory::CreateToolBoxBackground(this)),
       maTbxIndent_IncDec (ControlFactory::CreateToolBox(maTbxIndent_IncDecBackground.get(),SVX_RES(TBX_INDENT_INC_DEC))),
-      maTbxProDemoteBackground(ControlFactory::CreateToolBoxBackground(this)),
-      maTbxProDemote (ControlFactory::CreateToolBox(maTbxProDemoteBackground.get(),SVX_RES(TBX_INDENT_PRO_DEMOTE))),
+
+      maTopDist (new SvxRelativeField(this, SVX_RES(MF_ABOVE_PARASPACING))),
       maLeftIndent (new SvxRelativeField(this, SVX_RES(MF_BEFORE_INDENT))),
+
+      maBottomDist (new SvxRelativeField(this, SVX_RES(MF_BELOW_PARASPACING))),
       maRightIndent (new SvxRelativeField(this, SVX_RES(MF_AFTER_INDENT))),
+
+      maLineSPTbxBackground(ControlFactory::CreateToolBoxBackground(this)),
+      maLineSPTbx (ControlFactory::CreateToolBox(maLineSPTbxBackground.get(),SVX_RES(TBX_LINESP))),
       maFLineIndent (new SvxRelativeField(this, SVX_RES(MF_FL_INDENT))),
+
+      maTbxProDemoteBackground(ControlFactory::CreateToolBoxBackground(this)),
+      maTbxProDemote (ControlFactory::CreateToolBox(maTbxProDemoteBackground.get(),SVX_RES(TBX_INDENT_PRO_DEMOTE))),
       mpColorUpdater (),
       maFISpace1 ( this, SVX_RES( FI_SPACE1)),
       maFISpace2 ( this, SVX_RES( FI_SPACE2)),
diff --git a/svx/source/sidebar/paragraph/ParaPropertyPanel.hxx b/svx/source/sidebar/paragraph/ParaPropertyPanel.hxx
index e1701e3..3ed393b 100644
--- a/svx/source/sidebar/paragraph/ParaPropertyPanel.hxx
+++ b/svx/source/sidebar/paragraph/ParaPropertyPanel.hxx
@@ -108,20 +108,20 @@ private:
     ::boost::scoped_ptr<FixedText>          maFTUL;
     ::boost::scoped_ptr<Window>             maTbxUL_IncDecBackground;
     ::boost::scoped_ptr<ToolBox>            maTbxUL_IncDec;
+    ::boost::scoped_ptr<FixedText>          maFTIndent;
+    ::boost::scoped_ptr<Window>             maTbxIndent_IncDecBackground;
+    ::boost::scoped_ptr<ToolBox>            maTbxIndent_IncDec;
     ::boost::scoped_ptr<SvxRelativeField>   maTopDist;
+    ::boost::scoped_ptr<SvxRelativeField>   maLeftIndent;
     ::boost::scoped_ptr<SvxRelativeField>   maBottomDist;
+    ::boost::scoped_ptr<SvxRelativeField>   maRightIndent;
     //Line spacing
     ::boost::scoped_ptr<Window>             maLineSPTbxBackground;
     ::boost::scoped_ptr<ToolBox>            maLineSPTbx;
+    ::boost::scoped_ptr<SvxRelativeField>   maFLineIndent;
     //Indent
-    ::boost::scoped_ptr<FixedText>          maFTIndent;
-    ::boost::scoped_ptr<Window>             maTbxIndent_IncDecBackground;
-    ::boost::scoped_ptr<ToolBox>            maTbxIndent_IncDec;
     ::boost::scoped_ptr<Window>             maTbxProDemoteBackground;
     ::boost::scoped_ptr<ToolBox>            maTbxProDemote;
-    ::boost::scoped_ptr<SvxRelativeField>   maLeftIndent;
-    ::boost::scoped_ptr<SvxRelativeField>   maRightIndent;
-    ::boost::scoped_ptr<SvxRelativeField>   maFLineIndent;
     ::boost::scoped_ptr< ::svx::ToolboxButtonColorUpdater > mpColorUpdater;
 
     /**********************************************************
diff --git a/svx/source/sidebar/text/TextPropertyPanel.cxx b/svx/source/sidebar/text/TextPropertyPanel.cxx
index 575e5da..3a9d605 100644
--- a/svx/source/sidebar/text/TextPropertyPanel.cxx
+++ b/svx/source/sidebar/text/TextPropertyPanel.cxx
@@ -160,18 +160,14 @@ TextPropertyPanel::TextPropertyPanel (
     :   Control(pParent, SVX_RES(RID_SIDEBAR_TEXT_PANEL)),
         mpFontNameBox (new SvxSBFontNameBox(this, SVX_RES(CB_SBFONT_FONT))),
         maFontSizeBox       (this, SVX_RES(MB_SBFONT_FONTSIZE)),
-        mpToolBoxIncDecBackground(ControlFactory::CreateToolBoxBackground(this)),
-        mpToolBoxIncDec(ControlFactory::CreateToolBox(
-                mpToolBoxIncDecBackground.get(),
-                SVX_RES(TB_INCREASE_DECREASE))),
         mpToolBoxFontBackground(ControlFactory::CreateToolBoxBackground(this)),
         mpToolBoxFont(ControlFactory::CreateToolBox(
                 mpToolBoxFontBackground.get(),
                 SVX_RES(TB_FONT))),
-        mpToolBoxFontColorBackground(ControlFactory::CreateToolBoxBackground(this)),
-        mpToolBoxFontColor(ControlFactory::CreateToolBox(
-                mpToolBoxFontColorBackground.get(),
-                SVX_RES(TB_FONTCOLOR))),
+        mpToolBoxIncDecBackground(ControlFactory::CreateToolBoxBackground(this)),
+        mpToolBoxIncDec(ControlFactory::CreateToolBox(
+                mpToolBoxIncDecBackground.get(),
+                SVX_RES(TB_INCREASE_DECREASE))),
         mpToolBoxScriptBackground(ControlFactory::CreateToolBoxBackground(this)),
         mpToolBoxScript(ControlFactory::CreateToolBox(
                 mpToolBoxScriptBackground.get(),
@@ -184,6 +180,10 @@ TextPropertyPanel::TextPropertyPanel (
         mpToolBoxSpacing(ControlFactory::CreateToolBox(
                 mpToolBoxSpacingBackground.get(),
                 SVX_RES(TB_SPACING))),
+        mpToolBoxFontColorBackground(ControlFactory::CreateToolBoxBackground(this)),
+        mpToolBoxFontColor(ControlFactory::CreateToolBox(
+                mpToolBoxFontColorBackground.get(),
+                SVX_RES(TB_FONTCOLOR))),
         mpToolBoxHighlightBackground(ControlFactory::CreateToolBoxBackground(this)),
         mpToolBoxHighlight(ControlFactory::CreateToolBox(
                 mpToolBoxHighlightBackground.get(),
diff --git a/svx/source/sidebar/text/TextPropertyPanel.hxx b/svx/source/sidebar/text/TextPropertyPanel.hxx
index 553bc23..cb097d6 100644
--- a/svx/source/sidebar/text/TextPropertyPanel.hxx
+++ b/svx/source/sidebar/text/TextPropertyPanel.hxx
@@ -83,18 +83,18 @@ private:
     //ui controls
     ::boost::scoped_ptr<SvxSBFontNameBox> mpFontNameBox;
     FontSizeBox maFontSizeBox;
-    ::boost::scoped_ptr<Window> mpToolBoxIncDecBackground;
-    ::boost::scoped_ptr<ToolBox> mpToolBoxIncDec;
     ::boost::scoped_ptr<Window> mpToolBoxFontBackground;
     ::boost::scoped_ptr<ToolBox> mpToolBoxFont;
-    ::boost::scoped_ptr<Window> mpToolBoxFontColorBackground;
-    ::boost::scoped_ptr<ToolBox> mpToolBoxFontColor;
+    ::boost::scoped_ptr<Window> mpToolBoxIncDecBackground;
+    ::boost::scoped_ptr<ToolBox> mpToolBoxIncDec;
     ::boost::scoped_ptr<Window> mpToolBoxScriptBackground;
     ::boost::scoped_ptr<ToolBox> mpToolBoxScript;
     ::boost::scoped_ptr<Window> mpToolBoxScriptSwBackground;
     ::boost::scoped_ptr<ToolBox> mpToolBoxScriptSw;
     ::boost::scoped_ptr<Window> mpToolBoxSpacingBackground;
     ::boost::scoped_ptr<ToolBox> mpToolBoxSpacing;
+    ::boost::scoped_ptr<Window> mpToolBoxFontColorBackground;
+    ::boost::scoped_ptr<ToolBox> mpToolBoxFontColor;
     ::boost::scoped_ptr<Window> mpToolBoxHighlightBackground;
     ::boost::scoped_ptr<ToolBox> mpToolBoxHighlight;
     ::boost::scoped_ptr<ToolboxButtonColorUpdater> mpFontColorUpdater;


More information about the Libreoffice-commits mailing list