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