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