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 #ifndef __FRAMEWORK_DISPATCH_CLOSEDISPATCHER_HXX_ 29 #define __FRAMEWORK_DISPATCH_CLOSEDISPATCHER_HXX_ 30 31 //_______________________________________________ 32 // my own includes 33 34 #include <threadhelp/threadhelpbase.hxx> 35 #include <macros/xinterface.hxx> 36 #include <macros/xtypeprovider.hxx> 37 #include <macros/debug.hxx> 38 #include <macros/generic.hxx> 39 #include <stdtypes.h> 40 #include <general.h> 41 42 //_______________________________________________ 43 // interface includes 44 #include <com/sun/star/lang/XTypeProvider.hpp> 45 #include <com/sun/star/frame/XFrame.hpp> 46 #include <com/sun/star/frame/XStatusListener.hpp> 47 #include <com/sun/star/frame/XNotifyingDispatch.hpp> 48 #include <com/sun/star/frame/XDispatchInformationProvider.hpp> 49 #include <com/sun/star/util/URL.hpp> 50 #include <com/sun/star/frame/XDispatchResultListener.hpp> 51 #include <com/sun/star/lang/XMultiServiceFactory.hpp> 52 #include <com/sun/star/frame/DispatchResultState.hpp> 53 54 //_______________________________________________ 55 // other includes 56 #include <cppuhelper/weak.hxx> 57 #include <vcl/evntpost.hxx> 58 59 //_______________________________________________ 60 // namespace 61 62 namespace framework{ 63 64 //----------------------------------------------- 65 /** 66 @short helper to dispatch the URLs ".uno:CloseDoc"/".uno:CloseWin"/".uno:CloseFrame" 67 to close a frame/document or the whole application implicitly in case it was the last frame 68 69 @descr These URLs implements a special functionality to close a document or the whole frame ... 70 and handle the state, it was the last frame or document. Then we create the 71 default backing document which can be used to open new ones using the file open dialog 72 or some other menu entries. Or we terminate the whole application in case this backing mode shouldnt 73 be used. 74 */ 75 class CloseDispatcher : public css::lang::XTypeProvider 76 , public css::frame::XNotifyingDispatch // => XDispatch 77 , public css::frame::XDispatchInformationProvider 78 // baseclasses ... order is neccessary for right initialization! 79 , private ThreadHelpBase 80 , public ::cppu::OWeakObject 81 { 82 //------------------------------------------- 83 // types 84 85 private: 86 87 //--------------------------------------- 88 /** @short describe, which request must be done here. 89 @descr The incoming URLs {.uno:CloseDoc/CloseWin and CloseFrame 90 can be classified so and checked later performant.}*/ 91 enum EOperation 92 { 93 E_CLOSE_DOC, 94 E_CLOSE_FRAME, 95 E_CLOSE_WIN 96 }; 97 98 //------------------------------------------- 99 // member 100 101 private: 102 103 //--------------------------------------- 104 /** @short reference to an uno service manager, 105 which can be used to create own needed 106 uno resources. */ 107 css::uno::Reference< css::lang::XMultiServiceFactory > m_xSMGR; 108 109 //--------------------------------------- 110 /** @short reference to the target frame, which should be 111 closed by this dispatch. */ 112 css::uno::WeakReference< css::frame::XFrame > m_xCloseFrame; 113 114 //--------------------------------------- 115 /** @short used for asynchronous callbacks within the main thread. 116 @descr Internaly we work asynchronous. Because our callis 117 are not aware, that her request can kill its own environment ... */ 118 ::vcl::EventPoster m_aAsyncCallback; 119 120 //--------------------------------------- 121 /** @short used inside asyncronous callback to decide, 122 which operation must be executed. */ 123 EOperation m_eOperation; 124 125 //--------------------------------------- 126 /** @short for asynchronous operations we must hold us self alive! */ 127 css::uno::Reference< css::uno::XInterface > m_xSelfHold; 128 129 //--------------------------------------- 130 /** @short list of registered status listener */ 131 ListenerHash m_lStatusListener; 132 133 //--------------------------------------- 134 /** @short holded alive for internaly asynchronous operations! */ 135 css::uno::Reference< css::frame::XDispatchResultListener > m_xResultListener; 136 137 //------------------------------------------- 138 // native interface 139 140 public: 141 142 //--------------------------------------- 143 /** @short connect a new CloseDispatcher instance to its frame. 144 @descr One CloseDispatcher instance is bound to onw frame only. 145 That makes an implementation (e.g. of listener support) 146 much more easier .-) 147 148 @param xSMGR 149 an un oservice manager, which is needed to create uno resource 150 internaly. 151 152 @param xFrame 153 the frame where the corresponding dispatch was started. 154 155 @param sTarget 156 help us to find the right target for this close operation. 157 */ 158 CloseDispatcher(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR , 159 const css::uno::Reference< css::frame::XFrame >& xFrame , 160 const ::rtl::OUString& sTarget); 161 162 //--------------------------------------- 163 /** @short does nothing real. */ 164 virtual ~CloseDispatcher(); 165 166 //------------------------------------------- 167 // uno interface 168 169 public: 170 171 //--------------------------------------- 172 FWK_DECLARE_XINTERFACE 173 FWK_DECLARE_XTYPEPROVIDER 174 175 //--------------------------------------- 176 // XNotifyingDispatch 177 virtual void SAL_CALL dispatchWithNotification( const css::util::URL& aURL , 178 const css::uno::Sequence< css::beans::PropertyValue >& lArguments, 179 const css::uno::Reference< css::frame::XDispatchResultListener >& xListener ) throw(css::uno::RuntimeException); 180 181 //--------------------------------------- 182 // XDispatch 183 virtual void SAL_CALL dispatch ( const css::util::URL& aURL , 184 const css::uno::Sequence< css::beans::PropertyValue >& lArguments) throw(css::uno::RuntimeException); 185 virtual void SAL_CALL addStatusListener ( const css::uno::Reference< css::frame::XStatusListener >& xListener , 186 const css::util::URL& aURL ) throw(css::uno::RuntimeException); 187 virtual void SAL_CALL removeStatusListener( const css::uno::Reference< css::frame::XStatusListener >& xListener , 188 const css::util::URL& aURL ) throw(css::uno::RuntimeException); 189 190 //--------------------------------------- 191 // XDispatchInformationProvider 192 virtual css::uno::Sequence< sal_Int16 > SAL_CALL getSupportedCommandGroups ( ) throw (css::uno::RuntimeException); 193 virtual css::uno::Sequence< css::frame::DispatchInformation > SAL_CALL getConfigurableDispatchInformation( sal_Int16 nCommandGroup ) throw (css::uno::RuntimeException); 194 195 //------------------------------------------- 196 // internal helper 197 198 private: 199 200 //--------------------------------------- 201 /** @short a callback for asynchronous started operations. 202 203 @descr As already mentione, we make internaly all operations 204 asynchronous. Otherwhise our callis kill its own environment 205 during they call us ... 206 */ 207 DECL_LINK( impl_asyncCallback, void* ); 208 209 //--------------------------------------- 210 /** @short prepare m_xCloseFrame so it should be closeable without problems. 211 212 @descr Thats needed to be shure, that the document cant disagree 213 later with e.g. an office termination. 214 The problem: Closing of documents can show UI. If the user 215 ignores it and open/close other documents, we cant know 216 which state the office has after closing of this frame. 217 218 @param bAllowSuspend 219 force calling of XController->suspend(). 220 221 @param bCloseAllOtherViewsToo 222 if there are other top level frames, which 223 contains views to the same document then our m_xCloseFrame, 224 they are forced to be closed too. 225 We need it to implement the CLOSE_DOC semantic. 226 227 @return [boolean] 228 sal_True if closing was successfully. 229 */ 230 sal_Bool implts_prepareFrameForClosing(const css::uno::Reference< css::frame::XFrame >& xFrame , 231 sal_Bool bAllowSuspend , 232 sal_Bool bCloseAllOtherViewsToo, 233 sal_Bool& bControllerSuspended ); 234 235 //--------------------------------------- 236 /** @short close the member m_xCloseFrame. 237 238 @descr This method does not look for any document 239 inside this frame. Such views must be cleared 240 before (e.g. by calling implts_closeView()! 241 242 Otherwhise e.g. the XController->suspend() 243 call isnt made and no UI warn the user about 244 loosing document changes. Because the 245 frame is closed .... 246 247 @return [bool] 248 sal_True if closing was successfully. 249 */ 250 sal_Bool implts_closeFrame(); 251 252 //--------------------------------------- 253 /** @short set the special BackingComponent (now StartModule) 254 as new component of our m_xCloseFrame. 255 256 @return [bool] 257 sal_True if operation was successfully. 258 */ 259 sal_Bool implts_establishBackingMode(); 260 261 //--------------------------------------- 262 /** @short calls XDesktop->terminate(). 263 264 @descr No office code has to be called 265 afterwards! Because the process is dieing ... 266 The only exception is a might be registered 267 listener at this instance here. 268 Because he should know, that such things will happen :-) 269 270 @return [bool] 271 sal_True if termination of the application was started ... 272 */ 273 sal_Bool implts_terminateApplication(); 274 275 //--------------------------------------- 276 /** @short notify a DispatchResultListener. 277 278 @descr We check the listener reference before we use it. 279 So this method can be called everytimes! 280 281 @parama xListener 282 the listener, which should be notified. 283 Can be null! 284 285 @param nState 286 directly used as css::frame::DispatchResultState value. 287 288 @param aResult 289 not used yet realy ... 290 */ 291 void implts_notifyResultListener(const css::uno::Reference< css::frame::XDispatchResultListener >& xListener, 292 sal_Int16 nState , 293 const css::uno::Any& aResult ); 294 295 //--------------------------------------- 296 /** @short try to find the right target frame where this close request 297 must be realy done. 298 299 @descr The problem behind: closing some resources depends sometimes from the 300 context where its dispatched. Sometimes the start frame of the dispatch 301 has to be closed itself (target=_self) ... sometimes it's parent frame 302 has to be closed - BUT(!) it means a parent frame containing a top level 303 window. _top cant be used then for dispatch - because it adress TopFrames 304 not frames containg top level windows. So normaly _magic (which btw does not 305 exists at the moment .-) ) should be used. So we interpret target=<empty> 306 as _magic ! 307 308 @param xFrame 309 start point for search of right dispatch frame. 310 311 @param sTarget 312 give us an idea how this target frame must be searched. 313 */ 314 315 static css::uno::Reference< css::frame::XFrame > static_impl_searchRightTargetFrame(const css::uno::Reference< css::frame::XFrame >& xFrame , 316 const ::rtl::OUString& sTarget); 317 318 }; // class CloseDispatcher 319 320 } // namespace framework 321 322 #endif // #ifndef __FRAMEWORK_DISPATCH_CLOSEDISPATCHER_HXX_ 323