1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
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/awt/XVclWindowPeer.hpp>
26 #include <comphelper/processfactory.hxx>
27 #include <osl/mutex.hxx>
28 #include <vcl/svapp.hxx>
29 #include <vcl/dialog.hxx>
30 #include <tools/link.hxx>
31 #include <toolkit/helper/vclunohelper.hxx>
33 #include "documentcloser.hxx"
35 using namespace ::com::sun::star
;
38 // ====================================================================
39 // MainThreadFrameCloserRequest
40 // ====================================================================
42 class MainThreadFrameCloserRequest
44 uno::Reference
< frame::XFrame
> m_xFrame
;
47 MainThreadFrameCloserRequest( const uno::Reference
< frame::XFrame
>& xFrame
)
51 DECL_STATIC_LINK( MainThreadFrameCloserRequest
, worker
, MainThreadFrameCloserRequest
* );
53 static void Start( MainThreadFrameCloserRequest
* pRequest
);
56 // --------------------------------------------------------
57 void MainThreadFrameCloserRequest::Start( MainThreadFrameCloserRequest
* pMTRequest
)
61 if ( Application::GetMainThreadIdentifier() == osl_getThreadIdentifier( NULL
) )
63 // this is the main thread
64 worker( NULL
, pMTRequest
);
67 Application::PostUserEvent( STATIC_LINK( NULL
, MainThreadFrameCloserRequest
, worker
), pMTRequest
);
71 // --------------------------------------------------------
72 IMPL_STATIC_LINK( MainThreadFrameCloserRequest
, worker
, MainThreadFrameCloserRequest
*, pMTRequest
)
74 (void) pThis
; // unused
77 if ( pMTRequest
->m_xFrame
.is() )
79 // this is the main thread, the solar mutex must be locked
80 SolarMutexGuard aGuard
;
84 uno::Reference
< awt::XWindow
> xWindow
= pMTRequest
->m_xFrame
->getContainerWindow();
85 uno::Reference
< awt::XVclWindowPeer
> xWinPeer( xWindow
, uno::UNO_QUERY_THROW
);
87 xWindow
->setVisible( sal_False
);
89 // reparent the window
90 xWinPeer
->setProperty( OUString( "PluginParent" ),
91 uno::makeAny( (sal_Int64
) 0 ) );
93 Window
* pWindow
= VCLUnoHelper::GetWindow( xWindow
);
95 Dialog::EndAllDialogs( pWindow
);
97 catch( uno::Exception
& )
99 // ignore all the errors
104 uno::Reference
< util::XCloseable
> xCloseable( pMTRequest
->m_xFrame
, uno::UNO_QUERY_THROW
);
105 xCloseable
->close( sal_True
);
107 catch( uno::Exception
& )
109 // ignore all the errors
120 // ====================================================================
122 // ====================================================================
124 // --------------------------------------------------------
125 ODocumentCloser::ODocumentCloser( const uno::Reference
< uno::XComponentContext
>& xContext
)
126 : m_xContext( xContext
)
127 , m_pListenersContainer( NULL
)
128 , m_bDisposed( sal_False
)
129 , m_bInitialized( sal_False
)
133 // --------------------------------------------------------
134 ODocumentCloser::~ODocumentCloser()
136 if ( m_pListenersContainer
)
138 delete m_pListenersContainer
;
139 m_pListenersContainer
= NULL
;
144 // --------------------------------------------------------
145 void SAL_CALL
ODocumentCloser::dispose()
146 throw (uno::RuntimeException
)
148 ::osl::MutexGuard
aGuard( m_aMutex
);
151 throw lang::DisposedException();
153 lang::EventObject
aSource( static_cast< ::cppu::OWeakObject
* >(this) );
154 if ( m_pListenersContainer
)
155 m_pListenersContainer
->disposeAndClear( aSource
);
157 // TODO: trigger a main thread execution to close the frame
160 // the created object will be deleted after thread execution
161 MainThreadFrameCloserRequest
* pCloser
= new MainThreadFrameCloserRequest( m_xFrame
);
162 MainThreadFrameCloserRequest::Start( pCloser
);
165 m_bDisposed
= sal_True
;
168 // --------------------------------------------------------
169 void SAL_CALL
ODocumentCloser::addEventListener( const uno::Reference
< lang::XEventListener
>& xListener
)
170 throw (uno::RuntimeException
)
172 ::osl::MutexGuard
aGuard( m_aMutex
);
174 throw lang::DisposedException(); // TODO
176 if ( !m_pListenersContainer
)
177 m_pListenersContainer
= new ::cppu::OInterfaceContainerHelper( m_aMutex
);
179 m_pListenersContainer
->addInterface( xListener
);
182 // --------------------------------------------------------
183 void SAL_CALL
ODocumentCloser::removeEventListener( const uno::Reference
< lang::XEventListener
>& xListener
)
184 throw (uno::RuntimeException
)
186 ::osl::MutexGuard
aGuard( m_aMutex
);
187 if ( m_pListenersContainer
)
188 m_pListenersContainer
->removeInterface( xListener
);
192 // --------------------------------------------------------
193 void SAL_CALL
ODocumentCloser::initialize( const uno::Sequence
< uno::Any
>& aArguments
)
194 throw (uno::Exception
, uno::RuntimeException
)
196 ::osl::MutexGuard
aGuard( m_aMutex
);
197 if ( m_bInitialized
)
198 throw frame::DoubleInitializationException();
201 throw lang::DisposedException(); // TODO
204 throw uno::RuntimeException(); // the object must be refcounted already!
206 sal_Int32 nLen
= aArguments
.getLength();
208 throw lang::IllegalArgumentException(
209 OUString("Wrong count of parameters!" ),
210 uno::Reference
< uno::XInterface
>(),
213 if ( !( aArguments
[0] >>= m_xFrame
) || !m_xFrame
.is() )
214 throw lang::IllegalArgumentException(
215 OUString("Nonempty reference is expected as the first argument!" ),
216 uno::Reference
< uno::XInterface
>(),
219 m_bInitialized
= sal_True
;
224 // --------------------------------------------------------
225 OUString SAL_CALL
ODocumentCloser::getImplementationName( )
226 throw (uno::RuntimeException
)
228 return impl_staticGetImplementationName();
231 // --------------------------------------------------------
232 ::sal_Bool SAL_CALL
ODocumentCloser::supportsService( const OUString
& ServiceName
)
233 throw (uno::RuntimeException
)
235 uno::Sequence
< OUString
> aSeq
= impl_staticGetSupportedServiceNames();
237 for ( sal_Int32 nInd
= 0; nInd
< aSeq
.getLength(); nInd
++ )
238 if ( ServiceName
== aSeq
[nInd
] )
244 // --------------------------------------------------------
245 uno::Sequence
< OUString
> SAL_CALL
ODocumentCloser::getSupportedServiceNames()
246 throw (uno::RuntimeException
)
248 return impl_staticGetSupportedServiceNames();
252 // --------------------------------------------------------
253 uno::Sequence
< OUString
> SAL_CALL
ODocumentCloser::impl_staticGetSupportedServiceNames()
255 const OUString
aServiceName( "com.sun.star.embed.DocumentCloser" );
256 return uno::Sequence
< OUString
>( &aServiceName
, 1 );
259 // --------------------------------------------------------
260 OUString SAL_CALL
ODocumentCloser::impl_staticGetImplementationName()
262 return OUString( "com.sun.star.comp.embed.DocumentCloser" );
265 // --------------------------------------------------------
266 uno::Reference
< uno::XInterface
> SAL_CALL
ODocumentCloser::impl_staticCreateSelfInstance(
267 const uno::Reference
< lang::XMultiServiceFactory
>& xServiceManager
)
269 uno::Reference
< uno::XComponentContext
> xContext(
270 comphelper::getComponentContext( xServiceManager
) );
271 return static_cast< cppu::OWeakObject
* >( new ODocumentCloser( xContext
) );
274 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */