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