xref: /aoo41x/main/vcl/source/window/dlgctrl.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_vcl.hxx"
30 
31 #include <tools/debug.hxx>
32 
33 #include <svdata.hxx>
34 #include <window.h>
35 
36 #include <vcl/event.hxx>
37 #include <vcl/svapp.hxx>
38 #include <vcl/tabpage.hxx>
39 #include <vcl/tabctrl.hxx>
40 #include <vcl/tabdlg.hxx>
41 #include <vcl/button.hxx>
42 
43 #include <vcl/unohelp.hxx>
44 #include <com/sun/star/i18n/XCharacterClassification.hpp>
45 
46 using namespace ::com::sun::star;
47 
48 // =======================================================================
49 
50 static sal_Bool ImplHasIndirectTabParent( Window* pWindow )
51 {
52     // The window has inderect tab parent if it is included in tab hierarchy
53     // of the indirect parent window
54 
55     return ( pWindow && pWindow->GetParent()
56           && ( pWindow->GetParent()->ImplGetWindow()->GetStyle() & WB_CHILDDLGCTRL ) );
57 }
58 
59 // -----------------------------------------------------------------------
60 
61 static Window* ImplGetTopParentOfTabHierarchy( Window* pParent )
62 {
63     // The method allows to find the most close parent containing all the
64     // window from the current tab-hierarchy
65     // The direct parent should be provided as a parameter here
66 
67     Window* pResult = pParent;
68 
69     if ( pResult )
70     {
71         while ( pResult->GetParent() && ( pResult->ImplGetWindow()->GetStyle() & WB_CHILDDLGCTRL ) )
72             pResult = pResult->GetParent();
73     }
74 
75     return pResult;
76 }
77 
78 // -----------------------------------------------------------------------
79 
80 static Window* ImplGetSubChildWindow( Window* pParent, sal_uInt16 n, sal_uInt16& nIndex )
81 {
82     Window*     pTabPage = NULL;
83     Window*     pFoundWindow = NULL;
84 
85     Window*     pWindow = pParent->GetWindow( WINDOW_FIRSTCHILD );
86     Window*     pNextWindow = pWindow;
87     while ( pWindow )
88     {
89         pWindow = pWindow->ImplGetWindow();
90 
91         // Unsichtbare und disablte Fenster werden uebersprungen
92         if ( pTabPage || pWindow->IsVisible() )
93         {
94             // Wenn das letzte Control ein TabControl war, wird von
95             // diesem die TabPage genommen
96             if ( pTabPage )
97             {
98                 pFoundWindow = ImplGetSubChildWindow( pTabPage, n, nIndex );
99                 pTabPage = NULL;
100             }
101             else
102             {
103                 pFoundWindow = pWindow;
104 
105                 // Bei einem TabControl sich die aktuelle TabPage merken,
106                 // damit diese dann genommen wird
107                 if ( pWindow->GetType() == WINDOW_TABCONTROL )
108                 {
109                     TabControl* pTabControl = ((TabControl*)pWindow);
110                     // Feststellen, ob TabPage Child vom TabControl ist
111                     // und auch noch existiert (deshalb durch Vergleich,
112                     // indem alle ChildFenster getestet werden). Denn es
113                     // kann sein, das TabPages schon in einem Dialog-Dtor
114                     // zerstoert wurden, obwohl das TabControl noch
115                     // existiert.
116                     TabPage* pTempTabPage = pTabControl->GetTabPage( pTabControl->GetCurPageId() );
117                     if ( pTempTabPage )
118                     {
119                         Window* pTempWindow = pTabControl->GetWindow( WINDOW_FIRSTCHILD );
120                         while ( pTempWindow )
121                         {
122                             if ( pTempWindow->ImplGetWindow() == pTempTabPage )
123                             {
124                                 pTabPage = pTempTabPage;
125                                 break;
126                             }
127                             pTempWindow = pTempWindow->GetWindow( WINDOW_NEXT );
128                         }
129                     }
130                 }
131                 else if ( ( pWindow->GetStyle() & WB_DIALOGCONTROL )
132                        || ( pWindow->GetStyle() & WB_CHILDDLGCTRL ) )
133                     pFoundWindow = ImplGetSubChildWindow( pWindow, n, nIndex );
134             }
135 
136             if ( n == nIndex )
137                 return pFoundWindow;
138             nIndex++;
139         }
140 
141         if ( pTabPage )
142             pWindow = pTabPage;
143         else
144         {
145             pWindow = pNextWindow->GetWindow( WINDOW_NEXT );
146             pNextWindow = pWindow;
147         }
148     }
149 
150     nIndex--;
151     return pFoundWindow;
152 }
153 
154 // -----------------------------------------------------------------------
155 
156 static Window* ImplGetChildWindow( Window* pParent, sal_uInt16 n, sal_uInt16& nIndex, sal_Bool bTestEnable )
157 {
158     pParent = ImplGetTopParentOfTabHierarchy( pParent );
159 
160     nIndex = 0;
161     Window* pWindow = ImplGetSubChildWindow( pParent, n, nIndex );
162     if ( bTestEnable )
163     {
164         sal_uInt16 n2 = nIndex;
165         while ( pWindow && (!pWindow->IsEnabled() || !pWindow->IsInputEnabled()) )
166         {
167             n2 = nIndex+1;
168             nIndex = 0;
169             pWindow = ImplGetSubChildWindow( pParent, n2, nIndex );
170             if ( nIndex < n2 )
171                 break;
172         }
173 
174         if ( (nIndex < n2) && n )
175         {
176             do
177             {
178                 n--;
179                 nIndex = 0;
180                 pWindow = ImplGetSubChildWindow( pParent, n, nIndex );
181             }
182             while ( pWindow && n && (!pWindow->IsEnabled() || !pWindow->IsInputEnabled()) );
183         }
184     }
185     return pWindow;
186 }
187 
188 // -----------------------------------------------------------------------
189 
190 static Window* ImplGetNextWindow( Window* pParent, sal_uInt16 n, sal_uInt16& nIndex, sal_Bool bTestEnable )
191 {
192     Window* pWindow = ImplGetChildWindow( pParent, n+1, nIndex, bTestEnable );
193     if ( n == nIndex )
194     {
195         n = 0;
196         pWindow = ImplGetChildWindow( pParent, n, nIndex, bTestEnable );
197     }
198     return pWindow;
199 }
200 
201 // -----------------------------------------------------------------------
202 
203 Window* Window::ImplGetDlgWindow( sal_uInt16 nIndex, sal_uInt16 nType,
204                                   sal_uInt16 nFormStart, sal_uInt16 nFormEnd,
205                                   sal_uInt16* pIndex )
206 {
207     DBG_ASSERT( (nIndex >= nFormStart) && (nIndex <= nFormEnd),
208                 "Window::ImplGetDlgWindow() - nIndex not in Form" );
209 
210     Window* pWindow = NULL;
211     sal_uInt16  i;
212     sal_uInt16  nTemp;
213     sal_uInt16  nStartIndex;
214 
215     if ( nType == DLGWINDOW_PREV )
216     {
217         i = nIndex;
218         do
219         {
220             if ( i > nFormStart )
221                 i--;
222             else
223                 i = nFormEnd;
224             pWindow = ImplGetChildWindow( this, i, nTemp, sal_True );
225             if ( !pWindow )
226                 break;
227             if ( (i == nTemp) && (pWindow->GetStyle() & WB_TABSTOP) )
228                 break;
229         }
230         while ( i != nIndex );
231     }
232     else
233     {
234         i = nIndex;
235         pWindow = ImplGetChildWindow( this, i, i, (nType == DLGWINDOW_FIRST) );
236         if ( pWindow )
237         {
238             nStartIndex = i;
239 
240             if ( nType == DLGWINDOW_NEXT )
241             {
242                 if ( i < nFormEnd )
243                 {
244                     pWindow = ImplGetNextWindow( this, i, i, sal_True );
245                     if ( (i > nFormEnd) || (i < nFormStart) )
246                         pWindow = ImplGetChildWindow( this, nFormStart, i, sal_True );
247                 }
248                 else
249                     pWindow = ImplGetChildWindow( this, nFormStart, i, sal_True );
250             }
251 
252             if ( i <= nFormEnd )
253             {
254                 // 2ten Index mitfuehren, falls alle Controls disablte
255                 sal_uInt16 nStartIndex2 = i;
256                 sal_uInt16 nOldIndex = i+1;
257 
258                 do
259                 {
260                     if ( pWindow->GetStyle() & WB_TABSTOP )
261                         break;
262                     if( i == nOldIndex ) // only disabled controls ?
263                     {
264                         i = nStartIndex2;
265                         break;
266                     }
267                     nOldIndex = i;
268                     if ( (i > nFormEnd) || (i < nFormStart) )
269                         pWindow = ImplGetChildWindow( this, nFormStart, i, sal_True );
270                     else
271                         pWindow = ImplGetNextWindow( this, i, i, sal_True );
272                 }
273                 while ( (i != nStartIndex) && (i != nStartIndex2) );
274 
275                 if ( (i == nStartIndex2) &&
276                      (!(pWindow->GetStyle() & WB_TABSTOP) || !pWindow->IsEnabled()) )
277                     i = nStartIndex;
278             }
279         }
280 
281         if ( nType == DLGWINDOW_FIRST )
282         {
283             if ( pWindow )
284             {
285                 if ( pWindow->GetType() == WINDOW_TABCONTROL )
286                 {
287                     Window* pNextWindow = ImplGetDlgWindow( i, DLGWINDOW_NEXT );
288                     if ( pNextWindow )
289                     {
290                         if ( pWindow->IsChild( pNextWindow ) )
291                             pWindow = pNextWindow;
292                     }
293                 }
294 
295                 if ( !(pWindow->GetStyle() & WB_TABSTOP) )
296                     pWindow = NULL;
297             }
298         }
299     }
300 
301     if ( pIndex )
302         *pIndex = i;
303 
304     return pWindow;
305 }
306 
307 // -----------------------------------------------------------------------
308 
309 static Window* ImplFindDlgCtrlWindow( Window* pParent, Window* pWindow, sal_uInt16& rIndex,
310                                       sal_uInt16& rFormStart, sal_uInt16& rFormEnd )
311 {
312     Window* pSWindow;
313     Window* pSecondWindow = NULL;
314     Window* pTempWindow = NULL;
315     sal_uInt16  i;
316     sal_uInt16  nSecond_i = 0;
317     sal_uInt16  nFormStart = 0;
318     sal_uInt16  nSecondFormStart = 0;
319     sal_uInt16  nFormEnd;
320 
321     // Focus-Fenster in der Child-Liste suchen
322     Window* pFirstChildWindow = pSWindow = ImplGetChildWindow( pParent, 0, i, sal_False );
323 
324     if( pWindow == NULL )
325         pWindow = pSWindow;
326 
327     while ( pSWindow )
328     {
329         // the DialogControlStart mark is only accepted for the direct children
330         if ( !ImplHasIndirectTabParent( pSWindow )
331           && pSWindow->ImplGetWindow()->IsDialogControlStart() )
332             nFormStart = i;
333 
334         // SecondWindow wegen zusammengesetzten Controls wie
335         // ComboBoxen und Feldern
336         if ( pSWindow->ImplIsWindowOrChild( pWindow ) )
337         {
338             pSecondWindow = pSWindow;
339             nSecond_i = i;
340             nSecondFormStart = nFormStart;
341             if ( pSWindow == pWindow )
342                 break;
343         }
344 
345         pSWindow = ImplGetNextWindow( pParent, i, i, sal_False );
346         if ( !i )
347             pSWindow = NULL;
348     }
349 
350     if ( !pSWindow )
351     {
352         // Fenster nicht gefunden, dann koennen wir auch keine
353         // Steuerung uebernehmen
354         if ( !pSecondWindow )
355             return NULL;
356         else
357         {
358             pSWindow = pSecondWindow;
359             i = nSecond_i;
360             nFormStart = nSecondFormStart;
361         }
362     }
363 
364     // Start-Daten setzen
365     rIndex = i;
366     rFormStart = nFormStart;
367 
368     // Formularende suchen
369     nFormEnd = nFormStart;
370     pTempWindow = pSWindow;
371     sal_Int32 nIteration = 0;
372     do
373     {
374         nFormEnd = i;
375         pTempWindow = ImplGetNextWindow( pParent, i, i, sal_False );
376 
377         // the DialogControlStart mark is only accepted for the direct children
378         if ( !i
379           || ( pTempWindow && !ImplHasIndirectTabParent( pTempWindow )
380                && pTempWindow->ImplGetWindow()->IsDialogControlStart() ) )
381             break;
382 
383         if ( pTempWindow && pTempWindow == pFirstChildWindow )
384         {
385             // It is possible to go through the begin of hierarchy once
386             // while looking for DialogControlStart mark.
387             // If it happens second time, it looks like an endless loop,
388             // that should be impossible, but just for the case...
389             nIteration++;
390             if ( nIteration >= 2 )
391             {
392                 // this is an unexpected scenario
393                 DBG_ASSERT( sal_False, "It seems to be an endless loop!" );
394                 rFormStart = 0;
395                 break;
396             }
397         }
398     }
399     while ( pTempWindow );
400     rFormEnd = nFormEnd;
401 
402     return pSWindow;
403 }
404 
405 // -----------------------------------------------------------------------
406 
407 static Window* ImplFindAccelWindow( Window* pParent, sal_uInt16& rIndex, xub_Unicode cCharCode,
408                                     sal_uInt16 nFormStart, sal_uInt16 nFormEnd, sal_Bool bCheckEnable = sal_True )
409 {
410     DBG_ASSERT( (rIndex >= nFormStart) && (rIndex <= nFormEnd),
411                 "Window::ImplFindAccelWindow() - rIndex not in Form" );
412 
413     xub_Unicode cCompareChar;
414     sal_uInt16  nStart = rIndex;
415     sal_uInt16  i = rIndex;
416     int     bSearch = sal_True;
417     Window* pWindow;
418 
419     // MT: Where can we keep the CharClass?!
420     static uno::Reference< i18n::XCharacterClassification > xCharClass;
421     if ( !xCharClass.is() )
422         xCharClass = vcl::unohelper::CreateCharacterClassification();
423 
424     const ::com::sun::star::lang::Locale& rLocale = Application::GetSettings().GetUILocale();
425     cCharCode = xCharClass->toUpper( String(cCharCode), 0, 1, rLocale )[0];
426 
427     if ( i < nFormEnd )
428         pWindow = ImplGetNextWindow( pParent, i, i, sal_True );
429     else
430         pWindow = ImplGetChildWindow( pParent, nFormStart, i, sal_True );
431     while( bSearch && pWindow )
432     {
433         const XubString aStr = pWindow->GetText();
434         sal_uInt16 nPos = aStr.Search( '~' );
435         while ( nPos != STRING_NOTFOUND )
436         {
437             cCompareChar = aStr.GetChar( nPos+1 );
438             cCompareChar = xCharClass->toUpper( String(cCompareChar), 0, 1, rLocale )[0];
439             if ( cCompareChar == cCharCode )
440             {
441                 // Bei Static-Controls auf das naechste Controlm weiterschalten
442                 if ( (pWindow->GetType() == WINDOW_FIXEDTEXT)   ||
443                      (pWindow->GetType() == WINDOW_FIXEDLINE)   ||
444                      (pWindow->GetType() == WINDOW_GROUPBOX) )
445                     pWindow = pParent->ImplGetDlgWindow( i, DLGWINDOW_NEXT );
446                 rIndex = i;
447                 return pWindow;
448             }
449             nPos = aStr.Search( '~', nPos+1 );
450         }
451 
452         // #i93011# it would have made sense to have this really recursive
453         // right from the start. However this would cause unpredictable side effects now
454         // so instead we have a style bit for some child windows, that want their
455         // children checked for accelerators
456         if( (pWindow->GetStyle() & WB_CHILDDLGCTRL) != 0 )
457         {
458             sal_uInt16  nChildIndex;
459             sal_uInt16  nChildFormStart;
460             sal_uInt16  nChildFormEnd;
461 
462             // get form start and end
463             ::ImplFindDlgCtrlWindow( pWindow, NULL,
464                                      nChildIndex, nChildFormStart, nChildFormEnd );
465             Window* pAccelWin = ImplFindAccelWindow( pWindow, nChildIndex, cCharCode,
466                                                      nChildFormStart, nChildFormEnd,
467                                                      bCheckEnable );
468             if( pAccelWin )
469                 return pAccelWin;
470         }
471 
472         if ( i == nStart )
473             break;
474 
475         if ( i < nFormEnd )
476 		{
477             pWindow = ImplGetNextWindow( pParent, i, i, bCheckEnable );
478 			if( ! pWindow )
479 				pWindow = ImplGetChildWindow( pParent, nFormStart, i, bCheckEnable );
480 		}
481         else
482             pWindow = ImplGetChildWindow( pParent, nFormStart, i, bCheckEnable );
483     }
484 
485     return NULL;
486 }
487 
488 // -----------------------------------------------------------------------
489 
490 void Window::ImplControlFocus( sal_uInt16 nFlags )
491 {
492     if ( nFlags & GETFOCUS_MNEMONIC )
493     {
494         if ( GetType() == WINDOW_RADIOBUTTON )
495         {
496             if ( !((RadioButton*)this)->IsChecked() )
497                 ((RadioButton*)this)->ImplCallClick( sal_True, nFlags );
498             else
499                 ImplGrabFocus( nFlags );
500         }
501         else
502         {
503             ImplGrabFocus( nFlags );
504             if ( nFlags & GETFOCUS_UNIQUEMNEMONIC )
505             {
506                 if ( GetType() == WINDOW_CHECKBOX )
507                     ((CheckBox*)this)->ImplCheck();
508                 else if ( mpWindowImpl->mbPushButton )
509                 {
510                     ((PushButton*)this)->SetPressed( sal_True );
511                     ((PushButton*)this)->SetPressed( sal_False );
512                     ((PushButton*)this)->Click();
513                 }
514             }
515         }
516     }
517     else
518     {
519         if ( GetType() == WINDOW_RADIOBUTTON )
520         {
521             if ( !((RadioButton*)this)->IsChecked() )
522                 ((RadioButton*)this)->ImplCallClick( sal_True, nFlags );
523             else
524                 ImplGrabFocus( nFlags );
525         }
526         else
527             ImplGrabFocus( nFlags );
528     }
529 }
530 
531 // -----------------------------------------------------------------------
532 
533 sal_Bool Window::ImplDlgCtrl( const KeyEvent& rKEvt, sal_Bool bKeyInput )
534 {
535     KeyCode aKeyCode = rKEvt.GetKeyCode();
536     sal_uInt16  nKeyCode = aKeyCode.GetCode();
537     Window* pSWindow;
538     Window* pTempWindow;
539     Window* pButtonWindow;
540     sal_uInt16  i;
541     sal_uInt16  iButton;
542     sal_uInt16  iButtonStart;
543     sal_uInt16  iTemp;
544     sal_uInt16  nIndex;
545     sal_uInt16  nFormStart;
546     sal_uInt16  nFormEnd;
547     sal_uInt16  nDlgCtrlFlags;
548 
549     // Ohne Focus-Window koennen wir auch keine Steuerung uebernehmen
550     Window* pFocusWindow = Application::GetFocusWindow();
551     if ( !pFocusWindow || !ImplIsWindowOrChild( pFocusWindow ) )
552         return sal_False;
553 
554     // Focus-Fenster in der Child-Liste suchen
555     pSWindow = ::ImplFindDlgCtrlWindow( this, pFocusWindow,
556                                         nIndex, nFormStart, nFormEnd );
557     if ( !pSWindow )
558         return sal_False;
559     i = nIndex;
560 
561     nDlgCtrlFlags = 0;
562     pTempWindow = pSWindow;
563     do
564     {
565         nDlgCtrlFlags |= pTempWindow->GetDialogControlFlags();
566         if ( pTempWindow == this )
567             break;
568         pTempWindow = pTempWindow->ImplGetParent();
569     }
570     while ( pTempWindow );
571 
572     pButtonWindow = NULL;
573 
574     if ( nKeyCode == KEY_RETURN )
575     {
576         // Wir suchen zuerst nach einem DefPushButton/CancelButton
577         pButtonWindow = ImplGetChildWindow( this, nFormStart, iButton, sal_True );
578         iButtonStart = iButton;
579         while ( pButtonWindow )
580         {
581             if ( (pButtonWindow->GetStyle() & WB_DEFBUTTON) &&
582                  pButtonWindow->mpWindowImpl->mbPushButton )
583                 break;
584 
585             pButtonWindow = ImplGetNextWindow( this, iButton, iButton, sal_True );
586             if ( (iButton <= iButtonStart) || (iButton > nFormEnd) )
587                 pButtonWindow = NULL;
588         }
589 
590         if ( bKeyInput && !pButtonWindow && (nDlgCtrlFlags & WINDOW_DLGCTRL_RETURN) )
591         {
592             sal_uInt16  nType;
593             sal_uInt16  nGetFocusFlags = GETFOCUS_TAB;
594             sal_uInt16  nNewIndex;
595             sal_uInt16  iStart;
596             if ( aKeyCode.IsShift() )
597             {
598                 nType = DLGWINDOW_PREV;
599                 nGetFocusFlags |= GETFOCUS_BACKWARD;
600             }
601             else
602             {
603                 nType = DLGWINDOW_NEXT;
604                 nGetFocusFlags |= GETFOCUS_FORWARD;
605             }
606             iStart = i;
607             pTempWindow = ImplGetDlgWindow( i, nType, nFormStart, nFormEnd, &nNewIndex );
608             while ( pTempWindow && (pTempWindow != pSWindow) )
609             {
610                 if ( !pTempWindow->mpWindowImpl->mbPushButton )
611                 {
612                     // Around-Flag ermitteln
613                     if ( nType == DLGWINDOW_PREV )
614                     {
615                         if ( nNewIndex > iStart )
616                             nGetFocusFlags |= GETFOCUS_AROUND;
617                     }
618                     else
619                     {
620                         if ( nNewIndex < iStart )
621                             nGetFocusFlags |= GETFOCUS_AROUND;
622                     }
623                     pTempWindow->ImplControlFocus( nGetFocusFlags );
624                     return sal_True;
625                 }
626                 else
627                 {
628                     i = nNewIndex;
629                     pTempWindow = ImplGetDlgWindow( i, nType, nFormStart, nFormEnd, &nNewIndex );
630                 }
631                 if ( (i <= iStart) || (i > nFormEnd) )
632                     pTempWindow = NULL;
633             }
634             // Wenn es das gleiche Fenster ist, ein Get/LoseFocus
635             // simulieren, falls AROUND ausgewertet wird
636             if ( pTempWindow && (pTempWindow == pSWindow) )
637             {
638                 NotifyEvent aNEvt1( EVENT_LOSEFOCUS, pSWindow );
639                 if ( !ImplCallPreNotify( aNEvt1 ) )
640                     pSWindow->LoseFocus();
641                 pSWindow->mpWindowImpl->mnGetFocusFlags = nGetFocusFlags | GETFOCUS_AROUND;
642                 NotifyEvent aNEvt2( EVENT_GETFOCUS, pSWindow );
643                 if ( !ImplCallPreNotify( aNEvt2 ) )
644                     pSWindow->GetFocus();
645                 pSWindow->mpWindowImpl->mnGetFocusFlags = 0;
646                 return sal_True;
647             }
648         }
649     }
650     else if ( nKeyCode == KEY_ESCAPE )
651     {
652         // Wir suchen zuerst nach einem DefPushButton/CancelButton
653         pButtonWindow = ImplGetChildWindow( this, nFormStart, iButton, sal_True );
654         iButtonStart = iButton;
655         while ( pButtonWindow )
656         {
657             if ( pButtonWindow->GetType() == WINDOW_CANCELBUTTON )
658                 break;
659 
660             pButtonWindow = ImplGetNextWindow( this, iButton, iButton, sal_True );
661             if ( (iButton <= iButtonStart) || (iButton > nFormEnd) )
662                 pButtonWindow = NULL;
663         }
664 
665         if ( bKeyInput && mpWindowImpl->mpDlgCtrlDownWindow )
666         {
667             if ( mpWindowImpl->mpDlgCtrlDownWindow != pButtonWindow )
668             {
669                 ((PushButton*)mpWindowImpl->mpDlgCtrlDownWindow)->SetPressed( sal_False );
670                 mpWindowImpl->mpDlgCtrlDownWindow = NULL;
671                 return sal_True;
672             }
673         }
674     }
675     else if ( bKeyInput )
676     {
677         if ( nKeyCode == KEY_TAB )
678         {
679             // keine Alt-Taste abfangen, wegen Windows
680             if ( !aKeyCode.IsMod2() )
681             {
682                 sal_uInt16  nType;
683                 sal_uInt16  nGetFocusFlags = GETFOCUS_TAB;
684                 sal_uInt16  nNewIndex;
685                 sal_Bool    bFormular = sal_False;
686 
687                 // Bei Ctrl-Tab erstmal testen, ob zwischen Formularen
688                 // gesprungen werden soll
689                 if ( aKeyCode.IsMod1() )
690                 {
691                     // Gruppe suchen
692                     Window* pFormularFirstWindow = NULL;
693                     Window* pLastFormularFirstWindow = NULL;
694                     pTempWindow = ImplGetChildWindow( this, 0, iTemp, sal_False );
695                     Window* pPrevFirstFormularFirstWindow = NULL;
696                     Window* pFirstFormularFirstWindow = pTempWindow;
697                     while ( pTempWindow )
698                     {
699                         if ( pTempWindow->ImplGetWindow()->IsDialogControlStart() )
700                         {
701                             if ( iTemp != 0 )
702                                 bFormular = sal_True;
703                             if ( aKeyCode.IsShift() )
704                             {
705                                 if ( iTemp <= nIndex )
706                                     pFormularFirstWindow = pPrevFirstFormularFirstWindow;
707                                 pPrevFirstFormularFirstWindow = pTempWindow;
708                             }
709                             else
710                             {
711                                 if ( (iTemp > nIndex) && !pFormularFirstWindow )
712                                     pFormularFirstWindow = pTempWindow;
713                             }
714                             pLastFormularFirstWindow = pTempWindow;
715                         }
716 
717                         pTempWindow = ImplGetNextWindow( this, iTemp, iTemp, sal_False );
718                         if ( !iTemp )
719                             pTempWindow = NULL;
720                     }
721 
722                     if ( bFormular )
723                     {
724                         if ( !pFormularFirstWindow )
725                         {
726                             if ( aKeyCode.IsShift() )
727                                 pFormularFirstWindow = pLastFormularFirstWindow;
728                             else
729                                 pFormularFirstWindow = pFirstFormularFirstWindow;
730                         }
731 
732                         sal_uInt16 nFoundFormStart = 0;
733                         sal_uInt16 nFoundFormEnd = 0;
734                         sal_uInt16 nTempIndex = 0;
735                         if ( ::ImplFindDlgCtrlWindow( this, pFormularFirstWindow, nTempIndex,
736                                                       nFoundFormStart, nFoundFormEnd ) )
737                         {
738                             nTempIndex = nFoundFormStart;
739                             pFormularFirstWindow = ImplGetDlgWindow( nTempIndex, DLGWINDOW_FIRST, nFoundFormStart, nFoundFormEnd );
740                             if ( pFormularFirstWindow )
741                             {
742                                 pFormularFirstWindow->ImplControlFocus();
743                                 return sal_True;
744                             }
745                         }
746                     }
747                 }
748 
749                 if ( !bFormular )
750                 {
751                     // Only use Ctrl-TAB if it was allowed for the whole
752                     // dialog or for the current control (#103667#)
753                     if ( !aKeyCode.IsMod1() || (nDlgCtrlFlags & WINDOW_DLGCTRL_MOD1TAB) ||
754                         ( pSWindow->GetStyle() & WINDOW_DLGCTRL_MOD1TAB) )
755                     {
756                         if ( aKeyCode.IsShift() )
757                         {
758                             nType = DLGWINDOW_PREV;
759                             nGetFocusFlags |= GETFOCUS_BACKWARD;
760                         }
761                         else
762                         {
763                             nType = DLGWINDOW_NEXT;
764                             nGetFocusFlags |= GETFOCUS_FORWARD;
765                         }
766                         Window* pWindow = ImplGetDlgWindow( i, nType, nFormStart, nFormEnd, &nNewIndex );
767                         // Wenn es das gleiche Fenster ist, ein Get/LoseFocus
768                         // simulieren, falls AROUND ausgewertet wird
769                         if ( pWindow == pSWindow )
770                         {
771                             NotifyEvent aNEvt1( EVENT_LOSEFOCUS, pSWindow );
772                             if ( !ImplCallPreNotify( aNEvt1 ) )
773                                 pSWindow->LoseFocus();
774                             pSWindow->mpWindowImpl->mnGetFocusFlags = nGetFocusFlags | GETFOCUS_AROUND;
775                             NotifyEvent aNEvt2( EVENT_GETFOCUS, pSWindow );
776                             if ( !ImplCallPreNotify( aNEvt2 ) )
777                                 pSWindow->GetFocus();
778                             pSWindow->mpWindowImpl->mnGetFocusFlags = 0;
779                             return sal_True;
780                         }
781                         else if ( pWindow )
782                         {
783                             // Around-Flag ermitteln
784                             if ( nType == DLGWINDOW_PREV )
785                             {
786                                 if ( nNewIndex > i )
787                                     nGetFocusFlags |= GETFOCUS_AROUND;
788                             }
789                             else
790                             {
791                                 if ( nNewIndex < i )
792                                     nGetFocusFlags |= GETFOCUS_AROUND;
793                             }
794                             pWindow->ImplControlFocus( nGetFocusFlags );
795                             return sal_True;
796                         }
797                     }
798                 }
799             }
800         }
801         else if ( (nKeyCode == KEY_LEFT) || (nKeyCode == KEY_UP) )
802         {
803             Window* pWindow = pSWindow;
804             WinBits nStyle = pSWindow->GetStyle();
805             if ( !(nStyle & WB_GROUP) )
806             {
807                 pWindow = pWindow->GetWindow( WINDOW_PREV );
808                 while ( pWindow )
809                 {
810                     pWindow = pWindow->ImplGetWindow();
811 
812                     nStyle = pWindow->GetStyle();
813 
814                     if ( pWindow->IsVisible() && pWindow->IsEnabled() && pWindow->IsInputEnabled() )
815                     {
816                         if ( pWindow != pSWindow )
817                             pWindow->ImplControlFocus( GETFOCUS_CURSOR | GETFOCUS_BACKWARD );
818                         return sal_True;
819                     }
820 
821                     if ( nStyle & WB_GROUP )
822                         break;
823 
824                     pWindow = pWindow->GetWindow( WINDOW_PREV );
825                 }
826             }
827         }
828         else if ( (nKeyCode == KEY_RIGHT) || (nKeyCode == KEY_DOWN) )
829         {
830             Window* pWindow;
831             WinBits nStyle;
832             pWindow = pSWindow->GetWindow( WINDOW_NEXT );
833             while ( pWindow )
834             {
835                 pWindow = pWindow->ImplGetWindow();
836 
837                 nStyle = pWindow->GetStyle();
838 
839                 if ( nStyle & WB_GROUP )
840                     break;
841 
842                 if ( pWindow->IsVisible() && pWindow->IsEnabled() && pWindow->IsInputEnabled() )
843                 {
844                     pWindow->ImplControlFocus( GETFOCUS_CURSOR | GETFOCUS_BACKWARD );
845                     return sal_True;
846                 }
847 
848                 pWindow = pWindow->GetWindow( WINDOW_NEXT );
849             }
850         }
851         else
852         {
853             xub_Unicode c = rKEvt.GetCharCode();
854             if ( c )
855             {
856                 pSWindow = ::ImplFindAccelWindow( this, i, c, nFormStart, nFormEnd );
857                 if ( pSWindow )
858                 {
859                     sal_uInt16 nGetFocusFlags = GETFOCUS_MNEMONIC;
860                     if ( pSWindow == ::ImplFindAccelWindow( this, i, c, nFormStart, nFormEnd ) )
861                         nGetFocusFlags |= GETFOCUS_UNIQUEMNEMONIC;
862                     pSWindow->ImplControlFocus( nGetFocusFlags );
863                     return sal_True;
864                 }
865             }
866         }
867     }
868 
869     if ( pButtonWindow && pButtonWindow->IsVisible() && pButtonWindow->IsEnabled() && pButtonWindow->IsInputEnabled() )
870     {
871         if ( bKeyInput )
872         {
873             if ( mpWindowImpl->mpDlgCtrlDownWindow && (mpWindowImpl->mpDlgCtrlDownWindow != pButtonWindow) )
874             {
875                 ((PushButton*)mpWindowImpl->mpDlgCtrlDownWindow)->SetPressed( sal_False );
876                 mpWindowImpl->mpDlgCtrlDownWindow = NULL;
877             }
878 
879             ((PushButton*)pButtonWindow)->SetPressed( sal_True );
880             mpWindowImpl->mpDlgCtrlDownWindow = pButtonWindow;
881         }
882         else if ( mpWindowImpl->mpDlgCtrlDownWindow == pButtonWindow )
883         {
884             mpWindowImpl->mpDlgCtrlDownWindow = NULL;
885             ((PushButton*)pButtonWindow)->SetPressed( sal_False );
886             ((PushButton*)pButtonWindow)->Click();
887         }
888 
889         return sal_True;
890     }
891 
892     return sal_False;
893 }
894 
895 // -----------------------------------------------------------------------
896 
897 // checks if this window has dialog control
898 sal_Bool Window::ImplHasDlgCtrl()
899 {
900     Window* pDlgCtrlParent;
901     Window* pDlgCtrl;
902 
903     // lookup window for dialog control
904     pDlgCtrl = this;
905     pDlgCtrlParent = ImplGetParent();
906     while ( pDlgCtrlParent &&
907             !pDlgCtrlParent->ImplIsOverlapWindow() &&
908             ((pDlgCtrlParent->GetStyle() & (WB_DIALOGCONTROL | WB_NODIALOGCONTROL)) != WB_DIALOGCONTROL) )
909         pDlgCtrlParent = pDlgCtrlParent->ImplGetParent();
910 
911     if ( !pDlgCtrlParent || ((pDlgCtrlParent->GetStyle() & (WB_DIALOGCONTROL | WB_NODIALOGCONTROL)) != WB_DIALOGCONTROL) )
912         return sal_False;
913     else
914         return sal_True;
915 }
916 
917 void Window::ImplDlgCtrlNextWindow()
918 {
919     Window* pDlgCtrlParent;
920     Window* pDlgCtrl;
921     Window* pSWindow;
922     sal_uInt16  nIndex;
923     sal_uInt16  nFormStart;
924     sal_uInt16  nFormEnd;
925 
926     // lookup window for dialog control
927     pDlgCtrl = this;
928     pDlgCtrlParent = ImplGetParent();
929     while ( pDlgCtrlParent &&
930             !pDlgCtrlParent->ImplIsOverlapWindow() &&
931             ((pDlgCtrlParent->GetStyle() & (WB_DIALOGCONTROL | WB_NODIALOGCONTROL)) != WB_DIALOGCONTROL) )
932         pDlgCtrlParent = pDlgCtrlParent->ImplGetParent();
933 
934 if ( !pDlgCtrlParent || (GetStyle() & WB_NODIALOGCONTROL) || ((pDlgCtrlParent->GetStyle() & (WB_DIALOGCONTROL | WB_NODIALOGCONTROL)) != WB_DIALOGCONTROL) )
935         return;
936 
937     // lookup window in child list
938     pSWindow = ::ImplFindDlgCtrlWindow( pDlgCtrlParent, pDlgCtrl,
939                                         nIndex, nFormStart, nFormEnd );
940     if ( !pSWindow )
941         return;
942 
943     Window* pWindow = pDlgCtrlParent->ImplGetDlgWindow( nIndex, DLGWINDOW_NEXT, nFormStart, nFormEnd );
944     if ( pWindow && (pWindow != pSWindow) )
945         pWindow->ImplControlFocus();
946 }
947 
948 // -----------------------------------------------------------------------
949 
950 static void ImplDlgCtrlUpdateDefButton( Window* pParent, Window* pFocusWindow,
951                                         sal_Bool bGetFocus )
952 {
953     PushButton* pOldDefButton   = NULL;
954     PushButton* pNewDefButton   = NULL;
955     Window*     pSWindow;
956     sal_uInt16      i;
957     sal_uInt16      nFormStart;
958     sal_uInt16      nFormEnd;
959 
960     // Formular suchen
961     pSWindow = ::ImplFindDlgCtrlWindow( pParent, pFocusWindow, i, nFormStart, nFormEnd );
962     if ( !pSWindow )
963     {
964         nFormStart = 0;
965         nFormEnd = 0xFFFF;
966     }
967 
968     pSWindow = ImplGetChildWindow( pParent, nFormStart, i, sal_False );
969     while ( pSWindow )
970     {
971         if ( pSWindow->ImplIsPushButton() )
972         {
973             PushButton* pPushButton = (PushButton*)pSWindow;
974             if ( pPushButton->ImplIsDefButton() )
975                 pOldDefButton = pPushButton;
976             if ( pPushButton->HasChildPathFocus() )
977                 pNewDefButton = pPushButton;
978             else if ( !pNewDefButton && (pPushButton->GetStyle() & WB_DEFBUTTON) )
979                 pNewDefButton = pPushButton;
980         }
981 
982         pSWindow = ImplGetNextWindow( pParent, i, i, sal_False );
983         if ( !i || (i > nFormEnd) )
984             pSWindow = NULL;
985     }
986 
987     if ( !bGetFocus )
988     {
989         sal_uInt16 nDummy;
990         Window* pNewFocusWindow = Application::GetFocusWindow();
991         if ( !pNewFocusWindow || !pParent->ImplIsWindowOrChild( pNewFocusWindow ) )
992             pNewDefButton = NULL;
993         else if ( !::ImplFindDlgCtrlWindow( pParent, pNewFocusWindow, i, nDummy, nDummy ) ||
994                   (i < nFormStart) || (i > nFormEnd) )
995             pNewDefButton = NULL;
996     }
997 
998     if ( pOldDefButton != pNewDefButton )
999     {
1000         if ( pOldDefButton )
1001             pOldDefButton->ImplSetDefButton( sal_False );
1002         if ( pNewDefButton )
1003             pNewDefButton->ImplSetDefButton( sal_True );
1004     }
1005 }
1006 
1007 // -----------------------------------------------------------------------
1008 
1009 void Window::ImplDlgCtrlFocusChanged( Window* pWindow, sal_Bool bGetFocus )
1010 {
1011     if ( mpWindowImpl->mpDlgCtrlDownWindow && !bGetFocus )
1012     {
1013         ((PushButton*)mpWindowImpl->mpDlgCtrlDownWindow)->SetPressed( sal_False );
1014         mpWindowImpl->mpDlgCtrlDownWindow = NULL;
1015     }
1016 
1017     ImplDlgCtrlUpdateDefButton( this, pWindow, bGetFocus );
1018 }
1019 
1020 // -----------------------------------------------------------------------
1021 
1022 Window* Window::ImplFindDlgCtrlWindow( Window* pWindow )
1023 {
1024     sal_uInt16  nIndex;
1025     sal_uInt16  nFormStart;
1026     sal_uInt16  nFormEnd;
1027 
1028     // Focus-Fenster in der Child-Liste suchen und zurueckgeben
1029     return ::ImplFindDlgCtrlWindow( this, pWindow, nIndex, nFormStart, nFormEnd );
1030 }
1031 
1032 
1033 // -----------------------------------------------------------------------
1034 
1035 Window* Window::GetParentLabelFor( const Window* ) const
1036 {
1037     return NULL;
1038 }
1039 
1040 // -----------------------------------------------------------------------
1041 
1042 Window* Window::GetParentLabeledBy( const Window* ) const
1043 {
1044     return NULL;
1045 }
1046 
1047 // -----------------------------------------------------------------------
1048 
1049 static sal_Unicode getAccel( const String& rStr )
1050 {
1051     sal_Unicode nChar = 0;
1052     sal_uInt16 nPos = 0;
1053     do
1054     {
1055         nPos = rStr.Search( '~', nPos );
1056         if( nPos != STRING_NOTFOUND && nPos < rStr.Len() )
1057             nChar = rStr.GetChar( ++nPos );
1058         else
1059             nChar = 0;
1060     } while( nChar == '~' );
1061     return nChar;
1062 }
1063 
1064 static Window* ImplGetLabelFor( Window* pFrameWindow, WindowType nMyType, Window* pLabel, sal_Unicode nAccel )
1065 {
1066     Window* pWindow = NULL;
1067 
1068     if( nMyType == WINDOW_FIXEDTEXT		||
1069         nMyType == WINDOW_FIXEDLINE		||
1070         nMyType == WINDOW_GROUPBOX )
1071     {
1072         // #i100833# MT 2010/02: Group box and fixed lines can also lable a fixed text.
1073         // See tools/options/print for example.
1074         sal_Bool bThisIsAGroupControl = (nMyType == WINDOW_GROUPBOX) || (nMyType == WINDOW_FIXEDLINE);
1075         Window* pSWindow = NULL;
1076         // get index, form start and form end
1077         sal_uInt16 nIndex=0, nFormStart=0, nFormEnd=0;
1078         pSWindow = ::ImplFindDlgCtrlWindow( pFrameWindow,
1079                                            pLabel,
1080                                            nIndex,
1081                                            nFormStart,
1082                                            nFormEnd );
1083         if( nAccel )
1084         {
1085             // find the accelerated window
1086             pWindow = ::ImplFindAccelWindow( pFrameWindow,
1087                                              nIndex,
1088                                              nAccel,
1089                                              nFormStart,
1090                                              nFormEnd,
1091                                              sal_False );
1092         }
1093         else
1094         {
1095             // find the next control; if that is a fixed text
1096             // fixed line or group box, then return NULL
1097             while( nIndex < nFormEnd )
1098             {
1099                 nIndex++;
1100                 pSWindow = ::ImplGetChildWindow( pFrameWindow,
1101                                                  nIndex,
1102                                                  nIndex,
1103                                                  sal_False );
1104                 if( pSWindow && pSWindow->IsVisible() && ! (pSWindow->GetStyle() & WB_NOLABEL) )
1105                 {
1106                     WindowType nType = pSWindow->GetType();
1107                     if( nType != WINDOW_FIXEDTEXT	&&
1108                         nType != WINDOW_FIXEDLINE	&&
1109                         nType != WINDOW_GROUPBOX )
1110                     {
1111                         pWindow = pSWindow;
1112                     }
1113                     else if( bThisIsAGroupControl && ( nType == WINDOW_FIXEDTEXT ) )
1114                     {
1115                         pWindow = pSWindow;
1116                     }
1117                     break;
1118                 }
1119             }
1120         }
1121     }
1122 
1123     return pWindow;
1124 }
1125 
1126 Window* Window::GetAccessibleRelationLabelFor() const
1127 {
1128     if ( mpWindowImpl->mbDisableAccessibleLabelForRelation )
1129         return NULL;
1130 
1131 	if ( mpWindowImpl->mpAccessibleInfos && mpWindowImpl->mpAccessibleInfos->pLabelForWindow )
1132 		return mpWindowImpl->mpAccessibleInfos->pLabelForWindow;
1133 
1134 
1135     Window* pWindow = NULL;
1136     Window* pFrameWindow = ImplGetFrameWindow();
1137 
1138     WinBits nFrameStyle = pFrameWindow->GetStyle();
1139     if( ! ( nFrameStyle & WB_DIALOGCONTROL )
1140         || ( nFrameStyle & WB_NODIALOGCONTROL )
1141         )
1142         return NULL;
1143 
1144 	if ( mpWindowImpl->mpRealParent )
1145 		pWindow = mpWindowImpl->mpRealParent->GetParentLabelFor( this );
1146 
1147     if( pWindow )
1148         return pWindow;
1149 
1150     sal_Unicode nAccel = getAccel( GetText() );
1151 
1152     pWindow = ImplGetLabelFor( pFrameWindow, GetType(), const_cast<Window*>(this), nAccel );
1153     if( ! pWindow && mpWindowImpl->mpRealParent )
1154         pWindow = ImplGetLabelFor( mpWindowImpl->mpRealParent, GetType(), const_cast<Window*>(this), nAccel );
1155     return pWindow;
1156 }
1157 
1158 // -----------------------------------------------------------------------
1159 
1160 static Window* ImplGetLabeledBy( Window* pFrameWindow, WindowType nMyType, Window* pLabeled )
1161 {
1162     Window* pWindow = NULL;
1163     if ( (nMyType != WINDOW_GROUPBOX) && (nMyType != WINDOW_FIXEDLINE) )
1164     {
1165         // search for a control that labels this window
1166         // a label is considered the last fixed text, fixed line or group box
1167         // that comes before this control; with the exception of push buttons
1168         // which are labeled only if the fixed text, fixed line or group box
1169         // is directly before the control
1170 
1171         // get form start and form end and index of this control
1172         sal_uInt16 nIndex, nFormStart, nFormEnd;
1173         Window* pSWindow = ::ImplFindDlgCtrlWindow( pFrameWindow,
1174                                                     pLabeled,
1175                                                     nIndex,
1176                                                     nFormStart,
1177                                                     nFormEnd );
1178         if( pSWindow && nIndex != nFormStart )
1179         {
1180             if( nMyType == WINDOW_PUSHBUTTON		||
1181                 nMyType == WINDOW_HELPBUTTON		||
1182                 nMyType == WINDOW_OKBUTTON		||
1183                 nMyType == WINDOW_CANCELBUTTON )
1184             {
1185                 nFormStart = nIndex-1;
1186             }
1187             for( sal_uInt16 nSearchIndex = nIndex-1; nSearchIndex >= nFormStart; nSearchIndex-- )
1188             {
1189 				sal_uInt16 nFoundIndex = 0;
1190                 pSWindow = ::ImplGetChildWindow( pFrameWindow,
1191                                                  nSearchIndex,
1192                                                  nFoundIndex,
1193                                                  sal_False );
1194                 if( pSWindow && pSWindow->IsVisible() && !(pSWindow->GetStyle() & WB_NOLABEL) )
1195                 {
1196                     WindowType nType = pSWindow->GetType();
1197                     if ( ( nType == WINDOW_FIXEDTEXT	||
1198                           nType == WINDOW_FIXEDLINE	||
1199                           nType == WINDOW_GROUPBOX ) )
1200                     {
1201                         // a fixed text can't be labeld by a fixed text.
1202                         if ( ( nMyType != WINDOW_FIXEDTEXT ) || ( nType != WINDOW_FIXEDTEXT ) )
1203                             pWindow = pSWindow;
1204                         break;
1205                     }
1206                 }
1207 				if( nFoundIndex > nSearchIndex || nSearchIndex == 0 )
1208 					break;
1209             }
1210         }
1211     }
1212     return pWindow;
1213 }
1214 
1215 Window* Window::GetAccessibleRelationLabeledBy() const
1216 {
1217     if ( mpWindowImpl->mbDisableAccessibleLabeledByRelation )
1218         return NULL;
1219 
1220 	if ( mpWindowImpl->mpAccessibleInfos && mpWindowImpl->mpAccessibleInfos->pLabeledByWindow )
1221 		return mpWindowImpl->mpAccessibleInfos->pLabeledByWindow;
1222 
1223     Window* pWindow = NULL;
1224     Window* pFrameWindow = ImplGetFrameWindow();
1225 
1226 	if ( mpWindowImpl->mpRealParent )
1227 	{
1228 		pWindow = mpWindowImpl->mpRealParent->GetParentLabeledBy( this );
1229 
1230 		if( pWindow )
1231 		    return pWindow;
1232 	}
1233 
1234     // #i62723#, #104191# checkboxes and radiobuttons are not supposed to have labels
1235     if( GetType() == WINDOW_CHECKBOX || GetType() == WINDOW_RADIOBUTTON )
1236         return NULL;
1237 
1238 //    if( ! ( GetType() == WINDOW_FIXEDTEXT		||
1239 //            GetType() == WINDOW_FIXEDLINE		||
1240 //            GetType() == WINDOW_GROUPBOX ) )
1241     // #i100833# MT 2010/02: Group box and fixed lines can also lable a fixed text.
1242     // See tools/options/print for example.
1243 
1244     pWindow = ImplGetLabeledBy( pFrameWindow, GetType(), const_cast<Window*>(this) );
1245     if( ! pWindow && mpWindowImpl->mpRealParent )
1246         pWindow = ImplGetLabeledBy( mpWindowImpl->mpRealParent, GetType(), const_cast<Window*>(this) );
1247 
1248     return pWindow;
1249 }
1250 
1251 Window* Window::GetAccessibleRelationMemberOf() const
1252 {
1253 	Window* pWindow = NULL;
1254 	Window* pFrameWindow = GetParent();
1255 	if ( !pFrameWindow )
1256 	{
1257 		pFrameWindow = ImplGetFrameWindow();
1258 	}
1259 	// if( ! ( GetType() == WINDOW_FIXEDTEXT		||
1260 	if( !( GetType() == WINDOW_FIXEDLINE ||
1261 		GetType() == WINDOW_GROUPBOX ) )
1262 	{
1263 		// search for a control that makes member of this window
1264 		// it is considered the last fixed line or group box
1265 		// that comes before this control; with the exception of push buttons
1266 		// which are labeled only if the fixed line or group box
1267 		// is directly before the control
1268 		// get form start and form end and index of this control
1269 		sal_uInt16 nIndex, nFormStart, nFormEnd;
1270 		Window* pSWindow = ::ImplFindDlgCtrlWindow( pFrameWindow,
1271 			const_cast<Window*>(this),
1272 			nIndex,
1273 			nFormStart,
1274 			nFormEnd );
1275 		if( pSWindow && nIndex != nFormStart )
1276 		{
1277 			if( GetType() == WINDOW_PUSHBUTTON		||
1278 				GetType() == WINDOW_HELPBUTTON		||
1279 				GetType() == WINDOW_OKBUTTON		||
1280 				GetType() == WINDOW_CANCELBUTTON )
1281 			{
1282 				nFormStart = nIndex-1;
1283 			}
1284 			for( sal_uInt16 nSearchIndex = nIndex-1; nSearchIndex >= nFormStart; nSearchIndex-- )
1285 			{
1286 				sal_uInt16 nFoundIndex = 0;
1287 				pSWindow = ::ImplGetChildWindow( pFrameWindow,
1288 					nSearchIndex,
1289 					nFoundIndex,
1290 					sal_False );
1291 				if( pSWindow && pSWindow->IsVisible() &&
1292 					( pSWindow->GetType() == WINDOW_FIXEDLINE	||
1293 					pSWindow->GetType() == WINDOW_GROUPBOX ) )
1294 				{
1295 					pWindow = pSWindow;
1296 					break;
1297 				}
1298 				if( nFoundIndex > nSearchIndex || nSearchIndex == 0 )
1299 					break;
1300 			}
1301 		}
1302 	}
1303 	return pWindow;
1304 }
1305 //-----IAccessibility2 Implementation 2009
1306 
1307 // -----------------------------------------------------------------------
1308 
1309 KeyEvent Window::GetActivationKey() const
1310 {
1311     KeyEvent aKeyEvent;
1312 
1313     sal_Unicode nAccel = getAccel( GetText() );
1314     if( ! nAccel )
1315     {
1316         Window* pWindow = GetAccessibleRelationLabeledBy();
1317         if( pWindow )
1318             nAccel = getAccel( pWindow->GetText() );
1319     }
1320     if( nAccel )
1321     {
1322         sal_uInt16 nCode = 0;
1323         if( nAccel >= 'a' && nAccel <= 'z' )
1324             nCode = KEY_A + (nAccel-'a');
1325         else if( nAccel >= 'A' && nAccel <= 'Z' )
1326             nCode = KEY_A + (nAccel-'A');
1327         else if( nAccel >= '0' && nAccel <= '9' )
1328             nCode = KEY_0 + (nAccel-'0');
1329 		else if( nAccel == '.' )
1330 			nCode = KEY_POINT;
1331 		else if( nAccel == '-' )
1332 			nCode = KEY_SUBTRACT;
1333         KeyCode aKeyCode( nCode, sal_False, sal_False, sal_True, sal_False );
1334         aKeyEvent = KeyEvent( nAccel, aKeyCode );
1335     }
1336     return aKeyEvent;
1337 }
1338