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