update dev300-m58
[ooovba.git] / vcl / source / app / session.cxx
blob7c1f14a9e7d395a9bbe8d4c31fcd2f16fe2f7cec
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: session.cxx,v $
10 * $Revision: 1.11 $
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>
42 #include <list>
44 using namespace com::sun::star::uno;
45 using namespace com::sun::star::lang;
46 using namespace com::sun::star::frame;
47 using namespace rtl;
49 SalSession::~SalSession()
53 class VCLSession : public cppu::WeakComponentImplHelper1 < XSessionManagerClient >
55 struct Listener
57 Reference< XSessionManagerListener > m_xListener;
58 bool m_bInteractionRequested;
59 bool m_bInteractionDone;
60 bool m_bSaveDone;
62 Listener( const Reference< XSessionManagerListener >& xListener )
63 : m_xListener( xListener ),
64 m_bInteractionRequested( false ),
65 m_bInteractionDone( false ),
66 m_bSaveDone( false )
70 std::list< Listener > m_aListeners;
71 SalSession* m_pSession;
72 osl::Mutex m_aMutex;
73 bool m_bInteractionRequested;
74 bool m_bInteractionGranted;
75 bool m_bInteractionDone;
76 bool m_bSaveDone;
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 );
84 public:
85 VCLSession();
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 ),
102 m_bSaveDone( false )
104 DBG_ASSERT( pOneInstance == 0, "One instance of VCLSession only !" );
105 pOneInstance = this;
106 m_pSession = ImplGetSVData()->mpDefInst->CreateSalSession();
107 if( m_pSession )
108 m_pSession->SetCallback( SalSessionEventProc );
111 VCLSession::~VCLSession()
113 DBG_ASSERT( pOneInstance == this, "Another instance of VCLSession in destructor !" );
114 pOneInstance = NULL;
115 delete m_pSession;
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
133 m_bSaveDone = false;
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() )
143 if( m_pSession )
144 m_pSession->saveDone();
145 return;
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() )
171 if( m_pSession )
172 m_pSession->interactionDone( false );
173 return;
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 )
205 case Interaction:
207 SalSessionInteractionEvent* pIEv = static_cast<SalSessionInteractionEvent*>(pEvent);
208 pOneInstance->callInteractionGranted( pIEv->m_bInteractionGranted );
210 break;
211 case SaveRequest:
213 SalSessionSaveRequestEvent* pSEv = static_cast<SalSessionSaveRequestEvent*>(pEvent);
214 pOneInstance->callSaveRequested( pSEv->m_bShutdown, pSEv->m_bCancelable );
216 break;
217 case ShutdownCancel:
218 pOneInstance->callShutdownCancelled();
219 break;
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();
242 else
243 ++it;
247 void SAL_CALL VCLSession::queryInteraction( const Reference<XSessionManagerListener>& xListener ) throw( RuntimeException )
249 if( m_bInteractionGranted )
251 if( m_bInteractionDone )
252 xListener->approveInteraction( false );
253 else
254 xListener->approveInteraction( true );
255 return;
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 )
282 nRequested++;
283 if( xListener == it->m_xListener )
284 it->m_bInteractionDone = true;
286 if( it->m_bInteractionDone )
287 nDone++;
289 if( nDone == nRequested && nDone > 0 )
291 m_bInteractionDone = true;
292 if( m_pSession )
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 )
308 bSaveDone = false;
310 if( bSaveDone )
312 m_bSaveDone = true;
313 if( m_pSession )
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");
330 return aRet;
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 );