xref: /aoo41x/main/vcl/source/window/dlgctrl.cxx (revision 9f62ea84)
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                 if ( pWindow->IsVisible() && pWindow->IsEnabled() && pWindow->IsInputEnabled() )
839                 {
840                     pWindow->ImplControlFocus( GETFOCUS_CURSOR | GETFOCUS_BACKWARD );
841                     return sal_True;
842                 }
843 
844                 pWindow = pWindow->GetWindow( WINDOW_NEXT );
845             }
846         }
847         else
848         {
849             xub_Unicode c = rKEvt.GetCharCode();
850             if ( c )
851             {
852                 pSWindow = ::ImplFindAccelWindow( this, i, c, nFormStart, nFormEnd );
853                 if ( pSWindow )
854                 {
855                     sal_uInt16 nGetFocusFlags = GETFOCUS_MNEMONIC;
856                     if ( pSWindow == ::ImplFindAccelWindow( this, i, c, nFormStart, nFormEnd ) )
857                         nGetFocusFlags |= GETFOCUS_UNIQUEMNEMONIC;
858                     pSWindow->ImplControlFocus( nGetFocusFlags );
859                     return sal_True;
860                 }
861             }
862         }
863     }
864 
865     if ( pButtonWindow && pButtonWindow->IsVisible() && pButtonWindow->IsEnabled() && pButtonWindow->IsInputEnabled() )
866     {
867         if ( bKeyInput )
868         {
869             if ( mpWindowImpl->mpDlgCtrlDownWindow && (mpWindowImpl->mpDlgCtrlDownWindow != pButtonWindow) )
870             {
871                 ((PushButton*)mpWindowImpl->mpDlgCtrlDownWindow)->SetPressed( sal_False );
872                 mpWindowImpl->mpDlgCtrlDownWindow = NULL;
873             }
874 
875             ((PushButton*)pButtonWindow)->SetPressed( sal_True );
876             mpWindowImpl->mpDlgCtrlDownWindow = pButtonWindow;
877         }
878         else if ( mpWindowImpl->mpDlgCtrlDownWindow == pButtonWindow )
879         {
880             mpWindowImpl->mpDlgCtrlDownWindow = NULL;
881             ((PushButton*)pButtonWindow)->SetPressed( sal_False );
882             ((PushButton*)pButtonWindow)->Click();
883         }
884 
885         return sal_True;
886     }
887 
888     return sal_False;
889 }
890 
891 // -----------------------------------------------------------------------
892 
893 // checks if this window has dialog control
894 sal_Bool Window::ImplHasDlgCtrl()
895 {
896     Window* pDlgCtrlParent;
897     Window* pDlgCtrl;
898 
899     // lookup window for dialog control
900     pDlgCtrl = this;
901     pDlgCtrlParent = ImplGetParent();
902     while ( pDlgCtrlParent &&
903             !pDlgCtrlParent->ImplIsOverlapWindow() &&
904             ((pDlgCtrlParent->GetStyle() & (WB_DIALOGCONTROL | WB_NODIALOGCONTROL)) != WB_DIALOGCONTROL) )
905         pDlgCtrlParent = pDlgCtrlParent->ImplGetParent();
906 
907     if ( !pDlgCtrlParent || ((pDlgCtrlParent->GetStyle() & (WB_DIALOGCONTROL | WB_NODIALOGCONTROL)) != WB_DIALOGCONTROL) )
908         return sal_False;
909     else
910         return sal_True;
911 }
912 
913 void Window::ImplDlgCtrlNextWindow()
914 {
915     Window* pDlgCtrlParent;
916     Window* pDlgCtrl;
917     Window* pSWindow;
918     sal_uInt16  nIndex;
919     sal_uInt16  nFormStart;
920     sal_uInt16  nFormEnd;
921 
922     // lookup window for dialog control
923     pDlgCtrl = this;
924     pDlgCtrlParent = ImplGetParent();
925     while ( pDlgCtrlParent &&
926             !pDlgCtrlParent->ImplIsOverlapWindow() &&
927             ((pDlgCtrlParent->GetStyle() & (WB_DIALOGCONTROL | WB_NODIALOGCONTROL)) != WB_DIALOGCONTROL) )
928         pDlgCtrlParent = pDlgCtrlParent->ImplGetParent();
929 
930 if ( !pDlgCtrlParent || (GetStyle() & WB_NODIALOGCONTROL) || ((pDlgCtrlParent->GetStyle() & (WB_DIALOGCONTROL | WB_NODIALOGCONTROL)) != WB_DIALOGCONTROL) )
931         return;
932 
933     // lookup window in child list
934     pSWindow = ::ImplFindDlgCtrlWindow( pDlgCtrlParent, pDlgCtrl,
935                                         nIndex, nFormStart, nFormEnd );
936     if ( !pSWindow )
937         return;
938 
939     Window* pWindow = pDlgCtrlParent->ImplGetDlgWindow( nIndex, DLGWINDOW_NEXT, nFormStart, nFormEnd );
940     if ( pWindow && (pWindow != pSWindow) )
941         pWindow->ImplControlFocus();
942 }
943 
944 // -----------------------------------------------------------------------
945 
946 static void ImplDlgCtrlUpdateDefButton( Window* pParent, Window* pFocusWindow,
947                                         sal_Bool bGetFocus )
948 {
949     PushButton* pOldDefButton   = NULL;
950     PushButton* pNewDefButton   = NULL;
951     Window*     pSWindow;
952     sal_uInt16      i;
953     sal_uInt16      nFormStart;
954     sal_uInt16      nFormEnd;
955 
956     // Formular suchen
957     pSWindow = ::ImplFindDlgCtrlWindow( pParent, pFocusWindow, i, nFormStart, nFormEnd );
958     if ( !pSWindow )
959     {
960         nFormStart = 0;
961         nFormEnd = 0xFFFF;
962     }
963 
964     pSWindow = ImplGetChildWindow( pParent, nFormStart, i, sal_False );
965     while ( pSWindow )
966     {
967         if ( pSWindow->ImplIsPushButton() )
968         {
969             PushButton* pPushButton = (PushButton*)pSWindow;
970             if ( pPushButton->ImplIsDefButton() )
971                 pOldDefButton = pPushButton;
972             if ( pPushButton->HasChildPathFocus() )
973                 pNewDefButton = pPushButton;
974             else if ( !pNewDefButton && (pPushButton->GetStyle() & WB_DEFBUTTON) )
975                 pNewDefButton = pPushButton;
976         }
977 
978         pSWindow = ImplGetNextWindow( pParent, i, i, sal_False );
979         if ( !i || (i > nFormEnd) )
980             pSWindow = NULL;
981     }
982 
983     if ( !bGetFocus )
984     {
985         sal_uInt16 nDummy;
986         Window* pNewFocusWindow = Application::GetFocusWindow();
987         if ( !pNewFocusWindow || !pParent->ImplIsWindowOrChild( pNewFocusWindow ) )
988             pNewDefButton = NULL;
989         else if ( !::ImplFindDlgCtrlWindow( pParent, pNewFocusWindow, i, nDummy, nDummy ) ||
990                   (i < nFormStart) || (i > nFormEnd) )
991             pNewDefButton = NULL;
992     }
993 
994     if ( pOldDefButton != pNewDefButton )
995     {
996         if ( pOldDefButton )
997             pOldDefButton->ImplSetDefButton( sal_False );
998         if ( pNewDefButton )
999             pNewDefButton->ImplSetDefButton( sal_True );
1000     }
1001 }
1002 
1003 // -----------------------------------------------------------------------
1004 
1005 void Window::ImplDlgCtrlFocusChanged( Window* pWindow, sal_Bool bGetFocus )
1006 {
1007     if ( mpWindowImpl->mpDlgCtrlDownWindow && !bGetFocus )
1008     {
1009         ((PushButton*)mpWindowImpl->mpDlgCtrlDownWindow)->SetPressed( sal_False );
1010         mpWindowImpl->mpDlgCtrlDownWindow = NULL;
1011     }
1012 
1013     ImplDlgCtrlUpdateDefButton( this, pWindow, bGetFocus );
1014 }
1015 
1016 // -----------------------------------------------------------------------
1017 
1018 Window* Window::ImplFindDlgCtrlWindow( Window* pWindow )
1019 {
1020     sal_uInt16  nIndex;
1021     sal_uInt16  nFormStart;
1022     sal_uInt16  nFormEnd;
1023 
1024     // Focus-Fenster in der Child-Liste suchen und zurueckgeben
1025     return ::ImplFindDlgCtrlWindow( this, pWindow, nIndex, nFormStart, nFormEnd );
1026 }
1027 
1028 
1029 // -----------------------------------------------------------------------
1030 
1031 Window* Window::GetParentLabelFor( const Window* ) const
1032 {
1033     return NULL;
1034 }
1035 
1036 // -----------------------------------------------------------------------
1037 
1038 Window* Window::GetParentLabeledBy( const Window* ) const
1039 {
1040     return NULL;
1041 }
1042 
1043 // -----------------------------------------------------------------------
1044 
1045 static sal_Unicode getAccel( const String& rStr )
1046 {
1047     sal_Unicode nChar = 0;
1048     sal_uInt16 nPos = 0;
1049     do
1050     {
1051         nPos = rStr.Search( '~', nPos );
1052         if( nPos != STRING_NOTFOUND && nPos < rStr.Len() )
1053             nChar = rStr.GetChar( ++nPos );
1054         else
1055             nChar = 0;
1056     } while( nChar == '~' );
1057     return nChar;
1058 }
1059 
1060 static Window* ImplGetLabelFor( Window* pFrameWindow, WindowType nMyType, Window* pLabel, sal_Unicode nAccel )
1061 {
1062     Window* pWindow = NULL;
1063 
1064     if( nMyType == WINDOW_FIXEDTEXT		||
1065         nMyType == WINDOW_FIXEDLINE		||
1066         nMyType == WINDOW_GROUPBOX )
1067     {
1068         // #i100833# MT 2010/02: Group box and fixed lines can also lable a fixed text.
1069         // See tools/options/print for example.
1070         sal_Bool bThisIsAGroupControl = (nMyType == WINDOW_GROUPBOX) || (nMyType == WINDOW_FIXEDLINE);
1071         Window* pSWindow = NULL;
1072         // get index, form start and form end
1073         sal_uInt16 nIndex=0, nFormStart=0, nFormEnd=0;
1074         pSWindow = ::ImplFindDlgCtrlWindow( pFrameWindow,
1075                                            pLabel,
1076                                            nIndex,
1077                                            nFormStart,
1078                                            nFormEnd );
1079         if( nAccel )
1080         {
1081             // find the accelerated window
1082             pWindow = ::ImplFindAccelWindow( pFrameWindow,
1083                                              nIndex,
1084                                              nAccel,
1085                                              nFormStart,
1086                                              nFormEnd,
1087                                              sal_False );
1088         }
1089         else
1090         {
1091             // find the next control; if that is a fixed text
1092             // fixed line or group box, then return NULL
1093             while( nIndex < nFormEnd )
1094             {
1095                 nIndex++;
1096                 pSWindow = ::ImplGetChildWindow( pFrameWindow,
1097                                                  nIndex,
1098                                                  nIndex,
1099                                                  sal_False );
1100                 if( pSWindow && pSWindow->IsVisible() && ! (pSWindow->GetStyle() & WB_NOLABEL) )
1101                 {
1102                     WindowType nType = pSWindow->GetType();
1103                     if( nType != WINDOW_FIXEDTEXT	&&
1104                         nType != WINDOW_FIXEDLINE	&&
1105                         nType != WINDOW_GROUPBOX )
1106                     {
1107                         pWindow = pSWindow;
1108                     }
1109                     else if( bThisIsAGroupControl && ( nType == WINDOW_FIXEDTEXT ) )
1110                     {
1111                         pWindow = pSWindow;
1112                     }
1113                     break;
1114                 }
1115             }
1116         }
1117     }
1118 
1119     return pWindow;
1120 }
1121 
1122 Window* Window::GetAccessibleRelationLabelFor() const
1123 {
1124     if ( mpWindowImpl->mbDisableAccessibleLabelForRelation )
1125         return NULL;
1126 
1127 	if ( mpWindowImpl->mpAccessibleInfos && mpWindowImpl->mpAccessibleInfos->pLabelForWindow )
1128 		return mpWindowImpl->mpAccessibleInfos->pLabelForWindow;
1129 
1130 
1131     Window* pWindow = NULL;
1132     Window* pFrameWindow = ImplGetFrameWindow();
1133 
1134     WinBits nFrameStyle = pFrameWindow->GetStyle();
1135     if( ! ( nFrameStyle & WB_DIALOGCONTROL )
1136         || ( nFrameStyle & WB_NODIALOGCONTROL )
1137         )
1138         return NULL;
1139 
1140 	if ( mpWindowImpl->mpRealParent )
1141 		pWindow = mpWindowImpl->mpRealParent->GetParentLabelFor( this );
1142 
1143     if( pWindow )
1144         return pWindow;
1145 
1146     sal_Unicode nAccel = getAccel( GetText() );
1147 
1148     pWindow = ImplGetLabelFor( pFrameWindow, GetType(), const_cast<Window*>(this), nAccel );
1149     if( ! pWindow && mpWindowImpl->mpRealParent )
1150         pWindow = ImplGetLabelFor( mpWindowImpl->mpRealParent, GetType(), const_cast<Window*>(this), nAccel );
1151     return pWindow;
1152 }
1153 
1154 // -----------------------------------------------------------------------
1155 
1156 static Window* ImplGetLabeledBy( Window* pFrameWindow, WindowType nMyType, Window* pLabeled )
1157 {
1158     Window* pWindow = NULL;
1159     if ( (nMyType != WINDOW_GROUPBOX) && (nMyType != WINDOW_FIXEDLINE) )
1160     {
1161         // search for a control that labels this window
1162         // a label is considered the last fixed text, fixed line or group box
1163         // that comes before this control; with the exception of push buttons
1164         // which are labeled only if the fixed text, fixed line or group box
1165         // is directly before the control
1166 
1167         // get form start and form end and index of this control
1168         sal_uInt16 nIndex, nFormStart, nFormEnd;
1169         Window* pSWindow = ::ImplFindDlgCtrlWindow( pFrameWindow,
1170                                                     pLabeled,
1171                                                     nIndex,
1172                                                     nFormStart,
1173                                                     nFormEnd );
1174         if( pSWindow && nIndex != nFormStart )
1175         {
1176             if( nMyType == WINDOW_PUSHBUTTON		||
1177                 nMyType == WINDOW_HELPBUTTON		||
1178                 nMyType == WINDOW_OKBUTTON		||
1179                 nMyType == WINDOW_CANCELBUTTON )
1180             {
1181                 nFormStart = nIndex-1;
1182             }
1183             for( sal_uInt16 nSearchIndex = nIndex-1; nSearchIndex >= nFormStart; nSearchIndex-- )
1184             {
1185 				sal_uInt16 nFoundIndex = 0;
1186                 pSWindow = ::ImplGetChildWindow( pFrameWindow,
1187                                                  nSearchIndex,
1188                                                  nFoundIndex,
1189                                                  sal_False );
1190                 if( pSWindow && pSWindow->IsVisible() && !(pSWindow->GetStyle() & WB_NOLABEL) )
1191                 {
1192                     WindowType nType = pSWindow->GetType();
1193                     if ( ( nType == WINDOW_FIXEDTEXT	||
1194                           nType == WINDOW_FIXEDLINE	||
1195                           nType == WINDOW_GROUPBOX ) )
1196                     {
1197                         // a fixed text can't be labeld by a fixed text.
1198                         if ( ( nMyType != WINDOW_FIXEDTEXT ) || ( nType != WINDOW_FIXEDTEXT ) )
1199                             pWindow = pSWindow;
1200                         break;
1201                     }
1202                 }
1203 				if( nFoundIndex > nSearchIndex || nSearchIndex == 0 )
1204 					break;
1205             }
1206         }
1207     }
1208     return pWindow;
1209 }
1210 
1211 Window* Window::GetAccessibleRelationLabeledBy() const
1212 {
1213     if ( mpWindowImpl->mbDisableAccessibleLabeledByRelation )
1214         return NULL;
1215 
1216 	if ( mpWindowImpl->mpAccessibleInfos && mpWindowImpl->mpAccessibleInfos->pLabeledByWindow )
1217 		return mpWindowImpl->mpAccessibleInfos->pLabeledByWindow;
1218 
1219     Window* pWindow = NULL;
1220     Window* pFrameWindow = ImplGetFrameWindow();
1221 
1222 	if ( mpWindowImpl->mpRealParent )
1223 	{
1224 		pWindow = mpWindowImpl->mpRealParent->GetParentLabeledBy( this );
1225 
1226 		if( pWindow )
1227 		    return pWindow;
1228 	}
1229 
1230     // #i62723#, #104191# checkboxes and radiobuttons are not supposed to have labels
1231     if( GetType() == WINDOW_CHECKBOX || GetType() == WINDOW_RADIOBUTTON )
1232         return NULL;
1233 
1234 //    if( ! ( GetType() == WINDOW_FIXEDTEXT		||
1235 //            GetType() == WINDOW_FIXEDLINE		||
1236 //            GetType() == WINDOW_GROUPBOX ) )
1237     // #i100833# MT 2010/02: Group box and fixed lines can also lable a fixed text.
1238     // See tools/options/print for example.
1239 
1240     pWindow = ImplGetLabeledBy( pFrameWindow, GetType(), const_cast<Window*>(this) );
1241     if( ! pWindow && mpWindowImpl->mpRealParent )
1242         pWindow = ImplGetLabeledBy( mpWindowImpl->mpRealParent, GetType(), const_cast<Window*>(this) );
1243 
1244     return pWindow;
1245 }
1246 
1247 Window* Window::GetAccessibleRelationMemberOf() const
1248 {
1249 	Window* pWindow = NULL;
1250 	Window* pFrameWindow = GetParent();
1251 	if ( !pFrameWindow )
1252 	{
1253 		pFrameWindow = ImplGetFrameWindow();
1254 	}
1255 	// if( ! ( GetType() == WINDOW_FIXEDTEXT		||
1256 	if( !( GetType() == WINDOW_FIXEDLINE ||
1257 		GetType() == WINDOW_GROUPBOX ) )
1258 	{
1259 		// search for a control that makes member of this window
1260 		// it is considered the last fixed line or group box
1261 		// that comes before this control; with the exception of push buttons
1262 		// which are labeled only if the fixed line or group box
1263 		// is directly before the control
1264 		// get form start and form end and index of this control
1265 		sal_uInt16 nIndex, nFormStart, nFormEnd;
1266 		Window* pSWindow = ::ImplFindDlgCtrlWindow( pFrameWindow,
1267 			const_cast<Window*>(this),
1268 			nIndex,
1269 			nFormStart,
1270 			nFormEnd );
1271 		if( pSWindow && nIndex != nFormStart )
1272 		{
1273 			if( GetType() == WINDOW_PUSHBUTTON		||
1274 				GetType() == WINDOW_HELPBUTTON		||
1275 				GetType() == WINDOW_OKBUTTON		||
1276 				GetType() == WINDOW_CANCELBUTTON )
1277 			{
1278 				nFormStart = nIndex-1;
1279 			}
1280 			for( sal_uInt16 nSearchIndex = nIndex-1; nSearchIndex >= nFormStart; nSearchIndex-- )
1281 			{
1282 				sal_uInt16 nFoundIndex = 0;
1283 				pSWindow = ::ImplGetChildWindow( pFrameWindow,
1284 					nSearchIndex,
1285 					nFoundIndex,
1286 					sal_False );
1287 				if( pSWindow && pSWindow->IsVisible() &&
1288 					( pSWindow->GetType() == WINDOW_FIXEDLINE	||
1289 					pSWindow->GetType() == WINDOW_GROUPBOX ) )
1290 				{
1291 					pWindow = pSWindow;
1292 					break;
1293 				}
1294 				if( nFoundIndex > nSearchIndex || nSearchIndex == 0 )
1295 					break;
1296 			}
1297 		}
1298 	}
1299 	return pWindow;
1300 }
1301 //-----IAccessibility2 Implementation 2009
1302 
1303 // -----------------------------------------------------------------------
1304 
1305 KeyEvent Window::GetActivationKey() const
1306 {
1307     KeyEvent aKeyEvent;
1308 
1309     sal_Unicode nAccel = getAccel( GetText() );
1310     if( ! nAccel )
1311     {
1312         Window* pWindow = GetAccessibleRelationLabeledBy();
1313         if( pWindow )
1314             nAccel = getAccel( pWindow->GetText() );
1315     }
1316     if( nAccel )
1317     {
1318         sal_uInt16 nCode = 0;
1319         if( nAccel >= 'a' && nAccel <= 'z' )
1320             nCode = KEY_A + (nAccel-'a');
1321         else if( nAccel >= 'A' && nAccel <= 'Z' )
1322             nCode = KEY_A + (nAccel-'A');
1323         else if( nAccel >= '0' && nAccel <= '9' )
1324             nCode = KEY_0 + (nAccel-'0');
1325 		else if( nAccel == '.' )
1326 			nCode = KEY_POINT;
1327 		else if( nAccel == '-' )
1328 			nCode = KEY_SUBTRACT;
1329         KeyCode aKeyCode( nCode, sal_False, sal_False, sal_True, sal_False );
1330         aKeyEvent = KeyEvent( nAccel, aKeyCode );
1331     }
1332     return aKeyEvent;
1333 }
1334