summaryrefslogtreecommitdiff
path: root/framework/source/services/sessionlistener.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'framework/source/services/sessionlistener.cxx')
-rw-r--r--framework/source/services/sessionlistener.cxx179
1 files changed, 135 insertions, 44 deletions
diff --git a/framework/source/services/sessionlistener.cxx b/framework/source/services/sessionlistener.cxx
index 9bda14b891..eabcfcedf1 100644
--- a/framework/source/services/sessionlistener.cxx
+++ b/framework/source/services/sessionlistener.cxx
@@ -1,7 +1,7 @@
/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
+ *
* Copyright 2008 by Sun Microsystems, Inc.
*
* OpenOffice.org - a multi-platform office productivity suite
@@ -60,14 +60,15 @@
#include <com/sun/star/frame/XStorable.hpp>
#include <com/sun/star/frame/XComponentLoader.hpp>
#include <com/sun/star/frame/XDispatch.hpp>
+#include <com/sun/star/frame/XDesktop.hpp>
#include <com/sun/star/util/XModifiable.hpp>
#include <com/sun/star/util/XChangesBatch.hpp>
#include <com/sun/star/util/XURLTransformer.hpp>
#include <com/sun/star/util/URL.hpp>
#include <osl/time.h>
#include <comphelper/processfactory.hxx>
-#include <svtools/pathoptions.hxx>
-#include <svtools/internaloptions.hxx>
+#include <unotools/pathoptions.hxx>
+#include <unotools/internaloptions.hxx>
#include <stdio.h>
//_______________________________________________
// interface includes
@@ -103,12 +104,13 @@ namespace framework{
//***********************************************
// XInterface, XTypeProvider, XServiceInfo
-DEFINE_XINTERFACE_5(
+DEFINE_XINTERFACE_6(
SessionListener,
OWeakObject,
DIRECT_INTERFACE(css::lang::XTypeProvider),
DIRECT_INTERFACE(css::lang::XInitialization),
DIRECT_INTERFACE(css::frame::XSessionManagerListener),
+ DIRECT_INTERFACE(css::frame::XSessionManagerListener2),
DIRECT_INTERFACE(css::frame::XStatusListener),
DIRECT_INTERFACE(css::lang::XServiceInfo))
@@ -116,7 +118,7 @@ DEFINE_XTYPEPROVIDER_5(
SessionListener,
css::lang::XTypeProvider,
css::lang::XInitialization,
- css::frame::XSessionManagerListener,
+ css::frame::XSessionManagerListener2,
css::frame::XStatusListener,
css::lang::XServiceInfo)
@@ -137,19 +139,79 @@ SessionListener::SessionListener(const css::uno::Reference< css::lang::XMultiSer
: ThreadHelpBase (&Application::GetSolarMutex())
, OWeakObject ( )
, m_xSMGR (xSMGR )
- , m_bRestored( false )
+ , m_bRestored( sal_False )
+ , m_bSessionStoreRequested( sal_False )
+ , m_bAllowUserInteractionOnQuit( sal_False )
+ , m_bTerminated( sal_False )
{
}
SessionListener::~SessionListener()
{
- if (m_rSessionManager.is())
+ if (m_rSessionManager.is())
{
css::uno::Reference< XSessionManagerListener> me(this);
m_rSessionManager->removeSessionManagerListener(me);
}
}
+void SessionListener::StoreSession( sal_Bool bAsync )
+{
+ ResetableGuard aGuard(m_aLock);
+ try
+ {
+ // xd create SERVICENAME_AUTORECOVERY -> XDispatch
+ // xd->dispatch("vnd.sun.star.autorecovery:/doSessionSave, async=bAsync
+ // on stop event m_rSessionManager->saveDone(this); in case of asynchronous call
+ // in case of synchronous call the caller should do saveDone() call himself!
+
+ css::uno::Reference< XDispatch > xDispatch(m_xSMGR->createInstance(SERVICENAME_AUTORECOVERY), UNO_QUERY_THROW);
+ css::uno::Reference< XURLTransformer > xURLTransformer(m_xSMGR->createInstance(SERVICENAME_URLTRANSFORMER), UNO_QUERY_THROW);
+ URL aURL;
+ aURL.Complete = OUString::createFromAscii("vnd.sun.star.autorecovery:/doSessionSave");
+ xURLTransformer->parseStrict(aURL);
+
+ // in case of asynchronous call the notification will trigger saveDone()
+ if ( bAsync )
+ xDispatch->addStatusListener(this, aURL);
+
+ Sequence< PropertyValue > args(1);
+ args[0] = PropertyValue(OUString::createFromAscii("DispatchAsynchron"),-1,makeAny(bAsync),PropertyState_DIRECT_VALUE);
+ xDispatch->dispatch(aURL, args);
+ } catch (com::sun::star::uno::Exception& e) {
+ OString aMsg = OUStringToOString(e.Message, RTL_TEXTENCODING_UTF8);
+ OSL_ENSURE(sal_False, aMsg.getStr());
+ // save failed, but tell manager to go on if we havent yet dispatched the request
+ // in case of synchronous saving the notification is done by the caller
+ if ( bAsync && m_rSessionManager.is() )
+ m_rSessionManager->saveDone(this);
+ }
+}
+
+void SessionListener::QuitSessionQuietly()
+{
+ ResetableGuard aGuard(m_aLock);
+ try
+ {
+ // xd create SERVICENAME_AUTORECOVERY -> XDispatch
+ // xd->dispatch("vnd.sun.star.autorecovery:/doSessionQuietQuit, async=false
+ // it is done synchronously to avoid conflict with normal quit process
+
+ css::uno::Reference< XDispatch > xDispatch(m_xSMGR->createInstance(SERVICENAME_AUTORECOVERY), UNO_QUERY_THROW);
+ css::uno::Reference< XURLTransformer > xURLTransformer(m_xSMGR->createInstance(SERVICENAME_URLTRANSFORMER), UNO_QUERY_THROW);
+ URL aURL;
+ aURL.Complete = OUString::createFromAscii("vnd.sun.star.autorecovery:/doSessionQuietQuit");
+ xURLTransformer->parseStrict(aURL);
+
+ Sequence< PropertyValue > args(1);
+ args[0] = PropertyValue(OUString::createFromAscii("DispatchAsynchron"),-1,makeAny(sal_False),PropertyState_DIRECT_VALUE);
+ xDispatch->dispatch(aURL, args);
+ } catch (com::sun::star::uno::Exception& e) {
+ OString aMsg = OUStringToOString(e.Message, RTL_TEXTENCODING_UTF8);
+ OSL_ENSURE(sal_False, aMsg.getStr());
+ }
+}
+
void SAL_CALL SessionListener::disposing(const com::sun::star::lang::EventObject&) throw (RuntimeException)
{
}
@@ -170,6 +232,8 @@ void SAL_CALL SessionListener::initialize(const Sequence< Any >& args)
v.Value >>= aSMgr;
else if (v.Name.equalsAscii("SessionManager"))
v.Value >>= m_rSessionManager;
+ else if (v.Name.equalsAscii("AllowUserInteractionOnQuit"))
+ v.Value >>= m_bAllowUserInteractionOnQuit;
}
}
}
@@ -181,7 +245,7 @@ void SAL_CALL SessionListener::initialize(const Sequence< Any >& args)
{
m_rSessionManager->addSessionManagerListener(this);
}
-}
+}
void SAL_CALL SessionListener::statusChanged(const FeatureStateEvent& event)
throw (css::uno::RuntimeException)
@@ -190,8 +254,8 @@ void SAL_CALL SessionListener::statusChanged(const FeatureStateEvent& event)
{
if (event.FeatureDescriptor.compareToAscii("update")==0)
m_bRestored = sal_True; // a document was restored
- // if (event.FeatureDescriptor.compareToAscii("stop")==0)
-
+ // if (event.FeatureDescriptor.compareToAscii("stop")==0)
+
}
else if (event.FeatureURL.Complete.equalsAscii("vnd.sun.star.autorecovery:/doSessionSave"))
{
@@ -207,11 +271,11 @@ void SAL_CALL SessionListener::statusChanged(const FeatureStateEvent& event)
sal_Bool SAL_CALL SessionListener::doRestore()
throw (RuntimeException)
{
- ResetableGuard aGuard(m_aLock);
+ ResetableGuard aGuard(m_aLock);
m_bRestored = sal_False;
try {
css::uno::Reference< XDispatch > xDispatch(m_xSMGR->createInstance(SERVICENAME_AUTORECOVERY), UNO_QUERY_THROW);
-
+
URL aURL;
aURL.Complete = OUString::createFromAscii("vnd.sun.star.autorecovery:/doSessionRestore");
css::uno::Reference< XURLTransformer > xURLTransformer(m_xSMGR->createInstance(SERVICENAME_URLTRANSFORMER), UNO_QUERY_THROW);
@@ -220,7 +284,7 @@ sal_Bool SAL_CALL SessionListener::doRestore()
xDispatch->addStatusListener(this, aURL);
xDispatch->dispatch(aURL, args);
m_bRestored = sal_True;
-
+
} catch (com::sun::star::uno::Exception& e) {
OString aMsg = OUStringToOString(e.Message, RTL_TEXTENCODING_UTF8);
OSL_ENSURE(sal_False, aMsg.getStr());
@@ -235,46 +299,73 @@ void SAL_CALL SessionListener::doSave( sal_Bool bShutdown, sal_Bool /*bCancelabl
{
if (bShutdown)
{
- sal_Bool bDispatched = sal_False;
- ResetableGuard aGuard(m_aLock);
- try
- {
- // xd create SERVICENAME_AUTORECOVERY -> XDispatch
- // xd->dispatch("vnd.sun.star.autorecovery:/doSessionSave, async=true
- // on stop event m_rSessionManager->saveDone(this);
-
- css::uno::Reference< XDispatch > xDispatch(m_xSMGR->createInstance(SERVICENAME_AUTORECOVERY), UNO_QUERY_THROW);
- css::uno::Reference< XURLTransformer > xURLTransformer(m_xSMGR->createInstance(SERVICENAME_URLTRANSFORMER), UNO_QUERY_THROW);
- URL aURL;
- aURL.Complete = OUString::createFromAscii("vnd.sun.star.autorecovery:/doSessionSave");
- xURLTransformer->parseStrict(aURL);
- xDispatch->addStatusListener(this, aURL);
- Sequence< PropertyValue > args(1);
- args[0] = PropertyValue(OUString::createFromAscii("DispatchAsynchron"),-1,makeAny(sal_True),PropertyState_DIRECT_VALUE);
- xDispatch->dispatch(aURL, args);
- bDispatched = sal_True;
- // on stop event set call m_rSessionManager->saveDone(this);
- } catch (com::sun::star::uno::Exception& e) {
- OString aMsg = OUStringToOString(e.Message, RTL_TEXTENCODING_UTF8);
- OSL_ENSURE(sal_False, aMsg.getStr());
- // save failed, but tell manager to go on if we havent yet dispatched the request
- if (m_rSessionManager.is() && !bDispatched)
- m_rSessionManager->saveDone(this);
- }
+ m_bSessionStoreRequested = sal_True; // there is no need to protect it with mutex
+ if ( m_bAllowUserInteractionOnQuit && m_rSessionManager.is() )
+ m_rSessionManager->queryInteraction( static_cast< css::frame::XSessionManagerListener* >( this ) );
+ else
+ StoreSession( sal_True );
}
// we don't have anything to do so tell the session manager we're done
else if( m_rSessionManager.is() )
m_rSessionManager->saveDone( this );
}
-
-
-void SAL_CALL SessionListener::approveInteraction( sal_Bool /*bInteractionGranted*/ )
+void SAL_CALL SessionListener::approveInteraction( sal_Bool bInteractionGranted )
throw (RuntimeException)
-{}
+{
+ // do AutoSave as the first step
+ ResetableGuard aGuard(m_aLock);
+
+ if ( bInteractionGranted )
+ {
+ // close the office documents in normal way
+ try
+ {
+ // first of all let the session be stored to be sure that we lose no information
+ StoreSession( sal_False );
+
+ css::uno::Reference< css::frame::XDesktop > xDesktop( m_xSMGR->createInstance(SERVICENAME_DESKTOP), css::uno::UNO_QUERY_THROW);
+ m_bTerminated = xDesktop->terminate();
+
+ if ( m_rSessionManager.is() )
+ {
+ // false means that the application closing has been cancelled
+ if ( !m_bTerminated )
+ m_rSessionManager->cancelShutdown();
+ else
+ m_rSessionManager->interactionDone( this );
+ }
+ }
+ catch( css::uno::Exception& )
+ {
+ StoreSession( sal_True );
+ m_rSessionManager->interactionDone( this );
+ }
+
+ if ( m_rSessionManager.is() )
+ m_rSessionManager->saveDone(this);
+ }
+ else
+ {
+ StoreSession( sal_True );
+ }
+}
void SessionListener::shutdownCanceled()
throw (RuntimeException)
-{}
+{
+ // set the state back
+ m_bSessionStoreRequested = sal_False; // there is no need to protect it with mutex
+}
+
+void SessionListener::doQuit()
+ throw (RuntimeException)
+{
+ if ( m_bSessionStoreRequested && !m_bTerminated )
+ {
+ // let the session be closed quietly in this case
+ QuitSessionQuietly();
+ }
+}
}