1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: documentcloser.cxx,v $
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_svtools.hxx"
33 #include <com/sun/star/util/XCloseBroadcaster.hpp>
34 #include <com/sun/star/util/XCloseable.hpp>
35 #include <com/sun/star/lang/DisposedException.hpp>
36 #include <com/sun/star/lang/IllegalArgumentException.hpp>
37 #include <com/sun/star/frame/DoubleInitializationException.hpp>
38 #include <com/sun/star/frame/DoubleInitializationException.hpp>
39 #include <com/sun/star/beans/XPropertySet.hpp>
40 #include <com/sun/star/awt/XVclWindowPeer.hpp>
42 #include <vos/mutex.hxx>
43 #include <vcl/svapp.hxx>
44 #include <vcl/dialog.hxx>
45 #include <tools/link.hxx>
46 #include <toolkit/helper/vclunohelper.hxx>
48 #include "documentcloser.hxx"
50 using namespace ::com::sun::star
;
53 // ====================================================================
54 // MainThreadFrameCloserRequest
55 // ====================================================================
57 class MainThreadFrameCloserRequest
59 uno::Reference
< frame::XFrame
> m_xFrame
;
62 MainThreadFrameCloserRequest( const uno::Reference
< frame::XFrame
>& xFrame
)
66 DECL_STATIC_LINK( MainThreadFrameCloserRequest
, worker
, MainThreadFrameCloserRequest
* );
68 static void Start( MainThreadFrameCloserRequest
* pRequest
);
71 // --------------------------------------------------------
72 void MainThreadFrameCloserRequest::Start( MainThreadFrameCloserRequest
* pMTRequest
)
76 if ( Application::GetMainThreadIdentifier() == osl_getThreadIdentifier( NULL
) )
78 // this is the main thread
79 worker( NULL
, pMTRequest
);
82 Application::PostUserEvent( STATIC_LINK( NULL
, MainThreadFrameCloserRequest
, worker
), pMTRequest
);
86 // --------------------------------------------------------
87 IMPL_STATIC_LINK( MainThreadFrameCloserRequest
, worker
, MainThreadFrameCloserRequest
*, pMTRequest
)
89 (void) pThis
; // unused
92 if ( pMTRequest
->m_xFrame
.is() )
94 // this is the main thread, the solar mutex must be locked
95 ::vos::OGuard
aGuard( Application::GetSolarMutex() );
99 uno::Reference
< awt::XWindow
> xWindow
= pMTRequest
->m_xFrame
->getContainerWindow();
100 uno::Reference
< awt::XVclWindowPeer
> xWinPeer( xWindow
, uno::UNO_QUERY_THROW
);
102 xWindow
->setVisible( sal_False
);
104 // reparent the window
105 xWinPeer
->setProperty( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PluginParent" ) ),
106 uno::makeAny( (sal_Int64
) 0 ) );
108 Window
* pWindow
= VCLUnoHelper::GetWindow( xWindow
);
110 Dialog::EndAllDialogs( pWindow
);
112 catch( uno::Exception
& )
114 // ignore all the errors
119 uno::Reference
< util::XCloseable
> xCloseable( pMTRequest
->m_xFrame
, uno::UNO_QUERY_THROW
);
120 xCloseable
->close( sal_True
);
122 catch( uno::Exception
& )
124 // ignore all the errors
135 // ====================================================================
137 // ====================================================================
139 // --------------------------------------------------------
140 ODocumentCloser::ODocumentCloser( const uno::Reference
< uno::XComponentContext
>& xContext
)
141 : m_xContext( xContext
)
142 , m_pListenersContainer( NULL
)
143 , m_bDisposed( sal_False
)
144 , m_bInitialized( sal_False
)
148 // --------------------------------------------------------
149 ODocumentCloser::~ODocumentCloser()
151 if ( m_pListenersContainer
)
153 delete m_pListenersContainer
;
154 m_pListenersContainer
= NULL
;
159 // --------------------------------------------------------
160 void SAL_CALL
ODocumentCloser::dispose()
161 throw (uno::RuntimeException
)
163 ::osl::MutexGuard
aGuard( m_aMutex
);
166 throw lang::DisposedException();
168 lang::EventObject
aSource( static_cast< ::cppu::OWeakObject
* >(this) );
169 if ( m_pListenersContainer
)
170 m_pListenersContainer
->disposeAndClear( aSource
);
172 // TODO: trigger a main thread execution to close the frame
175 // the created object will be deleted after thread execution
176 MainThreadFrameCloserRequest
* pCloser
= new MainThreadFrameCloserRequest( m_xFrame
);
177 MainThreadFrameCloserRequest::Start( pCloser
);
180 m_bDisposed
= sal_True
;
183 // --------------------------------------------------------
184 void SAL_CALL
ODocumentCloser::addEventListener( const uno::Reference
< lang::XEventListener
>& xListener
)
185 throw (uno::RuntimeException
)
187 ::osl::MutexGuard
aGuard( m_aMutex
);
189 throw lang::DisposedException(); // TODO
191 if ( !m_pListenersContainer
)
192 m_pListenersContainer
= new ::cppu::OInterfaceContainerHelper( m_aMutex
);
194 m_pListenersContainer
->addInterface( xListener
);
197 // --------------------------------------------------------
198 void SAL_CALL
ODocumentCloser::removeEventListener( const uno::Reference
< lang::XEventListener
>& xListener
)
199 throw (uno::RuntimeException
)
201 ::osl::MutexGuard
aGuard( m_aMutex
);
202 if ( m_pListenersContainer
)
203 m_pListenersContainer
->removeInterface( xListener
);
207 // --------------------------------------------------------
208 void SAL_CALL
ODocumentCloser::initialize( const uno::Sequence
< uno::Any
>& aArguments
)
209 throw (uno::Exception
, uno::RuntimeException
)
211 ::osl::MutexGuard
aGuard( m_aMutex
);
212 if ( m_bInitialized
)
213 throw frame::DoubleInitializationException();
216 throw lang::DisposedException(); // TODO
219 throw uno::RuntimeException(); // the object must be refcounted already!
221 sal_Int32 nLen
= aArguments
.getLength();
223 throw lang::IllegalArgumentException(
224 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Wrong count of parameters!" ) ),
225 uno::Reference
< uno::XInterface
>(),
228 if ( !( aArguments
[0] >>= m_xFrame
) || !m_xFrame
.is() )
229 throw lang::IllegalArgumentException(
230 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Nonempty reference is expected as the first argument!" ) ),
231 uno::Reference
< uno::XInterface
>(),
234 m_bInitialized
= sal_True
;
239 // --------------------------------------------------------
240 ::rtl::OUString SAL_CALL
ODocumentCloser::getImplementationName( )
241 throw (uno::RuntimeException
)
243 return impl_staticGetImplementationName();
246 // --------------------------------------------------------
247 ::sal_Bool SAL_CALL
ODocumentCloser::supportsService( const ::rtl::OUString
& ServiceName
)
248 throw (uno::RuntimeException
)
250 uno::Sequence
< ::rtl::OUString
> aSeq
= impl_staticGetSupportedServiceNames();
252 for ( sal_Int32 nInd
= 0; nInd
< aSeq
.getLength(); nInd
++ )
253 if ( ServiceName
.compareTo( aSeq
[nInd
] ) == 0 )
259 // --------------------------------------------------------
260 uno::Sequence
< ::rtl::OUString
> SAL_CALL
ODocumentCloser::getSupportedServiceNames()
261 throw (uno::RuntimeException
)
263 return impl_staticGetSupportedServiceNames();
267 // --------------------------------------------------------
268 uno::Sequence
< ::rtl::OUString
> SAL_CALL
ODocumentCloser::impl_staticGetSupportedServiceNames()
270 const rtl::OUString
aServiceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.embed.DocumentCloser" ) );
271 return uno::Sequence
< rtl::OUString
>( &aServiceName
, 1 );
274 // --------------------------------------------------------
275 ::rtl::OUString SAL_CALL
ODocumentCloser::impl_staticGetImplementationName()
277 return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.embed.DocumentCloser" ) );
280 // --------------------------------------------------------
281 uno::Reference
< uno::XInterface
> SAL_CALL
ODocumentCloser::impl_staticCreateSelfInstance(
282 const uno::Reference
< lang::XMultiServiceFactory
>& xServiceManager
)
284 uno::Reference
< uno::XComponentContext
> xContext
;
285 uno::Reference
< beans::XPropertySet
> xPropSet( xServiceManager
, uno::UNO_QUERY
);
287 xPropSet
->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ) ) ) >>= xContext
;
289 if ( !xContext
.is() )
291 throw uno::RuntimeException(
292 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Unable to obtain component context from service manager!" ) ),
293 uno::Reference
< uno::XInterface
>() );
296 return static_cast< cppu::OWeakObject
* >( new ODocumentCloser( xContext
) );