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