/************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_automation.hxx" #include #include #include #ifndef _BASIC_TTRESHLP_HXX #include #endif #include "statemnt.hxx" #ifndef _RETSRTM_HXX #include "retstrm.hxx" #endif #include "rcontrol.hxx" #if OSL_DEBUG_LEVEL > 1 #include "editwin.hxx" #endif #include "profiler.hxx" #include #include // only needed for dynamic_cast in wintree #include #include #include #include #include #define WINDOW_ANYTYPE WINDOW_BASE TTProfiler *StatementList::pProfiler = NULL; StatementList *StatementList::pFirst = NULL; sal_Bool StatementList::bReadingCommands = sal_False; sal_Bool StatementList::bIsInReschedule = sal_False; sal_uInt16 StatementList::nModalCount = 0; Window *StatementList::pLastFocusWindow = NULL; sal_Bool StatementList::bWasDragManager = sal_False; sal_Bool StatementList::bWasPopupMenu = sal_False; sal_Bool StatementList::bBasicWasRunning = sal_False; RetStream *StatementList::pRet = NULL; sal_Bool StatementList::IsError = sal_False; sal_Bool StatementList::bDying = sal_False; sal_Bool StatementList::bExecuting = sal_False; StatementList *StatementList::pCurrentProfileStatement = NULL; sal_Bool StatementList::bUsePostEvents = sal_True; #if OSL_DEBUG_LEVEL > 1 EditWindow *StatementList::m_pDbgWin; #endif rtl::OString StatementList::aWindowWaitUId = rtl::OString(); Window *StatementList::pWindowWaitPointer = NULL; rtl::OString StatementList::aWindowWaitOldHelpId = rtl::OString(); rtl::OString StatementList::aWindowWaitOldUniqueId = rtl::OString(); sal_uInt16 StatementList::nUseBindings = 0; sal_uInt16 StatementList::aSubMenuId1 = 0; // Untermenüs bei PopupMenus sal_uInt16 StatementList::aSubMenuId2 = 0; // erstmal 2-Stufig sal_uInt16 StatementList::aSubMenuId3 = 0; // and now even 3 levels #i31512# SystemWindow *StatementList::pMenuWindow = NULL; TTProperties *StatementList::pTTProperties = NULL; sal_uInt16 StatementList::nMinTypeKeysDelay = 0; // Verzögerung der einzelnen Anschläge für TypeKeys sal_uInt16 StatementList::nMaxTypeKeysDelay = 0; sal_Bool StatementList::bDoTypeKeysDelay = sal_False; Window* StatementList::pFirstDocFrame = NULL; sal_Bool StatementList::bIsSlotInExecute = sal_False; sal_Bool StatementList::bCatchGPF = sal_True; IMPL_GEN_RES_STR; static TTSettings* pTTSettings = NULL; TTSettings* GetTTSettings() { if ( !pTTSettings ) { pTTSettings = new TTSettings; // DisplayHID pTTSettings->pDisplayInstance = NULL; pTTSettings->pDisplayHidWin = NULL; pTTSettings->Old = NULL; pTTSettings->Act = NULL; pTTSettings->aOriginalCaption.Erase(); // Translate pTTSettings->pTranslateWin = NULL; pTTSettings->bToTop = sal_True; } return pTTSettings; } // FIXME: HELPID #define IS_WINP_CLOSING(pWin) (pWin->GetHelpId().equals( "TT_Win_is_closing_HID" ) && pWin->GetUniqueId().equals( "TT_Win_is_closing_UID" )) /* UniString GEN_RES_STR0( sal_uLong nResId ) { return ResString( nResId ); } UniString GEN_RES_STR1( sal_uLong nResId, const UniString &Text1 ) { return GEN_RES_STR0( nResId ).Append( ArgString( 1, Text1 ) ); } UniString GEN_RES_STR2( sal_uLong nResId, const UniString &Text1, const UniString &Text2 ) { return GEN_RES_STR1( nResId, Text1 ).Append( ArgString( 2, Text2 ) ); } 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 ) );} */ StatementList::StatementList() : nRetryCount(MAX_RETRIES) , bStatementInQue(sal_False) { if (!pRet) pRet = new RetStream; // so Spät wie möglich, aber dennoch Zentral und auf jeden Fall rechtzeitig, da pRet private ist. } void StatementList::InitProfile() { if ( pProfiler ) { if ( pProfiler->IsProfilingPerCommand() || pProfiler->IsPartitioning() ) pProfiler->StartProfileInterval( pCurrentProfileStatement != this ); #if OSL_DEBUG_LEVEL > 1 if ( pCurrentProfileStatement != NULL && pCurrentProfileStatement != this ) pRet->GenReturn( RET_ProfileInfo, 0, CUniString("InitProfile von anderem Statement gerufen ohne SendProfile\n") ); #endif pCurrentProfileStatement = this; } } void StatementList::SendProfile( String aText ) { if ( pProfiler ) { if ( pCurrentProfileStatement == this ) { if ( pProfiler->IsProfilingPerCommand() || pProfiler->IsPartitioning() ) pProfiler->EndProfileInterval(); if ( pProfiler->IsProfilingPerCommand() ) pRet->GenReturn( RET_ProfileInfo, 0, pProfiler->GetProfileLine( aText ) ); if ( pProfiler->IsPartitioning() ) // FIXME: HELPID pRet->GenReturn( RET_ProfileInfo, S_ProfileTime, static_cast(pProfiler->GetPartitioningTime()) ); // GetPartitioningTime() sal_uLong != comm_ULONG on 64bit } if ( pProfiler->IsAutoProfiling() ) pRet->GenReturn( RET_ProfileInfo, 0, pProfiler->GetAutoProfiling() ); #if OSL_DEBUG_LEVEL > 1 if ( pCurrentProfileStatement == NULL ) pRet->GenReturn( RET_ProfileInfo, 0, CUniString("SendProfile ohne InitProfile\n") ); #endif pCurrentProfileStatement = NULL; } } void StatementList::QueStatement(StatementList *pAfterThis) { DBG_ASSERT(!bStatementInQue,"QueStatement für bereits eingetragenes Statement -> Abgebrochen"); if ( bStatementInQue ) return; bStatementInQue = sal_True; if ( pAfterThis ) { if ( pAfterThis->bStatementInQue ) { pNext = pAfterThis->pNext; pAfterThis->pNext = this; } else { // pAfterThis not in que -> already dequed -> add to front of list pNext = pFirst; pFirst = this; } } else // am Ende einfügen { pNext = NULL; if( !pFirst ) pFirst = this; else { StatementList *pList; pList = pFirst; while( pList->pNext ) pList = pList->pNext; pList->pNext = this; } } } void StatementList::Advance() { // pFirst ist static! pFirst = pNext; bStatementInQue = sal_False; pNext = NULL; } StatementList::~StatementList() { #if OSL_DEBUG_LEVEL > 1 m_pDbgWin->AddText( "Deleting \n" ); #endif DBG_ASSERT(!bReadingCommands,"Deleting commands while reading them!"); } Window* StatementList::GetDocWin( sal_uInt16 nNr ) { Window* pBase = Application::GetFirstTopLevelWindow(); while ( pBase ) { if ( IsDocWin( pBase ) ) { if ( !nNr ) return pBase; nNr--; } pBase = Application::GetNextTopLevelWindow( pBase ); } return NULL; } sal_uInt16 StatementList::GetDocFrameCount() { Window* pBase = Application::GetFirstTopLevelWindow(); sal_uInt16 nCount = 0; while ( pBase ) { if ( IsDocFrame( pBase ) ) nCount++; pBase = Application::GetNextTopLevelWindow( pBase ); } return nCount; } sal_uInt16 StatementList::GetDocWinCount() { Window* pBase = Application::GetFirstTopLevelWindow(); sal_uInt16 nCount = 0; while ( pBase ) { if ( IsDocWin( pBase ) ) nCount++; pBase = Application::GetNextTopLevelWindow( pBase ); } return nCount; } Window* StatementList::SearchAllWin( Window *pBase, Search &aSearch, sal_Bool MaybeBase ) { if ( !pBase && !aSearch.HasSearchFlag( SEARCH_NO_TOPLEVEL_WIN ) ) { sal_Bool bSearchFocusFirst = aSearch.HasSearchFlag( SEARCH_FOCUS_FIRST ); Window *pControl = NULL; if ( bSearchFocusFirst ) { // first test Parent of Focus Window pBase = Application::GetFocusWindow(); if ( pBase ) { DBG_ASSERT( WinPtrValid( pBase ), "GetFocusWindow is no valid WindowPointer" ); Window *pPParent = pBase; while ( pPParent->GET_REAL_PARENT() ) pPParent = pPParent->GET_REAL_PARENT(); // if ( !IsFirstDocFrame( pPParent ) ) // { // get overlap window. Will be dialog else document itself pBase = pBase->GetWindow( WINDOW_OVERLAP ); // set flag to find disabled elements. // This is better than an enabled one on another Window aSearch.AddSearchFlags( SEARCH_FIND_DISABLED ); // search on current Dialog first pControl = SearchAllWin( pBase, aSearch ); // search on current Document if ( !pControl && pBase != pPParent ) pControl = SearchAllWin( pPParent, aSearch ); aSearch.RemoveSearchFlags( SEARCH_FIND_DISABLED ); if ( pControl ) return pControl; // } } } pBase = Application::GetFirstTopLevelWindow(); // Skip FirstDocFrame // if ( bSearchFocusFirst && IsFirstDocFrame( pBase ) ) // pBase = Application::GetNextTopLevelWindow( pBase ); while ( pBase ) { pControl = SearchAllWin( pBase, aSearch ); if ( pControl ) return pControl; pBase = Application::GetNextTopLevelWindow( pBase ); // Skip FirstDocFrame // if ( bSearchFocusFirst && IsFirstDocFrame( pBase ) ) // pBase = Application::GetNextTopLevelWindow( pBase ); } return NULL; } Window *pResult = NULL; pResult = SearchClientWin( pBase, aSearch, MaybeBase ); if ( pResult ) return pResult; // if ( pBase->GetType() != WINDOW_BORDERWINDOW ) // return NULL; if ( !aSearch.HasSearchFlag( SEARCH_NOOVERLAP ) ) { if ( pBase->GetWindow( WINDOW_FIRSTOVERLAP ) ) pResult = SearchAllWin( pBase->GetWindow( WINDOW_FIRSTOVERLAP ), aSearch ); if ( !pResult && pBase->GetWindow( WINDOW_NEXT ) ) pResult = SearchAllWin( pBase->GetWindow( WINDOW_NEXT ), aSearch ); } return pResult; } Window* StatementList::SearchClientWin( Window *pBase, Search &aSearch, sal_Bool MaybeBase ) { if ( !pBase ) return NULL; if ( MaybeBase && aSearch.IsWinOK( pBase ) ) return pBase; Window *pResult = NULL; sal_uInt16 i; for( i = 0 ; i < pBase->GetChildCount() && !pResult; i++ ) pResult = SearchClientWin( pBase->GetChild(i), aSearch ); return pResult; } sal_Bool SearchUID::IsWinOK( Window *pWin ) { if ( aUId.equals( pWin->GetUniqueOrHelpId() ) ) { if ( ( pWin->IsEnabled() || HasSearchFlag( SEARCH_FIND_DISABLED ) ) && pWin->IsVisible() ) return sal_True; else { if ( !pMaybeResult ) pMaybeResult = pWin; return sal_False; } } else if ( pWin->GetType() == WINDOW_TOOLBOX ) // Buttons and Controls on ToolBox. { ToolBox *pTB = ((ToolBox*)pWin); sal_uInt16 i; for ( i = 0; i < pTB->GetItemCount() ; i++ ) { if ( aUId.equals( Str2Id( pTB->GetItemCommand(pTB->GetItemId( i )) ) ) || aUId.equals( pTB->GetHelpId(pTB->GetItemId( i )) ) ) { // ID matches. Window *pItemWin; pItemWin = pTB->GetItemWindow( pTB->GetItemId( i ) ); if ( bSearchButtonOnToolbox && pTB->GetItemType( i ) == TOOLBOXITEM_BUTTON && !pItemWin ) { // We got a Control, see if its valid also. // Same as above. if ( ( pTB->IsEnabled() || HasSearchFlag( SEARCH_FIND_DISABLED ) ) && pTB->IsVisible() ) { // We got a Button, see if its valid also. if ( ( pTB->IsItemEnabled(pTB->GetItemId(i)) || HasSearchFlag( SEARCH_FIND_DISABLED ) ) && pTB->IsItemVisible(pTB->GetItemId(i)) ) return sal_True; // We got a Button. else { // better a disabled Button on a valid ToolBox than an invalid ToolBox as below pMaybeResult = pTB; return sal_False; } } else if ( !pMaybeResult ) { // invalid ToolBox pMaybeResult = pTB; return sal_False; } } if ( pItemWin ) { // We got a Control, see if its valid also. // Same as above. if ( ( pItemWin->IsEnabled() || HasSearchFlag( SEARCH_FIND_DISABLED ) ) && pItemWin->IsVisible() ) { if ( !pAlternateResult ) // only take the first found ItemWindow #i35365 pAlternateResult = pItemWin; // since we cannot return a Window here return sal_False; // continue searching to prefer a window with the right ID #i32292 } else if ( !pMaybeResult ) { pMaybeResult = pItemWin; return sal_False; } } } } return sal_False; } else return sal_False; } Window* StatementList::SearchTree( rtl::OString aUId ,sal_Bool bSearchButtonOnToolbox ) { SearchUID aSearch(aUId,bSearchButtonOnToolbox); Window *pResult = SearchAllWin( NULL, aSearch ); if ( pResult ) return pResult; else if ( aSearch.GetAlternateResultWin() ) return aSearch.GetAlternateResultWin(); else return aSearch.GetMaybeWin(); } sal_Bool SearchWinPtr::IsWinOK( Window *pWin ) { return pWin == pTest; } sal_Bool StatementList::WinPtrValid(Window *pTest) { SearchWinPtr aSearch( pTest ); return SearchAllWin( NULL, aSearch ) != NULL; } sal_Bool SearchRT::IsWinOK( Window *pWin ) { if ( pWin->IsVisible() && pWin->GetType() == mnRT ) { mnCount++; if ( mnSkip ) { mnSkip--; return sal_False; } else return sal_True; } return sal_False; } Window* StatementList::GetWinByRT( Window *pBase, WindowType nRT, sal_Bool MaybeBase, sal_uInt16 nSkip, sal_Bool bSearchAll ) { SearchRT aSearch( nRT, 0, nSkip ); if ( bSearchAll ) aSearch.AddSearchFlags( SEARCH_FOCUS_FIRST | SEARCH_FIND_DISABLED ); else aSearch.AddSearchFlags( SEARCH_NOOVERLAP | SEARCH_NO_TOPLEVEL_WIN ); return SearchAllWin( pBase, aSearch, MaybeBase ); } sal_uInt16 StatementList::CountWinByRT( Window *pBase, WindowType nRT, sal_Bool MaybeBase ) { SearchRT aSearch( nRT, SEARCH_NOOVERLAP | SEARCH_NO_TOPLEVEL_WIN, 0xFFFF ); SearchAllWin( pBase, aSearch, MaybeBase ); return aSearch.GetCount(); } sal_Bool SearchScroll::IsWinOK( Window *pWin ) { if ( SearchRT::IsWinOK( pWin ) ) { DBG_ASSERT( pWin->GetStyle() & ( WB_HORZ | WB_VERT ), "Nither WB_HORZ nor WB_VERT set on ScrollBar"); return (( pWin->GetStyle() & WB_HORZ ) && ( nDirection == CONST_ALIGN_BOTTOM )) || (( pWin->GetStyle() & WB_VERT ) && ( nDirection == CONST_ALIGN_RIGHT )); } return sal_False; } ScrollBar* StatementList::GetScrollBar( Window *pBase, sal_uInt16 nDirection, sal_Bool MaybeBase ) { SearchScroll aSearch( nDirection, SEARCH_NOOVERLAP | SEARCH_NO_TOPLEVEL_WIN ); return (ScrollBar*)SearchAllWin( pBase, aSearch, MaybeBase ); } sal_Bool SearchPopupFloatingWin::IsWinOK( Window *pWin ) { return pWin->IsVisible() && pWin->GetType() == WINDOW_FLOATINGWINDOW && ((FloatingWindow*)pWin)->IsInPopupMode(); } Window* StatementList::GetPopupFloatingWin( sal_Bool MaybeBase ) { SearchPopupFloatingWin aSearch; return SearchAllWin( NULL, aSearch, MaybeBase ); } Menu* StatementList::GetMatchingMenu( Window* pWin, Menu* pBaseMenu ) { if ( pBaseMenu ) { if ( pBaseMenu->GetWindow() == pWin ) return pBaseMenu; sal_uInt16 i; // while ( pBaseMenu ) // { i = 0; while ( i < pBaseMenu->GetItemCount() ) { PopupMenu* pPopup = pBaseMenu->GetPopupMenu( pBaseMenu->GetItemId( i ) ); if ( pPopup && pPopup->GetWindow() ) { if ( pPopup->GetWindow() == pWin ) return pPopup; else { pBaseMenu = pPopup; i = 0; } } else i++; } // } } else { if ( PopupMenu::GetActivePopupMenu() ) { Menu* pMenu = GetMatchingMenu( pWin, PopupMenu::GetActivePopupMenu() ); if ( pMenu ) return pMenu; } sal_uInt16 nSkip = 0; Window* pMenuBarWin = NULL; while ( (pMenuBarWin = GetWinByRT( NULL, WINDOW_MENUBARWINDOW, sal_True, nSkip++, sal_True )) != NULL ) { Window* pParent = pMenuBarWin->GET_REAL_PARENT(); if ( pParent && pParent->GetType() == WINDOW_BORDERWINDOW && pParent->IsVisible() ) { Menu* pMenu = NULL; // find Menu of MenuBarWindow sal_uInt16 nCount; for ( nCount = 0 ; nCount < pParent->GetChildCount() ; nCount++ ) { if ( pParent->GetChild( nCount )->GetType() == WINDOW_WORKWINDOW ) pMenu = ((WorkWindow*)(pParent->GetChild( nCount )))->GetMenuBar(); } if ( pMenu ) { // check for menu bar in Task Window if ( pMenuBarWin == pWin ) return pMenu; // search submenues pMenu = GetMatchingMenu( pWin, pMenu ); if ( pMenu ) return pMenu; } } } } return NULL; } sal_Bool SearchActive::IsWinOK( Window *pWin ) { // 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()); // only matches ResID due to problems with UNIX Window Managers return pWin->IsVisible() && ( (nRT == WINDOW_ANYTYPE && IsDialog(pWin) ) || pWin->GetType() == nRT ); } Window* StatementList::GetActive( WindowType nRT, sal_Bool MaybeBase ) { SearchActive aSearch( nRT ); return SearchAllWin( NULL, aSearch, MaybeBase ); } sal_Bool SearchFadeSplitWin::IsWinOK( Window *pWin ) { #if OSL_DEBUG_LEVEL > 1 if ( pWin->GetType() == WINDOW_SPLITWINDOW ) { sal_Bool bResult; WindowAlign aAlign; bResult = pWin->IsVisible(); bResult = ((SplitWindow*)pWin)->IsFadeInButtonVisible(); bResult = ((SplitWindow*)pWin)->IsFadeOutButtonVisible(); bResult = ((SplitWindow*)pWin)->IsAutoHideButtonVisible(); aAlign = ((SplitWindow*)pWin)->GetAlign(); } #endif return pWin->IsVisible() && ( pWin->GetType() == WINDOW_SPLITWINDOW ) && (((SplitWindow*)pWin)->IsFadeInButtonVisible() || ((SplitWindow*)pWin)->IsFadeOutButtonVisible() ) /*&& ((SplitWindow*)pWin)->IsAutoHideButtonVisible()*/ && ((SplitWindow*)pWin)->GetAlign() == nAlign; } Window* StatementList::GetFadeSplitWin( Window *pBase, WindowAlign nAlign, sal_Bool MaybeBase ) { SearchFadeSplitWin aSearch( nAlign ); if ( GetpApp()->GetAppWindow() == pBase && pBase->GetType() != WINDOW_BORDERWINDOW ) pBase = pBase->GetWindow( WINDOW_OVERLAP ); return SearchAllWin( pBase, aSearch, MaybeBase ); } Window* StatementList::GetMouseWin() { Window *pBase = Application::GetFirstTopLevelWindow(); Window *pControl = NULL; while ( pBase ) { Window *pBaseFrame = pBase->GetWindow( WINDOW_OVERLAP ); Point aP = pBaseFrame->GetPointerPosPixel(); pControl = pBaseFrame->FindWindow( aP ); if ( pControl ) return pControl; pBase = Application::GetNextTopLevelWindow( pBase ); } return NULL; } Window* StatementList::GetFocus( WindowType nRT, sal_Bool MaybeBase ) { if ( nRT == WINDOW_TABCONTROL ) { Window *pResult = GetActive( WINDOW_TABDIALOG, MaybeBase); for( sal_uInt16 i = 0 ; pResult && i < pResult->GetChildCount(); i++ ) if ( pResult->GetChild(i)->GetType() == nRT ) return pResult->GetChild(i); } return NULL; } Window* StatementList::GetAnyActive( sal_Bool MaybeBase ) { Window *pControl; pControl = GetActive( WINDOW_MESSBOX, MaybeBase); if ( !pControl ) { pControl = GetActive( WINDOW_INFOBOX, MaybeBase); } if ( !pControl ) { pControl = GetActive( WINDOW_WARNINGBOX, MaybeBase); } if ( !pControl ) { pControl = GetActive( WINDOW_ERRORBOX, MaybeBase); } if ( !pControl ) { pControl = GetActive( WINDOW_QUERYBOX, MaybeBase); } if ( !pControl ) { pControl = GetActive( WINDOW_BUTTONDIALOG, MaybeBase); } if ( !pControl ) { pControl = GetActive( WINDOW_FILEDIALOG, MaybeBase); } if ( !pControl ) { pControl = GetActive( WINDOW_PATHDIALOG, MaybeBase); } if ( !pControl ) { pControl = GetActive( WINDOW_PRINTDIALOG, MaybeBase); } if ( !pControl ) { pControl = GetActive( WINDOW_PRINTERSETUPDIALOG, MaybeBase); } if ( !pControl ) { pControl = GetActive( WINDOW_COLORDIALOG, MaybeBase); } if ( !pControl ) { pControl = GetFocus( WINDOW_TABCONTROL, MaybeBase); } return pControl; } void StatementList::SetFirstDocFrame( Window* pWin ) { DBG_ASSERT( IsDocFrame( pWin ), "Non Document Frame set as first Document Frame" ); pFirstDocFrame = pWin; } Window* StatementList::GetFirstDocFrame() { if ( pFirstDocFrame && !WinPtrValid( pFirstDocFrame ) ) pFirstDocFrame = NULL; if ( pFirstDocFrame && !pFirstDocFrame->IsVisible() ) pFirstDocFrame = NULL; if ( pFirstDocFrame && !IsDocFrame( pFirstDocFrame ) ) pFirstDocFrame = NULL; if ( !pFirstDocFrame ) { Window* pBase = Application::GetFirstTopLevelWindow(); while ( pBase && !IsDocFrame( pBase ) ) pBase = Application::GetNextTopLevelWindow( pBase ); if ( pBase ) SetFirstDocFrame( pBase ); if ( !pBase ) // find just something { pBase = Application::GetFirstTopLevelWindow(); while ( pBase && !pBase->IsVisible() ) pBase = Application::GetNextTopLevelWindow( pBase ); return pBase; // just for now, later we will hopefully have a Window } } return pFirstDocFrame; } sal_Bool StatementList::IsFirstDocFrame( Window* pWin ) { return pWin && ( pWin == GetFirstDocFrame() || ( GetFirstDocFrame() && pWin == GetFirstDocFrame()->GetWindow( WINDOW_CLIENT ) ) ) && ( GetFirstDocFrame() && IsDocFrame( GetFirstDocFrame() ) ); } MenuBar* StatementList::GetDocFrameMenuBar( Window* pWin ) { if ( pWin && pWin->IsVisible() && pWin->GetType() == WINDOW_BORDERWINDOW ) { sal_uInt16 nCount; for ( nCount = 0 ; nCount < pWin->GetChildCount() ; nCount++ ) { if ( pWin->GetChild( nCount )->GetType() == WINDOW_WORKWINDOW ) return ((WorkWindow*)(pWin->GetChild( nCount )))->GetMenuBar(); } } return NULL; } // a Doc Frame is a Document or the Backing Window sal_Bool StatementList::IsDocFrame( Window* pWin ) { if ( pWin && pWin->IsVisible() && pWin->GetType() == WINDOW_BORDERWINDOW ) { sal_uInt16 nCount; sal_Bool bHasWorkWindow = sal_False; sal_Bool bHasMenuBar = sal_False; // #91724# it is now necessary to sort out the IME WIndow in Solaris as well. // so now we check for existence of WINDOW_WORKWINDOW and newly for // WINDOW_MENUBARWINDOW which contains the Menu and the close/min/max buttons for ( nCount = 0 ; nCount < pWin->GetChildCount() ; nCount++ ) { if ( pWin->GetChild( nCount )->GetType() == WINDOW_WORKWINDOW ) bHasWorkWindow = sal_True; if ( pWin->GetChild( nCount )->GetType() == WINDOW_MENUBARWINDOW ) bHasMenuBar = sal_True; } return bHasWorkWindow && bHasMenuBar; } return sal_False; } // a Doc Win is a real document (not the Backing Window) sal_Bool StatementList::IsDocWin( Window* pWin ) { if ( pWin && IsDocFrame( pWin ) ) { if ( GetDocFrameCount() != 1 ) return sal_True; else { // check for the close button to see if we are the last one or only the backing Window if ( GetDocFrameMenuBar( pWin ) ) return GetDocFrameMenuBar( pWin )->HasCloser(); } } return sal_False; } sal_Bool StatementList::IsIMEWin( Window* pWin ) // Input Window for CJK under Solaris { if ( pWin && pWin->IsVisible() && pWin->GetType() == WINDOW_BORDERWINDOW ) { sal_uInt16 nCount; sal_Bool bHasWorkWindow = sal_False; sal_Bool bHasWindow = sal_False; // #91724# it is now necessary to sort out the IME WIndow in Solaris as well. // so now we check for existence of WINDOW_WORKWINDOW and newly for // WINDOW_WINDOW which contains the Menu and the close/min/max buttons for ( nCount = 0 ; nCount < pWin->GetChildCount() ; nCount++ ) if ( pWin->GetChild( nCount )->GetType() == WINDOW_WORKWINDOW ) bHasWorkWindow = sal_True; for ( nCount = 0 ; nCount < pWin->GetChildCount() ; nCount++ ) if ( pWin->GetChild( nCount )->GetType() == WINDOW_WINDOW ) bHasWindow = sal_True; return bHasWorkWindow && !bHasWindow; } return sal_False; } UniString StatementList::Tree(Window *pBase, int Indent) { String aReturn, aSep; if ( !pBase ) { aSep.AssignAscii("============================\n"); aSep.ConvertLineEnd(); pBase = Application::GetFirstTopLevelWindow(); while ( pBase ) { Window *pBaseFrame = pBase->GetWindow( WINDOW_OVERLAP ); aReturn += aSep; aReturn += Tree( pBaseFrame, Indent+1 ); pBase = Application::GetNextTopLevelWindow( pBase ); } return aReturn; } aSep.AssignAscii("----------------------------\n"); aSep.ConvertLineEnd(); aReturn += ClientTree( pBase, Indent ); if ( pBase->GetWindow( WINDOW_FIRSTOVERLAP ) ) { aReturn += aSep; aReturn += Tree( pBase->GetWindow( WINDOW_FIRSTOVERLAP ), Indent+1 ); } if ( pBase->GetWindow( WINDOW_NEXT ) ) { aReturn += aSep; aReturn += Tree( pBase->GetWindow( WINDOW_NEXT ), Indent ); } return aReturn; } String StatementList::ClientTree(Window *pBase, int Indent) { #if OSL_DEBUG_LEVEL > 1 #define WRITE(Text) { m_pDbgWin->AddText(Text); aReturn += Text; } #define WRITEc(Text) { m_pDbgWin->AddText(Text); aReturn.AppendAscii(Text); } #else #define WRITE(Text) { aReturn += Text; } #define WRITEc(Text) { aReturn.AppendAscii(Text); } #endif String sIndent,aText,aReturn; sIndent.Expand(sal::static_int_cast< xub_StrLen >(2*Indent)); aText = pBase->GetText(); UniString t1,t2;t1 = CUniString("\n"); t2 = CUniString("\\n"); aText.SearchAndReplaceAll(t1,t2 ); WRITE(sIndent); if (pBase->IsDialog()) { WRITEc("*(Dialog(TH))"); } if (IsDialog( pBase )) { WRITEc("*(Dialog(GH))"); } if (pBase->HasFocus()) { WRITEc("*(Focus)"); } if (!pBase->IsEnabled()) { WRITEc("*(Disab)"); } if (pBase->IsVisible()) { WRITEc("*(Visible)"); } if ( IsDialog(pBase) && ((SystemWindow*)pBase)->IsActive() ) { WRITEc("*(Active)"); } if ( pBase->GetStyle() & WB_CLOSEABLE ) { WRITEc("*(Closable)"); } if ( pBase->GetType() == WINDOW_DOCKINGWINDOW && ((((DockingWindow*)pBase)->GetFloatStyle()) & WB_CLOSEABLE) ) { WRITEc("*(Closable Docking in Floatingstyle)"); } if ( pBase->GetStyle() & WB_DOCKABLE ) { WRITEc("*(Dockable)"); } if ( pBase->GetType() == WINDOW_SPLITWINDOW && (((SplitWindow*)pBase)->IsFadeInButtonVisible() || ((SplitWindow*)pBase)->IsFadeOutButtonVisible()) ) { WRITEc("*(FadeIn/Out)"); } WRITEc("Text: "); WRITE(aText); WRITEc("\n"); WRITE(sIndent); WRITEc("UId : "); WRITE(Id2Str(pBase->GetUniqueOrHelpId())); WRITEc(":0x"); WRITE( String::CreateFromInt64( sal::static_int_cast< sal_Int64 >( reinterpret_cast< sal_IntPtr >(pBase)), 16 )); WRITEc(":"); WRITE(pBase->GetQuickHelpText()); WRITEc(":"); WRITE(pBase->GetHelpText()); WRITEc("\n"); WRITE(sIndent); WRITEc("RTyp: "); WRITE(MakeStringNumber(TypeKenn,pBase->GetType())); if ( pBase->GetType() == WINDOW_CONTROL ) { if ( dynamic_cast< svt::EditBrowseBox* >(pBase) ) WRITEc("/BrowseBox") else if ( dynamic_cast< ValueSet* >(pBase) ) WRITEc("/ValueSet") else if ( dynamic_cast< svt::ORoadmap* >(pBase) ) WRITEc("/RoadMap") else if ( dynamic_cast< svt::IExtensionListBox* >(pBase) ) WRITEc("/ExtensionListBox") else if ( dynamic_cast< svt::table::TableControl* >(pBase) ) WRITEc("/TableControl") else WRITEc("/Unknown") } WRITEc("\n"); aReturn.ConvertLineEnd(); sal_uInt16 i; for (i = 0 ; i < pBase->GetChildCount() ; i++) { aReturn += ClientTree(pBase->GetChild(i),Indent+1); } return aReturn; } sal_Bool StatementList::CheckWindowWait() { static Time StartTime = Time(0L); // Abbruch wenn Fenster absolut nicht schliesst. if ( StartTime == Time(0L) ) StartTime = Time(); if ( pWindowWaitPointer ) { #if OSL_DEBUG_LEVEL > 1 m_pDbgWin->AddText( "Waiting for Window to close ... " ); #endif if ( WinPtrValid(pWindowWaitPointer) && IS_WINP_CLOSING(pWindowWaitPointer) ) { #if OSL_DEBUG_LEVEL > 1 m_pDbgWin->AddText( Id2Str(aWindowWaitUId).AppendAscii(" Still Open. RType=") ); m_pDbgWin->AddText( String::CreateFromInt32( pWindowWaitPointer->GetType() ).AppendAscii("\n") ); #endif // Ist die Zeit schonn abgelaufen? if ( StartTime + Time(0,0,10) < Time() ) // 10 Sekunden reichen wohl { #if OSL_DEBUG_LEVEL > 1 m_pDbgWin->AddText( "Close timed out. Going on!! " ); #endif pWindowWaitPointer->SetHelpId(aWindowWaitOldHelpId); pWindowWaitPointer->SetUniqueId(aWindowWaitOldUniqueId); aWindowWaitUId = rtl::OString(); pWindowWaitPointer = NULL; StartTime = Time(0L); return sal_True; } return sal_False; } pWindowWaitPointer = NULL; aWindowWaitUId = rtl::OString(); #if OSL_DEBUG_LEVEL > 1 m_pDbgWin->AddText( "Closed, Going on.\n" ); #endif } StartTime = Time(0L); return sal_True; } void StatementList::ReportError(String aMessage) { ReportError ( rtl::OString(), aMessage ); } void StatementList::ReportError(rtl::OString aUId, String aMessage) { pRet->GenError ( aUId, aMessage ); IsError = sal_True; } void StatementList::ReportError(String aMessage, sal_uLong nWhatever) { ReportError ( aMessage.AppendAscii(" ").Append(UniString::CreateFromInt32(nWhatever))); } void StatementList::DirectLog( sal_uLong nType, String aMessage ) { if ( pRet ) pRet->GenReturn( RET_DirectLoging, (sal_uInt16) nType, aMessage ); } #define CALL_EVENT_WITH_NOTIFY( EventType, Event, WinP, Method ) \ { \ if ( StatementList::WinPtrValid( WinP ) ) \ { \ NotifyEvent aNEvt( EventType, WinP, &Event ); \ if ( !WinP->PreNotify( aNEvt ) ) \ WinP->Method( Event ); \ } \ } void ImplKeyInput( Window* pWin, KeyEvent &aKEvnt, sal_Bool bForceDirect ) { if ( StatementList::bUsePostEvents && !bForceDirect ) { if ( StatementList::WinPtrValid( pWin ) ) { sal_uLong nID1; sal_uLong nID2; nID1 = Application::PostKeyEvent( VCLEVENT_WINDOW_KEYINPUT, pWin, &aKEvnt ); nID2 = Application::PostKeyEvent( VCLEVENT_WINDOW_KEYUP, pWin, &aKEvnt ); // wait after posting both events so deleting pWin will remove the second event also ImplEventWait( nID1 ); ImplEventWait( nID2 ); } } else { if ( !Application::CallAccel( aKEvnt.GetKeyCode() ) ) { CALL_EVENT_WITH_NOTIFY( EVENT_KEYINPUT, aKEvnt, pWin, KeyInput ) KeyCode aCode = aKEvnt.GetKeyCode(); if ( (aCode.GetCode() == KEY_CONTEXTMENU) || ((aCode.GetCode() == KEY_F10) && aCode.IsShift()) ) { if ( StatementList::WinPtrValid( pWin ) ) { Point aPos; // simulate mouseposition at center of window Size aSize = pWin->GetOutputSize(); aPos = Point( aSize.getWidth()/2, aSize.getHeight()/2 ); CommandEvent aEvent( aPos, COMMAND_CONTEXTMENU, sal_False ); ImplCommand( pWin, aEvent ); } } } CALL_EVENT_WITH_NOTIFY( EVENT_KEYUP, aKEvnt, pWin, KeyUp ) } }; void ImplMouseMove( Window* pWin, MouseEvent &aMEvnt, sal_Bool bForceDirect ) { if ( StatementList::bUsePostEvents && !bForceDirect ) { if ( StatementList::WinPtrValid( pWin ) ) { sal_uLong nID; nID = Application::PostMouseEvent( VCLEVENT_WINDOW_MOUSEMOVE, pWin, &aMEvnt ); ImplEventWait( nID ); } } else { // DragManager* pDragManager = DragManager::GetDragManager(); // if ( pDragManager ) // pDragManager->MouseMove( aMEvnt, pWin ); // else if ( pWin->IsTracking() ) { TrackingEvent aTEvt( aMEvnt ); pWin->Tracking( aTEvt ); } else CALL_EVENT_WITH_NOTIFY( EVENT_MOUSEMOVE, aMEvnt, pWin, MouseMove ) } }; void ImplMouseButtonDown( Window* pWin, MouseEvent &aMEvnt, sal_Bool bForceDirect ) { if ( StatementList::bUsePostEvents && !bForceDirect ) { if ( StatementList::WinPtrValid( pWin ) ) { sal_uLong nID; nID = Application::PostMouseEvent( VCLEVENT_WINDOW_MOUSEBUTTONDOWN, pWin, &aMEvnt ); ImplEventWait( nID ); } } else { CALL_EVENT_WITH_NOTIFY( EVENT_MOUSEBUTTONDOWN, aMEvnt, pWin, MouseButtonDown ) } }; void ImplMouseButtonUp( Window* pWin, MouseEvent &aMEvnt, sal_Bool bForceDirect ) { if ( StatementList::bUsePostEvents && !bForceDirect ) { if ( StatementList::WinPtrValid( pWin ) ) { sal_uLong nID; nID = Application::PostMouseEvent( VCLEVENT_WINDOW_MOUSEBUTTONUP, pWin, &aMEvnt ); ImplEventWait( nID ); } } else { // DragManager* pDragManager = DragManager::GetDragManager(); // if ( pDragManager ) // pDragManager->ButtonUp( aMEvnt, pWin ); // else if ( pWin->IsTracking() ) { // siehe #64693 die Position ist für Toolboxen relevant // #60020 Jetzt hoffentlich kein GPF mehr // Zuerst Tracking beenden ohne Event pWin->EndTracking( ENDTRACK_DONTCALLHDL ); // dann eigenen Event mit richtigem Maus-Event senden TrackingEvent aTEvt( aMEvnt, ENDTRACK_END ); pWin->Tracking( aTEvt ); } else CALL_EVENT_WITH_NOTIFY( EVENT_MOUSEBUTTONUP, aMEvnt, pWin, MouseButtonUp ) } }; void ImplEventWait( sal_uLong nID ) { while ( !Application::IsProcessedMouseOrKeyEvent( nID ) ) Application::Yield(); } void ImplCommand( Window* pWin, CommandEvent &aCmdEvnt ) { CALL_EVENT_WITH_NOTIFY( EVENT_COMMAND, aCmdEvnt, pWin, Command ) };