| /************************************************************** |
| * |
| * 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 <tools/time.hxx> |
| #include <vcl/splitwin.hxx> |
| #include <vcl/wrkwin.hxx> |
| #ifndef _BASIC_TTRESHLP_HXX |
| #include <basic/ttstrhlp.hxx> |
| #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 <vcl/floatwin.hxx> |
| #include <vcl/toolbox.hxx> |
| |
| // only needed for dynamic_cast in wintree |
| #include <svtools/editbrowsebox.hxx> |
| #include <svtools/valueset.hxx> |
| #include <svtools/roadmap.hxx> |
| #include <svtools/extensionlistbox.hxx> |
| #include <svtools/table/tablecontrol.hxx> |
| |
| #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<comm_ULONG>(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 ) |
| }; |
| |