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