Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include "sal/config.h"
30 : :
31 : : #include <boost/scoped_ptr.hpp>
32 : : #include <cppuhelper/compbase1.hxx>
33 : :
34 : : #include <tools/debug.hxx>
35 : :
36 : : #include <vcl/svapp.hxx>
37 : :
38 : : #include <svdata.hxx>
39 : : #include <salinst.hxx>
40 : : #include <salsession.hxx>
41 : :
42 : : #include <com/sun/star/frame/XSessionManagerClient.hpp>
43 : : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
44 : : #include <com/sun/star/frame/XSessionManagerListener2.hpp>
45 : :
46 : : #include <list>
47 : :
48 : : namespace {
49 : :
50 : : namespace css = com::sun::star;
51 : :
52 : : }
53 : :
54 : : using namespace com::sun::star::uno;
55 : : using namespace com::sun::star::lang;
56 : : using namespace com::sun::star::frame;
57 : :
58 : : using ::rtl::OUString;
59 : :
60 : 0 : SalSession::~SalSession()
61 : : {
62 [ # # ]: 0 : }
63 : :
64 : : class VCLSession:
65 : : private osl::Mutex,
66 : : public cppu::WeakComponentImplHelper1 < XSessionManagerClient >
67 : : {
68 : 0 : struct Listener
69 : : {
70 : : css::uno::Reference< XSessionManagerListener > m_xListener;
71 : : bool m_bInteractionRequested;
72 : : bool m_bInteractionDone;
73 : : bool m_bSaveDone;
74 : :
75 : 0 : Listener( const css::uno::Reference< XSessionManagerListener >& xListener )
76 : : : m_xListener( xListener ),
77 : : m_bInteractionRequested( false ),
78 : : m_bInteractionDone( false ),
79 : 0 : m_bSaveDone( false )
80 : 0 : {}
81 : : };
82 : :
83 : : std::list< Listener > m_aListeners;
84 : : boost::scoped_ptr< SalSession > m_pSession;
85 : : bool m_bInteractionRequested;
86 : : bool m_bInteractionGranted;
87 : : bool m_bInteractionDone;
88 : : bool m_bSaveDone;
89 : :
90 : : static void SalSessionEventProc( void* pData, SalSessionEvent* pEvent );
91 : :
92 [ # # ][ # # ]: 0 : virtual ~VCLSession() {}
[ # # ]
93 : :
94 : : virtual void SAL_CALL addSessionManagerListener( const css::uno::Reference< XSessionManagerListener >& xListener ) throw( RuntimeException );
95 : : virtual void SAL_CALL removeSessionManagerListener( const css::uno::Reference< XSessionManagerListener>& xListener ) throw( RuntimeException );
96 : : virtual void SAL_CALL queryInteraction( const css::uno::Reference< XSessionManagerListener >& xListener ) throw( RuntimeException );
97 : : virtual void SAL_CALL interactionDone( const css::uno::Reference< XSessionManagerListener >& xListener ) throw( RuntimeException );
98 : : virtual void SAL_CALL saveDone( const css::uno::Reference< XSessionManagerListener >& xListener ) throw( RuntimeException );
99 : : virtual sal_Bool SAL_CALL cancelShutdown() throw( RuntimeException );
100 : :
101 : : void callSaveRequested( bool bShutdown, bool bCancelable );
102 : : void callShutdownCancelled();
103 : : void callInteractionGranted( bool bGranted );
104 : : void callQuit();
105 : :
106 : : public:
107 : : VCLSession();
108 : : };
109 : :
110 : 0 : VCLSession::VCLSession()
111 : : : cppu::WeakComponentImplHelper1< XSessionManagerClient >( *static_cast< osl::Mutex * >(this) ),
112 [ # # ]: 0 : m_pSession( ImplGetSVData()->mpDefInst->CreateSalSession() ),
113 : : m_bInteractionRequested( false ),
114 : : m_bInteractionGranted( false ),
115 : : m_bInteractionDone( false ),
116 [ # # ][ # # ]: 0 : m_bSaveDone( false )
117 : : {
118 [ # # ]: 0 : if( m_pSession )
119 : 0 : m_pSession->SetCallback( SalSessionEventProc, this );
120 : 0 : }
121 : :
122 : 0 : void VCLSession::callSaveRequested( bool bShutdown, bool bCancelable )
123 : : {
124 [ # # ]: 0 : std::list< Listener > aListeners;
125 : : {
126 [ # # ]: 0 : osl::MutexGuard aGuard( *this );
127 : : // reset listener states
128 [ # # ]: 0 : for( std::list< Listener >::iterator it = m_aListeners.begin();
129 : 0 : it != m_aListeners.end(); ++it )
130 : : {
131 : 0 : it->m_bSaveDone = it->m_bInteractionRequested = it->m_bInteractionDone = false;
132 : : }
133 : :
134 : : // copy listener list since calling a listener may remove it.
135 [ # # ]: 0 : aListeners = m_aListeners;
136 : : // set back interaction state
137 : 0 : m_bSaveDone = false;
138 : 0 : m_bInteractionDone = false;
139 : : // without session we assume UI is always possible,
140 : : // so it was reqeusted and granted
141 : 0 : m_bInteractionRequested = m_bInteractionGranted = !m_pSession;
142 : :
143 : : // answer the session manager even if no listeners available anymore
144 : : DBG_ASSERT( ! aListeners.empty(), "saveRequested but no listeners !" );
145 [ # # ]: 0 : if( aListeners.empty() )
146 : : {
147 [ # # ]: 0 : if( m_pSession )
148 [ # # ]: 0 : m_pSession->saveDone();
149 : 0 : return;
150 [ # # ][ # # ]: 0 : }
151 : : }
152 : :
153 [ # # ]: 0 : sal_uLong nAcquireCount = Application::ReleaseSolarMutex();
154 [ # # ]: 0 : for( std::list< Listener >::const_iterator it = aListeners.begin(); it != aListeners.end(); ++it )
155 [ # # ][ # # ]: 0 : it->m_xListener->doSave( bShutdown, bCancelable );
156 [ # # ][ # # ]: 0 : Application::AcquireSolarMutex( nAcquireCount );
157 : : }
158 : :
159 : 0 : void VCLSession::callInteractionGranted( bool bInteractionGranted )
160 : : {
161 [ # # ]: 0 : std::list< Listener > aListeners;
162 : : {
163 [ # # ]: 0 : osl::MutexGuard aGuard( *this );
164 : : // copy listener list since calling a listener may remove it.
165 [ # # ]: 0 : for( std::list< Listener >::const_iterator it = m_aListeners.begin(); it != m_aListeners.end(); ++it )
166 [ # # ]: 0 : if( it->m_bInteractionRequested )
167 [ # # ]: 0 : aListeners.push_back( *it );
168 : :
169 : 0 : m_bInteractionGranted = bInteractionGranted;
170 : :
171 : : // answer the session manager even if no listeners available anymore
172 : : DBG_ASSERT( ! aListeners.empty(), "interactionGranted but no listeners !" );
173 [ # # ]: 0 : if( aListeners.empty() )
174 : : {
175 [ # # ]: 0 : if( m_pSession )
176 [ # # ]: 0 : m_pSession->interactionDone();
177 : 0 : return;
178 [ # # ][ # # ]: 0 : }
179 : : }
180 : :
181 [ # # ]: 0 : sal_uLong nAcquireCount = Application::ReleaseSolarMutex();
182 [ # # ]: 0 : for( std::list< Listener >::const_iterator it = aListeners.begin(); it != aListeners.end(); ++it )
183 [ # # ][ # # ]: 0 : it->m_xListener->approveInteraction( bInteractionGranted );
184 : :
185 [ # # ][ # # ]: 0 : Application::AcquireSolarMutex( nAcquireCount );
186 : : }
187 : :
188 : 0 : void VCLSession::callShutdownCancelled()
189 : : {
190 [ # # ]: 0 : std::list< Listener > aListeners;
191 : : {
192 [ # # ]: 0 : osl::MutexGuard aGuard( *this );
193 : : // copy listener list since calling a listener may remove it.
194 [ # # ]: 0 : aListeners = m_aListeners;
195 : : // set back interaction state
196 [ # # ]: 0 : m_bInteractionRequested = m_bInteractionDone = m_bInteractionGranted = false;
197 : : }
198 : :
199 [ # # ]: 0 : sal_uLong nAcquireCount = Application::ReleaseSolarMutex();
200 [ # # ]: 0 : for( std::list< Listener >::const_iterator it = aListeners.begin(); it != aListeners.end(); ++it )
201 [ # # ][ # # ]: 0 : it->m_xListener->shutdownCanceled();
202 [ # # ]: 0 : Application::AcquireSolarMutex( nAcquireCount );
203 : 0 : }
204 : :
205 : 0 : void VCLSession::callQuit()
206 : : {
207 [ # # ]: 0 : std::list< Listener > aListeners;
208 : : {
209 [ # # ]: 0 : osl::MutexGuard aGuard( *this );
210 : : // copy listener list since calling a listener may remove it.
211 [ # # ]: 0 : aListeners = m_aListeners;
212 : : // set back interaction state
213 [ # # ]: 0 : m_bInteractionRequested = m_bInteractionDone = m_bInteractionGranted = false;
214 : : }
215 : :
216 [ # # ]: 0 : sal_uLong nAcquireCount = Application::ReleaseSolarMutex();
217 [ # # ]: 0 : for( std::list< Listener >::const_iterator it = aListeners.begin(); it != aListeners.end(); ++it )
218 : : {
219 [ # # ]: 0 : css::uno::Reference< XSessionManagerListener2 > xListener2( it->m_xListener, UNO_QUERY );
220 [ # # ]: 0 : if( xListener2.is() )
221 [ # # ][ # # ]: 0 : xListener2->doQuit();
222 : 0 : }
223 [ # # ]: 0 : Application::AcquireSolarMutex( nAcquireCount );
224 : 0 : }
225 : :
226 : 0 : void VCLSession::SalSessionEventProc( void* pData, SalSessionEvent* pEvent )
227 : : {
228 : 0 : VCLSession * pThis = static_cast< VCLSession * >( pData );
229 [ # # # # : 0 : switch( pEvent->m_eType )
# ]
230 : : {
231 : : case Interaction:
232 : : {
233 : 0 : SalSessionInteractionEvent* pIEv = static_cast<SalSessionInteractionEvent*>(pEvent);
234 : 0 : pThis->callInteractionGranted( pIEv->m_bInteractionGranted );
235 : : }
236 : 0 : break;
237 : : case SaveRequest:
238 : : {
239 : 0 : SalSessionSaveRequestEvent* pSEv = static_cast<SalSessionSaveRequestEvent*>(pEvent);
240 : 0 : pThis->callSaveRequested( pSEv->m_bShutdown, pSEv->m_bCancelable );
241 : : }
242 : 0 : break;
243 : : case ShutdownCancel:
244 : 0 : pThis->callShutdownCancelled();
245 : 0 : break;
246 : : case Quit:
247 : 0 : pThis->callQuit();
248 : 0 : break;
249 : : }
250 : 0 : }
251 : :
252 : 0 : void SAL_CALL VCLSession::addSessionManagerListener( const css::uno::Reference<XSessionManagerListener>& xListener ) throw( RuntimeException )
253 : : {
254 [ # # ]: 0 : osl::MutexGuard aGuard( *this );
255 : :
256 [ # # ][ # # ]: 0 : m_aListeners.push_back( Listener( xListener ) );
[ # # ][ # # ]
257 : 0 : }
258 : :
259 : 0 : void SAL_CALL VCLSession::removeSessionManagerListener( const css::uno::Reference<XSessionManagerListener>& xListener ) throw( RuntimeException )
260 : : {
261 [ # # ]: 0 : osl::MutexGuard aGuard( *this );
262 : :
263 : 0 : std::list< Listener >::iterator it = m_aListeners.begin();
264 [ # # ]: 0 : while( it != m_aListeners.end() )
265 : : {
266 [ # # ][ # # ]: 0 : if( it->m_xListener == xListener )
267 : : {
268 [ # # ]: 0 : m_aListeners.erase( it );
269 : 0 : it = m_aListeners.begin();
270 : : }
271 : : else
272 : 0 : ++it;
273 [ # # ]: 0 : }
274 : 0 : }
275 : :
276 : 0 : void SAL_CALL VCLSession::queryInteraction( const css::uno::Reference<XSessionManagerListener>& xListener ) throw( RuntimeException )
277 : : {
278 [ # # ]: 0 : if( m_bInteractionGranted )
279 : : {
280 [ # # ]: 0 : if( m_bInteractionDone )
281 [ # # ][ # # ]: 0 : xListener->approveInteraction( false );
282 : : else
283 [ # # ][ # # ]: 0 : xListener->approveInteraction( true );
284 : 0 : return;
285 : : }
286 : :
287 [ # # ]: 0 : osl::MutexGuard aGuard( *this );
288 [ # # ]: 0 : if( ! m_bInteractionRequested )
289 : : {
290 [ # # ]: 0 : m_pSession->queryInteraction();
291 : 0 : m_bInteractionRequested = true;
292 : : }
293 [ # # ]: 0 : for( std::list< Listener >::iterator it = m_aListeners.begin(); it != m_aListeners.end(); ++it )
294 : : {
295 [ # # ][ # # ]: 0 : if( it->m_xListener == xListener )
296 : : {
297 : 0 : it->m_bInteractionRequested = true;
298 : 0 : it->m_bInteractionDone = false;
299 : : }
300 [ # # ]: 0 : }
301 : : }
302 : :
303 : 0 : void SAL_CALL VCLSession::interactionDone( const css::uno::Reference< XSessionManagerListener >& xListener ) throw( RuntimeException )
304 : : {
305 [ # # ]: 0 : osl::MutexGuard aGuard( *this );
306 : 0 : int nRequested = 0, nDone = 0;
307 [ # # ]: 0 : for( std::list< Listener >::iterator it = m_aListeners.begin(); it != m_aListeners.end(); ++it )
308 : : {
309 [ # # ]: 0 : if( it->m_bInteractionRequested )
310 : : {
311 : 0 : nRequested++;
312 [ # # ][ # # ]: 0 : if( xListener == it->m_xListener )
313 : 0 : it->m_bInteractionDone = true;
314 : : }
315 [ # # ]: 0 : if( it->m_bInteractionDone )
316 : 0 : nDone++;
317 : : }
318 [ # # ][ # # ]: 0 : if( nDone == nRequested && nDone > 0 )
319 : : {
320 : 0 : m_bInteractionDone = true;
321 [ # # ]: 0 : if( m_pSession )
322 [ # # ]: 0 : m_pSession->interactionDone();
323 [ # # ]: 0 : }
324 : 0 : }
325 : :
326 : 0 : void SAL_CALL VCLSession::saveDone( const css::uno::Reference< XSessionManagerListener >& xListener ) throw( RuntimeException )
327 : : {
328 [ # # ]: 0 : osl::MutexGuard aGuard( *this );
329 : :
330 : 0 : bool bSaveDone = true;
331 [ # # ]: 0 : for( std::list< Listener >::iterator it = m_aListeners.begin();
332 : 0 : it != m_aListeners.end(); ++it )
333 : : {
334 [ # # ][ # # ]: 0 : if( it->m_xListener == xListener )
335 : 0 : it->m_bSaveDone = true;
336 [ # # ]: 0 : if( ! it->m_bSaveDone )
337 : 0 : bSaveDone = false;
338 : : }
339 [ # # ]: 0 : if( bSaveDone )
340 : : {
341 : 0 : m_bSaveDone = true;
342 [ # # ]: 0 : if( m_pSession )
343 [ # # ]: 0 : m_pSession->saveDone();
344 [ # # ]: 0 : }
345 : 0 : }
346 : :
347 : 0 : sal_Bool SAL_CALL VCLSession::cancelShutdown() throw( RuntimeException )
348 : : {
349 [ # # ][ # # ]: 0 : return m_pSession && m_pSession->cancelShutdown();
350 : : }
351 : :
352 : : // service implementation
353 : :
354 : 248 : OUString SAL_CALL vcl_session_getImplementationName()
355 : : {
356 : 248 : return OUString( "com.sun.star.frame.VCLSessionManagerClient" );
357 : : }
358 : :
359 : 0 : Sequence< rtl::OUString > SAL_CALL vcl_session_getSupportedServiceNames()
360 : : {
361 : 0 : Sequence< OUString > aRet(1);
362 [ # # ]: 0 : aRet[0] = "com.sun.star.frame.SessionManagerClient";
363 : 0 : return aRet;
364 : : }
365 : :
366 : 0 : css::uno::Reference< XInterface > SAL_CALL vcl_session_createInstance( SAL_UNUSED_PARAMETER const css::uno::Reference< XMultiServiceFactory > & )
367 : : {
368 [ # # ]: 0 : return static_cast< cppu::OWeakObject * >(new VCLSession);
369 : : }
370 : :
371 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|