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