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