1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 #ifndef __FRAMEWORK_SERVICES_DESKTOP_HXX_ 25 #define __FRAMEWORK_SERVICES_DESKTOP_HXX_ 26 27 //_________________________________________________________________________________________________________________ 28 // my own includes 29 //_________________________________________________________________________________________________________________ 30 31 #include <classes/framecontainer.hxx> 32 #include <threadhelp/threadhelpbase.hxx> 33 #include <helper/oframes.hxx> 34 #include <macros/generic.hxx> 35 #include <macros/debug.hxx> 36 #include <macros/xinterface.hxx> 37 #include <macros/xtypeprovider.hxx> 38 #include <macros/xserviceinfo.hxx> 39 40 //_________________________________________________________________________________________________________________ 41 // interface includes 42 //_________________________________________________________________________________________________________________ 43 44 #include <com/sun/star/frame/XUntitledNumbers.hpp> 45 46 #include <com/sun/star/frame/XController.hpp> 47 #include <com/sun/star/frame/XDesktop.hpp> 48 #include <com/sun/star/frame/WindowArrange.hpp> 49 #include <com/sun/star/frame/TerminationVetoException.hpp> 50 #include <com/sun/star/frame/XTerminateListener.hpp> 51 #include <com/sun/star/frame/XWindowArranger.hpp> 52 #include <com/sun/star/frame/XTask.hpp> 53 #include <com/sun/star/frame/XStorable.hpp> 54 #include <com/sun/star/frame/XModel.hpp> 55 #include <com/sun/star/frame/XFramesSupplier.hpp> 56 #include <com/sun/star/frame/XFrames.hpp> 57 #include <com/sun/star/lang/XServiceName.hpp> 58 #include <com/sun/star/frame/XDispatchProvider.hpp> 59 #include <com/sun/star/frame/XDispatchProviderInterception.hpp> 60 #include <com/sun/star/frame/XComponentLoader.hpp> 61 #include <com/sun/star/frame/FrameAction.hpp> 62 #include <com/sun/star/task/XStatusIndicatorFactory.hpp> 63 #include <com/sun/star/frame/XTasksSupplier.hpp> 64 #include <com/sun/star/container/XEnumerationAccess.hpp> 65 #include <com/sun/star/lang/Locale.hpp> 66 #include <com/sun/star/frame/XDispatchResultListener.hpp> 67 #include <com/sun/star/lang/XEventListener.hpp> 68 #include <com/sun/star/frame/FeatureStateEvent.hpp> 69 #include <com/sun/star/task/XInteractionHandler.hpp> 70 #include <com/sun/star/frame/XDispatchRecorderSupplier.hpp> 71 72 //_________________________________________________________________________________________________________________ 73 // other includes 74 //_________________________________________________________________________________________________________________ 75 #include <unotools/cmdoptions.hxx> 76 #include <cppuhelper/propshlp.hxx> 77 #include <cppuhelper/interfacecontainer.hxx> 78 #include <cppuhelper/weak.hxx> 79 80 #include <comphelper/numberedcollection.hxx> 81 82 //_________________________________________________________________________________________________________________ 83 // namespace 84 //_________________________________________________________________________________________________________________ 85 86 namespace framework{ 87 88 //_________________________________________________________________________________________________________________ 89 // exported const 90 //_________________________________________________________________________________________________________________ 91 92 //_________________________________________________________________________________________________________________ 93 // exported definitions 94 //_________________________________________________________________________________________________________________ 95 96 enum ELoadState 97 { 98 E_NOTSET , 99 E_SUCCESSFUL , 100 E_FAILED , 101 E_INTERACTION 102 }; 103 104 /*-************************************************************************************************************//** 105 @short implement the topframe of frame tree 106 @descr This is the root of the frame tree. The desktop has no window, is not visible but he is the logical 107 "masternode" to build the hierarchy. 108 109 @implements XInterface 110 XTypeProvider 111 XServiceInfo 112 XDesktop 113 XComponentLoader 114 XTasksSupplier 115 XDispatchProvider 116 XFramesSupplier 117 XFrame 118 XComponent 119 XPropertySet 120 XFastPropertySet 121 XMultiPropertySet 122 XDispatchResultListener 123 XEventListener 124 XInteractionHandler 125 126 @base ThreadHelpBase 127 TransactionBase 128 OBroadcastHelper 129 OPropertySetHelper 130 131 @devstatus ready to use 132 @threadsafe yes 133 *//*-*************************************************************************************************************/ 134 class Desktop : // interfaces 135 public css::lang::XTypeProvider , 136 public css::lang::XServiceInfo , 137 public css::frame::XDesktop , 138 public css::frame::XComponentLoader , 139 public css::frame::XTasksSupplier , 140 public css::frame::XDispatchProvider , 141 public css::frame::XDispatchProviderInterception, 142 public css::frame::XFramesSupplier , // => XFrame => XComponent 143 public css::frame::XDispatchResultListener , // => XEventListener 144 public css::task::XInteractionHandler , 145 public css::frame::XUntitledNumbers , 146 // base classes 147 // Order is necessary for right initialization! 148 private ThreadHelpBase , 149 private TransactionBase , 150 public ::cppu::OBroadcastHelper , 151 public ::cppu::OPropertySetHelper , 152 public ::cppu::OWeakObject 153 { 154 // internal used types, const etcpp. 155 private: 156 157 //--------------------------------------------------------------------- 158 /** used temporary to know which listener was already called or not. */ 159 typedef ::std::vector< css::uno::Reference< css::frame::XTerminateListener > > TTerminateListenerList; 160 161 // public methods 162 public: 163 164 // constructor / destructor 165 Desktop( const css::uno::Reference< css::lang::XMultiServiceFactory >& xFactory ); 166 virtual ~Desktop( ); 167 168 // XInterface, XTypeProvider, XServiceInfo 169 FWK_DECLARE_XINTERFACE 170 FWK_DECLARE_XTYPEPROVIDER 171 DECLARE_XSERVICEINFO 172 173 //--------------------------------------------------------------------- 174 /** 175 @interface XDesktop 176 177 @short try to shutdown these desktop environment. 178 179 @descr Will try to close all frames. If at least one frame could 180 not be closed successfully termination will be stopped. 181 182 Registered termination listener will be taken into account 183 also. As special feature some of our registered listener 184 are well known by it's UNO implementation name. They are handled 185 different to all other listener. 186 187 Btw: Desktop.terminate() was designed in the past to be used 188 within an UI based envrionment. So it's allowed e.g. to 189 call XController.suspend() here. If UI isn't an option ... please 190 use XCloseable.close() at these desktop implementation. 191 ... if it will be supported in the future .-)) 192 193 @seealso XTerminateListener 194 @seealso XTerminateListener2 195 196 @return true if all open frames could be closed and no listener throwed 197 a veto exception; false otherwise. 198 199 @onerror False will be returned. 200 @threadsafe yes 201 */ 202 virtual ::sal_Bool SAL_CALL terminate() 203 throw( css::uno::RuntimeException ); 204 205 //--------------------------------------------------------------------- 206 /** 207 @interface XDesktop 208 209 @short add a listener for termination events 210 211 @descr Additional to adding normal listener these method was implemented special. 212 Every listener will be asked for it's uno implementation name. 213 Some of them are well known ... and the corresponding listener wont be added 214 to the container of "normal listener". Those listener will be set as special 215 member. 216 see e.g. member m_xSfxTerminator 217 218 @seealso terminate() 219 220 @param xListener 221 the listener for registration. 222 223 @threadsafe yes 224 */ 225 virtual void SAL_CALL addTerminateListener( const css::uno::Reference< css::frame::XTerminateListener >& xListener ) 226 throw( css::uno::RuntimeException ); 227 228 //--------------------------------------------------------------------- 229 /** 230 @interface XDesktop 231 232 @short remove a listener from this container. 233 234 @descr Additional to removing normal listener these method was implemented special. 235 Every listener will be asked for it's uno implementation name. 236 Some of them are well known ... and the corresponding listener was set as special member. 237 Now those special member will be reseted also. 238 see e.g. member m_xSfxTerminator 239 240 @seealso terminate() 241 242 @param xListener 243 the listener for deregistration. 244 245 @threadsafe yes 246 */ 247 virtual void SAL_CALL removeTerminateListener( const css::uno::Reference< css::frame::XTerminateListener >& xListener ) 248 throw( css::uno::RuntimeException ); 249 250 virtual css::uno::Reference< css::container::XEnumerationAccess > SAL_CALL getComponents ( ) throw( css::uno::RuntimeException ); 251 virtual css::uno::Reference< css::lang::XComponent > SAL_CALL getCurrentComponent ( ) throw( css::uno::RuntimeException ); 252 virtual css::uno::Reference< css::frame::XFrame > SAL_CALL getCurrentFrame ( ) throw( css::uno::RuntimeException ); 253 254 // XComponentLoader 255 virtual css::uno::Reference< css::lang::XComponent > SAL_CALL loadComponentFromURL ( const ::rtl::OUString& sURL , 256 const ::rtl::OUString& sTargetFrameName , 257 sal_Int32 nSearchFlags , 258 const css::uno::Sequence< css::beans::PropertyValue >& lArguments ) throw( css::io::IOException , 259 css::lang::IllegalArgumentException , 260 css::uno::RuntimeException ); 261 262 // XTasksSupplier 263 virtual css::uno::Reference< css::container::XEnumerationAccess > SAL_CALL getTasks ( ) throw( css::uno::RuntimeException ); 264 virtual css::uno::Reference< css::frame::XTask > SAL_CALL getActiveTask ( ) throw( css::uno::RuntimeException ); 265 266 // XDispatchProvider 267 virtual css::uno::Reference< css::frame::XDispatch > SAL_CALL queryDispatch ( const css::util::URL& aURL , 268 const ::rtl::OUString& sTargetFrameName , 269 sal_Int32 nSearchFlags ) throw( css::uno::RuntimeException ); 270 virtual css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > > SAL_CALL queryDispatches ( const css::uno::Sequence< css::frame::DispatchDescriptor >& lQueries ) throw( css::uno::RuntimeException ); 271 272 // XDispatchProviderInterception 273 virtual void SAL_CALL registerDispatchProviderInterceptor( const css::uno::Reference< css::frame::XDispatchProviderInterceptor >& xInterceptor) throw( css::uno::RuntimeException); 274 virtual void SAL_CALL releaseDispatchProviderInterceptor ( const css::uno::Reference< css::frame::XDispatchProviderInterceptor >& xInterceptor) throw( css::uno::RuntimeException); 275 276 // XFramesSupplier 277 virtual css::uno::Reference< css::frame::XFrames > SAL_CALL getFrames ( ) throw( css::uno::RuntimeException ); 278 virtual css::uno::Reference< css::frame::XFrame > SAL_CALL getActiveFrame ( ) throw( css::uno::RuntimeException ); 279 virtual void SAL_CALL setActiveFrame ( const css::uno::Reference< css::frame::XFrame >& xFrame ) throw( css::uno::RuntimeException ); 280 281 // XFrame 282 // Attention: findFrame() is implemented only! Other methods make no sense for our desktop! 283 virtual css::uno::Reference< css::frame::XFrame > SAL_CALL findFrame ( const ::rtl::OUString& sTargetFrameName , 284 sal_Int32 nSearchFlags ) throw( css::uno::RuntimeException ); 285 virtual void SAL_CALL initialize ( const css::uno::Reference< css::awt::XWindow >& xWindow ) throw( css::uno::RuntimeException ); 286 virtual css::uno::Reference< css::awt::XWindow > SAL_CALL getContainerWindow ( ) throw( css::uno::RuntimeException ); 287 virtual void SAL_CALL setCreator ( const css::uno::Reference< css::frame::XFramesSupplier >& xCreator ) throw( css::uno::RuntimeException ); 288 virtual css::uno::Reference< css::frame::XFramesSupplier > SAL_CALL getCreator ( ) throw( css::uno::RuntimeException ); 289 virtual ::rtl::OUString SAL_CALL getName ( ) throw( css::uno::RuntimeException ); 290 virtual void SAL_CALL setName ( const ::rtl::OUString& sName ) throw( css::uno::RuntimeException ); 291 virtual sal_Bool SAL_CALL isTop ( ) throw( css::uno::RuntimeException ); 292 virtual void SAL_CALL activate ( ) throw( css::uno::RuntimeException ); 293 virtual void SAL_CALL deactivate ( ) throw( css::uno::RuntimeException ); 294 virtual sal_Bool SAL_CALL isActive ( ) throw( css::uno::RuntimeException ); 295 virtual sal_Bool SAL_CALL setComponent ( const css::uno::Reference< css::awt::XWindow >& xComponentWindow , 296 const css::uno::Reference< css::frame::XController >& xController ) throw( css::uno::RuntimeException ); 297 virtual css::uno::Reference< css::awt::XWindow > SAL_CALL getComponentWindow ( ) throw( css::uno::RuntimeException ); 298 virtual css::uno::Reference< css::frame::XController > SAL_CALL getController ( ) throw( css::uno::RuntimeException ); 299 virtual void SAL_CALL contextChanged ( ) throw( css::uno::RuntimeException ); 300 virtual void SAL_CALL addFrameActionListener ( const css::uno::Reference< css::frame::XFrameActionListener >& xListener ) throw( css::uno::RuntimeException ); 301 virtual void SAL_CALL removeFrameActionListener ( const css::uno::Reference< css::frame::XFrameActionListener >& xListener ) throw( css::uno::RuntimeException ); 302 303 // XComponent 304 using cppu::OPropertySetHelper::disposing; 305 virtual void SAL_CALL dispose ( ) throw( css::uno::RuntimeException ); 306 virtual void SAL_CALL addEventListener ( const css::uno::Reference< css::lang::XEventListener >& xListener ) throw( css::uno::RuntimeException ); 307 virtual void SAL_CALL removeEventListener ( const css::uno::Reference< css::lang::XEventListener >& xListener ) throw( css::uno::RuntimeException ); 308 309 // XDispatchResultListener 310 virtual void SAL_CALL dispatchFinished ( const css::frame::DispatchResultEvent& aEvent ) throw( css::uno::RuntimeException ); 311 312 // XEventListener 313 virtual void SAL_CALL disposing ( const css::lang::EventObject& aSource ) throw( css::uno::RuntimeException ); 314 315 // XInteractionHandler 316 virtual void SAL_CALL handle ( const css::uno::Reference< css::task::XInteractionRequest >& xRequest ) throw( css::uno::RuntimeException ); 317 318 // css.frame.XUntitledNumbers 319 virtual ::sal_Int32 SAL_CALL leaseNumber( const css::uno::Reference< css::uno::XInterface >& xComponent ) 320 throw (css::lang::IllegalArgumentException, 321 css::uno::RuntimeException ); 322 323 // css.frame.XUntitledNumbers 324 virtual void SAL_CALL releaseNumber( ::sal_Int32 nNumber ) 325 throw (css::lang::IllegalArgumentException, 326 css::uno::RuntimeException ); 327 328 // css.frame.XUntitledNumbers 329 virtual void SAL_CALL releaseNumberForComponent( const css::uno::Reference< css::uno::XInterface >& xComponent ) 330 throw (css::lang::IllegalArgumentException, 331 css::uno::RuntimeException ); 332 333 // css.frame.XUntitledNumbers 334 virtual ::rtl::OUString SAL_CALL getUntitledPrefix() 335 throw (css::uno::RuntimeException); 336 337 //------------------------------------------------------------------------------------------------------------- 338 // protected methods 339 //------------------------------------------------------------------------------------------------------------- 340 protected: 341 342 // OPropertySetHelper 343 virtual sal_Bool SAL_CALL convertFastPropertyValue ( css::uno::Any& aConvertedValue , 344 css::uno::Any& aOldValue , 345 sal_Int32 nHandle , 346 const css::uno::Any& aValue ) throw( css::lang::IllegalArgumentException ); 347 virtual void SAL_CALL setFastPropertyValue_NoBroadcast( sal_Int32 nHandle , 348 const css::uno::Any& aValue ) throw( css::uno::Exception ); 349 using cppu::OPropertySetHelper::getFastPropertyValue; 350 virtual void SAL_CALL getFastPropertyValue ( css::uno::Any& aValue , 351 sal_Int32 nHandle ) const; 352 virtual ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper ( ); 353 virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo ( ) throw (css::uno::RuntimeException); 354 355 //------------------------------------------------------------------------------------------------------------- 356 // private methods 357 //------------------------------------------------------------------------------------------------------------- 358 private: 359 360 css::uno::Reference< css::lang::XComponent > impl_getFrameComponent ( const css::uno::Reference< css::frame::XFrame >& xFrame ) const; 361 static const css::uno::Sequence< css::beans::Property > impl_getStaticPropertyDescriptor( ); 362 363 //--------------------------------------------------------------------- 364 /** calls queryTermination() on every registered termination listener. 365 * 366 * Note: Only normal termination listener (registered in list m_aListenerContainer 367 * will be recognized here. Special listener like quick starter, pipe or others 368 * has to be handled explicitly ! 369 * 370 * @param [out] lCalledListener 371 * every called listener will be returned here. 372 * Those list will be used to informa all called listener 373 * about cancel this termination request. 374 * 375 * @param [out] bVeto 376 * will be true if at least one listener throwed a veto exception; 377 * false otherwise. 378 * 379 * @see impl_sendCancelTerminationEvent() 380 */ 381 void impl_sendQueryTerminationEvent(TTerminateListenerList& lCalledListener, 382 ::sal_Bool& bVeto ); 383 384 //--------------------------------------------------------------------- 385 /** calls cancelTermination() on every termination listener 386 * where queryTermination() was called before. 387 * 388 * Note: Only normal termination listener (registered in list m_aListenerContainer 389 * will be recognized here. Special listener like quick starter, pipe or others 390 * has to be handled explicitly ! 391 * 392 * @param [in] lCalledListener 393 * every listener in this list was called within its method 394 * queryTermination() before. 395 * 396 * @see impl_sendQueryTerminationEvent() 397 */ 398 void impl_sendCancelTerminationEvent(const TTerminateListenerList& lCalledListener); 399 400 //--------------------------------------------------------------------- 401 /** calls notifyTermination() on every registered termination listener. 402 * 403 * Note: Only normal termination listener (registered in list m_aListenerContainer 404 * will be recognized here. Special listener like quick starter, pipe or others 405 * has to be handled explicitly ! 406 */ 407 void impl_sendNotifyTerminationEvent(); 408 409 //--------------------------------------------------------------------- 410 /** try to close all open frames. 411 * 412 * Iterates over all child frames and try to close them. 413 * Given parameter bAllowUI enable/disable showing any UI 414 * (which mostly occur on calling XController->suspend()). 415 * 416 * These method doesn't stop if one frame could not be closed. 417 * It will ignore such frames and try all other ones. 418 * But it returns false in such case - true otherwise. 419 * 420 * @param bAllowUI 421 * enable/disable showing of UI. 422 * 423 * @return true if all frames could be closed; false otherwise. 424 */ 425 ::sal_Bool impl_closeFrames(::sal_Bool bAllowUI); 426 427 //------------------------------------------------------------------------------------------------------------- 428 // debug methods 429 // (should be private every time!) 430 //------------------------------------------------------------------------------------------------------------- 431 #ifdef ENABLE_ASSERTIONS 432 private: 433 434 static sal_Bool implcp_ctor ( const css::uno::Reference< css::lang::XMultiServiceFactory >& xFactory ); 435 static sal_Bool implcp_addEventListener ( const css::uno::Reference< css::lang::XEventListener >& xListener ); 436 static sal_Bool implcp_removeEventListener ( const css::uno::Reference< css::lang::XEventListener >& xListener ); 437 438 sal_Bool m_bIsTerminated ; /// check flag to protect us against dispose before terminate! 439 /// see dispose() for further informations! 440 441 #endif // #ifdef ENABLE_ASSERTIONS 442 443 //------------------------------------------------------------------------------------------------------------- 444 // variables 445 // (should be private every time!) 446 //------------------------------------------------------------------------------------------------------------- 447 private: 448 449 css::uno::Reference< css::lang::XMultiServiceFactory > m_xFactory ; /// reference to factory, which has create this instance 450 FrameContainer m_aChildTaskContainer ; /// array of child tasks (childs of desktop are tasks; and tasks are also frames - But pure frames are not accepted!) 451 ::cppu::OMultiTypeInterfaceContainerHelper m_aListenerContainer ; /// container for ALL Listener 452 css::uno::Reference< css::frame::XFrames > m_xFramesHelper ; /// helper for XFrames, XIndexAccess, XElementAccess and implementation of a childcontainer! 453 css::uno::Reference< css::frame::XDispatchProvider > m_xDispatchHelper ; /// helper to dispatch something for new tasks, created by "_blank"! 454 ELoadState m_eLoadState ; /// hold information about state of asynchron loading of component for loadComponentFromURL()! 455 css::uno::Reference< css::frame::XFrame > m_xLastFrame ; /// last target of "loadComponentFromURL()"! 456 css::uno::Any m_aInteractionRequest ; 457 sal_Bool m_bSuspendQuickstartVeto ; /// don't ask quickstart for a veto 458 SvtCommandOptions m_aCommandOptions ; /// ref counted class to support disabling commands defined by configuration file 459 ::rtl::OUString m_sName ; 460 ::rtl::OUString m_sTitle ; 461 css::uno::Reference< css::frame::XDispatchRecorderSupplier > m_xDispatchRecorderSupplier ; 462 463 //--------------------------------------------------------------------- 464 /** special terminate listener to close pipe and block external requests 465 * during/after termination process is/was running 466 */ 467 css::uno::Reference< css::frame::XTerminateListener > m_xPipeTerminator; 468 469 //--------------------------------------------------------------------- 470 /** special terminate listener shown inside system tray (quick starter) 471 * Will hinder the office on shutdown ... but wish to allow closing 472 * of open documents. And because thats different to a normal terminate listener 473 * it has to be handled special .-) 474 */ 475 css::uno::Reference< css::frame::XTerminateListener > m_xQuickLauncher; 476 477 //--------------------------------------------------------------------- 478 /** special terminate listener which loads images asynchronous for current open documents. 479 * Because internaly it uses blocking system APIs ... it can't be guaranteed that 480 * running jobs can be cancelled successfully if the corressponding document will be closed ... 481 * it will not hinder those documents on closing. Instead it let all jobs running ... 482 * but at least on terminate we have to wait for all those blocked requests. 483 * So these implementation must be a special terminate listener too .-( 484 */ 485 css::uno::Reference< css::frame::XTerminateListener > m_xSWThreadManager; 486 487 //--------------------------------------------------------------------- 488 /** special terminate listener shuting down the SfxApplication. 489 * Because these desktop instance closes documents and informs listener 490 * only ... it does not really shutdown the whole application. 491 * 492 * Btw: That wouldn't be possible by design ... because Desktop.terminate() 493 * has to return a boolean value about success ... it can't really shutdown the 494 * process .-) 495 * 496 * So we uses a trick: A special listener (exactly these one here) listen for notifyTermination() 497 * and shutdown the process asynchronous. But desktop has to make this special 498 * notification as really last one ... Otherwise it can happen that asynchronous 499 * shutdown will be faster then all other code around Desktop.terminate() .-)) 500 */ 501 css::uno::Reference< css::frame::XTerminateListener > m_xSfxTerminator; 502 503 css::uno::Reference< css::frame::XUntitledNumbers > m_xTitleNumberGenerator; 504 505 }; // class Desktop 506 507 } // namespace framework 508 509 #endif // #ifndef __FRAMEWORK_SERVICES_DESKTOP_HXX_ 510