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