1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: sta_list.cxx,v $
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>
39 #include "statemnt.hxx"
42 #include "retstrm.hxx"
44 #include "rcontrol.hxx"
46 #if OSL_DEBUG_LEVEL > 1
47 #include "editwin.hxx"
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
;
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
;
109 static TTSettings
* pTTSettings
= NULL
;
111 TTSettings
* GetTTSettings()
115 pTTSettings
= new TTSettings
;
118 pTTSettings
->pDisplayInstance
= NULL
;
119 pTTSettings
->pDisplayHidWin
= NULL
;
120 pTTSettings
->Old
= NULL
;
121 pTTSettings
->Act
= NULL
;
122 pTTSettings
->aOriginalCaption
.Erase();
125 pTTSettings
->pTranslateWin
= NULL
;
126 pTTSettings
->bToTop
= TRUE
;
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
)
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()
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") );
162 pCurrentProfileStatement
= this;
166 void StatementList::SendProfile( String aText
)
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") );
189 pCurrentProfileStatement
= NULL
;
193 void StatementList::QueStatement(StatementList
*pAfterThis
)
195 DBG_ASSERT(!bStatementInQue
,"QueStatement für bereits eingetragenes Statement -> Abgebrochen");
196 if ( bStatementInQue
)
199 bStatementInQue
= TRUE
;
202 if ( pAfterThis
->bStatementInQue
)
204 pNext
= pAfterThis
->pNext
;
205 pAfterThis
->pNext
= this;
208 { // pAfterThis not in que -> already dequed -> add to front of list
213 else // am Ende einfügen
220 StatementList
*pList
;
222 while( pList
->pNext
)
223 pList
= pList
->pNext
;
229 void StatementList::Advance()
230 { // pFirst ist static!
232 bStatementInQue
= FALSE
;
237 StatementList::~StatementList()
239 #if OSL_DEBUG_LEVEL > 1
240 m_pDbgWin
->AddText( "Deleting \n" );
242 DBG_ASSERT(!bReadingCommands
,"Deleting commands while reading them!");
245 Window
* StatementList::GetDocWin( USHORT nNr
)
247 Window
* pBase
= Application::GetFirstTopLevelWindow();
251 if ( IsDocWin( pBase
) )
257 pBase
= Application::GetNextTopLevelWindow( pBase
);
262 USHORT
StatementList::GetDocFrameCount()
264 Window
* pBase
= Application::GetFirstTopLevelWindow();
269 if ( IsDocFrame( pBase
) )
271 pBase
= Application::GetNextTopLevelWindow( pBase
);
276 USHORT
StatementList::GetDocWinCount()
278 Window
* pBase
= Application::GetFirstTopLevelWindow();
283 if ( IsDocWin( pBase
) )
285 pBase
= Application::GetNextTopLevelWindow( pBase
);
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();
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 ) )
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
);
333 pBase
= Application::GetFirstTopLevelWindow();
335 // Skip FirstDocFrame
336 // if ( bSearchFocusFirst && IsFirstDocFrame( pBase ) )
337 // pBase = Application::GetNextTopLevelWindow( pBase );
341 pControl
= SearchAllWin( pBase
, aSearch
);
345 pBase
= Application::GetNextTopLevelWindow( pBase
);
346 // Skip FirstDocFrame
347 // if ( bSearchFocusFirst && IsFirstDocFrame( pBase ) )
348 // pBase = Application::GetNextTopLevelWindow( pBase );
354 Window
*pResult
= NULL
;
355 pResult
= SearchClientWin( pBase
, aSearch
, MaybeBase
);
359 // if ( pBase->GetType() != WINDOW_BORDERWINDOW )
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
);
375 Window
* StatementList::SearchClientWin( Window
*pBase
, Search
&aSearch
, BOOL MaybeBase
)
380 if ( MaybeBase
&& aSearch
.IsWinOK( pBase
) )
383 Window
*pResult
= NULL
;
386 for( i
= 0 ; i
< pBase
->GetChildCount() && !pResult
; i
++ )
387 pResult
= SearchClientWin( pBase
->GetChild(i
), aSearch
);
393 BOOL
SearchUID::IsWinOK( Window
*pWin
)
395 if ( aUId
.Matches( pWin
->GetSmartUniqueOrHelpId() ) )
397 if ( ( pWin
->IsEnabled() || HasSearchFlag( SEARCH_FIND_DISABLED
) ) && pWin
->IsVisible() )
406 else if ( pWin
->GetType() == WINDOW_TOOLBOX
) // Buttons and Controls on ToolBox.
408 ToolBox
*pTB
= ((ToolBox
*)pWin
);
410 for ( i
= 0; i
< pTB
->GetItemCount() ; i
++ )
412 if ( aUId
.Matches( pTB
->GetItemCommand(pTB
->GetItemId( i
)) ) || aUId
.Matches( pTB
->GetHelpId(pTB
->GetItemId( i
)) ) )
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.
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.
426 { // better a disabled Button on a valid ToolBox than an invalid ToolBox as below
431 else if ( !pMaybeResult
)
438 { // We got a Control, see if its valid also.
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
;
460 Window
* StatementList::SearchTree( SmartId aUId
,BOOL bSearchButtonOnToolbox
)
462 SearchUID
aSearch(aUId
,bSearchButtonOnToolbox
);
464 Window
*pResult
= SearchAllWin( NULL
, aSearch
);
467 else if ( aSearch
.GetAlternateResultWin() )
468 return aSearch
.GetAlternateResultWin();
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
)
502 Window
* StatementList::GetWinByRT( Window
*pBase
, WindowType nRT
, BOOL MaybeBase
, USHORT nSkip
, BOOL bSearchAll
)
504 SearchRT
aSearch( nRT
, 0, nSkip
);
506 aSearch
.AddSearchFlags( SEARCH_FOCUS_FIRST
| SEARCH_FIND_DISABLED
);
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
));
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
)
557 if ( pBaseMenu
->GetWindow() == pWin
)
561 // while ( pBaseMenu )
564 while ( i
< pBaseMenu
->GetItemCount() )
566 PopupMenu
* pPopup
= pBaseMenu
->GetPopupMenu( pBaseMenu
->GetItemId( i
) );
567 if ( pPopup
&& pPopup
->GetWindow() )
569 if ( pPopup
->GetWindow() == pWin
)
584 if ( PopupMenu::GetActivePopupMenu() )
586 Menu
* pMenu
= GetMatchingMenu( pWin
, PopupMenu::GetActivePopupMenu() );
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() )
599 // find Menu of MenuBarWindow
601 for ( nCount
= 0 ; nCount
< pParent
->GetChildCount() ; nCount
++ )
603 if ( pParent
->GetChild( nCount
)->GetType() == WINDOW_WORKWINDOW
)
604 pMenu
= ((WorkWindow
*)(pParent
->GetChild( nCount
)))->GetMenuBar();
608 // check for menu bar in Task Window
609 if ( pMenuBarWin
== pWin
)
613 pMenu
= GetMatchingMenu( pWin
, pMenu
);
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
)
645 bResult
= pWin
->IsVisible();
646 bResult
= ((SplitWindow
*)pWin
)->IsFadeInButtonVisible();
647 bResult
= ((SplitWindow
*)pWin
)->IsFadeOutButtonVisible();
648 bResult
= ((SplitWindow
*)pWin
)->IsAutoHideButtonVisible();
649 aAlign
= ((SplitWindow
*)pWin
)->GetAlign();
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
;
673 Window
*pBaseFrame
= pBase
->GetWindow( WINDOW_OVERLAP
);
675 Point aP
= pBaseFrame
->GetPointerPosPixel();
676 pControl
= pBaseFrame
->FindWindow( aP
);
680 pBase
= Application::GetNextTopLevelWindow( pBase
);
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
);
699 Window
* StatementList::GetAnyActive( BOOL MaybeBase
)
703 pControl
= GetActive( WINDOW_MESSBOX
, MaybeBase
);
706 pControl
= GetActive( WINDOW_INFOBOX
, MaybeBase
);
710 pControl
= GetActive( WINDOW_WARNINGBOX
, MaybeBase
);
714 pControl
= GetActive( WINDOW_ERRORBOX
, MaybeBase
);
718 pControl
= GetActive( WINDOW_QUERYBOX
, MaybeBase
);
722 pControl
= GetActive( WINDOW_BUTTONDIALOG
, MaybeBase
);
726 pControl
= GetActive( WINDOW_FILEDIALOG
, MaybeBase
);
730 pControl
= GetActive( WINDOW_PATHDIALOG
, MaybeBase
);
734 pControl
= GetActive( WINDOW_PRINTDIALOG
, MaybeBase
);
738 pControl
= GetActive( WINDOW_PRINTERSETUPDIALOG
, MaybeBase
);
742 pControl
= GetActive( WINDOW_COLORDIALOG
, MaybeBase
);
746 pControl
= GetFocus( WINDOW_TABCONTROL
, MaybeBase
);
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
);
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
)
798 for ( nCount
= 0 ; nCount
< pWin
->GetChildCount() ; nCount
++ )
800 if ( pWin
->GetChild( nCount
)->GetType() == WINDOW_WORKWINDOW
)
801 return ((WorkWindow
*)(pWin
->GetChild( nCount
)))->GetMenuBar();
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
)
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
)
825 return bHasWorkWindow
&& bHasMenuBar
;
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 )
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();
847 BOOL
StatementList::IsIMEWin( Window
* pWin
) // Input Window for CJK under Solaris
849 if ( pWin
&& pWin
->IsVisible() && pWin
->GetType() == WINDOW_BORDERWINDOW
)
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
)
863 return bHasWorkWindow
&& !bHasWindow
;
868 UniString
StatementList::Tree(Window
*pBase
, int Indent
)
871 String aReturn
, aSep
;
874 aSep
.AssignAscii("============================\n");
875 aSep
.ConvertLineEnd();
876 pBase
= Application::GetFirstTopLevelWindow();
879 Window
*pBaseFrame
= pBase
->GetWindow( WINDOW_OVERLAP
);
882 aReturn
+= Tree( pBaseFrame
, Indent
+1 );
884 pBase
= Application::GetNextTopLevelWindow( pBase
);
890 aSep
.AssignAscii("----------------------------\n");
891 aSep
.ConvertLineEnd();
893 aReturn
+= ClientTree( pBase
, Indent
);
895 if ( pBase
->GetWindow( WINDOW_FIRSTOVERLAP
) )
898 aReturn
+= Tree( pBase
->GetWindow( WINDOW_FIRSTOVERLAP
), Indent
+1 );
901 if ( pBase
->GetWindow( WINDOW_NEXT
) )
904 aReturn
+= Tree( pBase
->GetWindow( WINDOW_NEXT
), Indent
);
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); }
916 #define WRITE(Text) { aReturn += Text; }
917 #define WRITEc(Text) { aReturn.AppendAscii(Text); }
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
);
931 if (pBase
->IsDialog())
933 WRITEc("*(Dialog(TH))");
935 if (IsDialog( pBase
))
937 WRITEc("*(Dialog(GH))");
939 if (pBase
->HasFocus())
943 if (!pBase
->IsEnabled())
947 if (pBase
->IsVisible())
949 WRITEc("*(Visible)");
951 if ( IsDialog(pBase
) && ((SystemWindow
*)pBase
)->IsActive() )
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)");
979 WRITE(UIdString(pBase
->GetSmartUniqueOrHelpId()));
982 String::CreateFromInt64(
983 sal::static_int_cast
< sal_Int64
>(
984 reinterpret_cast< sal_IntPtr
>(pBase
)),
987 WRITE(pBase
->GetQuickHelpText());
989 WRITE(pBase
->GetHelpText());
994 WRITE(MakeStringNumber(TypeKenn
,pBase
->GetType()));
995 if ( pBase
->GetType() == WINDOW_CONTROL
)
997 if ( dynamic_cast< svt::EditBrowseBox
* >(pBase
) )
999 else if ( dynamic_cast< ValueSet
* >(pBase
) )
1001 else if ( dynamic_cast< svt::ORoadmap
* >(pBase
) )
1003 else if ( dynamic_cast< svt::IExtensionListBox
* >(pBase
) )
1004 WRITEc("/ExtensionListBox")
1010 aReturn
.ConvertLineEnd();
1012 for (i
= 0 ; i
< pBase
->GetChildCount() ; i
++)
1014 aReturn
+= ClientTree(pBase
->GetChild(i
),Indent
+1);
1020 BOOL
StatementList::CheckWindowWait()
1022 static Time StartTime
= Time(0L); // Abbruch wenn Fenster absolut nicht schliesst.
1023 if ( StartTime
== Time(0L) )
1026 if ( pWindowWaitPointer
)
1028 #if OSL_DEBUG_LEVEL > 1
1029 m_pDbgWin
->AddText( "Waiting for Window to close ... " );
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") );
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!! " );
1044 pWindowWaitPointer
->SetSmartHelpId(aWindowWaitOldHelpId
, SMART_SET_ALL
);
1045 pWindowWaitPointer
->SetSmartUniqueId(aWindowWaitOldUniqueId
, SMART_SET_ALL
);
1047 aWindowWaitUId
= SmartId();
1048 pWindowWaitPointer
= NULL
;
1049 StartTime
= Time(0L);
1055 pWindowWaitPointer
= NULL
;
1056 aWindowWaitUId
= SmartId();
1057 #if OSL_DEBUG_LEVEL > 1
1058 m_pDbgWin
->AddText( "Closed, Going on.\n" );
1061 StartTime
= Time(0L);
1065 void StatementList::ReportError(String aMessage
)
1067 ReportError ( SmartId(), aMessage
);
1070 void StatementList::ReportError(SmartId aUId
, String aMessage
)
1072 pRet
->GenError ( aUId
, aMessage
);
1076 void StatementList::ReportError(String aMessage
, ULONG nWhatever
)
1078 ReportError ( aMessage
.AppendAscii(" ").Append(UniString::CreateFromInt32(nWhatever
)));
1081 void StatementList::DirectLog( ULONG nType
, String aMessage
)
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
) )
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
);
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
) )
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
) )
1147 nID
= Application::PostMouseEvent( VCLEVENT_WINDOW_MOUSEMOVE
, pWin
, &aMEvnt
);
1148 ImplEventWait( nID
);
1153 // DragManager* pDragManager = DragManager::GetDragManager();
1154 // if ( pDragManager )
1155 // pDragManager->MouseMove( aMEvnt, pWin );
1157 if ( pWin
->IsTracking() )
1159 TrackingEvent
aTEvt( aMEvnt
);
1160 pWin
->Tracking( aTEvt
);
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
) )
1174 nID
= Application::PostMouseEvent( VCLEVENT_WINDOW_MOUSEBUTTONDOWN
, pWin
, &aMEvnt
);
1175 ImplEventWait( nID
);
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
) )
1191 nID
= Application::PostMouseEvent( VCLEVENT_WINDOW_MOUSEBUTTONUP
, pWin
, &aMEvnt
);
1192 ImplEventWait( nID
);
1197 // DragManager* pDragManager = DragManager::GetDragManager();
1198 // if ( pDragManager )
1199 // pDragManager->ButtonUp( aMEvnt, pWin );
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
);
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
)