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