1*b1cdbd2cSJim Jagielski /**************************************************************
2*b1cdbd2cSJim Jagielski  *
3*b1cdbd2cSJim Jagielski  * Licensed to the Apache Software Foundation (ASF) under one
4*b1cdbd2cSJim Jagielski  * or more contributor license agreements.  See the NOTICE file
5*b1cdbd2cSJim Jagielski  * distributed with this work for additional information
6*b1cdbd2cSJim Jagielski  * regarding copyright ownership.  The ASF licenses this file
7*b1cdbd2cSJim Jagielski  * to you under the Apache License, Version 2.0 (the
8*b1cdbd2cSJim Jagielski  * "License"); you may not use this file except in compliance
9*b1cdbd2cSJim Jagielski  * with the License.  You may obtain a copy of the License at
10*b1cdbd2cSJim Jagielski  *
11*b1cdbd2cSJim Jagielski  *   http://www.apache.org/licenses/LICENSE-2.0
12*b1cdbd2cSJim Jagielski  *
13*b1cdbd2cSJim Jagielski  * Unless required by applicable law or agreed to in writing,
14*b1cdbd2cSJim Jagielski  * software distributed under the License is distributed on an
15*b1cdbd2cSJim Jagielski  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*b1cdbd2cSJim Jagielski  * KIND, either express or implied.  See the License for the
17*b1cdbd2cSJim Jagielski  * specific language governing permissions and limitations
18*b1cdbd2cSJim Jagielski  * under the License.
19*b1cdbd2cSJim Jagielski  *
20*b1cdbd2cSJim Jagielski  *************************************************************/
21*b1cdbd2cSJim Jagielski 
22*b1cdbd2cSJim Jagielski 
23*b1cdbd2cSJim Jagielski 
24*b1cdbd2cSJim Jagielski // MARKER(update_precomp.py): autogen include statement, do not remove
25*b1cdbd2cSJim Jagielski #include "precompiled_vcl.hxx"
26*b1cdbd2cSJim Jagielski 
27*b1cdbd2cSJim Jagielski #include <tools/rcid.h>
28*b1cdbd2cSJim Jagielski 
29*b1cdbd2cSJim Jagielski #include <vcl/dockwin.hxx>
30*b1cdbd2cSJim Jagielski #include <vcl/taskpanelist.hxx>
31*b1cdbd2cSJim Jagielski 
32*b1cdbd2cSJim Jagielski #include <svdata.hxx>
33*b1cdbd2cSJim Jagielski 
34*b1cdbd2cSJim Jagielski #include <functional>
35*b1cdbd2cSJim Jagielski #include <algorithm>
36*b1cdbd2cSJim Jagielski 
37*b1cdbd2cSJim Jagielski // can't have static linkage because SUNPRO 5.2 complains
ImplTaskPaneListGetPos(const Window * w)38*b1cdbd2cSJim Jagielski Point ImplTaskPaneListGetPos( const Window *w )
39*b1cdbd2cSJim Jagielski {
40*b1cdbd2cSJim Jagielski     Point pos;
41*b1cdbd2cSJim Jagielski 	if( w->ImplIsDockingWindow() )
42*b1cdbd2cSJim Jagielski     {
43*b1cdbd2cSJim Jagielski         pos = ((DockingWindow*)w)->GetPosPixel();
44*b1cdbd2cSJim Jagielski         Window *pF = ((DockingWindow*)w)->GetFloatingWindow();
45*b1cdbd2cSJim Jagielski         if( pF )
46*b1cdbd2cSJim Jagielski             pos = pF->OutputToAbsoluteScreenPixel( pF->ScreenToOutputPixel( pos ) );
47*b1cdbd2cSJim Jagielski         else
48*b1cdbd2cSJim Jagielski             pos = w->OutputToAbsoluteScreenPixel( pos );
49*b1cdbd2cSJim Jagielski     }
50*b1cdbd2cSJim Jagielski     else
51*b1cdbd2cSJim Jagielski         pos = w->OutputToAbsoluteScreenPixel( w->GetPosPixel() );
52*b1cdbd2cSJim Jagielski 
53*b1cdbd2cSJim Jagielski     return pos;
54*b1cdbd2cSJim Jagielski }
55*b1cdbd2cSJim Jagielski 
56*b1cdbd2cSJim Jagielski // compares window pos left-to-right
57*b1cdbd2cSJim Jagielski struct LTRSort : public ::std::binary_function< const Window*, const Window*, bool >
58*b1cdbd2cSJim Jagielski {
operator ()LTRSort59*b1cdbd2cSJim Jagielski     bool operator()( const Window* w1, const Window* w2 ) const
60*b1cdbd2cSJim Jagielski     {
61*b1cdbd2cSJim Jagielski         Point pos1(ImplTaskPaneListGetPos( w1 ));
62*b1cdbd2cSJim Jagielski         Point pos2(ImplTaskPaneListGetPos( w2 ));
63*b1cdbd2cSJim Jagielski 
64*b1cdbd2cSJim Jagielski         if( pos1.X() == pos2.X() )
65*b1cdbd2cSJim Jagielski             return ( pos1.Y() < pos2.Y() );
66*b1cdbd2cSJim Jagielski         else
67*b1cdbd2cSJim Jagielski             return ( pos1.X() < pos2.X() );
68*b1cdbd2cSJim Jagielski     }
69*b1cdbd2cSJim Jagielski };
70*b1cdbd2cSJim Jagielski struct LTRSortBackward : public ::std::binary_function< const Window*, const Window*, bool >
71*b1cdbd2cSJim Jagielski {
operator ()LTRSortBackward72*b1cdbd2cSJim Jagielski     bool operator()( const Window* w2, const Window* w1 ) const
73*b1cdbd2cSJim Jagielski     {
74*b1cdbd2cSJim Jagielski         Point pos1(ImplTaskPaneListGetPos( w1 ));
75*b1cdbd2cSJim Jagielski         Point pos2(ImplTaskPaneListGetPos( w2 ));
76*b1cdbd2cSJim Jagielski 
77*b1cdbd2cSJim Jagielski         if( pos1.X() == pos2.X() )
78*b1cdbd2cSJim Jagielski             return ( pos1.Y() < pos2.Y() );
79*b1cdbd2cSJim Jagielski         else
80*b1cdbd2cSJim Jagielski             return ( pos1.X() < pos2.X() );
81*b1cdbd2cSJim Jagielski     }
82*b1cdbd2cSJim Jagielski };
83*b1cdbd2cSJim Jagielski 
84*b1cdbd2cSJim Jagielski // --------------------------------------------------
85*b1cdbd2cSJim Jagielski 
ImplTaskPaneListGrabFocus(Window * pWindow)86*b1cdbd2cSJim Jagielski static void ImplTaskPaneListGrabFocus( Window *pWindow )
87*b1cdbd2cSJim Jagielski {
88*b1cdbd2cSJim Jagielski 	// put focus in child of floating windows which is typically a toolbar
89*b1cdbd2cSJim Jagielski 	// that can deal with the focus
90*b1cdbd2cSJim Jagielski 	if( pWindow->ImplIsFloatingWindow() && pWindow->GetWindow( WINDOW_FIRSTCHILD ) )
91*b1cdbd2cSJim Jagielski 		pWindow = pWindow->GetWindow( WINDOW_FIRSTCHILD );
92*b1cdbd2cSJim Jagielski 	pWindow->GrabFocus();
93*b1cdbd2cSJim Jagielski }
94*b1cdbd2cSJim Jagielski 
95*b1cdbd2cSJim Jagielski // --------------------------------------------------
96*b1cdbd2cSJim Jagielski 
TaskPaneList()97*b1cdbd2cSJim Jagielski TaskPaneList::TaskPaneList()
98*b1cdbd2cSJim Jagielski {
99*b1cdbd2cSJim Jagielski }
100*b1cdbd2cSJim Jagielski 
~TaskPaneList()101*b1cdbd2cSJim Jagielski TaskPaneList::~TaskPaneList()
102*b1cdbd2cSJim Jagielski {
103*b1cdbd2cSJim Jagielski }
104*b1cdbd2cSJim Jagielski 
105*b1cdbd2cSJim Jagielski // --------------------------------------------------
106*b1cdbd2cSJim Jagielski 
AddWindow(Window * pWindow)107*b1cdbd2cSJim Jagielski void TaskPaneList::AddWindow( Window *pWindow )
108*b1cdbd2cSJim Jagielski {
109*b1cdbd2cSJim Jagielski #if OSL_DEBUG_LEVEL > 0
110*b1cdbd2cSJim Jagielski     bool bDockingWindow=false;
111*b1cdbd2cSJim Jagielski     bool bToolbox=false;
112*b1cdbd2cSJim Jagielski     bool bDialog=false;
113*b1cdbd2cSJim Jagielski     bool bUnknown=false;
114*b1cdbd2cSJim Jagielski #endif
115*b1cdbd2cSJim Jagielski 
116*b1cdbd2cSJim Jagielski     if( pWindow )
117*b1cdbd2cSJim Jagielski     {
118*b1cdbd2cSJim Jagielski #if OSL_DEBUG_LEVEL > 0
119*b1cdbd2cSJim Jagielski         if( pWindow->GetType() == RSC_DOCKINGWINDOW )
120*b1cdbd2cSJim Jagielski             bDockingWindow = true;
121*b1cdbd2cSJim Jagielski         else if( pWindow->GetType() == RSC_TOOLBOX )
122*b1cdbd2cSJim Jagielski             bToolbox = true;
123*b1cdbd2cSJim Jagielski         else if( pWindow->IsDialog() )
124*b1cdbd2cSJim Jagielski             bDialog = true;
125*b1cdbd2cSJim Jagielski         else
126*b1cdbd2cSJim Jagielski             bUnknown = true;
127*b1cdbd2cSJim Jagielski #endif
128*b1cdbd2cSJim Jagielski 
129*b1cdbd2cSJim Jagielski         ::std::vector< Window* >::iterator insertionPos = mTaskPanes.end();
130*b1cdbd2cSJim Jagielski         for ( ::std::vector< Window* >::iterator p = mTaskPanes.begin();
131*b1cdbd2cSJim Jagielski               p != mTaskPanes.end();
132*b1cdbd2cSJim Jagielski               ++p
133*b1cdbd2cSJim Jagielski             )
134*b1cdbd2cSJim Jagielski         {
135*b1cdbd2cSJim Jagielski             if ( *p == pWindow )
136*b1cdbd2cSJim Jagielski                 // avoid duplicates
137*b1cdbd2cSJim Jagielski                 return;
138*b1cdbd2cSJim Jagielski 
139*b1cdbd2cSJim Jagielski             // If the new window is the child of an existing pane window, or vice versa,
140*b1cdbd2cSJim Jagielski             // ensure that in our pane list, *first* the child window appears, *then*
141*b1cdbd2cSJim Jagielski             // the ancestor window.
142*b1cdbd2cSJim Jagielski             // This is necessary for HandleKeyEvent: There, the list is traveled from the
143*b1cdbd2cSJim Jagielski             // beginning, until the first window is found which has the ChildPathFocus. Now
144*b1cdbd2cSJim Jagielski             // if this would be the ancestor window of another pane window, this would fudge
145*b1cdbd2cSJim Jagielski             // the result
146*b1cdbd2cSJim Jagielski             // 2004-09-27 - fs@openoffice.org, while fixing #i33573#, which included replacing
147*b1cdbd2cSJim Jagielski             // the original fix for #98916# with this one here.
148*b1cdbd2cSJim Jagielski             if ( pWindow->IsWindowOrChild( *p ) )
149*b1cdbd2cSJim Jagielski             {
150*b1cdbd2cSJim Jagielski                 insertionPos = p + 1;
151*b1cdbd2cSJim Jagielski                 break;
152*b1cdbd2cSJim Jagielski             }
153*b1cdbd2cSJim Jagielski             if ( (*p)->IsWindowOrChild( pWindow ) )
154*b1cdbd2cSJim Jagielski             {
155*b1cdbd2cSJim Jagielski                 insertionPos = p;
156*b1cdbd2cSJim Jagielski                 break;
157*b1cdbd2cSJim Jagielski             }
158*b1cdbd2cSJim Jagielski         }
159*b1cdbd2cSJim Jagielski 
160*b1cdbd2cSJim Jagielski         mTaskPanes.insert( insertionPos, pWindow );
161*b1cdbd2cSJim Jagielski         pWindow->ImplIsInTaskPaneList( sal_True );
162*b1cdbd2cSJim Jagielski     }
163*b1cdbd2cSJim Jagielski }
164*b1cdbd2cSJim Jagielski 
165*b1cdbd2cSJim Jagielski // --------------------------------------------------
166*b1cdbd2cSJim Jagielski 
RemoveWindow(Window * pWindow)167*b1cdbd2cSJim Jagielski void TaskPaneList::RemoveWindow( Window *pWindow )
168*b1cdbd2cSJim Jagielski {
169*b1cdbd2cSJim Jagielski 	::std::vector< Window* >::iterator p;
170*b1cdbd2cSJim Jagielski     p = ::std::find( mTaskPanes.begin(), mTaskPanes.end(), pWindow );
171*b1cdbd2cSJim Jagielski     if( p != mTaskPanes.end() )
172*b1cdbd2cSJim Jagielski     {
173*b1cdbd2cSJim Jagielski 	    mTaskPanes.erase( p );
174*b1cdbd2cSJim Jagielski         pWindow->ImplIsInTaskPaneList( sal_False );
175*b1cdbd2cSJim Jagielski     }
176*b1cdbd2cSJim Jagielski }
177*b1cdbd2cSJim Jagielski 
178*b1cdbd2cSJim Jagielski // --------------------------------------------------
179*b1cdbd2cSJim Jagielski 
IsInList(Window * pWindow)180*b1cdbd2cSJim Jagielski sal_Bool TaskPaneList::IsInList( Window *pWindow )
181*b1cdbd2cSJim Jagielski {
182*b1cdbd2cSJim Jagielski 	::std::vector< Window* >::iterator p;
183*b1cdbd2cSJim Jagielski     p = ::std::find( mTaskPanes.begin(), mTaskPanes.end(), pWindow );
184*b1cdbd2cSJim Jagielski     if( p != mTaskPanes.end() )
185*b1cdbd2cSJim Jagielski 	    return sal_True;
186*b1cdbd2cSJim Jagielski     else
187*b1cdbd2cSJim Jagielski         return sal_False;
188*b1cdbd2cSJim Jagielski }
189*b1cdbd2cSJim Jagielski 
190*b1cdbd2cSJim Jagielski // --------------------------------------------------
191*b1cdbd2cSJim Jagielski 
HandleKeyEvent(KeyEvent aKeyEvent)192*b1cdbd2cSJim Jagielski sal_Bool TaskPaneList::HandleKeyEvent( KeyEvent aKeyEvent )
193*b1cdbd2cSJim Jagielski {
194*b1cdbd2cSJim Jagielski 
195*b1cdbd2cSJim Jagielski     // F6 cycles through everything and works always
196*b1cdbd2cSJim Jagielski 
197*b1cdbd2cSJim Jagielski     // MAV, #i104204#
198*b1cdbd2cSJim Jagielski     // The old design was the following one:
199*b1cdbd2cSJim Jagielski     // < Ctrl-TAB cycles through Menubar, Toolbars and Floatingwindows only and is
200*b1cdbd2cSJim Jagielski     // < only active if one of those items has the focus
201*b1cdbd2cSJim Jagielski     //
202*b1cdbd2cSJim Jagielski     // Since the design of Ctrl-Tab looks to be inconsistent ( non-modal dialogs are not reachable
203*b1cdbd2cSJim Jagielski     // and the shortcut conflicts with tab-control shortcut ), it is no more supported
204*b1cdbd2cSJim Jagielski     sal_Bool bSplitterOnly = sal_False;
205*b1cdbd2cSJim Jagielski     sal_Bool bFocusInList = sal_False;
206*b1cdbd2cSJim Jagielski 	KeyCode aKeyCode = aKeyEvent.GetKeyCode();
207*b1cdbd2cSJim Jagielski     sal_Bool bForward = !aKeyCode.IsShift();
208*b1cdbd2cSJim Jagielski 	if( aKeyCode.GetCode() == KEY_F6 && ! aKeyCode.IsMod2() ) // F6
209*b1cdbd2cSJim Jagielski 	{
210*b1cdbd2cSJim Jagielski         bSplitterOnly = aKeyCode.IsMod1() && aKeyCode.IsShift();
211*b1cdbd2cSJim Jagielski 
212*b1cdbd2cSJim Jagielski 		// is the focus in the list ?
213*b1cdbd2cSJim Jagielski 		::std::vector< Window* >::iterator p = mTaskPanes.begin();
214*b1cdbd2cSJim Jagielski 		while( p != mTaskPanes.end() )
215*b1cdbd2cSJim Jagielski         {
216*b1cdbd2cSJim Jagielski             Window *pWin = *p;
217*b1cdbd2cSJim Jagielski 			if( pWin->HasChildPathFocus( sal_True ) )
218*b1cdbd2cSJim Jagielski 			{
219*b1cdbd2cSJim Jagielski                 bFocusInList = sal_True;
220*b1cdbd2cSJim Jagielski 
221*b1cdbd2cSJim Jagielski                 // Ctrl-F6 goes directly to the document
222*b1cdbd2cSJim Jagielski                 if( !pWin->IsDialog() && aKeyCode.IsMod1() && !aKeyCode.IsShift() )
223*b1cdbd2cSJim Jagielski                 {
224*b1cdbd2cSJim Jagielski 		            pWin->GrabFocusToDocument();
225*b1cdbd2cSJim Jagielski 		            return sal_True;
226*b1cdbd2cSJim Jagielski                 }
227*b1cdbd2cSJim Jagielski 
228*b1cdbd2cSJim Jagielski 				// activate next task pane
229*b1cdbd2cSJim Jagielski                 Window *pNextWin = NULL;
230*b1cdbd2cSJim Jagielski 
231*b1cdbd2cSJim Jagielski                 if( bSplitterOnly )
232*b1cdbd2cSJim Jagielski                     pNextWin = FindNextSplitter( *p, sal_True );
233*b1cdbd2cSJim Jagielski                 else
234*b1cdbd2cSJim Jagielski                     pNextWin = FindNextFloat( *p, bForward );
235*b1cdbd2cSJim Jagielski 
236*b1cdbd2cSJim Jagielski 				if( pNextWin != pWin )
237*b1cdbd2cSJim Jagielski 				{
238*b1cdbd2cSJim Jagielski 					ImplGetSVData()->maWinData.mbNoSaveFocus = sal_True;
239*b1cdbd2cSJim Jagielski 					ImplTaskPaneListGrabFocus( pNextWin );
240*b1cdbd2cSJim Jagielski 					ImplGetSVData()->maWinData.mbNoSaveFocus = sal_False;
241*b1cdbd2cSJim Jagielski 				}
242*b1cdbd2cSJim Jagielski                 else
243*b1cdbd2cSJim Jagielski                 {
244*b1cdbd2cSJim Jagielski                     // forward key if no splitter found
245*b1cdbd2cSJim Jagielski                     if( bSplitterOnly )
246*b1cdbd2cSJim Jagielski                         return sal_False;
247*b1cdbd2cSJim Jagielski 
248*b1cdbd2cSJim Jagielski                     // we did not find another taskpane, so
249*b1cdbd2cSJim Jagielski                     // put focus back into document
250*b1cdbd2cSJim Jagielski                     pWin->GrabFocusToDocument();
251*b1cdbd2cSJim Jagielski                 }
252*b1cdbd2cSJim Jagielski 
253*b1cdbd2cSJim Jagielski 				return sal_True;
254*b1cdbd2cSJim Jagielski 			}
255*b1cdbd2cSJim Jagielski 			else
256*b1cdbd2cSJim Jagielski 				p++;
257*b1cdbd2cSJim Jagielski         }
258*b1cdbd2cSJim Jagielski 
259*b1cdbd2cSJim Jagielski         // the focus is not in the list: activate first float if F6 was pressed
260*b1cdbd2cSJim Jagielski         if( !bFocusInList )
261*b1cdbd2cSJim Jagielski         {
262*b1cdbd2cSJim Jagielski             Window *pWin;
263*b1cdbd2cSJim Jagielski             if( bSplitterOnly )
264*b1cdbd2cSJim Jagielski                 pWin = FindNextSplitter( NULL, sal_True );
265*b1cdbd2cSJim Jagielski             else
266*b1cdbd2cSJim Jagielski                 pWin = FindNextFloat( NULL, bForward );
267*b1cdbd2cSJim Jagielski             if( pWin )
268*b1cdbd2cSJim Jagielski             {
269*b1cdbd2cSJim Jagielski 				ImplTaskPaneListGrabFocus( pWin );
270*b1cdbd2cSJim Jagielski                 return sal_True;
271*b1cdbd2cSJim Jagielski             }
272*b1cdbd2cSJim Jagielski         }
273*b1cdbd2cSJim Jagielski 	}
274*b1cdbd2cSJim Jagielski 
275*b1cdbd2cSJim Jagielski 	return sal_False;
276*b1cdbd2cSJim Jagielski }
277*b1cdbd2cSJim Jagielski 
278*b1cdbd2cSJim Jagielski // --------------------------------------------------
279*b1cdbd2cSJim Jagielski 
280*b1cdbd2cSJim Jagielski //  returns next valid pane
FindNextPane(Window * pWindow,sal_Bool bForward)281*b1cdbd2cSJim Jagielski Window* TaskPaneList::FindNextPane( Window *pWindow, sal_Bool bForward )
282*b1cdbd2cSJim Jagielski {
283*b1cdbd2cSJim Jagielski     if( bForward )
284*b1cdbd2cSJim Jagielski         ::std::stable_sort( mTaskPanes.begin(), mTaskPanes.end(), LTRSort() );
285*b1cdbd2cSJim Jagielski     else
286*b1cdbd2cSJim Jagielski         ::std::stable_sort( mTaskPanes.begin(), mTaskPanes.end(), LTRSortBackward() );
287*b1cdbd2cSJim Jagielski 
288*b1cdbd2cSJim Jagielski 	::std::vector< Window* >::iterator p = mTaskPanes.begin();
289*b1cdbd2cSJim Jagielski 	while( p != mTaskPanes.end() )
290*b1cdbd2cSJim Jagielski     {
291*b1cdbd2cSJim Jagielski         if( *p == pWindow )
292*b1cdbd2cSJim Jagielski         {
293*b1cdbd2cSJim Jagielski             unsigned n = mTaskPanes.size();
294*b1cdbd2cSJim Jagielski             while( --n )
295*b1cdbd2cSJim Jagielski             {
296*b1cdbd2cSJim Jagielski 		        if( ++p == mTaskPanes.end() )
297*b1cdbd2cSJim Jagielski 			        p = mTaskPanes.begin();
298*b1cdbd2cSJim Jagielski                 if( (*p)->IsReallyVisible() && !(*p)->IsDialog() && !(*p)->ImplIsSplitter() )
299*b1cdbd2cSJim Jagielski 				{
300*b1cdbd2cSJim Jagielski 					pWindow = *p;
301*b1cdbd2cSJim Jagielski 					break;
302*b1cdbd2cSJim Jagielski 				}
303*b1cdbd2cSJim Jagielski             }
304*b1cdbd2cSJim Jagielski             break;
305*b1cdbd2cSJim Jagielski         }
306*b1cdbd2cSJim Jagielski         else
307*b1cdbd2cSJim Jagielski             ++p;
308*b1cdbd2cSJim Jagielski     }
309*b1cdbd2cSJim Jagielski 
310*b1cdbd2cSJim Jagielski 	return pWindow;
311*b1cdbd2cSJim Jagielski }
312*b1cdbd2cSJim Jagielski 
313*b1cdbd2cSJim Jagielski // --------------------------------------------------
314*b1cdbd2cSJim Jagielski 
315*b1cdbd2cSJim Jagielski // returns next splitter
FindNextSplitter(Window * pWindow,sal_Bool bForward)316*b1cdbd2cSJim Jagielski Window* TaskPaneList::FindNextSplitter( Window *pWindow, sal_Bool bForward )
317*b1cdbd2cSJim Jagielski {
318*b1cdbd2cSJim Jagielski     if( bForward )
319*b1cdbd2cSJim Jagielski         ::std::stable_sort( mTaskPanes.begin(), mTaskPanes.end(), LTRSort() );
320*b1cdbd2cSJim Jagielski     else
321*b1cdbd2cSJim Jagielski         ::std::stable_sort( mTaskPanes.begin(), mTaskPanes.end(), LTRSortBackward() );
322*b1cdbd2cSJim Jagielski 
323*b1cdbd2cSJim Jagielski 	::std::vector< Window* >::iterator p = mTaskPanes.begin();
324*b1cdbd2cSJim Jagielski 	while( p != mTaskPanes.end() )
325*b1cdbd2cSJim Jagielski     {
326*b1cdbd2cSJim Jagielski         if( !pWindow || *p == pWindow )
327*b1cdbd2cSJim Jagielski         {
328*b1cdbd2cSJim Jagielski             unsigned n = mTaskPanes.size();
329*b1cdbd2cSJim Jagielski             while( --n )
330*b1cdbd2cSJim Jagielski             {
331*b1cdbd2cSJim Jagielski                 if( pWindow )   // increment before test
332*b1cdbd2cSJim Jagielski                     ++p;
333*b1cdbd2cSJim Jagielski 		        if( p == mTaskPanes.end() )
334*b1cdbd2cSJim Jagielski 			        p = mTaskPanes.begin();
335*b1cdbd2cSJim Jagielski                 if( (*p)->ImplIsSplitter() && (*p)->IsReallyVisible() && !(*p)->IsDialog() && (*p)->GetParent()->HasChildPathFocus() )
336*b1cdbd2cSJim Jagielski 				{
337*b1cdbd2cSJim Jagielski 					pWindow = *p;
338*b1cdbd2cSJim Jagielski 					break;
339*b1cdbd2cSJim Jagielski 				}
340*b1cdbd2cSJim Jagielski                 if( !pWindow )  // increment after test, otherwise first element is skipped
341*b1cdbd2cSJim Jagielski                     ++p;
342*b1cdbd2cSJim Jagielski             }
343*b1cdbd2cSJim Jagielski             break;
344*b1cdbd2cSJim Jagielski         }
345*b1cdbd2cSJim Jagielski         else
346*b1cdbd2cSJim Jagielski             ++p;
347*b1cdbd2cSJim Jagielski     }
348*b1cdbd2cSJim Jagielski 
349*b1cdbd2cSJim Jagielski 	return pWindow;
350*b1cdbd2cSJim Jagielski }
351*b1cdbd2cSJim Jagielski 
352*b1cdbd2cSJim Jagielski // --------------------------------------------------
353*b1cdbd2cSJim Jagielski 
354*b1cdbd2cSJim Jagielski // returns first valid item (regardless of type) if pWindow==0, otherwise returns next valid float
FindNextFloat(Window * pWindow,sal_Bool bForward)355*b1cdbd2cSJim Jagielski Window* TaskPaneList::FindNextFloat( Window *pWindow, sal_Bool bForward )
356*b1cdbd2cSJim Jagielski {
357*b1cdbd2cSJim Jagielski     if( bForward )
358*b1cdbd2cSJim Jagielski         ::std::stable_sort( mTaskPanes.begin(), mTaskPanes.end(), LTRSort() );
359*b1cdbd2cSJim Jagielski     else
360*b1cdbd2cSJim Jagielski         ::std::stable_sort( mTaskPanes.begin(), mTaskPanes.end(), LTRSortBackward() );
361*b1cdbd2cSJim Jagielski 
362*b1cdbd2cSJim Jagielski 	::std::vector< Window* >::iterator p = mTaskPanes.begin();
363*b1cdbd2cSJim Jagielski 	while( p != mTaskPanes.end() )
364*b1cdbd2cSJim Jagielski     {
365*b1cdbd2cSJim Jagielski         if( !pWindow || *p == pWindow )
366*b1cdbd2cSJim Jagielski         {
367*b1cdbd2cSJim Jagielski             while( p != mTaskPanes.end() )
368*b1cdbd2cSJim Jagielski             {
369*b1cdbd2cSJim Jagielski                 if( pWindow )   // increment before test
370*b1cdbd2cSJim Jagielski                     ++p;
371*b1cdbd2cSJim Jagielski 		        if( p == mTaskPanes.end() )
372*b1cdbd2cSJim Jagielski 			        break; // do not wrap, send focus back to document at end of list
373*b1cdbd2cSJim Jagielski                 /* #i83908# do not use the menubar if it is native and invisible
374*b1cdbd2cSJim Jagielski                    this relies on MenuBar::ImplCreate setting the height of the menubar
375*b1cdbd2cSJim Jagielski                    to 0 in this case
376*b1cdbd2cSJim Jagielski                 */
377*b1cdbd2cSJim Jagielski                 if( (*p)->IsReallyVisible() && !(*p)->ImplIsSplitter() &&
378*b1cdbd2cSJim Jagielski                     ( (*p)->GetType() != WINDOW_MENUBARWINDOW || (*p)->GetSizePixel().Height() > 0 )
379*b1cdbd2cSJim Jagielski                     )
380*b1cdbd2cSJim Jagielski 				{
381*b1cdbd2cSJim Jagielski                     pWindow = *p;
382*b1cdbd2cSJim Jagielski 					break;
383*b1cdbd2cSJim Jagielski 				}
384*b1cdbd2cSJim Jagielski                 if( !pWindow )  // increment after test, otherwise first element is skipped
385*b1cdbd2cSJim Jagielski                     ++p;
386*b1cdbd2cSJim Jagielski             }
387*b1cdbd2cSJim Jagielski             break;
388*b1cdbd2cSJim Jagielski         }
389*b1cdbd2cSJim Jagielski         else
390*b1cdbd2cSJim Jagielski             ++p;
391*b1cdbd2cSJim Jagielski     }
392*b1cdbd2cSJim Jagielski 
393*b1cdbd2cSJim Jagielski 	return pWindow;
394*b1cdbd2cSJim Jagielski }
395*b1cdbd2cSJim Jagielski 
396*b1cdbd2cSJim Jagielski // --------------------------------------------------
397*b1cdbd2cSJim Jagielski 
398