1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_toolkit.hxx" 30 #include <com/sun/star/awt/WindowEvent.hpp> 31 #include <comphelper/processfactory.hxx> 32 33 #include <toolkit/helper/unowrapper.hxx> 34 #include <toolkit/helper/vclunohelper.hxx> 35 #include <toolkit/helper/convert.hxx> 36 #include <toolkit/awt/vclxwindow.hxx> 37 #include <toolkit/awt/vclxwindows.hxx> 38 #include <toolkit/awt/vclxcontainer.hxx> 39 #include <toolkit/awt/vclxtopwindow.hxx> 40 #include <toolkit/awt/vclxgraphics.hxx> 41 42 #include "toolkit/dllapi.h" 43 #include <vcl/svapp.hxx> 44 #include <vcl/syswin.hxx> 45 #include <vcl/menu.hxx> 46 47 #include <tools/debug.hxx> 48 49 using namespace ::com::sun::star; 50 51 ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer > CreateXWindow( Window* pWindow ) 52 { 53 switch ( pWindow->GetType() ) 54 { 55 case WINDOW_IMAGERADIOBUTTON: 56 case WINDOW_IMAGEBUTTON: 57 case WINDOW_SPINBUTTON: 58 case WINDOW_MENUBUTTON: 59 case WINDOW_MOREBUTTON: 60 case WINDOW_PUSHBUTTON: 61 case WINDOW_HELPBUTTON: 62 case WINDOW_OKBUTTON: 63 case WINDOW_CANCELBUTTON: return new VCLXButton; 64 case WINDOW_CHECKBOX: return new VCLXCheckBox; 65 // --> OD 2009-06-29 #i95042# 66 // A Window of type <MetricBox> is inherited from type <ComboBox>. 67 // Thus, it does make more sense to return a <VCLXComboBox> instance 68 // instead of only a <VCLXWindow> instance, especially regarding its 69 // corresponding accessibility API. 70 case WINDOW_METRICBOX: 71 case WINDOW_COMBOBOX: return new VCLXComboBox; 72 case WINDOW_SPINFIELD: 73 case WINDOW_NUMERICFIELD: 74 case WINDOW_CURRENCYFIELD: return new VCLXNumericField; 75 case WINDOW_DATEFIELD: return new VCLXDateField; 76 case WINDOW_MULTILINEEDIT: 77 case WINDOW_EDIT: return new VCLXEdit; 78 case WINDOW_METRICFIELD: return new VCLXSpinField; 79 case WINDOW_MESSBOX: 80 case WINDOW_INFOBOX: 81 case WINDOW_WARNINGBOX: 82 case WINDOW_QUERYBOX: 83 case WINDOW_ERRORBOX: return new VCLXMessageBox; 84 case WINDOW_FIXEDIMAGE: return new VCLXImageControl; 85 case WINDOW_FIXEDTEXT: return new VCLXFixedText; 86 case WINDOW_MULTILISTBOX: 87 case WINDOW_LISTBOX: return new VCLXListBox; 88 case WINDOW_LONGCURRENCYFIELD: return new VCLXCurrencyField; 89 case WINDOW_DIALOG: 90 case WINDOW_MODALDIALOG: 91 case WINDOW_TABDIALOG: 92 case WINDOW_BUTTONDIALOG: 93 case WINDOW_MODELESSDIALOG: return new VCLXDialog; 94 case WINDOW_PATTERNFIELD: return new VCLXPatternField; 95 case WINDOW_RADIOBUTTON: return new VCLXRadioButton; 96 case WINDOW_SCROLLBAR: return new VCLXScrollBar; 97 case WINDOW_TIMEFIELD: return new VCLXTimeField; 98 99 case WINDOW_SYSWINDOW: 100 case WINDOW_WORKWINDOW: 101 case WINDOW_DOCKINGWINDOW: 102 case WINDOW_FLOATINGWINDOW: 103 case WINDOW_HELPTEXTWINDOW: return new VCLXTopWindow; 104 105 case WINDOW_WINDOW: 106 case WINDOW_TABPAGE: return new VCLXContainer; 107 108 case WINDOW_TOOLBOX: return new VCLXToolBox; 109 110 // case WINDOW_FIXEDLINE: 111 // case WINDOW_FIXEDBITMAP: 112 // case WINDOW_DATEBOX: 113 // case WINDOW_GROUPBOX: 114 // case WINDOW_LONGCURRENCYBOX: 115 // case WINDOW_SPLITTER: 116 // case WINDOW_STATUSBAR: 117 // case WINDOW_TABCONTROL: 118 // case WINDOW_NUMERICBOX: 119 // case WINDOW_TRISTATEBOX: 120 // case WINDOW_TIMEBOX: 121 // case WINDOW_SPLITWINDOW: 122 // case WINDOW_SCROLLBARBOX: 123 // case WINDOW_PATTERNBOX: 124 // case WINDOW_CURRENCYBOX: 125 default: return new VCLXWindow( true ); 126 } 127 } 128 129 // ---------------------------------------------------- 130 // class UnoWrapper 131 // ---------------------------------------------------- 132 133 extern "C" { 134 135 TOOLKIT_DLLPUBLIC UnoWrapperBase* CreateUnoWrapper() 136 { 137 return new UnoWrapper( NULL ); 138 } 139 140 } // extern "C" 141 142 143 UnoWrapper::UnoWrapper( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XToolkit>& rxToolkit ) 144 { 145 mxToolkit = rxToolkit; 146 } 147 148 void UnoWrapper::Destroy() 149 { 150 delete this; 151 } 152 153 UnoWrapper::~UnoWrapper() 154 { 155 } 156 157 ::com::sun::star::uno::Reference< ::com::sun::star::awt::XToolkit> UnoWrapper::GetVCLToolkit() 158 { 159 if ( !mxToolkit.is() ) 160 mxToolkit = VCLUnoHelper::CreateToolkit(); 161 return mxToolkit.get(); 162 } 163 164 ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer> UnoWrapper::GetWindowInterface( Window* pWindow, sal_Bool bCreate ) 165 { 166 ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer> xPeer = pWindow->GetWindowPeer(); 167 if ( !xPeer.is() && bCreate ) 168 { 169 xPeer = CreateXWindow( pWindow ); 170 SetWindowInterface( pWindow, xPeer ); 171 } 172 return xPeer; 173 } 174 175 void UnoWrapper::SetWindowInterface( Window* pWindow, ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer> xIFace ) 176 { 177 VCLXWindow* pVCLXWindow = VCLXWindow::GetImplementation( xIFace ); 178 179 DBG_ASSERT( pVCLXWindow, "SetComponentInterface - unsupported type" ); 180 if ( pVCLXWindow ) 181 { 182 ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer> xPeer = pWindow->GetWindowPeer(); 183 if( xPeer.is() ) 184 { 185 bool bSameInstance( pVCLXWindow == dynamic_cast< VCLXWindow* >( xPeer.get() )); 186 DBG_ASSERT( bSameInstance, "UnoWrapper::SetWindowInterface: there already *is* a WindowInterface for this window!" ); 187 if ( bSameInstance ) 188 return; 189 } 190 pVCLXWindow->SetWindow( pWindow ); 191 pWindow->SetWindowPeer( xIFace, pVCLXWindow ); 192 } 193 } 194 195 ::com::sun::star::uno::Reference< ::com::sun::star::awt::XGraphics> UnoWrapper::CreateGraphics( OutputDevice* pOutDev ) 196 { 197 ::com::sun::star::uno::Reference< ::com::sun::star::awt::XGraphics> xGrf; 198 VCLXGraphics* pGrf = new VCLXGraphics; 199 xGrf = pGrf; 200 pGrf->Init( pOutDev ); 201 return xGrf; 202 } 203 204 void UnoWrapper::ReleaseAllGraphics( OutputDevice* pOutDev ) 205 { 206 List* pLst = pOutDev->GetUnoGraphicsList(); 207 if ( pLst ) 208 { 209 for ( sal_uInt32 n = 0; n < pLst->Count(); n++ ) 210 { 211 VCLXGraphics* pGrf = (VCLXGraphics*)pLst->GetObject( n ); 212 pGrf->SetOutputDevice( NULL ); 213 } 214 } 215 216 } 217 218 // MT: Wurde im Window-CTOR gerufen, damit Container-Listener 219 // vom Parent reagieren, aber hat sowieso nicht richtig funktioniert, 220 // weil im Window-CTOR das Interface noch nicht da ist! 221 // => Nur Listener rufen, wenn ueber das ::com::sun::star::awt::Toolkit erzeugt 222 223 /* 224 void ImplSmartWindowCreated( Window* pNewWindow ) 225 { 226 UNOWindowData* pParentUNOData = pNewWindow->GetParent() ? 227 pNewWindow->GetParent()->GetUNOData() : NULL; 228 229 if ( pParentUNOData && pParentUNOData->GetListeners( EL_CONTAINER ) ) 230 { 231 UNOWindowData* pUNOData = pNewWindow->GetUNOData(); 232 if ( !pUNOData ) 233 pUNOData = ImplSmartCreateUNOData( pNewWindow ); 234 235 ::com::sun::star::awt::VclContainerEvent aEvent; 236 aEvent.Source = (UsrObject*)pParentUNOData->GetWindowPeer(); 237 aEvent.Id = VCLCOMPONENT_ADDED; 238 aEvent.Child = (UsrObject*)pUNOData->GetWindowPeer(); 239 240 EventList* pLst = pParentUNOData->GetListeners( EL_CONTAINER ); 241 for ( sal_uInt32 n = 0; n < pLst->Count(); n++ ) 242 { 243 ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener > * pRef = pLst->GetObject( n ); 244 ((::com::sun::star::awt::XVclContainerListener*)(::com::sun::star::lang::XEventListener*)*pRef)->windowAdded( aEvent ); 245 } 246 } 247 } 248 */ 249 250 sal_Bool lcl_ImplIsParent( Window* pParentWindow, Window* pPossibleChild ) 251 { 252 Window* pWindow = ( pPossibleChild != pParentWindow ) ? pPossibleChild : NULL; 253 while ( pWindow && ( pWindow != pParentWindow ) ) 254 pWindow = pWindow->GetParent(); 255 256 return pWindow ? sal_True : sal_False; 257 } 258 259 void UnoWrapper::WindowDestroyed( Window* pWindow ) 260 { 261 // ggf. existieren noch von ::com::sun::star::loader::Java erzeugte Childs, die sonst erst 262 // im Garbage-Collector zerstoert werden... 263 Window* pChild = pWindow->GetWindow( WINDOW_FIRSTCHILD ); 264 while ( pChild ) 265 { 266 Window* pNextChild = pChild->GetWindow( WINDOW_NEXT ); 267 268 Window* pClient = pChild->GetWindow( WINDOW_CLIENT ); 269 if ( pClient->GetWindowPeer() ) 270 { 271 ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent > xComp( pClient->GetComponentInterface( sal_False ), ::com::sun::star::uno::UNO_QUERY ); 272 xComp->dispose(); 273 } 274 275 pChild = pNextChild; 276 } 277 278 // ::com::sun::star::chaos::System-Windows suchen... 279 Window* pOverlap = pWindow->GetWindow( WINDOW_OVERLAP ); 280 pOverlap = pOverlap->GetWindow( WINDOW_FIRSTOVERLAP ); 281 while ( pOverlap ) 282 { 283 Window* pNextOverlap = pOverlap->GetWindow( WINDOW_NEXT ); 284 Window* pClient = pOverlap->GetWindow( WINDOW_CLIENT ); 285 286 if ( pClient->GetWindowPeer() && lcl_ImplIsParent( pWindow, pClient ) ) 287 { 288 ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent > xComp( pClient->GetComponentInterface( sal_False ), ::com::sun::star::uno::UNO_QUERY ); 289 xComp->dispose(); 290 } 291 292 pOverlap = pNextOverlap; 293 } 294 295 Window* pParent = pWindow->GetParent(); 296 if ( pParent && pParent->GetWindowPeer() ) 297 pParent->GetWindowPeer()->notifyWindowRemoved( *pWindow ); 298 299 VCLXWindow* pWindowPeer = pWindow->GetWindowPeer(); 300 uno::Reference< lang::XComponent > xWindowPeerComp( pWindow->GetComponentInterface( sal_False ), uno::UNO_QUERY ); 301 OSL_ENSURE( ( pWindowPeer != NULL ) == ( xWindowPeerComp.is() == sal_True ), 302 "UnoWrapper::WindowDestroyed: inconsistency in the window's peers!" ); 303 if ( pWindowPeer ) 304 { 305 pWindowPeer->SetWindow( NULL ); 306 pWindow->SetWindowPeer( NULL, NULL ); 307 } 308 if ( xWindowPeerComp.is() ) 309 xWindowPeerComp->dispose(); 310 311 // #102132# Iterate over frames after setting Window peer to NULL, 312 // because while destroying other frames, we get get into the method again and try 313 // to destroy this window again... 314 // #i42462#/#116855# no, don't loop: Instead, just ensure that all our top-window-children 315 // are disposed, too (which should also be a valid fix for #102132#, but doesn't have the extreme 316 // performance penalties) 317 if ( pWindow ) 318 { 319 Window* pTopWindowChild = pWindow->GetWindow( WINDOW_FIRSTTOPWINDOWCHILD ); 320 while ( pTopWindowChild ) 321 { 322 OSL_ENSURE( pTopWindowChild->GetParent() == pWindow, 323 "UnoWrapper::WindowDestroyed: inconsistency in the SystemWindow relationship!" ); 324 325 Window* pNextTopChild = pTopWindowChild->GetWindow( WINDOW_NEXTTOPWINDOWSIBLING ); 326 327 //the window still could be on the stack, so we have to 328 // use lazy delete ( it will automatically 329 // disconnect from the currently destroyed parent window ) 330 pTopWindowChild->doLazyDelete(); 331 332 pTopWindowChild = pNextTopChild; 333 } 334 } 335 } 336 337 // ---------------------------------------------------------------------------- 338 ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > UnoWrapper::CreateAccessible( Menu* pMenu, sal_Bool bIsMenuBar ) 339 { 340 return maAccessibleFactoryAccess.getFactory().createAccessible( pMenu, bIsMenuBar ); 341 } 342