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_automation.hxx" 26 #include <tools/time.hxx> 27 #include <vcl/splitwin.hxx> 28 #include <vcl/wrkwin.hxx> 29 #ifndef _BASIC_TTRESHLP_HXX 30 #include <basic/ttstrhlp.hxx> 31 #endif 32 #include "statemnt.hxx" 33 34 #ifndef _RETSRTM_HXX 35 #include "retstrm.hxx" 36 #endif 37 #include "rcontrol.hxx" 38 39 #if OSL_DEBUG_LEVEL > 1 40 #include "editwin.hxx" 41 #endif 42 43 #include "profiler.hxx" 44 #include <vcl/floatwin.hxx> 45 #include <vcl/toolbox.hxx> 46 47 // only needed for dynamic_cast in wintree 48 #include <svtools/editbrowsebox.hxx> 49 #include <svtools/valueset.hxx> 50 #include <svtools/roadmap.hxx> 51 #include <svtools/extensionlistbox.hxx> 52 #include <svtools/table/tablecontrol.hxx> 53 54 #define WINDOW_ANYTYPE WINDOW_BASE 55 56 57 TTProfiler *StatementList::pProfiler = NULL; 58 StatementList *StatementList::pFirst = NULL; 59 sal_Bool StatementList::bReadingCommands = sal_False; 60 sal_Bool StatementList::bIsInReschedule = sal_False; 61 sal_uInt16 StatementList::nModalCount = 0; 62 Window *StatementList::pLastFocusWindow = NULL; 63 sal_Bool StatementList::bWasDragManager = sal_False; 64 sal_Bool StatementList::bWasPopupMenu = sal_False; 65 sal_Bool StatementList::bBasicWasRunning = sal_False; 66 RetStream *StatementList::pRet = NULL; 67 sal_Bool StatementList::IsError = sal_False; 68 sal_Bool StatementList::bDying = sal_False; 69 sal_Bool StatementList::bExecuting = sal_False; 70 StatementList *StatementList::pCurrentProfileStatement = NULL; 71 sal_Bool StatementList::bUsePostEvents = sal_True; 72 #if OSL_DEBUG_LEVEL > 1 73 EditWindow *StatementList::m_pDbgWin; 74 #endif 75 76 77 rtl::OString StatementList::aWindowWaitUId = rtl::OString(); 78 Window *StatementList::pWindowWaitPointer = NULL; 79 rtl::OString StatementList::aWindowWaitOldHelpId = rtl::OString(); 80 rtl::OString StatementList::aWindowWaitOldUniqueId = rtl::OString(); 81 sal_uInt16 StatementList::nUseBindings = 0; 82 83 sal_uInt16 StatementList::aSubMenuId1 = 0; // Untermen�s bei PopupMenus 84 sal_uInt16 StatementList::aSubMenuId2 = 0; // erstmal 2-Stufig 85 sal_uInt16 StatementList::aSubMenuId3 = 0; // and now even 3 levels #i31512# 86 SystemWindow *StatementList::pMenuWindow = NULL; 87 TTProperties *StatementList::pTTProperties = NULL; 88 89 sal_uInt16 StatementList::nMinTypeKeysDelay = 0; // Verz�gerung der einzelnen Anschl�ge f�r TypeKeys 90 sal_uInt16 StatementList::nMaxTypeKeysDelay = 0; 91 sal_Bool StatementList::bDoTypeKeysDelay = sal_False; 92 93 Window* StatementList::pFirstDocFrame = NULL; 94 95 sal_Bool StatementList::bIsSlotInExecute = sal_False; 96 97 sal_Bool StatementList::bCatchGPF = sal_True; 98 99 100 IMPL_GEN_RES_STR; 101 102 103 static TTSettings* pTTSettings = NULL; 104 105 TTSettings* GetTTSettings() 106 { 107 if ( !pTTSettings ) 108 { 109 pTTSettings = new TTSettings; 110 111 // DisplayHID 112 pTTSettings->pDisplayInstance = NULL; 113 pTTSettings->pDisplayHidWin = NULL; 114 pTTSettings->Old = NULL; 115 pTTSettings->Act = NULL; 116 pTTSettings->aOriginalCaption.Erase(); 117 118 // Translate 119 pTTSettings->pTranslateWin = NULL; 120 pTTSettings->bToTop = sal_True; 121 } 122 123 return pTTSettings; 124 } 125 126 127 128 129 // FIXME: HELPID 130 #define IS_WINP_CLOSING(pWin) (pWin->GetHelpId().equals( "TT_Win_is_closing_HID" ) && pWin->GetUniqueId().equals( "TT_Win_is_closing_UID" )) 131 132 /* 133 UniString GEN_RES_STR0( sal_uLong nResId ) { return ResString( nResId ); } 134 UniString GEN_RES_STR1( sal_uLong nResId, const UniString &Text1 ) { return GEN_RES_STR0( nResId ).Append( ArgString( 1, Text1 ) ); } 135 UniString GEN_RES_STR2( sal_uLong nResId, const UniString &Text1, const UniString &Text2 ) { return GEN_RES_STR1( nResId, Text1 ).Append( ArgString( 2, Text2 ) ); } 136 UniString GEN_RES_STR3( sal_uLong nResId, const UniString &Text1, const UniString &Text2, const UniString &Text3 ) { return GEN_RES_STR2( nResId, Text1, Text2 ).Append( ArgString( 3, Text3 ) );} 137 */ 138 StatementList::StatementList() 139 : nRetryCount(MAX_RETRIES) 140 , bStatementInQue(sal_False) 141 { 142 if (!pRet) 143 pRet = new RetStream; // so Sp�t wie m�glich, aber dennoch Zentral und auf jeden Fall rechtzeitig, da pRet private ist. 144 } 145 146 void StatementList::InitProfile() 147 { 148 if ( pProfiler ) 149 { 150 if ( pProfiler->IsProfilingPerCommand() || pProfiler->IsPartitioning() ) 151 pProfiler->StartProfileInterval( pCurrentProfileStatement != this ); 152 153 #if OSL_DEBUG_LEVEL > 1 154 if ( pCurrentProfileStatement != NULL && pCurrentProfileStatement != this ) 155 pRet->GenReturn( RET_ProfileInfo, 0, CUniString("InitProfile von anderem Statement gerufen ohne SendProfile\n") ); 156 #endif 157 pCurrentProfileStatement = this; 158 } 159 } 160 161 void StatementList::SendProfile( String aText ) 162 { 163 if ( pProfiler ) 164 { 165 if ( pCurrentProfileStatement == this ) 166 { 167 if ( pProfiler->IsProfilingPerCommand() || pProfiler->IsPartitioning() ) 168 pProfiler->EndProfileInterval(); 169 170 if ( pProfiler->IsProfilingPerCommand() ) 171 pRet->GenReturn( RET_ProfileInfo, 0, pProfiler->GetProfileLine( aText ) ); 172 173 if ( pProfiler->IsPartitioning() ) 174 // FIXME: HELPID 175 pRet->GenReturn( RET_ProfileInfo, S_ProfileTime, static_cast<comm_ULONG>(pProfiler->GetPartitioningTime()) ); // GetPartitioningTime() sal_uLong != comm_ULONG on 64bit 176 } 177 178 if ( pProfiler->IsAutoProfiling() ) 179 pRet->GenReturn( RET_ProfileInfo, 0, pProfiler->GetAutoProfiling() ); 180 181 #if OSL_DEBUG_LEVEL > 1 182 if ( pCurrentProfileStatement == NULL ) 183 pRet->GenReturn( RET_ProfileInfo, 0, CUniString("SendProfile ohne InitProfile\n") ); 184 #endif 185 pCurrentProfileStatement = NULL; 186 } 187 } 188 189 void StatementList::QueStatement(StatementList *pAfterThis) 190 { 191 DBG_ASSERT(!bStatementInQue,"QueStatement f�r bereits eingetragenes Statement -> Abgebrochen"); 192 if ( bStatementInQue ) 193 return; 194 195 bStatementInQue = sal_True; 196 if ( pAfterThis ) 197 { 198 if ( pAfterThis->bStatementInQue ) 199 { 200 pNext = pAfterThis->pNext; 201 pAfterThis->pNext = this; 202 } 203 else 204 { // pAfterThis not in que -> already dequed -> add to front of list 205 pNext = pFirst; 206 pFirst = this; 207 } 208 } 209 else // am Ende einf�gen 210 { 211 pNext = NULL; 212 if( !pFirst ) 213 pFirst = this; 214 else 215 { 216 StatementList *pList; 217 pList = pFirst; 218 while( pList->pNext ) 219 pList = pList->pNext; 220 pList->pNext = this; 221 } 222 } 223 } 224 225 void StatementList::Advance() 226 { // pFirst ist static! 227 pFirst = pNext; 228 bStatementInQue = sal_False; 229 pNext = NULL; 230 } 231 232 233 StatementList::~StatementList() 234 { 235 #if OSL_DEBUG_LEVEL > 1 236 m_pDbgWin->AddText( "Deleting \n" ); 237 #endif 238 DBG_ASSERT(!bReadingCommands,"Deleting commands while reading them!"); 239 } 240 241 Window* StatementList::GetDocWin( sal_uInt16 nNr ) 242 { 243 Window* pBase = Application::GetFirstTopLevelWindow(); 244 245 while ( pBase ) 246 { 247 if ( IsDocWin( pBase ) ) 248 { 249 if ( !nNr ) 250 return pBase; 251 nNr--; 252 } 253 pBase = Application::GetNextTopLevelWindow( pBase ); 254 } 255 return NULL; 256 } 257 258 sal_uInt16 StatementList::GetDocFrameCount() 259 { 260 Window* pBase = Application::GetFirstTopLevelWindow(); 261 sal_uInt16 nCount = 0; 262 263 while ( pBase ) 264 { 265 if ( IsDocFrame( pBase ) ) 266 nCount++; 267 pBase = Application::GetNextTopLevelWindow( pBase ); 268 } 269 return nCount; 270 } 271 272 sal_uInt16 StatementList::GetDocWinCount() 273 { 274 Window* pBase = Application::GetFirstTopLevelWindow(); 275 sal_uInt16 nCount = 0; 276 277 while ( pBase ) 278 { 279 if ( IsDocWin( pBase ) ) 280 nCount++; 281 pBase = Application::GetNextTopLevelWindow( pBase ); 282 } 283 return nCount; 284 } 285 286 Window* StatementList::SearchAllWin( Window *pBase, Search &aSearch, sal_Bool MaybeBase ) 287 { 288 289 if ( !pBase && !aSearch.HasSearchFlag( SEARCH_NO_TOPLEVEL_WIN ) ) 290 { 291 sal_Bool bSearchFocusFirst = aSearch.HasSearchFlag( SEARCH_FOCUS_FIRST ); 292 293 Window *pControl = NULL; 294 if ( bSearchFocusFirst ) 295 { 296 // first test Parent of Focus Window 297 pBase = Application::GetFocusWindow(); 298 if ( pBase ) 299 { 300 DBG_ASSERT( WinPtrValid( pBase ), "GetFocusWindow is no valid WindowPointer" ); 301 Window *pPParent = pBase; 302 while ( pPParent->GET_REAL_PARENT() ) 303 pPParent = pPParent->GET_REAL_PARENT(); 304 305 // if ( !IsFirstDocFrame( pPParent ) ) 306 // { 307 // get overlap window. Will be dialog else document itself 308 pBase = pBase->GetWindow( WINDOW_OVERLAP ); 309 310 // set flag to find disabled elements. 311 // This is better than an enabled one on another Window 312 aSearch.AddSearchFlags( SEARCH_FIND_DISABLED ); 313 314 // search on current Dialog first 315 pControl = SearchAllWin( pBase, aSearch ); 316 317 // search on current Document 318 if ( !pControl && pBase != pPParent ) 319 pControl = SearchAllWin( pPParent, aSearch ); 320 321 aSearch.RemoveSearchFlags( SEARCH_FIND_DISABLED ); 322 323 if ( pControl ) 324 return pControl; 325 // } 326 } 327 } 328 329 pBase = Application::GetFirstTopLevelWindow(); 330 331 // Skip FirstDocFrame 332 // if ( bSearchFocusFirst && IsFirstDocFrame( pBase ) ) 333 // pBase = Application::GetNextTopLevelWindow( pBase ); 334 335 while ( pBase ) 336 { 337 pControl = SearchAllWin( pBase, aSearch ); 338 if ( pControl ) 339 return pControl; 340 341 pBase = Application::GetNextTopLevelWindow( pBase ); 342 // Skip FirstDocFrame 343 // if ( bSearchFocusFirst && IsFirstDocFrame( pBase ) ) 344 // pBase = Application::GetNextTopLevelWindow( pBase ); 345 } 346 return NULL; 347 } 348 349 350 Window *pResult = NULL; 351 pResult = SearchClientWin( pBase, aSearch, MaybeBase ); 352 if ( pResult ) 353 return pResult; 354 355 // if ( pBase->GetType() != WINDOW_BORDERWINDOW ) 356 // return NULL; 357 358 if ( !aSearch.HasSearchFlag( SEARCH_NOOVERLAP ) ) 359 { 360 if ( pBase->GetWindow( WINDOW_FIRSTOVERLAP ) ) 361 pResult = SearchAllWin( pBase->GetWindow( WINDOW_FIRSTOVERLAP ), aSearch ); 362 363 if ( !pResult && pBase->GetWindow( WINDOW_NEXT ) ) 364 pResult = SearchAllWin( pBase->GetWindow( WINDOW_NEXT ), aSearch ); 365 } 366 367 return pResult; 368 } 369 370 371 Window* StatementList::SearchClientWin( Window *pBase, Search &aSearch, sal_Bool MaybeBase ) 372 { 373 if ( !pBase ) 374 return NULL; 375 376 if ( MaybeBase && aSearch.IsWinOK( pBase ) ) 377 return pBase; 378 379 Window *pResult = NULL; 380 381 sal_uInt16 i; 382 for( i = 0 ; i < pBase->GetChildCount() && !pResult; i++ ) 383 pResult = SearchClientWin( pBase->GetChild(i), aSearch ); 384 385 return pResult; 386 } 387 388 389 sal_Bool SearchUID::IsWinOK( Window *pWin ) 390 { 391 if ( aUId.equals( pWin->GetUniqueOrHelpId() ) ) 392 { 393 if ( ( pWin->IsEnabled() || HasSearchFlag( SEARCH_FIND_DISABLED ) ) && pWin->IsVisible() ) 394 return sal_True; 395 else 396 { 397 if ( !pMaybeResult ) 398 pMaybeResult = pWin; 399 return sal_False; 400 } 401 } 402 else if ( pWin->GetType() == WINDOW_TOOLBOX ) // Buttons and Controls on ToolBox. 403 { 404 ToolBox *pTB = ((ToolBox*)pWin); 405 sal_uInt16 i; 406 for ( i = 0; i < pTB->GetItemCount() ; i++ ) 407 { 408 if ( aUId.equals( Str2Id( pTB->GetItemCommand(pTB->GetItemId( i )) ) ) || aUId.equals( pTB->GetHelpId(pTB->GetItemId( i )) ) ) 409 { // ID matches. 410 Window *pItemWin; 411 pItemWin = pTB->GetItemWindow( pTB->GetItemId( i ) ); 412 413 if ( bSearchButtonOnToolbox && pTB->GetItemType( i ) == TOOLBOXITEM_BUTTON && !pItemWin ) 414 { // We got a Control, see if its valid also. 415 // Same as above. 416 if ( ( pTB->IsEnabled() || HasSearchFlag( SEARCH_FIND_DISABLED ) ) && pTB->IsVisible() ) 417 { // We got a Button, see if its valid also. 418 if ( ( pTB->IsItemEnabled(pTB->GetItemId(i)) || HasSearchFlag( SEARCH_FIND_DISABLED ) ) 419 && pTB->IsItemVisible(pTB->GetItemId(i)) ) 420 return sal_True; // We got a Button. 421 else 422 { // better a disabled Button on a valid ToolBox than an invalid ToolBox as below 423 pMaybeResult = pTB; 424 return sal_False; 425 } 426 } 427 else if ( !pMaybeResult ) 428 { // invalid ToolBox 429 pMaybeResult = pTB; 430 return sal_False; 431 } 432 } 433 if ( pItemWin ) 434 { // We got a Control, see if its valid also. 435 // Same as above. 436 if ( ( pItemWin->IsEnabled() || HasSearchFlag( SEARCH_FIND_DISABLED ) ) && pItemWin->IsVisible() ) 437 { 438 if ( !pAlternateResult ) // only take the first found ItemWindow #i35365 439 pAlternateResult = pItemWin; // since we cannot return a Window here 440 return sal_False; // continue searching to prefer a window with the right ID #i32292 441 } 442 else if ( !pMaybeResult ) 443 { 444 pMaybeResult = pItemWin; 445 return sal_False; 446 } 447 } 448 } 449 } 450 return sal_False; 451 } 452 else 453 return sal_False; 454 } 455 456 Window* StatementList::SearchTree( rtl::OString aUId ,sal_Bool bSearchButtonOnToolbox ) 457 { 458 SearchUID aSearch(aUId,bSearchButtonOnToolbox); 459 460 Window *pResult = SearchAllWin( NULL, aSearch ); 461 if ( pResult ) 462 return pResult; 463 else if ( aSearch.GetAlternateResultWin() ) 464 return aSearch.GetAlternateResultWin(); 465 else 466 return aSearch.GetMaybeWin(); 467 } 468 469 470 sal_Bool SearchWinPtr::IsWinOK( Window *pWin ) 471 { 472 return pWin == pTest; 473 } 474 475 sal_Bool StatementList::WinPtrValid(Window *pTest) 476 { 477 SearchWinPtr aSearch( pTest ); 478 return SearchAllWin( NULL, aSearch ) != NULL; 479 } 480 481 482 sal_Bool SearchRT::IsWinOK( Window *pWin ) 483 { 484 if ( pWin->IsVisible() && pWin->GetType() == mnRT ) 485 { 486 mnCount++; 487 if ( mnSkip ) 488 { 489 mnSkip--; 490 return sal_False; 491 } 492 else 493 return sal_True; 494 } 495 return sal_False; 496 } 497 498 Window* StatementList::GetWinByRT( Window *pBase, WindowType nRT, sal_Bool MaybeBase, sal_uInt16 nSkip, sal_Bool bSearchAll ) 499 { 500 SearchRT aSearch( nRT, 0, nSkip ); 501 if ( bSearchAll ) 502 aSearch.AddSearchFlags( SEARCH_FOCUS_FIRST | SEARCH_FIND_DISABLED ); 503 else 504 aSearch.AddSearchFlags( SEARCH_NOOVERLAP | SEARCH_NO_TOPLEVEL_WIN ); 505 506 return SearchAllWin( pBase, aSearch, MaybeBase ); 507 } 508 509 sal_uInt16 StatementList::CountWinByRT( Window *pBase, WindowType nRT, sal_Bool MaybeBase ) 510 { 511 SearchRT aSearch( nRT, SEARCH_NOOVERLAP | SEARCH_NO_TOPLEVEL_WIN, 0xFFFF ); 512 513 SearchAllWin( pBase, aSearch, MaybeBase ); 514 return aSearch.GetCount(); 515 } 516 517 sal_Bool SearchScroll::IsWinOK( Window *pWin ) 518 { 519 if ( SearchRT::IsWinOK( pWin ) ) 520 { 521 DBG_ASSERT( pWin->GetStyle() & ( WB_HORZ | WB_VERT ), "Nither WB_HORZ nor WB_VERT set on ScrollBar"); 522 return (( pWin->GetStyle() & WB_HORZ ) && ( nDirection == CONST_ALIGN_BOTTOM )) 523 || (( pWin->GetStyle() & WB_VERT ) && ( nDirection == CONST_ALIGN_RIGHT )); 524 } 525 return sal_False; 526 } 527 528 ScrollBar* StatementList::GetScrollBar( Window *pBase, sal_uInt16 nDirection, sal_Bool MaybeBase ) 529 { 530 SearchScroll aSearch( nDirection, SEARCH_NOOVERLAP | SEARCH_NO_TOPLEVEL_WIN ); 531 532 return (ScrollBar*)SearchAllWin( pBase, aSearch, MaybeBase ); 533 } 534 535 536 sal_Bool SearchPopupFloatingWin::IsWinOK( Window *pWin ) 537 { 538 return pWin->IsVisible() && pWin->GetType() == WINDOW_FLOATINGWINDOW && ((FloatingWindow*)pWin)->IsInPopupMode(); 539 } 540 541 Window* StatementList::GetPopupFloatingWin( sal_Bool MaybeBase ) 542 { 543 SearchPopupFloatingWin aSearch; 544 545 return SearchAllWin( NULL, aSearch, MaybeBase ); 546 } 547 548 549 Menu* StatementList::GetMatchingMenu( Window* pWin, Menu* pBaseMenu ) 550 { 551 if ( pBaseMenu ) 552 { 553 if ( pBaseMenu->GetWindow() == pWin ) 554 return pBaseMenu; 555 556 sal_uInt16 i; 557 // while ( pBaseMenu ) 558 // { 559 i = 0; 560 while ( i < pBaseMenu->GetItemCount() ) 561 { 562 PopupMenu* pPopup = pBaseMenu->GetPopupMenu( pBaseMenu->GetItemId( i ) ); 563 if ( pPopup && pPopup->GetWindow() ) 564 { 565 if ( pPopup->GetWindow() == pWin ) 566 return pPopup; 567 else 568 { 569 pBaseMenu = pPopup; 570 i = 0; 571 } 572 } 573 else 574 i++; 575 } 576 // } 577 } 578 else 579 { 580 if ( PopupMenu::GetActivePopupMenu() ) 581 { 582 Menu* pMenu = GetMatchingMenu( pWin, PopupMenu::GetActivePopupMenu() ); 583 if ( pMenu ) 584 return pMenu; 585 } 586 587 sal_uInt16 nSkip = 0; 588 Window* pMenuBarWin = NULL; 589 while ( (pMenuBarWin = GetWinByRT( NULL, WINDOW_MENUBARWINDOW, sal_True, nSkip++, sal_True )) != NULL ) 590 { 591 Window* pParent = pMenuBarWin->GET_REAL_PARENT(); 592 if ( pParent && pParent->GetType() == WINDOW_BORDERWINDOW && pParent->IsVisible() ) 593 { 594 Menu* pMenu = NULL; 595 // find Menu of MenuBarWindow 596 sal_uInt16 nCount; 597 for ( nCount = 0 ; nCount < pParent->GetChildCount() ; nCount++ ) 598 { 599 if ( pParent->GetChild( nCount )->GetType() == WINDOW_WORKWINDOW ) 600 pMenu = ((WorkWindow*)(pParent->GetChild( nCount )))->GetMenuBar(); 601 } 602 if ( pMenu ) 603 { 604 // check for menu bar in Task Window 605 if ( pMenuBarWin == pWin ) 606 return pMenu; 607 608 // search submenues 609 pMenu = GetMatchingMenu( pWin, pMenu ); 610 if ( pMenu ) 611 return pMenu; 612 } 613 } 614 } 615 } 616 return NULL; 617 } 618 619 620 sal_Bool SearchActive::IsWinOK( Window *pWin ) 621 { 622 // return pWin->IsVisible() && ( (nRT == WINDOW_ANYTYPE && IsDialog(pWin) ) || pWin->GetType() == nRT ) && (nRT == WINDOW_FILEDIALOG || nRT == WINDOW_PATHDIALOG || nRT == WINDOW_PRINTDIALOG || nRT == WINDOW_PRINTERSETUPDIALOG || nRT == WINDOW_COLORDIALOG || ((SystemWindow*)pWin)->IsActive()); 623 // only matches ResID due to problems with UNIX Window Managers 624 return pWin->IsVisible() && ( (nRT == WINDOW_ANYTYPE && IsDialog(pWin) ) || pWin->GetType() == nRT ); 625 } 626 627 Window* StatementList::GetActive( WindowType nRT, sal_Bool MaybeBase ) 628 { 629 SearchActive aSearch( nRT ); 630 631 return SearchAllWin( NULL, aSearch, MaybeBase ); 632 } 633 634 sal_Bool SearchFadeSplitWin::IsWinOK( Window *pWin ) 635 { 636 #if OSL_DEBUG_LEVEL > 1 637 if ( pWin->GetType() == WINDOW_SPLITWINDOW ) 638 { 639 sal_Bool bResult; 640 WindowAlign aAlign; 641 bResult = pWin->IsVisible(); 642 bResult = ((SplitWindow*)pWin)->IsFadeInButtonVisible(); 643 bResult = ((SplitWindow*)pWin)->IsFadeOutButtonVisible(); 644 bResult = ((SplitWindow*)pWin)->IsAutoHideButtonVisible(); 645 aAlign = ((SplitWindow*)pWin)->GetAlign(); 646 } 647 #endif 648 return pWin->IsVisible() && ( pWin->GetType() == WINDOW_SPLITWINDOW ) 649 && (((SplitWindow*)pWin)->IsFadeInButtonVisible() || ((SplitWindow*)pWin)->IsFadeOutButtonVisible() ) 650 /*&& ((SplitWindow*)pWin)->IsAutoHideButtonVisible()*/ && ((SplitWindow*)pWin)->GetAlign() == nAlign; 651 } 652 653 Window* StatementList::GetFadeSplitWin( Window *pBase, WindowAlign nAlign, sal_Bool MaybeBase ) 654 { 655 SearchFadeSplitWin aSearch( nAlign ); 656 657 if ( GetpApp()->GetAppWindow() == pBase && pBase->GetType() != WINDOW_BORDERWINDOW ) 658 pBase = pBase->GetWindow( WINDOW_OVERLAP ); 659 660 return SearchAllWin( pBase, aSearch, MaybeBase ); 661 } 662 663 Window* StatementList::GetMouseWin() 664 { 665 Window *pBase = Application::GetFirstTopLevelWindow(); 666 Window *pControl = NULL; 667 while ( pBase ) 668 { 669 Window *pBaseFrame = pBase->GetWindow( WINDOW_OVERLAP ); 670 671 Point aP = pBaseFrame->GetPointerPosPixel(); 672 pControl = pBaseFrame->FindWindow( aP ); 673 if ( pControl ) 674 return pControl; 675 676 pBase = Application::GetNextTopLevelWindow( pBase ); 677 } 678 return NULL; 679 } 680 681 Window* StatementList::GetFocus( WindowType nRT, sal_Bool MaybeBase ) 682 { 683 684 if ( nRT == WINDOW_TABCONTROL ) 685 { 686 Window *pResult = GetActive( WINDOW_TABDIALOG, MaybeBase); 687 for( sal_uInt16 i = 0 ; pResult && i < pResult->GetChildCount(); i++ ) 688 if ( pResult->GetChild(i)->GetType() == nRT ) 689 return pResult->GetChild(i); 690 } 691 692 return NULL; 693 } 694 695 Window* StatementList::GetAnyActive( sal_Bool MaybeBase ) 696 { 697 Window *pControl; 698 699 pControl = GetActive( WINDOW_MESSBOX, MaybeBase); 700 if ( !pControl ) 701 { 702 pControl = GetActive( WINDOW_INFOBOX, MaybeBase); 703 } 704 if ( !pControl ) 705 { 706 pControl = GetActive( WINDOW_WARNINGBOX, MaybeBase); 707 } 708 if ( !pControl ) 709 { 710 pControl = GetActive( WINDOW_ERRORBOX, MaybeBase); 711 } 712 if ( !pControl ) 713 { 714 pControl = GetActive( WINDOW_QUERYBOX, MaybeBase); 715 } 716 if ( !pControl ) 717 { 718 pControl = GetActive( WINDOW_BUTTONDIALOG, MaybeBase); 719 } 720 if ( !pControl ) 721 { 722 pControl = GetActive( WINDOW_FILEDIALOG, MaybeBase); 723 } 724 if ( !pControl ) 725 { 726 pControl = GetActive( WINDOW_PATHDIALOG, MaybeBase); 727 } 728 if ( !pControl ) 729 { 730 pControl = GetActive( WINDOW_PRINTDIALOG, MaybeBase); 731 } 732 if ( !pControl ) 733 { 734 pControl = GetActive( WINDOW_PRINTERSETUPDIALOG, MaybeBase); 735 } 736 if ( !pControl ) 737 { 738 pControl = GetActive( WINDOW_COLORDIALOG, MaybeBase); 739 } 740 if ( !pControl ) 741 { 742 pControl = GetFocus( WINDOW_TABCONTROL, MaybeBase); 743 } 744 745 return pControl; 746 } 747 748 void StatementList::SetFirstDocFrame( Window* pWin ) 749 { 750 DBG_ASSERT( IsDocFrame( pWin ), "Non Document Frame set as first Document Frame" ); 751 pFirstDocFrame = pWin; 752 } 753 754 Window* StatementList::GetFirstDocFrame() 755 { 756 757 if ( pFirstDocFrame && !WinPtrValid( pFirstDocFrame ) ) 758 pFirstDocFrame = NULL; 759 if ( pFirstDocFrame && !pFirstDocFrame->IsVisible() ) 760 pFirstDocFrame = NULL; 761 if ( pFirstDocFrame && !IsDocFrame( pFirstDocFrame ) ) 762 pFirstDocFrame = NULL; 763 if ( !pFirstDocFrame ) 764 { 765 Window* pBase = Application::GetFirstTopLevelWindow(); 766 while ( pBase && !IsDocFrame( pBase ) ) 767 pBase = Application::GetNextTopLevelWindow( pBase ); 768 769 if ( pBase ) 770 SetFirstDocFrame( pBase ); 771 772 if ( !pBase ) // find just something 773 { 774 pBase = Application::GetFirstTopLevelWindow(); 775 while ( pBase && !pBase->IsVisible() ) 776 pBase = Application::GetNextTopLevelWindow( pBase ); 777 778 return pBase; // just for now, later we will hopefully have a Window 779 } 780 } 781 return pFirstDocFrame; 782 } 783 784 sal_Bool StatementList::IsFirstDocFrame( Window* pWin ) 785 { 786 return pWin && ( pWin == GetFirstDocFrame() || ( GetFirstDocFrame() && pWin == GetFirstDocFrame()->GetWindow( WINDOW_CLIENT ) ) ) && ( GetFirstDocFrame() && IsDocFrame( GetFirstDocFrame() ) ); 787 } 788 789 MenuBar* StatementList::GetDocFrameMenuBar( Window* pWin ) 790 { 791 if ( pWin && pWin->IsVisible() && pWin->GetType() == WINDOW_BORDERWINDOW ) 792 { 793 sal_uInt16 nCount; 794 for ( nCount = 0 ; nCount < pWin->GetChildCount() ; nCount++ ) 795 { 796 if ( pWin->GetChild( nCount )->GetType() == WINDOW_WORKWINDOW ) 797 return ((WorkWindow*)(pWin->GetChild( nCount )))->GetMenuBar(); 798 } 799 } 800 return NULL; 801 } 802 803 // a Doc Frame is a Document or the Backing Window 804 sal_Bool StatementList::IsDocFrame( Window* pWin ) 805 { 806 if ( pWin && pWin->IsVisible() && pWin->GetType() == WINDOW_BORDERWINDOW ) 807 { 808 sal_uInt16 nCount; 809 sal_Bool bHasWorkWindow = sal_False; 810 sal_Bool bHasMenuBar = sal_False; 811 // #91724# it is now necessary to sort out the IME WIndow in Solaris as well. 812 // so now we check for existence of WINDOW_WORKWINDOW and newly for 813 // WINDOW_MENUBARWINDOW which contains the Menu and the close/min/max buttons 814 for ( nCount = 0 ; nCount < pWin->GetChildCount() ; nCount++ ) 815 { 816 if ( pWin->GetChild( nCount )->GetType() == WINDOW_WORKWINDOW ) 817 bHasWorkWindow = sal_True; 818 if ( pWin->GetChild( nCount )->GetType() == WINDOW_MENUBARWINDOW ) 819 bHasMenuBar = sal_True; 820 } 821 return bHasWorkWindow && bHasMenuBar; 822 } 823 return sal_False; 824 } 825 826 // a Doc Win is a real document (not the Backing Window) 827 sal_Bool StatementList::IsDocWin( Window* pWin ) 828 { 829 if ( pWin && IsDocFrame( pWin ) ) 830 { 831 if ( GetDocFrameCount() != 1 ) 832 return sal_True; 833 else 834 { 835 // check for the close button to see if we are the last one or only the backing Window 836 if ( GetDocFrameMenuBar( pWin ) ) 837 return GetDocFrameMenuBar( pWin )->HasCloser(); 838 } 839 } 840 return sal_False; 841 } 842 843 sal_Bool StatementList::IsIMEWin( Window* pWin ) // Input Window for CJK under Solaris 844 { 845 if ( pWin && pWin->IsVisible() && pWin->GetType() == WINDOW_BORDERWINDOW ) 846 { 847 sal_uInt16 nCount; 848 sal_Bool bHasWorkWindow = sal_False; 849 sal_Bool bHasWindow = sal_False; 850 // #91724# it is now necessary to sort out the IME WIndow in Solaris as well. 851 // so now we check for existence of WINDOW_WORKWINDOW and newly for 852 // WINDOW_WINDOW which contains the Menu and the close/min/max buttons 853 for ( nCount = 0 ; nCount < pWin->GetChildCount() ; nCount++ ) 854 if ( pWin->GetChild( nCount )->GetType() == WINDOW_WORKWINDOW ) 855 bHasWorkWindow = sal_True; 856 for ( nCount = 0 ; nCount < pWin->GetChildCount() ; nCount++ ) 857 if ( pWin->GetChild( nCount )->GetType() == WINDOW_WINDOW ) 858 bHasWindow = sal_True; 859 return bHasWorkWindow && !bHasWindow; 860 } 861 return sal_False; 862 } 863 864 UniString StatementList::Tree(Window *pBase, int Indent) 865 { 866 867 String aReturn, aSep; 868 if ( !pBase ) 869 { 870 aSep.AssignAscii("============================\n"); 871 aSep.ConvertLineEnd(); 872 pBase = Application::GetFirstTopLevelWindow(); 873 while ( pBase ) 874 { 875 Window *pBaseFrame = pBase->GetWindow( WINDOW_OVERLAP ); 876 877 aReturn += aSep; 878 aReturn += Tree( pBaseFrame, Indent+1 ); 879 880 pBase = Application::GetNextTopLevelWindow( pBase ); 881 } 882 return aReturn; 883 } 884 885 886 aSep.AssignAscii("----------------------------\n"); 887 aSep.ConvertLineEnd(); 888 889 aReturn += ClientTree( pBase, Indent ); 890 891 if ( pBase->GetWindow( WINDOW_FIRSTOVERLAP ) ) 892 { 893 aReturn += aSep; 894 aReturn += Tree( pBase->GetWindow( WINDOW_FIRSTOVERLAP ), Indent+1 ); 895 } 896 897 if ( pBase->GetWindow( WINDOW_NEXT ) ) 898 { 899 aReturn += aSep; 900 aReturn += Tree( pBase->GetWindow( WINDOW_NEXT ), Indent ); 901 } 902 903 return aReturn; 904 } 905 906 String StatementList::ClientTree(Window *pBase, int Indent) 907 { 908 #if OSL_DEBUG_LEVEL > 1 909 #define WRITE(Text) { m_pDbgWin->AddText(Text); aReturn += Text; } 910 #define WRITEc(Text) { m_pDbgWin->AddText(Text); aReturn.AppendAscii(Text); } 911 #else 912 #define WRITE(Text) { aReturn += Text; } 913 #define WRITEc(Text) { aReturn.AppendAscii(Text); } 914 #endif 915 916 String sIndent,aText,aReturn; 917 sIndent.Expand(sal::static_int_cast< xub_StrLen >(2*Indent)); 918 919 aText = pBase->GetText(); 920 921 922 UniString t1,t2;t1 = CUniString("\n"); t2 = CUniString("\\n"); 923 aText.SearchAndReplaceAll(t1,t2 ); 924 925 WRITE(sIndent); 926 927 if (pBase->IsDialog()) 928 { 929 WRITEc("*(Dialog(TH))"); 930 } 931 if (IsDialog( pBase )) 932 { 933 WRITEc("*(Dialog(GH))"); 934 } 935 if (pBase->HasFocus()) 936 { 937 WRITEc("*(Focus)"); 938 } 939 if (!pBase->IsEnabled()) 940 { 941 WRITEc("*(Disab)"); 942 } 943 if (pBase->IsVisible()) 944 { 945 WRITEc("*(Visible)"); 946 } 947 if ( IsDialog(pBase) && ((SystemWindow*)pBase)->IsActive() ) 948 { 949 WRITEc("*(Active)"); 950 } 951 if ( pBase->GetStyle() & WB_CLOSEABLE ) 952 { 953 WRITEc("*(Closable)"); 954 } 955 if ( pBase->GetType() == WINDOW_DOCKINGWINDOW && 956 ((((DockingWindow*)pBase)->GetFloatStyle()) & WB_CLOSEABLE) ) 957 { 958 WRITEc("*(Closable Docking in Floatingstyle)"); 959 } 960 if ( pBase->GetStyle() & WB_DOCKABLE ) 961 { 962 WRITEc("*(Dockable)"); 963 } 964 if ( pBase->GetType() == WINDOW_SPLITWINDOW && 965 (((SplitWindow*)pBase)->IsFadeInButtonVisible() || ((SplitWindow*)pBase)->IsFadeOutButtonVisible()) ) 966 { 967 WRITEc("*(FadeIn/Out)"); 968 } 969 WRITEc("Text: "); 970 WRITE(aText); 971 WRITEc("\n"); 972 973 WRITE(sIndent); 974 WRITEc("UId : "); 975 WRITE(Id2Str(pBase->GetUniqueOrHelpId())); 976 WRITEc(":0x"); 977 WRITE( 978 String::CreateFromInt64( 979 sal::static_int_cast< sal_Int64 >( 980 reinterpret_cast< sal_IntPtr >(pBase)), 981 16 )); 982 WRITEc(":"); 983 WRITE(pBase->GetQuickHelpText()); 984 WRITEc(":"); 985 WRITE(pBase->GetHelpText()); 986 WRITEc("\n"); 987 988 WRITE(sIndent); 989 WRITEc("RTyp: "); 990 WRITE(MakeStringNumber(TypeKenn,pBase->GetType())); 991 if ( pBase->GetType() == WINDOW_CONTROL ) 992 { 993 if ( dynamic_cast< svt::EditBrowseBox* >(pBase) ) 994 WRITEc("/BrowseBox") 995 else if ( dynamic_cast< ValueSet* >(pBase) ) 996 WRITEc("/ValueSet") 997 else if ( dynamic_cast< svt::ORoadmap* >(pBase) ) 998 WRITEc("/RoadMap") 999 else if ( dynamic_cast< svt::IExtensionListBox* >(pBase) ) 1000 WRITEc("/ExtensionListBox") 1001 else if ( dynamic_cast< svt::table::TableControl* >(pBase) ) 1002 WRITEc("/TableControl") 1003 else 1004 WRITEc("/Unknown") 1005 } 1006 WRITEc("\n"); 1007 1008 aReturn.ConvertLineEnd(); 1009 sal_uInt16 i; 1010 for (i = 0 ; i < pBase->GetChildCount() ; i++) 1011 { 1012 aReturn += ClientTree(pBase->GetChild(i),Indent+1); 1013 } 1014 return aReturn; 1015 } 1016 1017 1018 sal_Bool StatementList::CheckWindowWait() 1019 { 1020 static Time StartTime = Time(0L); // Abbruch wenn Fenster absolut nicht schliesst. 1021 if ( StartTime == Time(0L) ) 1022 StartTime = Time(); 1023 1024 if ( pWindowWaitPointer ) 1025 { 1026 #if OSL_DEBUG_LEVEL > 1 1027 m_pDbgWin->AddText( "Waiting for Window to close ... " ); 1028 #endif 1029 if ( WinPtrValid(pWindowWaitPointer) && IS_WINP_CLOSING(pWindowWaitPointer) ) 1030 { 1031 #if OSL_DEBUG_LEVEL > 1 1032 m_pDbgWin->AddText( Id2Str(aWindowWaitUId).AppendAscii(" Still Open. RType=") ); 1033 m_pDbgWin->AddText( String::CreateFromInt32( pWindowWaitPointer->GetType() ).AppendAscii("\n") ); 1034 #endif 1035 1036 // Ist die Zeit schonn abgelaufen? 1037 if ( StartTime + Time(0,0,10) < Time() ) // 10 Sekunden reichen wohl 1038 { 1039 #if OSL_DEBUG_LEVEL > 1 1040 m_pDbgWin->AddText( "Close timed out. Going on!! " ); 1041 #endif 1042 pWindowWaitPointer->SetHelpId(aWindowWaitOldHelpId); 1043 pWindowWaitPointer->SetUniqueId(aWindowWaitOldUniqueId); 1044 1045 aWindowWaitUId = rtl::OString(); 1046 pWindowWaitPointer = NULL; 1047 StartTime = Time(0L); 1048 return sal_True; 1049 } 1050 1051 return sal_False; 1052 } 1053 pWindowWaitPointer = NULL; 1054 aWindowWaitUId = rtl::OString(); 1055 #if OSL_DEBUG_LEVEL > 1 1056 m_pDbgWin->AddText( "Closed, Going on.\n" ); 1057 #endif 1058 } 1059 StartTime = Time(0L); 1060 return sal_True; 1061 } 1062 1063 void StatementList::ReportError(String aMessage) 1064 { 1065 ReportError ( rtl::OString(), aMessage ); 1066 } 1067 1068 void StatementList::ReportError(rtl::OString aUId, String aMessage) 1069 { 1070 pRet->GenError ( aUId, aMessage ); 1071 IsError = sal_True; 1072 } 1073 1074 void StatementList::ReportError(String aMessage, sal_uLong nWhatever) 1075 { 1076 ReportError ( aMessage.AppendAscii(" ").Append(UniString::CreateFromInt32(nWhatever))); 1077 } 1078 1079 void StatementList::DirectLog( sal_uLong nType, String aMessage ) 1080 { 1081 if ( pRet ) 1082 pRet->GenReturn( RET_DirectLoging, (sal_uInt16) nType, aMessage ); 1083 } 1084 1085 1086 #define CALL_EVENT_WITH_NOTIFY( EventType, Event, WinP, Method ) \ 1087 { \ 1088 if ( StatementList::WinPtrValid( WinP ) ) \ 1089 { \ 1090 NotifyEvent aNEvt( EventType, WinP, &Event ); \ 1091 if ( !WinP->PreNotify( aNEvt ) ) \ 1092 WinP->Method( Event ); \ 1093 } \ 1094 } 1095 1096 void ImplKeyInput( Window* pWin, KeyEvent &aKEvnt, sal_Bool bForceDirect ) 1097 { 1098 1099 if ( StatementList::bUsePostEvents && !bForceDirect ) 1100 { 1101 if ( StatementList::WinPtrValid( pWin ) ) 1102 { 1103 sal_uLong nID1; 1104 sal_uLong nID2; 1105 nID1 = Application::PostKeyEvent( VCLEVENT_WINDOW_KEYINPUT, pWin, &aKEvnt ); 1106 nID2 = Application::PostKeyEvent( VCLEVENT_WINDOW_KEYUP, pWin, &aKEvnt ); 1107 // wait after posting both events so deleting pWin will remove the second event also 1108 ImplEventWait( nID1 ); 1109 ImplEventWait( nID2 ); 1110 } 1111 } 1112 else 1113 { 1114 if ( !Application::CallAccel( aKEvnt.GetKeyCode() ) ) 1115 { 1116 CALL_EVENT_WITH_NOTIFY( EVENT_KEYINPUT, aKEvnt, pWin, KeyInput ) 1117 1118 KeyCode aCode = aKEvnt.GetKeyCode(); 1119 if ( (aCode.GetCode() == KEY_CONTEXTMENU) || ((aCode.GetCode() == KEY_F10) && aCode.IsShift()) ) 1120 { 1121 if ( StatementList::WinPtrValid( pWin ) ) 1122 { 1123 Point aPos; 1124 // simulate mouseposition at center of window 1125 Size aSize = pWin->GetOutputSize(); 1126 aPos = Point( aSize.getWidth()/2, aSize.getHeight()/2 ); 1127 1128 CommandEvent aEvent( aPos, COMMAND_CONTEXTMENU, sal_False ); 1129 ImplCommand( pWin, aEvent ); 1130 } 1131 } 1132 } 1133 1134 CALL_EVENT_WITH_NOTIFY( EVENT_KEYUP, aKEvnt, pWin, KeyUp ) 1135 } 1136 }; 1137 1138 void ImplMouseMove( Window* pWin, MouseEvent &aMEvnt, sal_Bool bForceDirect ) 1139 { 1140 if ( StatementList::bUsePostEvents && !bForceDirect ) 1141 { 1142 if ( StatementList::WinPtrValid( pWin ) ) 1143 { 1144 sal_uLong nID; 1145 nID = Application::PostMouseEvent( VCLEVENT_WINDOW_MOUSEMOVE, pWin, &aMEvnt ); 1146 ImplEventWait( nID ); 1147 } 1148 } 1149 else 1150 { 1151 // DragManager* pDragManager = DragManager::GetDragManager(); 1152 // if ( pDragManager ) 1153 // pDragManager->MouseMove( aMEvnt, pWin ); 1154 // else 1155 if ( pWin->IsTracking() ) 1156 { 1157 TrackingEvent aTEvt( aMEvnt ); 1158 pWin->Tracking( aTEvt ); 1159 } 1160 else 1161 CALL_EVENT_WITH_NOTIFY( EVENT_MOUSEMOVE, aMEvnt, pWin, MouseMove ) 1162 } 1163 }; 1164 1165 void ImplMouseButtonDown( Window* pWin, MouseEvent &aMEvnt, sal_Bool bForceDirect ) 1166 { 1167 if ( StatementList::bUsePostEvents && !bForceDirect ) 1168 { 1169 if ( StatementList::WinPtrValid( pWin ) ) 1170 { 1171 sal_uLong nID; 1172 nID = Application::PostMouseEvent( VCLEVENT_WINDOW_MOUSEBUTTONDOWN, pWin, &aMEvnt ); 1173 ImplEventWait( nID ); 1174 } 1175 } 1176 else 1177 { 1178 CALL_EVENT_WITH_NOTIFY( EVENT_MOUSEBUTTONDOWN, aMEvnt, pWin, MouseButtonDown ) 1179 } 1180 }; 1181 1182 void ImplMouseButtonUp( Window* pWin, MouseEvent &aMEvnt, sal_Bool bForceDirect ) 1183 { 1184 if ( StatementList::bUsePostEvents && !bForceDirect ) 1185 { 1186 if ( StatementList::WinPtrValid( pWin ) ) 1187 { 1188 sal_uLong nID; 1189 nID = Application::PostMouseEvent( VCLEVENT_WINDOW_MOUSEBUTTONUP, pWin, &aMEvnt ); 1190 ImplEventWait( nID ); 1191 } 1192 } 1193 else 1194 { 1195 // DragManager* pDragManager = DragManager::GetDragManager(); 1196 // if ( pDragManager ) 1197 // pDragManager->ButtonUp( aMEvnt, pWin ); 1198 // else 1199 if ( pWin->IsTracking() ) 1200 { 1201 // siehe #64693 die Position ist f�r Toolboxen relevant 1202 // #60020 Jetzt hoffentlich kein GPF mehr 1203 // Zuerst Tracking beenden ohne Event 1204 pWin->EndTracking( ENDTRACK_DONTCALLHDL ); 1205 // dann eigenen Event mit richtigem Maus-Event senden 1206 TrackingEvent aTEvt( aMEvnt, ENDTRACK_END ); 1207 pWin->Tracking( aTEvt ); 1208 } 1209 else 1210 CALL_EVENT_WITH_NOTIFY( EVENT_MOUSEBUTTONUP, aMEvnt, pWin, MouseButtonUp ) 1211 } 1212 }; 1213 1214 void ImplEventWait( sal_uLong nID ) 1215 { 1216 while ( !Application::IsProcessedMouseOrKeyEvent( nID ) ) 1217 Application::Yield(); 1218 } 1219 1220 void ImplCommand( Window* pWin, CommandEvent &aCmdEvnt ) 1221 { 1222 CALL_EVENT_WITH_NOTIFY( EVENT_COMMAND, aCmdEvnt, pWin, Command ) 1223 }; 1224 1225