| /************************************************************** |
| * |
| * 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_toolkit.hxx" |
| #include <com/sun/star/awt/WindowEvent.hpp> |
| #include <comphelper/processfactory.hxx> |
| |
| #include <toolkit/helper/unowrapper.hxx> |
| #include <toolkit/helper/vclunohelper.hxx> |
| #include <toolkit/helper/convert.hxx> |
| #include <toolkit/awt/vclxwindow.hxx> |
| #include <toolkit/awt/vclxwindows.hxx> |
| #include <toolkit/awt/vclxcontainer.hxx> |
| #include <toolkit/awt/vclxtopwindow.hxx> |
| #include <toolkit/awt/vclxgraphics.hxx> |
| |
| #include "toolkit/dllapi.h" |
| #include <vcl/svapp.hxx> |
| #include <vcl/syswin.hxx> |
| #include <vcl/menu.hxx> |
| |
| #include <tools/debug.hxx> |
| |
| using namespace ::com::sun::star; |
| |
| ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer > CreateXWindow( Window* pWindow ) |
| { |
| switch ( pWindow->GetType() ) |
| { |
| case WINDOW_IMAGERADIOBUTTON: |
| case WINDOW_IMAGEBUTTON: |
| case WINDOW_SPINBUTTON: |
| case WINDOW_MENUBUTTON: |
| case WINDOW_MOREBUTTON: |
| case WINDOW_PUSHBUTTON: |
| case WINDOW_HELPBUTTON: |
| case WINDOW_OKBUTTON: |
| case WINDOW_CANCELBUTTON: return new VCLXButton; |
| case WINDOW_CHECKBOX: return new VCLXCheckBox; |
| // --> OD 2009-06-29 #i95042# |
| // A Window of type <MetricBox> is inherited from type <ComboBox>. |
| // Thus, it does make more sense to return a <VCLXComboBox> instance |
| // instead of only a <VCLXWindow> instance, especially regarding its |
| // corresponding accessibility API. |
| case WINDOW_METRICBOX: |
| case WINDOW_COMBOBOX: return new VCLXComboBox; |
| case WINDOW_SPINFIELD: |
| case WINDOW_NUMERICFIELD: |
| case WINDOW_CURRENCYFIELD: return new VCLXNumericField; |
| case WINDOW_DATEFIELD: return new VCLXDateField; |
| case WINDOW_MULTILINEEDIT: |
| case WINDOW_EDIT: return new VCLXEdit; |
| case WINDOW_METRICFIELD: return new VCLXSpinField; |
| case WINDOW_MESSBOX: |
| case WINDOW_INFOBOX: |
| case WINDOW_WARNINGBOX: |
| case WINDOW_QUERYBOX: |
| case WINDOW_ERRORBOX: return new VCLXMessageBox; |
| case WINDOW_FIXEDIMAGE: return new VCLXImageControl; |
| case WINDOW_FIXEDTEXT: return new VCLXFixedText; |
| case WINDOW_MULTILISTBOX: |
| case WINDOW_LISTBOX: return new VCLXListBox; |
| case WINDOW_LONGCURRENCYFIELD: return new VCLXCurrencyField; |
| case WINDOW_DIALOG: |
| case WINDOW_MODALDIALOG: |
| case WINDOW_TABDIALOG: |
| case WINDOW_BUTTONDIALOG: |
| case WINDOW_MODELESSDIALOG: return new VCLXDialog; |
| case WINDOW_PATTERNFIELD: return new VCLXPatternField; |
| case WINDOW_RADIOBUTTON: return new VCLXRadioButton; |
| case WINDOW_SCROLLBAR: return new VCLXScrollBar; |
| case WINDOW_TIMEFIELD: return new VCLXTimeField; |
| |
| case WINDOW_SYSWINDOW: |
| case WINDOW_WORKWINDOW: |
| case WINDOW_DOCKINGWINDOW: |
| case WINDOW_FLOATINGWINDOW: |
| case WINDOW_HELPTEXTWINDOW: return new VCLXTopWindow; |
| |
| case WINDOW_WINDOW: |
| case WINDOW_TABPAGE: return new VCLXContainer; |
| |
| case WINDOW_TOOLBOX: return new VCLXToolBox; |
| |
| // case WINDOW_FIXEDLINE: |
| // case WINDOW_FIXEDBITMAP: |
| // case WINDOW_DATEBOX: |
| // case WINDOW_GROUPBOX: |
| // case WINDOW_LONGCURRENCYBOX: |
| // case WINDOW_SPLITTER: |
| // case WINDOW_STATUSBAR: |
| // case WINDOW_TABCONTROL: |
| // case WINDOW_NUMERICBOX: |
| // case WINDOW_TRISTATEBOX: |
| // case WINDOW_TIMEBOX: |
| // case WINDOW_SPLITWINDOW: |
| // case WINDOW_SCROLLBARBOX: |
| // case WINDOW_PATTERNBOX: |
| // case WINDOW_CURRENCYBOX: |
| default: return new VCLXWindow( true ); |
| } |
| } |
| |
| // ---------------------------------------------------- |
| // class UnoWrapper |
| // ---------------------------------------------------- |
| |
| extern "C" { |
| |
| TOOLKIT_DLLPUBLIC UnoWrapperBase* CreateUnoWrapper() |
| { |
| return new UnoWrapper( NULL ); |
| } |
| |
| } // extern "C" |
| |
| |
| UnoWrapper::UnoWrapper( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XToolkit>& rxToolkit ) |
| { |
| mxToolkit = rxToolkit; |
| } |
| |
| void UnoWrapper::Destroy() |
| { |
| delete this; |
| } |
| |
| UnoWrapper::~UnoWrapper() |
| { |
| } |
| |
| ::com::sun::star::uno::Reference< ::com::sun::star::awt::XToolkit> UnoWrapper::GetVCLToolkit() |
| { |
| if ( !mxToolkit.is() ) |
| mxToolkit = VCLUnoHelper::CreateToolkit(); |
| return mxToolkit.get(); |
| } |
| |
| ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer> UnoWrapper::GetWindowInterface( Window* pWindow, sal_Bool bCreate ) |
| { |
| ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer> xPeer = pWindow->GetWindowPeer(); |
| if ( !xPeer.is() && bCreate ) |
| { |
| xPeer = CreateXWindow( pWindow ); |
| SetWindowInterface( pWindow, xPeer ); |
| } |
| return xPeer; |
| } |
| |
| void UnoWrapper::SetWindowInterface( Window* pWindow, ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer> xIFace ) |
| { |
| VCLXWindow* pVCLXWindow = VCLXWindow::GetImplementation( xIFace ); |
| |
| DBG_ASSERT( pVCLXWindow, "SetComponentInterface - unsupported type" ); |
| if ( pVCLXWindow ) |
| { |
| ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer> xPeer = pWindow->GetWindowPeer(); |
| if( xPeer.is() ) |
| { |
| bool bSameInstance( pVCLXWindow == dynamic_cast< VCLXWindow* >( xPeer.get() )); |
| DBG_ASSERT( bSameInstance, "UnoWrapper::SetWindowInterface: there already *is* a WindowInterface for this window!" ); |
| if ( bSameInstance ) |
| return; |
| } |
| pVCLXWindow->SetWindow( pWindow ); |
| pWindow->SetWindowPeer( xIFace, pVCLXWindow ); |
| } |
| } |
| |
| ::com::sun::star::uno::Reference< ::com::sun::star::awt::XGraphics> UnoWrapper::CreateGraphics( OutputDevice* pOutDev ) |
| { |
| ::com::sun::star::uno::Reference< ::com::sun::star::awt::XGraphics> xGrf; |
| VCLXGraphics* pGrf = new VCLXGraphics; |
| xGrf = pGrf; |
| pGrf->Init( pOutDev ); |
| return xGrf; |
| } |
| |
| void UnoWrapper::ReleaseAllGraphics( OutputDevice* pOutDev ) |
| { |
| List* pLst = pOutDev->GetUnoGraphicsList(); |
| if ( pLst ) |
| { |
| for ( sal_uInt32 n = 0; n < pLst->Count(); n++ ) |
| { |
| VCLXGraphics* pGrf = (VCLXGraphics*)pLst->GetObject( n ); |
| pGrf->SetOutputDevice( NULL ); |
| } |
| } |
| |
| } |
| |
| // MT: Wurde im Window-CTOR gerufen, damit Container-Listener |
| // vom Parent reagieren, aber hat sowieso nicht richtig funktioniert, |
| // weil im Window-CTOR das Interface noch nicht da ist! |
| // => Nur Listener rufen, wenn ueber das ::com::sun::star::awt::Toolkit erzeugt |
| |
| /* |
| void ImplSmartWindowCreated( Window* pNewWindow ) |
| { |
| UNOWindowData* pParentUNOData = pNewWindow->GetParent() ? |
| pNewWindow->GetParent()->GetUNOData() : NULL; |
| |
| if ( pParentUNOData && pParentUNOData->GetListeners( EL_CONTAINER ) ) |
| { |
| UNOWindowData* pUNOData = pNewWindow->GetUNOData(); |
| if ( !pUNOData ) |
| pUNOData = ImplSmartCreateUNOData( pNewWindow ); |
| |
| ::com::sun::star::awt::VclContainerEvent aEvent; |
| aEvent.Source = (UsrObject*)pParentUNOData->GetWindowPeer(); |
| aEvent.Id = VCLCOMPONENT_ADDED; |
| aEvent.Child = (UsrObject*)pUNOData->GetWindowPeer(); |
| |
| EventList* pLst = pParentUNOData->GetListeners( EL_CONTAINER ); |
| for ( sal_uInt32 n = 0; n < pLst->Count(); n++ ) |
| { |
| ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener > * pRef = pLst->GetObject( n ); |
| ((::com::sun::star::awt::XVclContainerListener*)(::com::sun::star::lang::XEventListener*)*pRef)->windowAdded( aEvent ); |
| } |
| } |
| } |
| */ |
| |
| sal_Bool lcl_ImplIsParent( Window* pParentWindow, Window* pPossibleChild ) |
| { |
| Window* pWindow = ( pPossibleChild != pParentWindow ) ? pPossibleChild : NULL; |
| while ( pWindow && ( pWindow != pParentWindow ) ) |
| pWindow = pWindow->GetParent(); |
| |
| return pWindow ? sal_True : sal_False; |
| } |
| |
| void UnoWrapper::WindowDestroyed( Window* pWindow ) |
| { |
| // ggf. existieren noch von ::com::sun::star::loader::Java erzeugte Childs, die sonst erst |
| // im Garbage-Collector zerstoert werden... |
| Window* pChild = pWindow->GetWindow( WINDOW_FIRSTCHILD ); |
| while ( pChild ) |
| { |
| Window* pNextChild = pChild->GetWindow( WINDOW_NEXT ); |
| |
| Window* pClient = pChild->GetWindow( WINDOW_CLIENT ); |
| if ( pClient->GetWindowPeer() ) |
| { |
| ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent > xComp( pClient->GetComponentInterface( sal_False ), ::com::sun::star::uno::UNO_QUERY ); |
| xComp->dispose(); |
| } |
| |
| pChild = pNextChild; |
| } |
| |
| // ::com::sun::star::chaos::System-Windows suchen... |
| Window* pOverlap = pWindow->GetWindow( WINDOW_OVERLAP ); |
| pOverlap = pOverlap->GetWindow( WINDOW_FIRSTOVERLAP ); |
| while ( pOverlap ) |
| { |
| Window* pNextOverlap = pOverlap->GetWindow( WINDOW_NEXT ); |
| Window* pClient = pOverlap->GetWindow( WINDOW_CLIENT ); |
| |
| if ( pClient->GetWindowPeer() && lcl_ImplIsParent( pWindow, pClient ) ) |
| { |
| ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent > xComp( pClient->GetComponentInterface( sal_False ), ::com::sun::star::uno::UNO_QUERY ); |
| xComp->dispose(); |
| } |
| |
| pOverlap = pNextOverlap; |
| } |
| |
| Window* pParent = pWindow->GetParent(); |
| if ( pParent && pParent->GetWindowPeer() ) |
| pParent->GetWindowPeer()->notifyWindowRemoved( *pWindow ); |
| |
| VCLXWindow* pWindowPeer = pWindow->GetWindowPeer(); |
| uno::Reference< lang::XComponent > xWindowPeerComp( pWindow->GetComponentInterface( sal_False ), uno::UNO_QUERY ); |
| OSL_ENSURE( ( pWindowPeer != NULL ) == ( xWindowPeerComp.is() == sal_True ), |
| "UnoWrapper::WindowDestroyed: inconsistency in the window's peers!" ); |
| if ( pWindowPeer ) |
| { |
| pWindowPeer->SetWindow( NULL ); |
| pWindow->SetWindowPeer( NULL, NULL ); |
| } |
| if ( xWindowPeerComp.is() ) |
| xWindowPeerComp->dispose(); |
| |
| // #102132# Iterate over frames after setting Window peer to NULL, |
| // because while destroying other frames, we get get into the method again and try |
| // to destroy this window again... |
| // #i42462#/#116855# no, don't loop: Instead, just ensure that all our top-window-children |
| // are disposed, too (which should also be a valid fix for #102132#, but doesn't have the extreme |
| // performance penalties) |
| if ( pWindow ) |
| { |
| Window* pTopWindowChild = pWindow->GetWindow( WINDOW_FIRSTTOPWINDOWCHILD ); |
| while ( pTopWindowChild ) |
| { |
| OSL_ENSURE( pTopWindowChild->GetParent() == pWindow, |
| "UnoWrapper::WindowDestroyed: inconsistency in the SystemWindow relationship!" ); |
| |
| Window* pNextTopChild = pTopWindowChild->GetWindow( WINDOW_NEXTTOPWINDOWSIBLING ); |
| |
| //the window still could be on the stack, so we have to |
| // use lazy delete ( it will automatically |
| // disconnect from the currently destroyed parent window ) |
| pTopWindowChild->doLazyDelete(); |
| |
| pTopWindowChild = pNextTopChild; |
| } |
| } |
| } |
| |
| // ---------------------------------------------------------------------------- |
| ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > UnoWrapper::CreateAccessible( Menu* pMenu, sal_Bool bIsMenuBar ) |
| { |
| return maAccessibleFactoryAccess.getFactory().createAccessible( pMenu, bIsMenuBar ); |
| } |