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