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 //IAccessibility2 Implementation 2009----- 839 //Solution:Pure window shouldn't get window after controls such as buttons. 840 //if ( pWindow->IsVisible() && pWindow->IsEnabled() && pWindow->IsInputEnabled() ) 841 if ( pWindow->IsVisible() && pWindow->IsEnabled() && 842 pWindow->IsInputEnabled() && ( 843 pWindow->GetType() != WINDOW_WINDOW && 844 pWindow->GetType() != WINDOW_SYSWINDOW && 845 pWindow->GetType() != WINDOW_WORKWINDOW && 846 pWindow->GetType() != WINDOW_CONTROL 847 ) 848 ) 849 //-----IAccessibility2 Implementation 2009 850 { 851 pWindow->ImplControlFocus( GETFOCUS_CURSOR | GETFOCUS_BACKWARD ); 852 return sal_True; 853 } 854 855 pWindow = pWindow->GetWindow( WINDOW_NEXT ); 856 } 857 } 858 else 859 { 860 xub_Unicode c = rKEvt.GetCharCode(); 861 if ( c ) 862 { 863 pSWindow = ::ImplFindAccelWindow( this, i, c, nFormStart, nFormEnd ); 864 if ( pSWindow ) 865 { 866 sal_uInt16 nGetFocusFlags = GETFOCUS_MNEMONIC; 867 if ( pSWindow == ::ImplFindAccelWindow( this, i, c, nFormStart, nFormEnd ) ) 868 nGetFocusFlags |= GETFOCUS_UNIQUEMNEMONIC; 869 pSWindow->ImplControlFocus( nGetFocusFlags ); 870 return sal_True; 871 } 872 } 873 } 874 } 875 876 if ( pButtonWindow && pButtonWindow->IsVisible() && pButtonWindow->IsEnabled() && pButtonWindow->IsInputEnabled() ) 877 { 878 if ( bKeyInput ) 879 { 880 if ( mpWindowImpl->mpDlgCtrlDownWindow && (mpWindowImpl->mpDlgCtrlDownWindow != pButtonWindow) ) 881 { 882 ((PushButton*)mpWindowImpl->mpDlgCtrlDownWindow)->SetPressed( sal_False ); 883 mpWindowImpl->mpDlgCtrlDownWindow = NULL; 884 } 885 886 ((PushButton*)pButtonWindow)->SetPressed( sal_True ); 887 mpWindowImpl->mpDlgCtrlDownWindow = pButtonWindow; 888 } 889 else if ( mpWindowImpl->mpDlgCtrlDownWindow == pButtonWindow ) 890 { 891 mpWindowImpl->mpDlgCtrlDownWindow = NULL; 892 ((PushButton*)pButtonWindow)->SetPressed( sal_False ); 893 ((PushButton*)pButtonWindow)->Click(); 894 } 895 896 return sal_True; 897 } 898 899 return sal_False; 900 } 901 902 // ----------------------------------------------------------------------- 903 904 // checks if this window has dialog control 905 sal_Bool Window::ImplHasDlgCtrl() 906 { 907 Window* pDlgCtrlParent; 908 Window* pDlgCtrl; 909 910 // lookup window for dialog control 911 pDlgCtrl = this; 912 pDlgCtrlParent = ImplGetParent(); 913 while ( pDlgCtrlParent && 914 !pDlgCtrlParent->ImplIsOverlapWindow() && 915 ((pDlgCtrlParent->GetStyle() & (WB_DIALOGCONTROL | WB_NODIALOGCONTROL)) != WB_DIALOGCONTROL) ) 916 pDlgCtrlParent = pDlgCtrlParent->ImplGetParent(); 917 918 if ( !pDlgCtrlParent || ((pDlgCtrlParent->GetStyle() & (WB_DIALOGCONTROL | WB_NODIALOGCONTROL)) != WB_DIALOGCONTROL) ) 919 return sal_False; 920 else 921 return sal_True; 922 } 923 924 void Window::ImplDlgCtrlNextWindow() 925 { 926 Window* pDlgCtrlParent; 927 Window* pDlgCtrl; 928 Window* pSWindow; 929 sal_uInt16 nIndex; 930 sal_uInt16 nFormStart; 931 sal_uInt16 nFormEnd; 932 933 // lookup window for dialog control 934 pDlgCtrl = this; 935 pDlgCtrlParent = ImplGetParent(); 936 while ( pDlgCtrlParent && 937 !pDlgCtrlParent->ImplIsOverlapWindow() && 938 ((pDlgCtrlParent->GetStyle() & (WB_DIALOGCONTROL | WB_NODIALOGCONTROL)) != WB_DIALOGCONTROL) ) 939 pDlgCtrlParent = pDlgCtrlParent->ImplGetParent(); 940 941 if ( !pDlgCtrlParent || (GetStyle() & WB_NODIALOGCONTROL) || ((pDlgCtrlParent->GetStyle() & (WB_DIALOGCONTROL | WB_NODIALOGCONTROL)) != WB_DIALOGCONTROL) ) 942 return; 943 944 // lookup window in child list 945 pSWindow = ::ImplFindDlgCtrlWindow( pDlgCtrlParent, pDlgCtrl, 946 nIndex, nFormStart, nFormEnd ); 947 if ( !pSWindow ) 948 return; 949 950 Window* pWindow = pDlgCtrlParent->ImplGetDlgWindow( nIndex, DLGWINDOW_NEXT, nFormStart, nFormEnd ); 951 if ( pWindow && (pWindow != pSWindow) ) 952 pWindow->ImplControlFocus(); 953 } 954 955 // ----------------------------------------------------------------------- 956 957 static void ImplDlgCtrlUpdateDefButton( Window* pParent, Window* pFocusWindow, 958 sal_Bool bGetFocus ) 959 { 960 PushButton* pOldDefButton = NULL; 961 PushButton* pNewDefButton = NULL; 962 Window* pSWindow; 963 sal_uInt16 i; 964 sal_uInt16 nFormStart; 965 sal_uInt16 nFormEnd; 966 967 // Formular suchen 968 pSWindow = ::ImplFindDlgCtrlWindow( pParent, pFocusWindow, i, nFormStart, nFormEnd ); 969 if ( !pSWindow ) 970 { 971 nFormStart = 0; 972 nFormEnd = 0xFFFF; 973 } 974 975 pSWindow = ImplGetChildWindow( pParent, nFormStart, i, sal_False ); 976 while ( pSWindow ) 977 { 978 if ( pSWindow->ImplIsPushButton() ) 979 { 980 PushButton* pPushButton = (PushButton*)pSWindow; 981 if ( pPushButton->ImplIsDefButton() ) 982 pOldDefButton = pPushButton; 983 if ( pPushButton->HasChildPathFocus() ) 984 pNewDefButton = pPushButton; 985 else if ( !pNewDefButton && (pPushButton->GetStyle() & WB_DEFBUTTON) ) 986 pNewDefButton = pPushButton; 987 } 988 989 pSWindow = ImplGetNextWindow( pParent, i, i, sal_False ); 990 if ( !i || (i > nFormEnd) ) 991 pSWindow = NULL; 992 } 993 994 if ( !bGetFocus ) 995 { 996 sal_uInt16 nDummy; 997 Window* pNewFocusWindow = Application::GetFocusWindow(); 998 if ( !pNewFocusWindow || !pParent->ImplIsWindowOrChild( pNewFocusWindow ) ) 999 pNewDefButton = NULL; 1000 else if ( !::ImplFindDlgCtrlWindow( pParent, pNewFocusWindow, i, nDummy, nDummy ) || 1001 (i < nFormStart) || (i > nFormEnd) ) 1002 pNewDefButton = NULL; 1003 } 1004 1005 if ( pOldDefButton != pNewDefButton ) 1006 { 1007 if ( pOldDefButton ) 1008 pOldDefButton->ImplSetDefButton( sal_False ); 1009 if ( pNewDefButton ) 1010 pNewDefButton->ImplSetDefButton( sal_True ); 1011 } 1012 } 1013 1014 // ----------------------------------------------------------------------- 1015 1016 void Window::ImplDlgCtrlFocusChanged( Window* pWindow, sal_Bool bGetFocus ) 1017 { 1018 if ( mpWindowImpl->mpDlgCtrlDownWindow && !bGetFocus ) 1019 { 1020 ((PushButton*)mpWindowImpl->mpDlgCtrlDownWindow)->SetPressed( sal_False ); 1021 mpWindowImpl->mpDlgCtrlDownWindow = NULL; 1022 } 1023 1024 ImplDlgCtrlUpdateDefButton( this, pWindow, bGetFocus ); 1025 } 1026 1027 // ----------------------------------------------------------------------- 1028 1029 Window* Window::ImplFindDlgCtrlWindow( Window* pWindow ) 1030 { 1031 sal_uInt16 nIndex; 1032 sal_uInt16 nFormStart; 1033 sal_uInt16 nFormEnd; 1034 1035 // Focus-Fenster in der Child-Liste suchen und zurueckgeben 1036 return ::ImplFindDlgCtrlWindow( this, pWindow, nIndex, nFormStart, nFormEnd ); 1037 } 1038 1039 1040 // ----------------------------------------------------------------------- 1041 1042 Window* Window::GetParentLabelFor( const Window* ) const 1043 { 1044 return NULL; 1045 } 1046 1047 // ----------------------------------------------------------------------- 1048 1049 Window* Window::GetParentLabeledBy( const Window* ) const 1050 { 1051 return NULL; 1052 } 1053 1054 // ----------------------------------------------------------------------- 1055 1056 static sal_Unicode getAccel( const String& rStr ) 1057 { 1058 sal_Unicode nChar = 0; 1059 sal_uInt16 nPos = 0; 1060 do 1061 { 1062 nPos = rStr.Search( '~', nPos ); 1063 if( nPos != STRING_NOTFOUND && nPos < rStr.Len() ) 1064 nChar = rStr.GetChar( ++nPos ); 1065 else 1066 nChar = 0; 1067 } while( nChar == '~' ); 1068 return nChar; 1069 } 1070 1071 static Window* ImplGetLabelFor( Window* pFrameWindow, WindowType nMyType, Window* pLabel, sal_Unicode nAccel ) 1072 { 1073 Window* pWindow = NULL; 1074 1075 if( nMyType == WINDOW_FIXEDTEXT || 1076 nMyType == WINDOW_FIXEDLINE || 1077 nMyType == WINDOW_GROUPBOX ) 1078 { 1079 // #i100833# MT 2010/02: Group box and fixed lines can also lable a fixed text. 1080 // See tools/options/print for example. 1081 sal_Bool bThisIsAGroupControl = (nMyType == WINDOW_GROUPBOX) || (nMyType == WINDOW_FIXEDLINE); 1082 Window* pSWindow = NULL; 1083 // get index, form start and form end 1084 sal_uInt16 nIndex=0, nFormStart=0, nFormEnd=0; 1085 pSWindow = ::ImplFindDlgCtrlWindow( pFrameWindow, 1086 pLabel, 1087 nIndex, 1088 nFormStart, 1089 nFormEnd ); 1090 if( nAccel ) 1091 { 1092 // find the accelerated window 1093 pWindow = ::ImplFindAccelWindow( pFrameWindow, 1094 nIndex, 1095 nAccel, 1096 nFormStart, 1097 nFormEnd, 1098 sal_False ); 1099 } 1100 else 1101 { 1102 // find the next control; if that is a fixed text 1103 // fixed line or group box, then return NULL 1104 while( nIndex < nFormEnd ) 1105 { 1106 nIndex++; 1107 pSWindow = ::ImplGetChildWindow( pFrameWindow, 1108 nIndex, 1109 nIndex, 1110 sal_False ); 1111 if( pSWindow && pSWindow->IsVisible() && ! (pSWindow->GetStyle() & WB_NOLABEL) ) 1112 { 1113 WindowType nType = pSWindow->GetType(); 1114 if( nType != WINDOW_FIXEDTEXT && 1115 nType != WINDOW_FIXEDLINE && 1116 nType != WINDOW_GROUPBOX ) 1117 { 1118 pWindow = pSWindow; 1119 } 1120 else if( bThisIsAGroupControl && ( nType == WINDOW_FIXEDTEXT ) ) 1121 { 1122 pWindow = pSWindow; 1123 } 1124 break; 1125 } 1126 } 1127 } 1128 } 1129 1130 return pWindow; 1131 } 1132 1133 Window* Window::GetAccessibleRelationLabelFor() const 1134 { 1135 if ( mpWindowImpl->mbDisableAccessibleLabelForRelation ) 1136 return NULL; 1137 1138 if ( mpWindowImpl->mpAccessibleInfos && mpWindowImpl->mpAccessibleInfos->pLabelForWindow ) 1139 return mpWindowImpl->mpAccessibleInfos->pLabelForWindow; 1140 1141 1142 Window* pWindow = NULL; 1143 Window* pFrameWindow = ImplGetFrameWindow(); 1144 1145 WinBits nFrameStyle = pFrameWindow->GetStyle(); 1146 if( ! ( nFrameStyle & WB_DIALOGCONTROL ) 1147 || ( nFrameStyle & WB_NODIALOGCONTROL ) 1148 ) 1149 return NULL; 1150 1151 if ( mpWindowImpl->mpRealParent ) 1152 pWindow = mpWindowImpl->mpRealParent->GetParentLabelFor( this ); 1153 1154 if( pWindow ) 1155 return pWindow; 1156 1157 sal_Unicode nAccel = getAccel( GetText() ); 1158 1159 pWindow = ImplGetLabelFor( pFrameWindow, GetType(), const_cast<Window*>(this), nAccel ); 1160 if( ! pWindow && mpWindowImpl->mpRealParent ) 1161 pWindow = ImplGetLabelFor( mpWindowImpl->mpRealParent, GetType(), const_cast<Window*>(this), nAccel ); 1162 return pWindow; 1163 } 1164 1165 // ----------------------------------------------------------------------- 1166 1167 static Window* ImplGetLabeledBy( Window* pFrameWindow, WindowType nMyType, Window* pLabeled ) 1168 { 1169 Window* pWindow = NULL; 1170 if ( (nMyType != WINDOW_GROUPBOX) && (nMyType != WINDOW_FIXEDLINE) ) 1171 { 1172 // search for a control that labels this window 1173 // a label is considered the last fixed text, fixed line or group box 1174 // that comes before this control; with the exception of push buttons 1175 // which are labeled only if the fixed text, fixed line or group box 1176 // is directly before the control 1177 1178 // get form start and form end and index of this control 1179 sal_uInt16 nIndex, nFormStart, nFormEnd; 1180 Window* pSWindow = ::ImplFindDlgCtrlWindow( pFrameWindow, 1181 pLabeled, 1182 nIndex, 1183 nFormStart, 1184 nFormEnd ); 1185 if( pSWindow && nIndex != nFormStart ) 1186 { 1187 if( nMyType == WINDOW_PUSHBUTTON || 1188 nMyType == WINDOW_HELPBUTTON || 1189 nMyType == WINDOW_OKBUTTON || 1190 nMyType == WINDOW_CANCELBUTTON ) 1191 { 1192 nFormStart = nIndex-1; 1193 } 1194 for( sal_uInt16 nSearchIndex = nIndex-1; nSearchIndex >= nFormStart; nSearchIndex-- ) 1195 { 1196 sal_uInt16 nFoundIndex = 0; 1197 pSWindow = ::ImplGetChildWindow( pFrameWindow, 1198 nSearchIndex, 1199 nFoundIndex, 1200 sal_False ); 1201 if( pSWindow && pSWindow->IsVisible() && !(pSWindow->GetStyle() & WB_NOLABEL) ) 1202 { 1203 WindowType nType = pSWindow->GetType(); 1204 if ( ( nType == WINDOW_FIXEDTEXT || 1205 nType == WINDOW_FIXEDLINE || 1206 nType == WINDOW_GROUPBOX ) ) 1207 { 1208 // a fixed text can't be labeld by a fixed text. 1209 if ( ( nMyType != WINDOW_FIXEDTEXT ) || ( nType != WINDOW_FIXEDTEXT ) ) 1210 pWindow = pSWindow; 1211 break; 1212 } 1213 } 1214 if( nFoundIndex > nSearchIndex || nSearchIndex == 0 ) 1215 break; 1216 } 1217 } 1218 } 1219 return pWindow; 1220 } 1221 1222 Window* Window::GetAccessibleRelationLabeledBy() const 1223 { 1224 if ( mpWindowImpl->mbDisableAccessibleLabeledByRelation ) 1225 return NULL; 1226 1227 if ( mpWindowImpl->mpAccessibleInfos && mpWindowImpl->mpAccessibleInfos->pLabeledByWindow ) 1228 return mpWindowImpl->mpAccessibleInfos->pLabeledByWindow; 1229 1230 Window* pWindow = NULL; 1231 Window* pFrameWindow = ImplGetFrameWindow(); 1232 1233 if ( mpWindowImpl->mpRealParent ) 1234 { 1235 pWindow = mpWindowImpl->mpRealParent->GetParentLabeledBy( this ); 1236 1237 if( pWindow ) 1238 return pWindow; 1239 } 1240 1241 // #i62723#, #104191# checkboxes and radiobuttons are not supposed to have labels 1242 if( GetType() == WINDOW_CHECKBOX || GetType() == WINDOW_RADIOBUTTON ) 1243 return NULL; 1244 1245 // if( ! ( GetType() == WINDOW_FIXEDTEXT || 1246 // GetType() == WINDOW_FIXEDLINE || 1247 // GetType() == WINDOW_GROUPBOX ) ) 1248 // #i100833# MT 2010/02: Group box and fixed lines can also lable a fixed text. 1249 // See tools/options/print for example. 1250 1251 pWindow = ImplGetLabeledBy( pFrameWindow, GetType(), const_cast<Window*>(this) ); 1252 if( ! pWindow && mpWindowImpl->mpRealParent ) 1253 pWindow = ImplGetLabeledBy( mpWindowImpl->mpRealParent, GetType(), const_cast<Window*>(this) ); 1254 1255 return pWindow; 1256 } 1257 1258 Window* Window::GetAccessibleRelationMemberOf() const 1259 { 1260 Window* pWindow = NULL; 1261 Window* pFrameWindow = GetParent(); 1262 if ( !pFrameWindow ) 1263 { 1264 pFrameWindow = ImplGetFrameWindow(); 1265 } 1266 // if( ! ( GetType() == WINDOW_FIXEDTEXT || 1267 if( !( GetType() == WINDOW_FIXEDLINE || 1268 GetType() == WINDOW_GROUPBOX ) ) 1269 { 1270 // search for a control that makes member of this window 1271 // it is considered the last fixed line or group box 1272 // that comes before this control; with the exception of push buttons 1273 // which are labeled only if the fixed line or group box 1274 // is directly before the control 1275 // get form start and form end and index of this control 1276 sal_uInt16 nIndex, nFormStart, nFormEnd; 1277 Window* pSWindow = ::ImplFindDlgCtrlWindow( pFrameWindow, 1278 const_cast<Window*>(this), 1279 nIndex, 1280 nFormStart, 1281 nFormEnd ); 1282 if( pSWindow && nIndex != nFormStart ) 1283 { 1284 if( GetType() == WINDOW_PUSHBUTTON || 1285 GetType() == WINDOW_HELPBUTTON || 1286 GetType() == WINDOW_OKBUTTON || 1287 GetType() == WINDOW_CANCELBUTTON ) 1288 { 1289 nFormStart = nIndex-1; 1290 } 1291 for( sal_uInt16 nSearchIndex = nIndex-1; nSearchIndex >= nFormStart; nSearchIndex-- ) 1292 { 1293 sal_uInt16 nFoundIndex = 0; 1294 pSWindow = ::ImplGetChildWindow( pFrameWindow, 1295 nSearchIndex, 1296 nFoundIndex, 1297 sal_False ); 1298 if( pSWindow && pSWindow->IsVisible() && 1299 ( pSWindow->GetType() == WINDOW_FIXEDLINE || 1300 pSWindow->GetType() == WINDOW_GROUPBOX ) ) 1301 { 1302 pWindow = pSWindow; 1303 break; 1304 } 1305 if( nFoundIndex > nSearchIndex || nSearchIndex == 0 ) 1306 break; 1307 } 1308 } 1309 } 1310 return pWindow; 1311 } 1312 //-----IAccessibility2 Implementation 2009 1313 1314 // ----------------------------------------------------------------------- 1315 1316 KeyEvent Window::GetActivationKey() const 1317 { 1318 KeyEvent aKeyEvent; 1319 1320 sal_Unicode nAccel = getAccel( GetText() ); 1321 if( ! nAccel ) 1322 { 1323 Window* pWindow = GetAccessibleRelationLabeledBy(); 1324 if( pWindow ) 1325 nAccel = getAccel( pWindow->GetText() ); 1326 } 1327 if( nAccel ) 1328 { 1329 sal_uInt16 nCode = 0; 1330 if( nAccel >= 'a' && nAccel <= 'z' ) 1331 nCode = KEY_A + (nAccel-'a'); 1332 else if( nAccel >= 'A' && nAccel <= 'Z' ) 1333 nCode = KEY_A + (nAccel-'A'); 1334 else if( nAccel >= '0' && nAccel <= '9' ) 1335 nCode = KEY_0 + (nAccel-'0'); 1336 else if( nAccel == '.' ) 1337 nCode = KEY_POINT; 1338 else if( nAccel == '-' ) 1339 nCode = KEY_SUBTRACT; 1340 KeyCode aKeyCode( nCode, sal_False, sal_False, sal_True, sal_False ); 1341 aKeyEvent = KeyEvent( nAccel, aKeyCode ); 1342 } 1343 return aKeyEvent; 1344 } 1345