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