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: session.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_vcl.hxx"
33 #include <vcl/svapp.hxx>
34 #include <vcl/svdata.hxx>
35 #include <vcl/salinst.hxx>
36 #include <vcl/salsession.hxx>
37 #include <cppuhelper/compbase1.hxx>
38 #include <tools/debug.hxx>
39 #include <com/sun/star/frame/XSessionManagerClient.hpp>
40 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
44 using namespace com::sun::star::uno
;
45 using namespace com::sun::star::lang
;
46 using namespace com::sun::star::frame
;
49 SalSession::~SalSession()
53 class VCLSession
: public cppu::WeakComponentImplHelper1
< XSessionManagerClient
>
57 Reference
< XSessionManagerListener
> m_xListener
;
58 bool m_bInteractionRequested
;
59 bool m_bInteractionDone
;
62 Listener( const Reference
< XSessionManagerListener
>& xListener
)
63 : m_xListener( xListener
),
64 m_bInteractionRequested( false ),
65 m_bInteractionDone( false ),
70 std::list
< Listener
> m_aListeners
;
71 SalSession
* m_pSession
;
73 bool m_bInteractionRequested
;
74 bool m_bInteractionGranted
;
75 bool m_bInteractionDone
;
78 static void SalSessionEventProc( SalSessionEvent
* pEvent
);
79 static VCLSession
* pOneInstance
;
81 void callSaveRequested( bool bShutdown
, bool bCancelable
);
82 void callShutdownCancelled();
83 void callInteractionGranted( bool bGranted
);
86 virtual ~VCLSession();
88 virtual void SAL_CALL
addSessionManagerListener( const Reference
< XSessionManagerListener
>& xListener
) throw( RuntimeException
);
89 virtual void SAL_CALL
removeSessionManagerListener( const Reference
< XSessionManagerListener
>& xListener
) throw( RuntimeException
);
90 virtual void SAL_CALL
queryInteraction( const Reference
< XSessionManagerListener
>& xListener
) throw( RuntimeException
);
91 virtual void SAL_CALL
interactionDone( const Reference
< XSessionManagerListener
>& xListener
, sal_Bool bCancelShutdown
) throw( RuntimeException
);
92 virtual void SAL_CALL
saveDone( const Reference
< XSessionManagerListener
>& xListener
) throw( RuntimeException
);
95 VCLSession
* VCLSession::pOneInstance
= NULL
;
97 VCLSession::VCLSession()
98 : cppu::WeakComponentImplHelper1
< XSessionManagerClient
>( m_aMutex
),
99 m_bInteractionRequested( false ),
100 m_bInteractionGranted( false ),
101 m_bInteractionDone( false ),
104 DBG_ASSERT( pOneInstance
== 0, "One instance of VCLSession only !" );
106 m_pSession
= ImplGetSVData()->mpDefInst
->CreateSalSession();
108 m_pSession
->SetCallback( SalSessionEventProc
);
111 VCLSession::~VCLSession()
113 DBG_ASSERT( pOneInstance
== this, "Another instance of VCLSession in destructor !" );
118 void VCLSession::callSaveRequested( bool bShutdown
, bool bCancelable
)
120 std::list
< Listener
> aListeners
;
122 osl::MutexGuard
aGuard( m_aMutex
);
123 // reset listener states
124 for( std::list
< Listener
>::iterator it
= m_aListeners
.begin();
125 it
!= m_aListeners
.end(); ++it
)
127 it
->m_bSaveDone
= it
->m_bInteractionRequested
= it
->m_bInteractionDone
= false;
130 // copy listener list since calling a listener may remove it.
131 aListeners
= m_aListeners
;
132 // set back interaction state
134 m_bInteractionDone
= false;
135 // without session we assume UI is always possible,
136 // so it was reqeusted and granted
137 m_bInteractionRequested
= m_bInteractionGranted
= m_pSession
? false : true;
139 // answer the session manager even if no listeners available anymore
140 DBG_ASSERT( ! aListeners
.empty(), "saveRequested but no listeners !" );
141 if( aListeners
.empty() )
144 m_pSession
->saveDone();
149 ULONG nAcquireCount
= Application::ReleaseSolarMutex();
150 for( std::list
< Listener
>::const_iterator it
= aListeners
.begin(); it
!= aListeners
.end(); ++it
)
151 it
->m_xListener
->doSave( bShutdown
, bCancelable
);
152 Application::AcquireSolarMutex( nAcquireCount
);
155 void VCLSession::callInteractionGranted( bool bInteractionGranted
)
157 std::list
< Listener
> aListeners
;
159 osl::MutexGuard
aGuard( m_aMutex
);
160 // copy listener list since calling a listener may remove it.
161 for( std::list
< Listener
>::const_iterator it
= m_aListeners
.begin(); it
!= m_aListeners
.end(); ++it
)
162 if( it
->m_bInteractionRequested
)
163 aListeners
.push_back( *it
);
165 m_bInteractionGranted
= bInteractionGranted
;
167 // answer the session manager even if no listeners available anymore
168 DBG_ASSERT( ! aListeners
.empty(), "interactionGranted but no listeners !" );
169 if( aListeners
.empty() )
172 m_pSession
->interactionDone( false );
177 ULONG nAcquireCount
= Application::ReleaseSolarMutex();
178 for( std::list
< Listener
>::const_iterator it
= aListeners
.begin(); it
!= aListeners
.end(); ++it
)
179 it
->m_xListener
->approveInteraction( bInteractionGranted
);
181 Application::AcquireSolarMutex( nAcquireCount
);
184 void VCLSession::callShutdownCancelled()
186 std::list
< Listener
> aListeners
;
188 osl::MutexGuard
aGuard( m_aMutex
);
189 // copy listener list since calling a listener may remove it.
190 aListeners
= m_aListeners
;
191 // set back interaction state
192 m_bInteractionRequested
= m_bInteractionDone
= m_bInteractionGranted
= false;
195 ULONG nAcquireCount
= Application::ReleaseSolarMutex();
196 for( std::list
< Listener
>::const_iterator it
= aListeners
.begin(); it
!= aListeners
.end(); ++it
)
197 it
->m_xListener
->shutdownCanceled();
198 Application::AcquireSolarMutex( nAcquireCount
);
201 void VCLSession::SalSessionEventProc( SalSessionEvent
* pEvent
)
203 switch( pEvent
->m_eType
)
207 SalSessionInteractionEvent
* pIEv
= static_cast<SalSessionInteractionEvent
*>(pEvent
);
208 pOneInstance
->callInteractionGranted( pIEv
->m_bInteractionGranted
);
213 SalSessionSaveRequestEvent
* pSEv
= static_cast<SalSessionSaveRequestEvent
*>(pEvent
);
214 pOneInstance
->callSaveRequested( pSEv
->m_bShutdown
, pSEv
->m_bCancelable
);
218 pOneInstance
->callShutdownCancelled();
223 void SAL_CALL
VCLSession::addSessionManagerListener( const Reference
<XSessionManagerListener
>& xListener
) throw( RuntimeException
)
225 osl::MutexGuard
aGuard( m_aMutex
);
227 m_aListeners
.push_back( Listener( xListener
) );
230 void SAL_CALL
VCLSession::removeSessionManagerListener( const Reference
<XSessionManagerListener
>& xListener
) throw( RuntimeException
)
232 osl::MutexGuard
aGuard( m_aMutex
);
234 std::list
< Listener
>::iterator it
= m_aListeners
.begin();
235 while( it
!= m_aListeners
.end() )
237 if( it
->m_xListener
== xListener
)
239 m_aListeners
.erase( it
);
240 it
= m_aListeners
.begin();
247 void SAL_CALL
VCLSession::queryInteraction( const Reference
<XSessionManagerListener
>& xListener
) throw( RuntimeException
)
249 if( m_bInteractionGranted
)
251 if( m_bInteractionDone
)
252 xListener
->approveInteraction( false );
254 xListener
->approveInteraction( true );
258 osl::MutexGuard
aGuard( m_aMutex
);
259 if( ! m_bInteractionRequested
)
261 m_pSession
->queryInteraction();
262 m_bInteractionRequested
= true;
264 for( std::list
< Listener
>::iterator it
= m_aListeners
.begin(); it
!= m_aListeners
.end(); ++it
)
266 if( it
->m_xListener
== xListener
)
268 it
->m_bInteractionRequested
= true;
269 it
->m_bInteractionDone
= false;
274 void SAL_CALL
VCLSession::interactionDone( const Reference
< XSessionManagerListener
>& xListener
, sal_Bool bCancelShutdown
) throw( RuntimeException
)
276 osl::MutexGuard
aGuard( m_aMutex
);
277 int nRequested
= 0, nDone
= 0;
278 for( std::list
< Listener
>::iterator it
= m_aListeners
.begin(); it
!= m_aListeners
.end(); ++it
)
280 if( it
->m_bInteractionRequested
)
283 if( xListener
== it
->m_xListener
)
284 it
->m_bInteractionDone
= true;
286 if( it
->m_bInteractionDone
)
289 if( nDone
== nRequested
&& nDone
> 0 )
291 m_bInteractionDone
= true;
293 m_pSession
->interactionDone( bCancelShutdown
);
297 void SAL_CALL
VCLSession::saveDone( const Reference
< XSessionManagerListener
>& xListener
) throw( RuntimeException
)
299 osl::MutexGuard
aGuard( m_aMutex
);
301 bool bSaveDone
= true;
302 for( std::list
< Listener
>::iterator it
= m_aListeners
.begin();
303 it
!= m_aListeners
.end(); ++it
)
305 if( it
->m_xListener
== xListener
)
306 it
->m_bSaveDone
= true;
307 if( ! it
->m_bSaveDone
)
314 m_pSession
->saveDone();
318 // service implementation
320 OUString SAL_CALL
vcl_session_getImplementationName()
322 static OUString
aImplementationName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.VCLSessionManagerClient" ) );
323 return aImplementationName
;
326 Sequence
< rtl::OUString
> SAL_CALL
vcl_session_getSupportedServiceNames()
328 Sequence
< OUString
> aRet(1);
329 aRet
[0] = OUString::createFromAscii("com.sun.star.frame.SessionManagerClient");
333 Reference
< XInterface
> SAL_CALL
vcl_session_createInstance( const Reference
< XMultiServiceFactory
> & /*xMultiServiceFactory*/ )
335 ImplSVData
* pSVData
= ImplGetSVData();
336 if( ! pSVData
->xSMClient
.is() )
337 pSVData
->xSMClient
= new VCLSession();
339 return Reference
< XInterface
>(pSVData
->xSMClient
, UNO_QUERY
);