1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: sessionlistener.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_framework.hxx"
33 //_______________________________________________
36 #ifndef __FRAMEWORK_SERVICES_TYPEDETECTION_HXX_
37 #include <services/sessionlistener.hxx>
39 #include <threadhelp/readguard.hxx>
40 #include <threadhelp/resetableguard.hxx>
41 #include <protocols.h>
44 #include <osl/thread.h>
47 #include <vcl/svapp.hxx>
48 #include <tools/urlobj.hxx>
49 #include <tools/tempfile.hxx>
50 #include <unotools/tempfile.hxx>
51 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
52 #include <com/sun/star/lang/XComponent.hpp>
53 #include <com/sun/star/container/XNameAccess.hpp>
54 #include <com/sun/star/container/XNameContainer.hpp>
55 #include <com/sun/star/beans/NamedValue.hpp>
56 #include <com/sun/star/beans/PropertyValue.hpp>
57 #include <com/sun/star/beans/PropertyState.hpp>
58 #include <com/sun/star/beans/XPropertySet.hpp>
59 #include <com/sun/star/frame/XFramesSupplier.hpp>
60 #include <com/sun/star/frame/XStorable.hpp>
61 #include <com/sun/star/frame/XComponentLoader.hpp>
62 #include <com/sun/star/frame/XDispatch.hpp>
63 #include <com/sun/star/util/XModifiable.hpp>
64 #include <com/sun/star/util/XChangesBatch.hpp>
65 #include <com/sun/star/util/XURLTransformer.hpp>
66 #include <com/sun/star/util/URL.hpp>
68 #include <comphelper/processfactory.hxx>
69 #include <svtools/pathoptions.hxx>
70 #include <svtools/internaloptions.hxx>
72 //_______________________________________________
74 #include <com/sun/star/uno/Any.hxx>
76 #include <com/sun/star/uno/Sequence.hxx>
77 //_______________________________________________
78 // includes of other projects
80 //_______________________________________________
83 using namespace com::sun::star::uno
;
84 using namespace com::sun::star::util
;
85 using namespace com::sun::star::frame
;
86 using namespace com::sun::star::lang
;
87 using namespace com::sun::star::beans
;
88 using namespace com::sun::star::container
;
94 //_______________________________________________
97 //_______________________________________________
98 // non exported definitions
100 //_______________________________________________
103 //***********************************************
104 // XInterface, XTypeProvider, XServiceInfo
109 DIRECT_INTERFACE(css::lang::XTypeProvider
),
110 DIRECT_INTERFACE(css::lang::XInitialization
),
111 DIRECT_INTERFACE(css::frame::XSessionManagerListener
),
112 DIRECT_INTERFACE(css::frame::XStatusListener
),
113 DIRECT_INTERFACE(css::lang::XServiceInfo
))
115 DEFINE_XTYPEPROVIDER_5(
117 css::lang::XTypeProvider
,
118 css::lang::XInitialization
,
119 css::frame::XSessionManagerListener
,
120 css::frame::XStatusListener
,
121 css::lang::XServiceInfo
)
123 DEFINE_XSERVICEINFO_ONEINSTANCESERVICE(
126 SERVICENAME_SESSIONLISTENER
,
127 IMPLEMENTATIONNAME_SESSIONLISTENER
)
129 DEFINE_INIT_SERVICE(SessionListener
,
131 /* Add special code for initialization here, if you have to use your own instance
132 during your ctor is still in progress! */
136 SessionListener::SessionListener(const css::uno::Reference
< css::lang::XMultiServiceFactory
>& xSMGR
)
137 : ThreadHelpBase (&Application::GetSolarMutex())
140 , m_bRestored( false )
144 SessionListener::~SessionListener()
146 if (m_rSessionManager
.is())
148 css::uno::Reference
< XSessionManagerListener
> me(this);
149 m_rSessionManager
->removeSessionManagerListener(me
);
153 void SAL_CALL
SessionListener::disposing(const com::sun::star::lang::EventObject
&) throw (RuntimeException
)
157 void SAL_CALL
SessionListener::initialize(const Sequence
< Any
>& args
)
158 throw (RuntimeException
)
161 OUString aSMgr
= OUString::createFromAscii("com.sun.star.frame.SessionManagerClient");
162 if (args
.getLength() > 0)
165 for (int i
= 0; i
< args
.getLength(); i
++)
169 if (v
.Name
.equalsAscii("SessionManagerName"))
171 else if (v
.Name
.equalsAscii("SessionManager"))
172 v
.Value
>>= m_rSessionManager
;
176 if (!m_rSessionManager
.is())
177 m_rSessionManager
= css::uno::Reference
< XSessionManagerClient
>
178 (m_xSMGR
->createInstance(aSMgr
), UNO_QUERY
);
180 if (m_rSessionManager
.is())
182 m_rSessionManager
->addSessionManagerListener(this);
186 void SAL_CALL
SessionListener::statusChanged(const FeatureStateEvent
& event
)
187 throw (css::uno::RuntimeException
)
189 if (event
.FeatureURL
.Complete
.equalsAscii("vnd.sun.star.autorecovery:/doSessionRestore"))
191 if (event
.FeatureDescriptor
.compareToAscii("update")==0)
192 m_bRestored
= sal_True
; // a document was restored
193 // if (event.FeatureDescriptor.compareToAscii("stop")==0)
196 else if (event
.FeatureURL
.Complete
.equalsAscii("vnd.sun.star.autorecovery:/doSessionSave"))
198 if (event
.FeatureDescriptor
.compareToAscii("stop")==0)
200 if (m_rSessionManager
.is())
201 m_rSessionManager
->saveDone(this); // done with save
207 sal_Bool SAL_CALL
SessionListener::doRestore()
208 throw (RuntimeException
)
210 ResetableGuard
aGuard(m_aLock
);
211 m_bRestored
= sal_False
;
213 css::uno::Reference
< XDispatch
> xDispatch(m_xSMGR
->createInstance(SERVICENAME_AUTORECOVERY
), UNO_QUERY_THROW
);
216 aURL
.Complete
= OUString::createFromAscii("vnd.sun.star.autorecovery:/doSessionRestore");
217 css::uno::Reference
< XURLTransformer
> xURLTransformer(m_xSMGR
->createInstance(SERVICENAME_URLTRANSFORMER
), UNO_QUERY_THROW
);
218 xURLTransformer
->parseStrict(aURL
);
219 Sequence
< PropertyValue
> args
;
220 xDispatch
->addStatusListener(this, aURL
);
221 xDispatch
->dispatch(aURL
, args
);
222 m_bRestored
= sal_True
;
224 } catch (com::sun::star::uno::Exception
& e
) {
225 OString aMsg
= OUStringToOString(e
.Message
, RTL_TEXTENCODING_UTF8
);
226 OSL_ENSURE(sal_False
, aMsg
.getStr());
232 void SessionListener::_saveAutorecovery( sal_Bool bSessionSave
)
234 sal_Bool bDispatched
= sal_False
;
235 ResetableGuard
aGuard(m_aLock
);
239 // xd create SERVICENAME_AUTORECOVERY -> XDispatch
240 // xd->dispatch("vnd.sun.star.autorecovery:/doSessionSave, async=true
241 // on stop event m_rSessionManager->saveDone(this);
242 // ON autosave ( bSessionSave == false)
243 // xd->dispatch("vnd.sun.star.autorecovery:/doAutoSave, async=false
245 css::uno::Reference
< XDispatch
> xDispatch(m_xSMGR
->createInstance(SERVICENAME_AUTORECOVERY
), UNO_QUERY_THROW
);
246 css::uno::Reference
< XURLTransformer
> xURLTransformer(m_xSMGR
->createInstance(SERVICENAME_URLTRANSFORMER
), UNO_QUERY_THROW
);
248 aURL
.Complete
= OUString::createFromAscii(bSessionSave
249 ? "vnd.sun.star.autorecovery:/doSessionSave"
250 : "vnd.sun.star.autorecovery:/doAutoSave");
251 xURLTransformer
->parseStrict(aURL
);
253 xDispatch
->addStatusListener(this, aURL
);
254 Sequence
< PropertyValue
> args(1);
255 args
[0] = PropertyValue(OUString::createFromAscii("DispatchAsynchron"),-1,makeAny(bSessionSave
),PropertyState_DIRECT_VALUE
);
256 xDispatch
->dispatch(aURL
, args
);
257 bDispatched
= sal_True
;
258 // on stop event set call m_rSessionManager->saveDone(this);
259 } catch (com::sun::star::uno::Exception
& e
) {
260 OString aMsg
= OUStringToOString(e
.Message
, RTL_TEXTENCODING_UTF8
);
261 OSL_ENSURE(sal_False
, aMsg
.getStr());
262 // save failed, but tell manager to go on if we havent yet dispatched the request
263 if (m_rSessionManager
.is() && !bDispatched
&& bSessionSave
)
264 m_rSessionManager
->saveDone(this);
268 void SAL_CALL
SessionListener::doSave( sal_Bool bShutdown
, sal_Bool bCancelable
)
269 throw (RuntimeException
)
273 _saveAutorecovery( !bCancelable
);
275 _requestInteraction();
277 // we don't have anything to do so tell the session manager we're done
278 else if( m_rSessionManager
.is() )
279 m_rSessionManager
->saveDone( this );
284 void SAL_CALL
SessionListener::approveInteraction( sal_Bool bInteractionGranted
)
285 throw (RuntimeException
)
287 if( bInteractionGranted
) {
288 bool bExit
= GetpApp()->QueryExit();
290 if( m_rSessionManager
.is() )
291 m_rSessionManager
->saveDone( this );
293 _finishInteraction( !bExit
);
295 _saveAutorecovery( sal_True
);
298 void SessionListener::shutdownCanceled()
299 throw (RuntimeException
)
302 void SessionListener::_requestInteraction()
304 m_rSessionManager
->queryInteraction(Reference
<XSessionManagerListener
>(this));
307 void SessionListener::_finishInteraction( sal_Bool bCancelShutdown
)
309 m_rSessionManager
->interactionDone(Reference
< XSessionManagerListener
>(this), bCancelShutdown
);