Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*
3 : : * This file is part of the LibreOffice project.
4 : : *
5 : : * This Source Code Form is subject to the terms of the Mozilla Public
6 : : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : : *
9 : : * This file incorporates work covered by the following license notice:
10 : : *
11 : : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : : * contributor license agreements. See the NOTICE file distributed
13 : : * with this work for additional information regarding copyright
14 : : * ownership. The ASF licenses this file to you under the Apache
15 : : * License, Version 2.0 (the "License"); you may not use this file
16 : : * except in compliance with the License. You may obtain a copy of
17 : : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : : */
19 : :
20 : : #include <com/sun/star/util/XCloseBroadcaster.hpp>
21 : : #include <com/sun/star/util/XCloseable.hpp>
22 : : #include <com/sun/star/lang/DisposedException.hpp>
23 : : #include <com/sun/star/lang/IllegalArgumentException.hpp>
24 : : #include <com/sun/star/frame/DoubleInitializationException.hpp>
25 : : #include <com/sun/star/beans/XPropertySet.hpp>
26 : : #include <com/sun/star/awt/XVclWindowPeer.hpp>
27 : :
28 : : #include <osl/mutex.hxx>
29 : : #include <vcl/svapp.hxx>
30 : : #include <vcl/dialog.hxx>
31 : : #include <tools/link.hxx>
32 : : #include <toolkit/helper/vclunohelper.hxx>
33 : :
34 : : #include "documentcloser.hxx"
35 : :
36 : : using namespace ::com::sun::star;
37 : :
38 : :
39 : : // ====================================================================
40 : : // MainThreadFrameCloserRequest
41 : : // ====================================================================
42 : :
43 : 0 : class MainThreadFrameCloserRequest
44 : : {
45 : : uno::Reference< frame::XFrame > m_xFrame;
46 : :
47 : : public:
48 : 0 : MainThreadFrameCloserRequest( const uno::Reference< frame::XFrame >& xFrame )
49 : 0 : : m_xFrame( xFrame )
50 : 0 : {}
51 : :
52 : : DECL_STATIC_LINK( MainThreadFrameCloserRequest, worker, MainThreadFrameCloserRequest* );
53 : :
54 : : static void Start( MainThreadFrameCloserRequest* pRequest );
55 : : };
56 : :
57 : : // --------------------------------------------------------
58 : 0 : void MainThreadFrameCloserRequest::Start( MainThreadFrameCloserRequest* pMTRequest )
59 : : {
60 [ # # ]: 0 : if ( pMTRequest )
61 : : {
62 [ # # ]: 0 : if ( Application::GetMainThreadIdentifier() == osl_getThreadIdentifier( NULL ) )
63 : : {
64 : : // this is the main thread
65 : 0 : worker( NULL, pMTRequest );
66 : : }
67 : : else
68 [ # # ]: 0 : Application::PostUserEvent( STATIC_LINK( NULL, MainThreadFrameCloserRequest, worker ), pMTRequest );
69 : : }
70 : 0 : }
71 : :
72 : : // --------------------------------------------------------
73 : 0 : IMPL_STATIC_LINK( MainThreadFrameCloserRequest, worker, MainThreadFrameCloserRequest*, pMTRequest )
74 : : {
75 : : (void) pThis; // unused
76 [ # # ]: 0 : if ( pMTRequest )
77 : : {
78 [ # # ]: 0 : if ( pMTRequest->m_xFrame.is() )
79 : : {
80 : : // this is the main thread, the solar mutex must be locked
81 [ # # ]: 0 : SolarMutexGuard aGuard;
82 : :
83 : : try
84 : : {
85 [ # # ][ # # ]: 0 : uno::Reference< awt::XWindow > xWindow = pMTRequest->m_xFrame->getContainerWindow();
86 [ # # ]: 0 : uno::Reference< awt::XVclWindowPeer > xWinPeer( xWindow, uno::UNO_QUERY_THROW );
87 : :
88 [ # # ][ # # ]: 0 : xWindow->setVisible( sal_False );
89 : :
90 : : // reparent the window
91 [ # # ]: 0 : xWinPeer->setProperty( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PluginParent" ) ),
92 [ # # ][ # # ]: 0 : uno::makeAny( (sal_Int64) 0 ) );
[ # # ]
93 : :
94 [ # # ]: 0 : Window* pWindow = VCLUnoHelper::GetWindow( xWindow );
95 [ # # ]: 0 : if ( pWindow )
96 [ # # ][ # # ]: 0 : Dialog::EndAllDialogs( pWindow );
97 : : }
98 [ # # ]: 0 : catch( uno::Exception& )
99 : : {
100 : : // ignore all the errors
101 : : }
102 : :
103 : : try
104 : : {
105 [ # # ]: 0 : uno::Reference< util::XCloseable > xCloseable( pMTRequest->m_xFrame, uno::UNO_QUERY_THROW );
106 [ # # ][ # # ]: 0 : xCloseable->close( sal_True );
[ # # ]
107 : : }
108 [ # # ]: 0 : catch( uno::Exception& )
109 : : {
110 : : // ignore all the errors
111 [ # # ]: 0 : }
112 : : }
113 : :
114 [ # # ]: 0 : delete pMTRequest;
115 : : }
116 : :
117 : 0 : return 0;
118 : : }
119 : :
120 : :
121 : : // ====================================================================
122 : : // ODocumentCloser
123 : : // ====================================================================
124 : :
125 : : // --------------------------------------------------------
126 : 0 : ODocumentCloser::ODocumentCloser( const uno::Reference< uno::XComponentContext >& xContext )
127 : : : m_xContext( xContext )
128 : : , m_pListenersContainer( NULL )
129 : : , m_bDisposed( sal_False )
130 [ # # ]: 0 : , m_bInitialized( sal_False )
131 : : {
132 : 0 : }
133 : :
134 : : // --------------------------------------------------------
135 [ # # ]: 0 : ODocumentCloser::~ODocumentCloser()
136 : : {
137 [ # # ]: 0 : if ( m_pListenersContainer )
138 : : {
139 [ # # ][ # # ]: 0 : delete m_pListenersContainer;
140 : 0 : m_pListenersContainer = NULL;
141 : : }
142 [ # # ]: 0 : }
143 : :
144 : : // XComponent
145 : : // --------------------------------------------------------
146 : 0 : void SAL_CALL ODocumentCloser::dispose()
147 : : throw (uno::RuntimeException)
148 : : {
149 [ # # ]: 0 : ::osl::MutexGuard aGuard( m_aMutex );
150 : :
151 [ # # ]: 0 : if ( m_bDisposed )
152 [ # # ]: 0 : throw lang::DisposedException();
153 : :
154 [ # # ][ # # ]: 0 : lang::EventObject aSource( static_cast< ::cppu::OWeakObject* >(this) );
155 [ # # ]: 0 : if ( m_pListenersContainer )
156 [ # # ]: 0 : m_pListenersContainer->disposeAndClear( aSource );
157 : :
158 : : // TODO: trigger a main thread execution to close the frame
159 [ # # ]: 0 : if ( m_xFrame.is() )
160 : : {
161 : : // the created object will be deleted after thread execution
162 [ # # ][ # # ]: 0 : MainThreadFrameCloserRequest* pCloser = new MainThreadFrameCloserRequest( m_xFrame );
163 [ # # ]: 0 : MainThreadFrameCloserRequest::Start( pCloser );
164 : : }
165 : :
166 [ # # ][ # # ]: 0 : m_bDisposed = sal_True;
167 : 0 : }
168 : :
169 : : // --------------------------------------------------------
170 : 0 : void SAL_CALL ODocumentCloser::addEventListener( const uno::Reference< lang::XEventListener >& xListener )
171 : : throw (uno::RuntimeException)
172 : : {
173 [ # # ]: 0 : ::osl::MutexGuard aGuard( m_aMutex );
174 [ # # ]: 0 : if ( m_bDisposed )
175 [ # # ]: 0 : throw lang::DisposedException(); // TODO
176 : :
177 [ # # ]: 0 : if ( !m_pListenersContainer )
178 [ # # ]: 0 : m_pListenersContainer = new ::cppu::OInterfaceContainerHelper( m_aMutex );
179 : :
180 [ # # ][ # # ]: 0 : m_pListenersContainer->addInterface( xListener );
181 : 0 : }
182 : :
183 : : // --------------------------------------------------------
184 : 0 : void SAL_CALL ODocumentCloser::removeEventListener( const uno::Reference< lang::XEventListener >& xListener )
185 : : throw (uno::RuntimeException)
186 : : {
187 [ # # ]: 0 : ::osl::MutexGuard aGuard( m_aMutex );
188 [ # # ]: 0 : if ( m_pListenersContainer )
189 [ # # ][ # # ]: 0 : m_pListenersContainer->removeInterface( xListener );
190 : 0 : }
191 : :
192 : : // XInitialization
193 : : // --------------------------------------------------------
194 : 0 : void SAL_CALL ODocumentCloser::initialize( const uno::Sequence< uno::Any >& aArguments )
195 : : throw (uno::Exception, uno::RuntimeException)
196 : : {
197 [ # # ]: 0 : ::osl::MutexGuard aGuard( m_aMutex );
198 [ # # ]: 0 : if ( m_bInitialized )
199 [ # # ]: 0 : throw frame::DoubleInitializationException();
200 : :
201 [ # # ]: 0 : if ( m_bDisposed )
202 [ # # ]: 0 : throw lang::DisposedException(); // TODO
203 : :
204 [ # # ]: 0 : if ( !m_refCount )
205 [ # # ]: 0 : throw uno::RuntimeException(); // the object must be refcounted already!
206 : :
207 : 0 : sal_Int32 nLen = aArguments.getLength();
208 [ # # ]: 0 : if ( nLen != 1 )
209 : : throw lang::IllegalArgumentException(
210 : : ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Wrong count of parameters!" ) ),
211 : : uno::Reference< uno::XInterface >(),
212 [ # # ][ # # ]: 0 : 0 );
213 : :
214 [ # # ][ # # ]: 0 : if ( !( aArguments[0] >>= m_xFrame ) || !m_xFrame.is() )
[ # # ][ # # ]
215 : : throw lang::IllegalArgumentException(
216 : : ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Nonempty reference is expected as the first argument!" ) ),
217 : : uno::Reference< uno::XInterface >(),
218 [ # # ][ # # ]: 0 : 0 );
219 : :
220 [ # # ]: 0 : m_bInitialized = sal_True;
221 : 0 : }
222 : :
223 : :
224 : : // XServiceInfo
225 : : // --------------------------------------------------------
226 : 0 : ::rtl::OUString SAL_CALL ODocumentCloser::getImplementationName( )
227 : : throw (uno::RuntimeException)
228 : : {
229 : 0 : return impl_staticGetImplementationName();
230 : : }
231 : :
232 : : // --------------------------------------------------------
233 : 0 : ::sal_Bool SAL_CALL ODocumentCloser::supportsService( const ::rtl::OUString& ServiceName )
234 : : throw (uno::RuntimeException)
235 : : {
236 [ # # ]: 0 : uno::Sequence< ::rtl::OUString > aSeq = impl_staticGetSupportedServiceNames();
237 : :
238 [ # # ]: 0 : for ( sal_Int32 nInd = 0; nInd < aSeq.getLength(); nInd++ )
239 [ # # ][ # # ]: 0 : if ( ServiceName.compareTo( aSeq[nInd] ) == 0 )
240 : 0 : return sal_True;
241 : :
242 [ # # ]: 0 : return sal_False;
243 : : }
244 : :
245 : : // --------------------------------------------------------
246 : 0 : uno::Sequence< ::rtl::OUString > SAL_CALL ODocumentCloser::getSupportedServiceNames()
247 : : throw (uno::RuntimeException)
248 : : {
249 : 0 : return impl_staticGetSupportedServiceNames();
250 : : }
251 : :
252 : : // Static methods
253 : : // --------------------------------------------------------
254 : 0 : uno::Sequence< ::rtl::OUString > SAL_CALL ODocumentCloser::impl_staticGetSupportedServiceNames()
255 : : {
256 [ # # ]: 0 : const rtl::OUString aServiceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.embed.DocumentCloser" ) );
257 [ # # ]: 0 : return uno::Sequence< rtl::OUString >( &aServiceName, 1 );
258 : : }
259 : :
260 : : // --------------------------------------------------------
261 : 0 : ::rtl::OUString SAL_CALL ODocumentCloser::impl_staticGetImplementationName()
262 : : {
263 : 0 : return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.embed.DocumentCloser" ) );
264 : : }
265 : :
266 : : // --------------------------------------------------------
267 : 0 : uno::Reference< uno::XInterface > SAL_CALL ODocumentCloser::impl_staticCreateSelfInstance(
268 : : const uno::Reference< lang::XMultiServiceFactory >& xServiceManager )
269 : : {
270 : 0 : uno::Reference< uno::XComponentContext > xContext;
271 [ # # ]: 0 : uno::Reference< beans::XPropertySet > xPropSet( xServiceManager, uno::UNO_QUERY );
272 [ # # ]: 0 : if ( xPropSet.is() )
273 [ # # ][ # # ]: 0 : xPropSet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ) ) ) >>= xContext;
[ # # ][ # # ]
274 : :
275 [ # # ]: 0 : if ( !xContext.is() )
276 : : {
277 : : throw uno::RuntimeException(
278 : : rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Unable to obtain component context from service manager!" ) ),
279 [ # # ][ # # ]: 0 : uno::Reference< uno::XInterface >() );
280 : : }
281 : :
282 [ # # ][ # # ]: 0 : return static_cast< cppu::OWeakObject * >( new ODocumentCloser( xContext ) );
283 : : }
284 : :
285 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|