1 /*************************************************************************
2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3  *
4  * Copyright 2000, 2010 Oracle and/or its affiliates.
5  *
6  * OpenOffice.org - a multi-platform office productivity suite
7  *
8  * This file is part of OpenOffice.org.
9  *
10  * OpenOffice.org is free software: you can redistribute it and/or modify
11  * it under the terms of the GNU Lesser General Public License version 3
12  * only, as published by the Free Software Foundation.
13  *
14  * OpenOffice.org is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU Lesser General Public License version 3 for more details
18  * (a copy is included in the LICENSE file that accompanied this code).
19  *
20  * You should have received a copy of the GNU Lesser General Public License
21  * version 3 along with OpenOffice.org.  If not, see
22  * <http://www.openoffice.org/license.html>
23  * for a copy of the LGPLv3 License.
24  *
25 ************************************************************************/
26 
27 #include "precompiled_svtools.hxx"
28 
29 #include "svtools/toolpanel/tablayouter.hxx"
30 #include "svtools/toolpanel/toolpaneldeck.hxx"
31 #include "svtools/toolpanel/paneltabbar.hxx"
32 #include "svtaccessiblefactory.hxx"
33 
34 #include <tools/gen.hxx>
35 #include <tools/diagnose_ex.h>
36 
37 //........................................................................
38 namespace svt
39 {
40 //........................................................................
41 
42     using ::com::sun::star::uno::Reference;
43     using ::com::sun::star::accessibility::XAccessible;
44 
45 	//====================================================================
46 	//= TabDeckLayouter_Data
47 	//====================================================================
48     struct TabDeckLayouter_Data
49     {
50         TabAlignment                    eAlignment;
51         IToolPanelDeck&                 rPanels;
52         ::std::auto_ptr< PanelTabBar >  pTabBar;
53         AccessibleFactoryAccess         aAccessibleFactory;
54 
55         TabDeckLayouter_Data( Window& i_rParent, IToolPanelDeck& i_rPanels,
56                 const TabAlignment i_eAlignment, const TabItemContent i_eItemContent )
57             :eAlignment( i_eAlignment )
58             ,rPanels( i_rPanels )
59             ,pTabBar( new PanelTabBar( i_rParent, i_rPanels, i_eAlignment, i_eItemContent ) )
60         {
61             pTabBar->Show();
62         }
63     };
64 
65 	//====================================================================
66 	//= helper
67 	//====================================================================
68     namespace
69     {
70         static bool lcl_isVerticalTabBar( const TabAlignment i_eAlignment )
71         {
72             return  ( i_eAlignment == TABS_RIGHT )
73                 ||  ( i_eAlignment == TABS_LEFT );
74         }
75 
76         static bool lcl_checkDisposed( const TabDeckLayouter_Data& i_rData )
77         {
78             if ( !i_rData.pTabBar.get() )
79             {
80                 OSL_ENSURE( false, "lcl_checkDisposed: already disposed!" );
81                 return true;
82             }
83             return false;
84         }
85     }
86 
87 	//====================================================================
88 	//= TabDeckLayouter
89 	//====================================================================
90 	//--------------------------------------------------------------------
91     TabDeckLayouter::TabDeckLayouter( Window& i_rParent, IToolPanelDeck& i_rPanels,
92             const TabAlignment i_eAlignment, const TabItemContent i_eItemContent )
93         :m_pData( new TabDeckLayouter_Data( i_rParent, i_rPanels, i_eAlignment, i_eItemContent ) )
94     {
95     }
96 
97 	//--------------------------------------------------------------------
98     TabDeckLayouter::~TabDeckLayouter()
99     {
100     }
101 
102 	//--------------------------------------------------------------------
103     IMPLEMENT_IREFERENCE( TabDeckLayouter )
104 
105 	//--------------------------------------------------------------------
106     TabItemContent TabDeckLayouter::GetTabItemContent() const
107     {
108         if ( lcl_checkDisposed( *m_pData ) )
109             return TABITEM_IMAGE_AND_TEXT;
110         return m_pData->pTabBar->GetTabItemContent();
111     }
112 
113 	//--------------------------------------------------------------------
114     void TabDeckLayouter::SetTabItemContent( const TabItemContent& i_eItemContent )
115     {
116         if ( lcl_checkDisposed( *m_pData ) )
117             return;
118         m_pData->pTabBar->SetTabItemContent( i_eItemContent );
119     }
120 
121 	//--------------------------------------------------------------------
122     TabAlignment TabDeckLayouter::GetTabAlignment() const
123     {
124         if ( lcl_checkDisposed( *m_pData ) )
125             return TABS_RIGHT;
126         return m_pData->eAlignment;
127     }
128 
129 	//--------------------------------------------------------------------
130     ::boost::optional< size_t > TabDeckLayouter::GetFocusedPanelItem() const
131     {
132         if ( lcl_checkDisposed( *m_pData ) )
133             return ::boost::optional< size_t >();
134         return m_pData->pTabBar->GetFocusedPanelItem();
135     }
136 
137 	//--------------------------------------------------------------------
138     void TabDeckLayouter::FocusPanelItem( const size_t i_nItemPos )
139     {
140         if ( lcl_checkDisposed( *m_pData ) )
141             return;
142         m_pData->pTabBar->FocusPanelItem( i_nItemPos );
143     }
144 
145 	//--------------------------------------------------------------------
146     bool TabDeckLayouter::IsPanelSelectorEnabled() const
147     {
148         if ( lcl_checkDisposed( *m_pData ) )
149             return false;
150         return m_pData->pTabBar->IsEnabled();
151     }
152 
153 	//--------------------------------------------------------------------
154     bool TabDeckLayouter::IsPanelSelectorVisible() const
155     {
156         if ( lcl_checkDisposed( *m_pData ) )
157             return false;
158         return m_pData->pTabBar->IsVisible();
159     }
160 
161 	//--------------------------------------------------------------------
162     Rectangle TabDeckLayouter::GetItemScreenRect( const size_t i_nItemPos ) const
163     {
164         if ( lcl_checkDisposed( *m_pData ) )
165             return Rectangle();
166         return m_pData->pTabBar->GetItemScreenRect( i_nItemPos );
167     }
168 
169 	//--------------------------------------------------------------------
170     Rectangle TabDeckLayouter::Layout( const Rectangle& i_rDeckPlayground )
171     {
172         if ( lcl_checkDisposed( *m_pData ) )
173             return i_rDeckPlayground;
174 
175         const Size aPreferredSize( m_pData->pTabBar->GetOptimalSize( WINDOWSIZE_PREFERRED ) );
176         if ( lcl_isVerticalTabBar( m_pData->eAlignment ) )
177         {
178             Size aTabBarSize =  ( aPreferredSize.Width() < i_rDeckPlayground.GetWidth() )
179                             ?   aPreferredSize
180                             :   m_pData->pTabBar->GetOptimalSize( WINDOWSIZE_MINIMUM );
181             aTabBarSize.Height() = i_rDeckPlayground.GetHeight();
182 
183             Rectangle aPanelRect( i_rDeckPlayground );
184             if ( m_pData->eAlignment == TABS_RIGHT )
185             {
186                 aPanelRect.Right() -= aTabBarSize.Width();
187                 Point aTabBarTopLeft( aPanelRect.TopRight() );
188                 aTabBarTopLeft.X() += 1;
189                 m_pData->pTabBar->SetPosSizePixel( aTabBarTopLeft, aTabBarSize );
190             }
191             else
192             {
193                 m_pData->pTabBar->SetPosSizePixel( aPanelRect.TopLeft(), aTabBarSize );
194                 aPanelRect.Left() += aTabBarSize.Width();
195             }
196             if ( aPanelRect.Left() >= aPanelRect.Right() )
197                 aPanelRect = Rectangle();
198 
199             return aPanelRect;
200         }
201 
202         Size aTabBarSize =  ( aPreferredSize.Height() < i_rDeckPlayground.GetHeight() )
203                         ?   aPreferredSize
204                         :   m_pData->pTabBar->GetOptimalSize( WINDOWSIZE_MINIMUM );
205         aTabBarSize.Width() = i_rDeckPlayground.GetWidth();
206 
207         Rectangle aPanelRect( i_rDeckPlayground );
208         if ( m_pData->eAlignment == TABS_TOP )
209         {
210             m_pData->pTabBar->SetPosSizePixel( aPanelRect.TopLeft(), aTabBarSize );
211             aPanelRect.Top() += aTabBarSize.Height();
212         }
213         else
214         {
215             aPanelRect.Bottom() -= aTabBarSize.Height();
216             Point aTabBarTopLeft( aPanelRect.BottomLeft() );
217             aTabBarTopLeft.Y() -= 1;
218             m_pData->pTabBar->SetPosSizePixel( aTabBarTopLeft, aTabBarSize );
219         }
220         if ( aPanelRect.Top() >= aPanelRect.Bottom() )
221             aPanelRect = Rectangle();
222 
223         return aPanelRect;
224     }
225 
226 	//--------------------------------------------------------------------
227     void TabDeckLayouter::Destroy()
228     {
229         m_pData->pTabBar.reset();
230     }
231 
232 	//--------------------------------------------------------------------
233     void TabDeckLayouter::SetFocusToPanelSelector()
234     {
235         if ( lcl_checkDisposed( *m_pData ) )
236             return;
237         m_pData->pTabBar->GrabFocus();
238     }
239 
240 	//--------------------------------------------------------------------
241     size_t TabDeckLayouter::GetAccessibleChildCount() const
242     {
243         if ( lcl_checkDisposed( *m_pData ) )
244             return 0;
245 
246         return 1;
247     }
248 
249     //--------------------------------------------------------------------
250     Reference< XAccessible > TabDeckLayouter::GetAccessibleChild( const size_t i_nChildIndex, const Reference< XAccessible >& i_rParentAccessible )
251     {
252         (void)i_nChildIndex;
253         (void)i_rParentAccessible;
254         if ( lcl_checkDisposed( *m_pData ) )
255             return NULL;
256 
257         return m_pData->pTabBar->GetAccessible( sal_True );
258     }
259 
260 //........................................................................
261 } // namespace svt
262 //........................................................................
263