update dev300-m58
[ooovba.git] / automation / source / server / sta_list.cxx
blobed0799471c933607e74bf51ca7761b18a520039a
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: sta_list.cxx,v $
10 * $Revision: 1.30 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_automation.hxx"
33 #include <tools/time.hxx>
34 #include <vcl/splitwin.hxx>
35 #include <vcl/wrkwin.hxx>
36 #ifndef _BASIC_TTRESHLP_HXX
37 #include <basic/ttstrhlp.hxx>
38 #endif
39 #include "statemnt.hxx"
41 #ifndef _RETSRTM_HXX
42 #include "retstrm.hxx"
43 #endif
44 #include "rcontrol.hxx"
46 #if OSL_DEBUG_LEVEL > 1
47 #include "editwin.hxx"
48 #endif
50 #include "profiler.hxx"
51 #include <vcl/floatwin.hxx>
52 #include <vcl/toolbox.hxx>
54 // only needed for dynamic_cast in wintree
55 #include <svtools/editbrowsebox.hxx>
56 #include <svtools/valueset.hxx>
57 #include <svtools/roadmap.hxx>
58 #include <svtools/extensionlistbox.hxx>
60 #define WINDOW_ANYTYPE WINDOW_BASE
63 TTProfiler *StatementList::pProfiler = NULL;
64 StatementList *StatementList::pFirst = NULL;
65 BOOL StatementList::bReadingCommands = FALSE;
66 BOOL StatementList::bIsInReschedule = FALSE;
67 USHORT StatementList::nModalCount = 0;
68 Window *StatementList::pLastFocusWindow = NULL;
69 BOOL StatementList::bWasDragManager = FALSE;
70 BOOL StatementList::bWasPopupMenu = FALSE;
71 BOOL StatementList::bBasicWasRunning = FALSE;
72 RetStream *StatementList::pRet = NULL;
73 BOOL StatementList::IsError = FALSE;
74 BOOL StatementList::bDying = FALSE;
75 BOOL StatementList::bExecuting = FALSE;
76 StatementList *StatementList::pCurrentProfileStatement = NULL;
77 BOOL StatementList::bUsePostEvents = TRUE;
78 #if OSL_DEBUG_LEVEL > 1
79 EditWindow *StatementList::m_pDbgWin;
80 #endif
83 SmartId StatementList::aWindowWaitUId = SmartId();
84 Window *StatementList::pWindowWaitPointer = NULL;
85 SmartId StatementList::aWindowWaitOldHelpId = SmartId();
86 SmartId StatementList::aWindowWaitOldUniqueId = SmartId();
87 USHORT StatementList::nUseBindings = 0;
89 SmartId StatementList::aSubMenuId1 = SmartId(); // Untermenüs bei PopupMenus
90 SmartId StatementList::aSubMenuId2 = SmartId(); // erstmal 2-Stufig
91 SmartId StatementList::aSubMenuId3 = SmartId(); // and now even 3 levels #i31512#
92 SystemWindow *StatementList::pMenuWindow = NULL;
93 TTProperties *StatementList::pTTProperties = NULL;
95 USHORT StatementList::nMinTypeKeysDelay = 0; // Verzögerung der einzelnen Anschläge für TypeKeys
96 USHORT StatementList::nMaxTypeKeysDelay = 0;
97 BOOL StatementList::bDoTypeKeysDelay = FALSE;
99 Window* StatementList::pFirstDocFrame = NULL;
101 BOOL StatementList::bIsSlotInExecute = FALSE;
103 BOOL StatementList::bCatchGPF = TRUE;
106 IMPL_GEN_RES_STR;
109 static TTSettings* pTTSettings = NULL;
111 TTSettings* GetTTSettings()
113 if ( !pTTSettings )
115 pTTSettings = new TTSettings;
117 // DisplayHID
118 pTTSettings->pDisplayInstance = NULL;
119 pTTSettings->pDisplayHidWin = NULL;
120 pTTSettings->Old = NULL;
121 pTTSettings->Act = NULL;
122 pTTSettings->aOriginalCaption.Erase();
124 // Translate
125 pTTSettings->pTranslateWin = NULL;
126 pTTSettings->bToTop = TRUE;
129 return pTTSettings;
135 #define IS_WINP_CLOSING(pWin) (pWin->GetSmartHelpId().Matches( 4321 ) && pWin->GetSmartUniqueId().Matches( 1234 ))
138 UniString GEN_RES_STR0( ULONG nResId ) { return ResString( nResId ); }
139 UniString GEN_RES_STR1( ULONG nResId, const UniString &Text1 ) { return GEN_RES_STR0( nResId ).Append( ArgString( 1, Text1 ) ); }
140 UniString GEN_RES_STR2( ULONG nResId, const UniString &Text1, const UniString &Text2 ) { return GEN_RES_STR1( nResId, Text1 ).Append( ArgString( 2, Text2 ) ); }
141 UniString GEN_RES_STR3( ULONG nResId, const UniString &Text1, const UniString &Text2, const UniString &Text3 ) { return GEN_RES_STR2( nResId, Text1, Text2 ).Append( ArgString( 3, Text3 ) );}
143 StatementList::StatementList()
144 : nRetryCount(MAX_RETRIES)
145 , bStatementInQue(FALSE)
147 if (!pRet)
148 pRet = new RetStream; // so Spät wie möglich, aber dennoch Zentral und auf jeden Fall rechtzeitig, da pRet private ist.
151 void StatementList::InitProfile()
153 if ( pProfiler )
155 if ( pProfiler->IsProfilingPerCommand() || pProfiler->IsPartitioning() )
156 pProfiler->StartProfileInterval( pCurrentProfileStatement != this );
158 #if OSL_DEBUG_LEVEL > 1
159 if ( pCurrentProfileStatement != NULL && pCurrentProfileStatement != this )
160 pRet->GenReturn( RET_ProfileInfo, SmartId(), CUniString("InitProfile von anderem Statement gerufen ohne SendProfile\n") );
161 #endif
162 pCurrentProfileStatement = this;
166 void StatementList::SendProfile( String aText )
168 if ( pProfiler )
170 if ( pCurrentProfileStatement == this )
172 if ( pProfiler->IsProfilingPerCommand() || pProfiler->IsPartitioning() )
173 pProfiler->EndProfileInterval();
175 if ( pProfiler->IsProfilingPerCommand() )
176 pRet->GenReturn( RET_ProfileInfo, SmartId(), pProfiler->GetProfileLine( aText ) );
178 if ( pProfiler->IsPartitioning() )
179 pRet->GenReturn( RET_ProfileInfo, SmartId( S_ProfileTime ), static_cast<comm_ULONG>(pProfiler->GetPartitioningTime()) ); // GetPartitioningTime() ULONG != comm_ULONG on 64bit
182 if ( pProfiler->IsAutoProfiling() )
183 pRet->GenReturn( RET_ProfileInfo, SmartId(), pProfiler->GetAutoProfiling() );
185 #if OSL_DEBUG_LEVEL > 1
186 if ( pCurrentProfileStatement == NULL )
187 pRet->GenReturn( RET_ProfileInfo, SmartId(), CUniString("SendProfile ohne InitProfile\n") );
188 #endif
189 pCurrentProfileStatement = NULL;
193 void StatementList::QueStatement(StatementList *pAfterThis)
195 DBG_ASSERT(!bStatementInQue,"QueStatement für bereits eingetragenes Statement -> Abgebrochen");
196 if ( bStatementInQue )
197 return;
199 bStatementInQue = TRUE;
200 if ( pAfterThis )
202 if ( pAfterThis->bStatementInQue )
204 pNext = pAfterThis->pNext;
205 pAfterThis->pNext = this;
207 else
208 { // pAfterThis not in que -> already dequed -> add to front of list
209 pNext = pFirst;
210 pFirst = this;
213 else // am Ende einfügen
215 pNext = NULL;
216 if( !pFirst )
217 pFirst = this;
218 else
220 StatementList *pList;
221 pList = pFirst;
222 while( pList->pNext )
223 pList = pList->pNext;
224 pList->pNext = this;
229 void StatementList::Advance()
230 { // pFirst ist static!
231 pFirst = pNext;
232 bStatementInQue = FALSE;
233 pNext = NULL;
237 StatementList::~StatementList()
239 #if OSL_DEBUG_LEVEL > 1
240 m_pDbgWin->AddText( "Deleting \n" );
241 #endif
242 DBG_ASSERT(!bReadingCommands,"Deleting commands while reading them!");
245 Window* StatementList::GetDocWin( USHORT nNr )
247 Window* pBase = Application::GetFirstTopLevelWindow();
249 while ( pBase )
251 if ( IsDocWin( pBase ) )
253 if ( !nNr )
254 return pBase;
255 nNr--;
257 pBase = Application::GetNextTopLevelWindow( pBase );
259 return NULL;
262 USHORT StatementList::GetDocFrameCount()
264 Window* pBase = Application::GetFirstTopLevelWindow();
265 USHORT nCount = 0;
267 while ( pBase )
269 if ( IsDocFrame( pBase ) )
270 nCount++;
271 pBase = Application::GetNextTopLevelWindow( pBase );
273 return nCount;
276 USHORT StatementList::GetDocWinCount()
278 Window* pBase = Application::GetFirstTopLevelWindow();
279 USHORT nCount = 0;
281 while ( pBase )
283 if ( IsDocWin( pBase ) )
284 nCount++;
285 pBase = Application::GetNextTopLevelWindow( pBase );
287 return nCount;
290 Window* StatementList::SearchAllWin( Window *pBase, Search &aSearch, BOOL MaybeBase )
293 if ( !pBase && !aSearch.HasSearchFlag( SEARCH_NO_TOPLEVEL_WIN ) )
295 BOOL bSearchFocusFirst = aSearch.HasSearchFlag( SEARCH_FOCUS_FIRST );
297 Window *pControl = NULL;
298 if ( bSearchFocusFirst )
300 // first test Parent of Focus Window
301 pBase = Application::GetFocusWindow();
302 if ( pBase )
304 DBG_ASSERT( WinPtrValid( pBase ), "GetFocusWindow is no valid WindowPointer" );
305 Window *pPParent = pBase;
306 while ( pPParent->GET_REAL_PARENT() )
307 pPParent = pPParent->GET_REAL_PARENT();
309 // if ( !IsFirstDocFrame( pPParent ) )
310 // {
311 // get overlap window. Will be dialog else document itself
312 pBase = pBase->GetWindow( WINDOW_OVERLAP );
314 // set flag to find disabled elements.
315 // This is better than an enabled one on another Window
316 aSearch.AddSearchFlags( SEARCH_FIND_DISABLED );
318 // search on current Dialog first
319 pControl = SearchAllWin( pBase, aSearch );
321 // search on current Document
322 if ( !pControl && pBase != pPParent )
323 pControl = SearchAllWin( pPParent, aSearch );
325 aSearch.RemoveSearchFlags( SEARCH_FIND_DISABLED );
327 if ( pControl )
328 return pControl;
329 // }
333 pBase = Application::GetFirstTopLevelWindow();
335 // Skip FirstDocFrame
336 // if ( bSearchFocusFirst && IsFirstDocFrame( pBase ) )
337 // pBase = Application::GetNextTopLevelWindow( pBase );
339 while ( pBase )
341 pControl = SearchAllWin( pBase, aSearch );
342 if ( pControl )
343 return pControl;
345 pBase = Application::GetNextTopLevelWindow( pBase );
346 // Skip FirstDocFrame
347 // if ( bSearchFocusFirst && IsFirstDocFrame( pBase ) )
348 // pBase = Application::GetNextTopLevelWindow( pBase );
350 return NULL;
354 Window *pResult = NULL;
355 pResult = SearchClientWin( pBase, aSearch, MaybeBase );
356 if ( pResult )
357 return pResult;
359 // if ( pBase->GetType() != WINDOW_BORDERWINDOW )
360 // return NULL;
362 if ( !aSearch.HasSearchFlag( SEARCH_NOOVERLAP ) )
364 if ( pBase->GetWindow( WINDOW_FIRSTOVERLAP ) )
365 pResult = SearchAllWin( pBase->GetWindow( WINDOW_FIRSTOVERLAP ), aSearch );
367 if ( !pResult && pBase->GetWindow( WINDOW_NEXT ) )
368 pResult = SearchAllWin( pBase->GetWindow( WINDOW_NEXT ), aSearch );
371 return pResult;
375 Window* StatementList::SearchClientWin( Window *pBase, Search &aSearch, BOOL MaybeBase )
377 if ( !pBase )
378 return NULL;
380 if ( MaybeBase && aSearch.IsWinOK( pBase ) )
381 return pBase;
383 Window *pResult = NULL;
385 USHORT i;
386 for( i = 0 ; i < pBase->GetChildCount() && !pResult; i++ )
387 pResult = SearchClientWin( pBase->GetChild(i), aSearch );
389 return pResult;
393 BOOL SearchUID::IsWinOK( Window *pWin )
395 if ( aUId.Matches( pWin->GetSmartUniqueOrHelpId() ) )
397 if ( ( pWin->IsEnabled() || HasSearchFlag( SEARCH_FIND_DISABLED ) ) && pWin->IsVisible() )
398 return TRUE;
399 else
401 if ( !pMaybeResult )
402 pMaybeResult = pWin;
403 return FALSE;
406 else if ( pWin->GetType() == WINDOW_TOOLBOX ) // Buttons and Controls on ToolBox.
408 ToolBox *pTB = ((ToolBox*)pWin);
409 USHORT i;
410 for ( i = 0; i < pTB->GetItemCount() ; i++ )
412 if ( aUId.Matches( pTB->GetItemCommand(pTB->GetItemId( i )) ) || aUId.Matches( pTB->GetHelpId(pTB->GetItemId( i )) ) )
413 { // ID matches.
414 Window *pItemWin;
415 pItemWin = pTB->GetItemWindow( pTB->GetItemId( i ) );
417 if ( bSearchButtonOnToolbox && pTB->GetItemType( i ) == TOOLBOXITEM_BUTTON && !pItemWin )
418 { // We got a Control, see if its valid also.
419 // Same as above.
420 if ( ( pTB->IsEnabled() || HasSearchFlag( SEARCH_FIND_DISABLED ) ) && pTB->IsVisible() )
421 { // We got a Button, see if its valid also.
422 if ( ( pTB->IsItemEnabled(pTB->GetItemId(i)) || HasSearchFlag( SEARCH_FIND_DISABLED ) )
423 && pTB->IsItemVisible(pTB->GetItemId(i)) )
424 return TRUE; // We got a Button.
425 else
426 { // better a disabled Button on a valid ToolBox than an invalid ToolBox as below
427 pMaybeResult = pTB;
428 return FALSE;
431 else if ( !pMaybeResult )
432 { // invalid ToolBox
433 pMaybeResult = pTB;
434 return FALSE;
437 if ( pItemWin )
438 { // We got a Control, see if its valid also.
439 // Same as above.
440 if ( ( pItemWin->IsEnabled() || HasSearchFlag( SEARCH_FIND_DISABLED ) ) && pItemWin->IsVisible() )
442 if ( !pAlternateResult ) // only take the first found ItemWindow #i35365
443 pAlternateResult = pItemWin; // since we cannot return a Window here
444 return FALSE; // continue searching to prefer a window with the right ID #i32292
446 else if ( !pMaybeResult )
448 pMaybeResult = pItemWin;
449 return FALSE;
454 return FALSE;
456 else
457 return FALSE;
460 Window* StatementList::SearchTree( SmartId aUId ,BOOL bSearchButtonOnToolbox )
462 SearchUID aSearch(aUId,bSearchButtonOnToolbox);
464 Window *pResult = SearchAllWin( NULL, aSearch );
465 if ( pResult )
466 return pResult;
467 else if ( aSearch.GetAlternateResultWin() )
468 return aSearch.GetAlternateResultWin();
469 else
470 return aSearch.GetMaybeWin();
474 BOOL SearchWinPtr::IsWinOK( Window *pWin )
476 return pWin == pTest;
479 BOOL StatementList::WinPtrValid(Window *pTest)
481 SearchWinPtr aSearch( pTest );
482 return SearchAllWin( NULL, aSearch ) != NULL;
486 BOOL SearchRT::IsWinOK( Window *pWin )
488 if ( pWin->IsVisible() && pWin->GetType() == mnRT )
490 mnCount++;
491 if ( mnSkip )
493 mnSkip--;
494 return FALSE;
496 else
497 return TRUE;
499 return FALSE;
502 Window* StatementList::GetWinByRT( Window *pBase, WindowType nRT, BOOL MaybeBase, USHORT nSkip, BOOL bSearchAll )
504 SearchRT aSearch( nRT, 0, nSkip );
505 if ( bSearchAll )
506 aSearch.AddSearchFlags( SEARCH_FOCUS_FIRST | SEARCH_FIND_DISABLED );
507 else
508 aSearch.AddSearchFlags( SEARCH_NOOVERLAP | SEARCH_NO_TOPLEVEL_WIN );
510 return SearchAllWin( pBase, aSearch, MaybeBase );
513 USHORT StatementList::CountWinByRT( Window *pBase, WindowType nRT, BOOL MaybeBase )
515 SearchRT aSearch( nRT, SEARCH_NOOVERLAP | SEARCH_NO_TOPLEVEL_WIN, 0xFFFF );
517 SearchAllWin( pBase, aSearch, MaybeBase );
518 return aSearch.GetCount();
521 BOOL SearchScroll::IsWinOK( Window *pWin )
523 if ( SearchRT::IsWinOK( pWin ) )
525 DBG_ASSERT( pWin->GetStyle() & ( WB_HORZ | WB_VERT ), "Nither WB_HORZ nor WB_VERT set on ScrollBar");
526 return (( pWin->GetStyle() & WB_HORZ ) && ( nDirection == CONST_ALIGN_BOTTOM ))
527 || (( pWin->GetStyle() & WB_VERT ) && ( nDirection == CONST_ALIGN_RIGHT ));
529 return FALSE;
532 ScrollBar* StatementList::GetScrollBar( Window *pBase, USHORT nDirection, BOOL MaybeBase )
534 SearchScroll aSearch( nDirection, SEARCH_NOOVERLAP | SEARCH_NO_TOPLEVEL_WIN );
536 return (ScrollBar*)SearchAllWin( pBase, aSearch, MaybeBase );
540 BOOL SearchPopupFloatingWin::IsWinOK( Window *pWin )
542 return pWin->IsVisible() && pWin->GetType() == WINDOW_FLOATINGWINDOW && ((FloatingWindow*)pWin)->IsInPopupMode();
545 Window* StatementList::GetPopupFloatingWin( BOOL MaybeBase )
547 SearchPopupFloatingWin aSearch;
549 return SearchAllWin( NULL, aSearch, MaybeBase );
553 Menu* StatementList::GetMatchingMenu( Window* pWin, Menu* pBaseMenu )
555 if ( pBaseMenu )
557 if ( pBaseMenu->GetWindow() == pWin )
558 return pBaseMenu;
560 USHORT i;
561 // while ( pBaseMenu )
562 // {
563 i = 0;
564 while ( i < pBaseMenu->GetItemCount() )
566 PopupMenu* pPopup = pBaseMenu->GetPopupMenu( pBaseMenu->GetItemId( i ) );
567 if ( pPopup && pPopup->GetWindow() )
569 if ( pPopup->GetWindow() == pWin )
570 return pPopup;
571 else
573 pBaseMenu = pPopup;
574 i = 0;
577 else
578 i++;
580 // }
582 else
584 if ( PopupMenu::GetActivePopupMenu() )
586 Menu* pMenu = GetMatchingMenu( pWin, PopupMenu::GetActivePopupMenu() );
587 if ( pMenu )
588 return pMenu;
591 USHORT nSkip = 0;
592 Window* pMenuBarWin = NULL;
593 while ( (pMenuBarWin = GetWinByRT( NULL, WINDOW_MENUBARWINDOW, TRUE, nSkip++, TRUE )) != NULL )
595 Window* pParent = pMenuBarWin->GET_REAL_PARENT();
596 if ( pParent && pParent->GetType() == WINDOW_BORDERWINDOW && pParent->IsVisible() )
598 Menu* pMenu = NULL;
599 // find Menu of MenuBarWindow
600 USHORT nCount;
601 for ( nCount = 0 ; nCount < pParent->GetChildCount() ; nCount++ )
603 if ( pParent->GetChild( nCount )->GetType() == WINDOW_WORKWINDOW )
604 pMenu = ((WorkWindow*)(pParent->GetChild( nCount )))->GetMenuBar();
606 if ( pMenu )
608 // check for menu bar in Task Window
609 if ( pMenuBarWin == pWin )
610 return pMenu;
612 // search submenues
613 pMenu = GetMatchingMenu( pWin, pMenu );
614 if ( pMenu )
615 return pMenu;
620 return NULL;
624 BOOL SearchActive::IsWinOK( Window *pWin )
626 // 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());
627 // only matches ResID due to problems with UNIX Window Managers
628 return pWin->IsVisible() && ( (nRT == WINDOW_ANYTYPE && IsDialog(pWin) ) || pWin->GetType() == nRT );
631 Window* StatementList::GetActive( WindowType nRT, BOOL MaybeBase )
633 SearchActive aSearch( nRT );
635 return SearchAllWin( NULL, aSearch, MaybeBase );
638 BOOL SearchFadeSplitWin::IsWinOK( Window *pWin )
640 #if OSL_DEBUG_LEVEL > 1
641 if ( pWin->GetType() == WINDOW_SPLITWINDOW )
643 BOOL bResult;
644 WindowAlign aAlign;
645 bResult = pWin->IsVisible();
646 bResult = ((SplitWindow*)pWin)->IsFadeInButtonVisible();
647 bResult = ((SplitWindow*)pWin)->IsFadeOutButtonVisible();
648 bResult = ((SplitWindow*)pWin)->IsAutoHideButtonVisible();
649 aAlign = ((SplitWindow*)pWin)->GetAlign();
651 #endif
652 return pWin->IsVisible() && ( pWin->GetType() == WINDOW_SPLITWINDOW )
653 && (((SplitWindow*)pWin)->IsFadeInButtonVisible() || ((SplitWindow*)pWin)->IsFadeOutButtonVisible() )
654 /*&& ((SplitWindow*)pWin)->IsAutoHideButtonVisible()*/ && ((SplitWindow*)pWin)->GetAlign() == nAlign;
657 Window* StatementList::GetFadeSplitWin( Window *pBase, WindowAlign nAlign, BOOL MaybeBase )
659 SearchFadeSplitWin aSearch( nAlign );
661 if ( GetpApp()->GetAppWindow() == pBase && pBase->GetType() != WINDOW_BORDERWINDOW )
662 pBase = pBase->GetWindow( WINDOW_OVERLAP );
664 return SearchAllWin( pBase, aSearch, MaybeBase );
667 Window* StatementList::GetMouseWin()
669 Window *pBase = Application::GetFirstTopLevelWindow();
670 Window *pControl = NULL;
671 while ( pBase )
673 Window *pBaseFrame = pBase->GetWindow( WINDOW_OVERLAP );
675 Point aP = pBaseFrame->GetPointerPosPixel();
676 pControl = pBaseFrame->FindWindow( aP );
677 if ( pControl )
678 return pControl;
680 pBase = Application::GetNextTopLevelWindow( pBase );
682 return NULL;
685 Window* StatementList::GetFocus( WindowType nRT, BOOL MaybeBase )
688 if ( nRT == WINDOW_TABCONTROL )
690 Window *pResult = GetActive( WINDOW_TABDIALOG, MaybeBase);
691 for( USHORT i = 0 ; pResult && i < pResult->GetChildCount(); i++ )
692 if ( pResult->GetChild(i)->GetType() == nRT )
693 return pResult->GetChild(i);
696 return NULL;
699 Window* StatementList::GetAnyActive( BOOL MaybeBase )
701 Window *pControl;
703 pControl = GetActive( WINDOW_MESSBOX, MaybeBase);
704 if ( !pControl )
706 pControl = GetActive( WINDOW_INFOBOX, MaybeBase);
708 if ( !pControl )
710 pControl = GetActive( WINDOW_WARNINGBOX, MaybeBase);
712 if ( !pControl )
714 pControl = GetActive( WINDOW_ERRORBOX, MaybeBase);
716 if ( !pControl )
718 pControl = GetActive( WINDOW_QUERYBOX, MaybeBase);
720 if ( !pControl )
722 pControl = GetActive( WINDOW_BUTTONDIALOG, MaybeBase);
724 if ( !pControl )
726 pControl = GetActive( WINDOW_FILEDIALOG, MaybeBase);
728 if ( !pControl )
730 pControl = GetActive( WINDOW_PATHDIALOG, MaybeBase);
732 if ( !pControl )
734 pControl = GetActive( WINDOW_PRINTDIALOG, MaybeBase);
736 if ( !pControl )
738 pControl = GetActive( WINDOW_PRINTERSETUPDIALOG, MaybeBase);
740 if ( !pControl )
742 pControl = GetActive( WINDOW_COLORDIALOG, MaybeBase);
744 if ( !pControl )
746 pControl = GetFocus( WINDOW_TABCONTROL, MaybeBase);
749 return pControl;
752 void StatementList::SetFirstDocFrame( Window* pWin )
754 DBG_ASSERT( IsDocFrame( pWin ), "Non Document Frame set as first Document Frame" );
755 pFirstDocFrame = pWin;
758 Window* StatementList::GetFirstDocFrame()
761 if ( pFirstDocFrame && !WinPtrValid( pFirstDocFrame ) )
762 pFirstDocFrame = NULL;
763 if ( pFirstDocFrame && !pFirstDocFrame->IsVisible() )
764 pFirstDocFrame = NULL;
765 if ( pFirstDocFrame && !IsDocFrame( pFirstDocFrame ) )
766 pFirstDocFrame = NULL;
767 if ( !pFirstDocFrame )
769 Window* pBase = Application::GetFirstTopLevelWindow();
770 while ( pBase && !IsDocFrame( pBase ) )
771 pBase = Application::GetNextTopLevelWindow( pBase );
773 if ( pBase )
774 SetFirstDocFrame( pBase );
776 if ( !pBase ) // find just something
778 pBase = Application::GetFirstTopLevelWindow();
779 while ( pBase && !pBase->IsVisible() )
780 pBase = Application::GetNextTopLevelWindow( pBase );
782 return pBase; // just for now, later we will hopefully have a Window
785 return pFirstDocFrame;
788 BOOL StatementList::IsFirstDocFrame( Window* pWin )
790 return pWin && ( pWin == GetFirstDocFrame() || ( GetFirstDocFrame() && pWin == GetFirstDocFrame()->GetWindow( WINDOW_CLIENT ) ) ) && ( GetFirstDocFrame() && IsDocFrame( GetFirstDocFrame() ) );
793 MenuBar* StatementList::GetDocFrameMenuBar( Window* pWin )
795 if ( pWin && pWin->IsVisible() && pWin->GetType() == WINDOW_BORDERWINDOW )
797 USHORT nCount;
798 for ( nCount = 0 ; nCount < pWin->GetChildCount() ; nCount++ )
800 if ( pWin->GetChild( nCount )->GetType() == WINDOW_WORKWINDOW )
801 return ((WorkWindow*)(pWin->GetChild( nCount )))->GetMenuBar();
804 return NULL;
807 // a Doc Frame is a Document or the Backing Window
808 BOOL StatementList::IsDocFrame( Window* pWin )
810 if ( pWin && pWin->IsVisible() && pWin->GetType() == WINDOW_BORDERWINDOW )
812 USHORT nCount;
813 BOOL bHasWorkWindow = FALSE;
814 BOOL bHasMenuBar = FALSE;
815 // #91724# it is now necessary to sort out the IME WIndow in Solaris as well.
816 // so now we check for existence of WINDOW_WORKWINDOW and newly for
817 // WINDOW_MENUBARWINDOW which contains the Menu and the close/min/max buttons
818 for ( nCount = 0 ; nCount < pWin->GetChildCount() ; nCount++ )
820 if ( pWin->GetChild( nCount )->GetType() == WINDOW_WORKWINDOW )
821 bHasWorkWindow = TRUE;
822 if ( pWin->GetChild( nCount )->GetType() == WINDOW_MENUBARWINDOW )
823 bHasMenuBar = TRUE;
825 return bHasWorkWindow && bHasMenuBar;
827 return FALSE;
830 // a Doc Win is a real document (not the Backing Window)
831 BOOL StatementList::IsDocWin( Window* pWin )
833 if ( pWin && IsDocFrame( pWin ) )
835 if ( GetDocFrameCount() != 1 )
836 return TRUE;
837 else
839 // check for the close button to see if we are the last one or only the backing Window
840 if ( GetDocFrameMenuBar( pWin ) )
841 return GetDocFrameMenuBar( pWin )->HasCloser();
844 return FALSE;
847 BOOL StatementList::IsIMEWin( Window* pWin ) // Input Window for CJK under Solaris
849 if ( pWin && pWin->IsVisible() && pWin->GetType() == WINDOW_BORDERWINDOW )
851 USHORT nCount;
852 BOOL bHasWorkWindow = FALSE;
853 BOOL bHasWindow = FALSE;
854 // #91724# it is now necessary to sort out the IME WIndow in Solaris as well.
855 // so now we check for existence of WINDOW_WORKWINDOW and newly for
856 // WINDOW_WINDOW which contains the Menu and the close/min/max buttons
857 for ( nCount = 0 ; nCount < pWin->GetChildCount() ; nCount++ )
858 if ( pWin->GetChild( nCount )->GetType() == WINDOW_WORKWINDOW )
859 bHasWorkWindow = TRUE;
860 for ( nCount = 0 ; nCount < pWin->GetChildCount() ; nCount++ )
861 if ( pWin->GetChild( nCount )->GetType() == WINDOW_WINDOW )
862 bHasWindow = TRUE;
863 return bHasWorkWindow && !bHasWindow;
865 return FALSE;
868 UniString StatementList::Tree(Window *pBase, int Indent)
871 String aReturn, aSep;
872 if ( !pBase )
874 aSep.AssignAscii("============================\n");
875 aSep.ConvertLineEnd();
876 pBase = Application::GetFirstTopLevelWindow();
877 while ( pBase )
879 Window *pBaseFrame = pBase->GetWindow( WINDOW_OVERLAP );
881 aReturn += aSep;
882 aReturn += Tree( pBaseFrame, Indent+1 );
884 pBase = Application::GetNextTopLevelWindow( pBase );
886 return aReturn;
890 aSep.AssignAscii("----------------------------\n");
891 aSep.ConvertLineEnd();
893 aReturn += ClientTree( pBase, Indent );
895 if ( pBase->GetWindow( WINDOW_FIRSTOVERLAP ) )
897 aReturn += aSep;
898 aReturn += Tree( pBase->GetWindow( WINDOW_FIRSTOVERLAP ), Indent+1 );
901 if ( pBase->GetWindow( WINDOW_NEXT ) )
903 aReturn += aSep;
904 aReturn += Tree( pBase->GetWindow( WINDOW_NEXT ), Indent );
907 return aReturn;
910 String StatementList::ClientTree(Window *pBase, int Indent)
912 #if OSL_DEBUG_LEVEL > 1
913 #define WRITE(Text) { m_pDbgWin->AddText(Text); aReturn += Text; }
914 #define WRITEc(Text) { m_pDbgWin->AddText(Text); aReturn.AppendAscii(Text); }
915 #else
916 #define WRITE(Text) { aReturn += Text; }
917 #define WRITEc(Text) { aReturn.AppendAscii(Text); }
918 #endif
920 String sIndent,aText,aReturn;
921 sIndent.Expand(sal::static_int_cast< xub_StrLen >(2*Indent));
923 aText = pBase->GetText();
926 UniString t1,t2;t1 = CUniString("\n"); t2 = CUniString("\\n");
927 aText.SearchAndReplaceAll(t1,t2 );
929 WRITE(sIndent);
931 if (pBase->IsDialog())
933 WRITEc("*(Dialog(TH))");
935 if (IsDialog( pBase ))
937 WRITEc("*(Dialog(GH))");
939 if (pBase->HasFocus())
941 WRITEc("*(Focus)");
943 if (!pBase->IsEnabled())
945 WRITEc("*(Disab)");
947 if (pBase->IsVisible())
949 WRITEc("*(Visible)");
951 if ( IsDialog(pBase) && ((SystemWindow*)pBase)->IsActive() )
953 WRITEc("*(Active)");
955 if ( pBase->GetStyle() & WB_CLOSEABLE )
957 WRITEc("*(Closable)");
959 if ( pBase->GetType() == WINDOW_DOCKINGWINDOW &&
960 ((((DockingWindow*)pBase)->GetFloatStyle()) & WB_CLOSEABLE) )
962 WRITEc("*(Closable Docking in Floatingstyle)");
964 if ( pBase->GetStyle() & WB_DOCKABLE )
966 WRITEc("*(Dockable)");
968 if ( pBase->GetType() == WINDOW_SPLITWINDOW &&
969 (((SplitWindow*)pBase)->IsFadeInButtonVisible() || ((SplitWindow*)pBase)->IsFadeOutButtonVisible()) )
971 WRITEc("*(FadeIn/Out)");
973 WRITEc("Text: ");
974 WRITE(aText);
975 WRITEc("\n");
977 WRITE(sIndent);
978 WRITEc("UId : ");
979 WRITE(UIdString(pBase->GetSmartUniqueOrHelpId()));
980 WRITEc(":0x");
981 WRITE(
982 String::CreateFromInt64(
983 sal::static_int_cast< sal_Int64 >(
984 reinterpret_cast< sal_IntPtr >(pBase)),
985 16 ));
986 WRITEc(":");
987 WRITE(pBase->GetQuickHelpText());
988 WRITEc(":");
989 WRITE(pBase->GetHelpText());
990 WRITEc("\n");
992 WRITE(sIndent);
993 WRITEc("RTyp: ");
994 WRITE(MakeStringNumber(TypeKenn,pBase->GetType()));
995 if ( pBase->GetType() == WINDOW_CONTROL )
997 if ( dynamic_cast< svt::EditBrowseBox* >(pBase) )
998 WRITEc("/BrowseBox")
999 else if ( dynamic_cast< ValueSet* >(pBase) )
1000 WRITEc("/ValueSet")
1001 else if ( dynamic_cast< svt::ORoadmap* >(pBase) )
1002 WRITEc("/RoadMap")
1003 else if ( dynamic_cast< svt::IExtensionListBox* >(pBase) )
1004 WRITEc("/ExtensionListBox")
1005 else
1006 WRITEc("/Unknown")
1008 WRITEc("\n");
1010 aReturn.ConvertLineEnd();
1011 USHORT i;
1012 for (i = 0 ; i < pBase->GetChildCount() ; i++)
1014 aReturn += ClientTree(pBase->GetChild(i),Indent+1);
1016 return aReturn;
1020 BOOL StatementList::CheckWindowWait()
1022 static Time StartTime = Time(0L); // Abbruch wenn Fenster absolut nicht schliesst.
1023 if ( StartTime == Time(0L) )
1024 StartTime = Time();
1026 if ( pWindowWaitPointer )
1028 #if OSL_DEBUG_LEVEL > 1
1029 m_pDbgWin->AddText( "Waiting for Window to close ... " );
1030 #endif
1031 if ( WinPtrValid(pWindowWaitPointer) && IS_WINP_CLOSING(pWindowWaitPointer) )
1033 #if OSL_DEBUG_LEVEL > 1
1034 m_pDbgWin->AddText( aWindowWaitUId.GetText().AppendAscii(" Still Open. RType=") );
1035 m_pDbgWin->AddText( String::CreateFromInt32( pWindowWaitPointer->GetType() ).AppendAscii("\n") );
1036 #endif
1038 // Ist die Zeit schonn abgelaufen?
1039 if ( StartTime + Time(0,0,10) < Time() ) // 10 Sekunden reichen wohl
1041 #if OSL_DEBUG_LEVEL > 1
1042 m_pDbgWin->AddText( "Close timed out. Going on!! " );
1043 #endif
1044 pWindowWaitPointer->SetSmartHelpId(aWindowWaitOldHelpId, SMART_SET_ALL);
1045 pWindowWaitPointer->SetSmartUniqueId(aWindowWaitOldUniqueId, SMART_SET_ALL);
1047 aWindowWaitUId = SmartId();
1048 pWindowWaitPointer = NULL;
1049 StartTime = Time(0L);
1050 return TRUE;
1053 return FALSE;
1055 pWindowWaitPointer = NULL;
1056 aWindowWaitUId = SmartId();
1057 #if OSL_DEBUG_LEVEL > 1
1058 m_pDbgWin->AddText( "Closed, Going on.\n" );
1059 #endif
1061 StartTime = Time(0L);
1062 return TRUE;
1065 void StatementList::ReportError(String aMessage)
1067 ReportError ( SmartId(), aMessage );
1070 void StatementList::ReportError(SmartId aUId, String aMessage)
1072 pRet->GenError ( aUId, aMessage );
1073 IsError = TRUE;
1076 void StatementList::ReportError(String aMessage, ULONG nWhatever)
1078 ReportError ( aMessage.AppendAscii(" ").Append(UniString::CreateFromInt32(nWhatever)));
1081 void StatementList::DirectLog( ULONG nType, String aMessage )
1083 if ( pRet )
1084 pRet->GenReturn( RET_DirectLoging, SmartId(nType), aMessage );
1088 #define CALL_EVENT_WITH_NOTIFY( EventType, Event, WinP, Method ) \
1090 if ( StatementList::WinPtrValid( WinP ) ) \
1092 NotifyEvent aNEvt( EventType, WinP, &Event ); \
1093 if ( !WinP->PreNotify( aNEvt ) ) \
1094 WinP->Method( Event ); \
1098 void ImplKeyInput( Window* pWin, KeyEvent &aKEvnt, BOOL bForceDirect )
1101 if ( StatementList::bUsePostEvents && !bForceDirect )
1103 if ( StatementList::WinPtrValid( pWin ) )
1105 ULONG nID1;
1106 ULONG nID2;
1107 nID1 = Application::PostKeyEvent( VCLEVENT_WINDOW_KEYINPUT, pWin, &aKEvnt );
1108 nID2 = Application::PostKeyEvent( VCLEVENT_WINDOW_KEYUP, pWin, &aKEvnt );
1109 // wait after posting both events so deleting pWin will remove the second event also
1110 ImplEventWait( nID1 );
1111 ImplEventWait( nID2 );
1114 else
1116 if ( !Application::CallAccel( aKEvnt.GetKeyCode() ) )
1118 CALL_EVENT_WITH_NOTIFY( EVENT_KEYINPUT, aKEvnt, pWin, KeyInput )
1120 KeyCode aCode = aKEvnt.GetKeyCode();
1121 if ( (aCode.GetCode() == KEY_CONTEXTMENU) || ((aCode.GetCode() == KEY_F10) && aCode.IsShift()) )
1123 if ( StatementList::WinPtrValid( pWin ) )
1125 Point aPos;
1126 // simulate mouseposition at center of window
1127 Size aSize = pWin->GetOutputSize();
1128 aPos = Point( aSize.getWidth()/2, aSize.getHeight()/2 );
1130 CommandEvent aEvent( aPos, COMMAND_CONTEXTMENU, FALSE );
1131 ImplCommand( pWin, aEvent );
1136 CALL_EVENT_WITH_NOTIFY( EVENT_KEYUP, aKEvnt, pWin, KeyUp )
1140 void ImplMouseMove( Window* pWin, MouseEvent &aMEvnt, BOOL bForceDirect )
1142 if ( StatementList::bUsePostEvents && !bForceDirect )
1144 if ( StatementList::WinPtrValid( pWin ) )
1146 ULONG nID;
1147 nID = Application::PostMouseEvent( VCLEVENT_WINDOW_MOUSEMOVE, pWin, &aMEvnt );
1148 ImplEventWait( nID );
1151 else
1153 // DragManager* pDragManager = DragManager::GetDragManager();
1154 // if ( pDragManager )
1155 // pDragManager->MouseMove( aMEvnt, pWin );
1156 // else
1157 if ( pWin->IsTracking() )
1159 TrackingEvent aTEvt( aMEvnt );
1160 pWin->Tracking( aTEvt );
1162 else
1163 CALL_EVENT_WITH_NOTIFY( EVENT_MOUSEMOVE, aMEvnt, pWin, MouseMove )
1167 void ImplMouseButtonDown( Window* pWin, MouseEvent &aMEvnt, BOOL bForceDirect )
1169 if ( StatementList::bUsePostEvents && !bForceDirect )
1171 if ( StatementList::WinPtrValid( pWin ) )
1173 ULONG nID;
1174 nID = Application::PostMouseEvent( VCLEVENT_WINDOW_MOUSEBUTTONDOWN, pWin, &aMEvnt );
1175 ImplEventWait( nID );
1178 else
1180 CALL_EVENT_WITH_NOTIFY( EVENT_MOUSEBUTTONDOWN, aMEvnt, pWin, MouseButtonDown )
1184 void ImplMouseButtonUp( Window* pWin, MouseEvent &aMEvnt, BOOL bForceDirect )
1186 if ( StatementList::bUsePostEvents && !bForceDirect )
1188 if ( StatementList::WinPtrValid( pWin ) )
1190 ULONG nID;
1191 nID = Application::PostMouseEvent( VCLEVENT_WINDOW_MOUSEBUTTONUP, pWin, &aMEvnt );
1192 ImplEventWait( nID );
1195 else
1197 // DragManager* pDragManager = DragManager::GetDragManager();
1198 // if ( pDragManager )
1199 // pDragManager->ButtonUp( aMEvnt, pWin );
1200 // else
1201 if ( pWin->IsTracking() )
1203 // siehe #64693 die Position ist für Toolboxen relevant
1204 // #60020 Jetzt hoffentlich kein GPF mehr
1205 // Zuerst Tracking beenden ohne Event
1206 pWin->EndTracking( ENDTRACK_DONTCALLHDL );
1207 // dann eigenen Event mit richtigem Maus-Event senden
1208 TrackingEvent aTEvt( aMEvnt, ENDTRACK_END );
1209 pWin->Tracking( aTEvt );
1211 else
1212 CALL_EVENT_WITH_NOTIFY( EVENT_MOUSEBUTTONUP, aMEvnt, pWin, MouseButtonUp )
1216 void ImplEventWait( ULONG nID )
1218 while ( !Application::IsProcessedMouseOrKeyEvent( nID ) )
1219 Application::Yield();
1222 void ImplCommand( Window* pWin, CommandEvent &aCmdEvnt )
1224 CALL_EVENT_WITH_NOTIFY( EVENT_COMMAND, aCmdEvnt, pWin, Command )