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