build fix
[LibreOffice.git] / fpicker / source / office / commonpicker.cxx
blobf498a79c0d0acef7d368f07e1ce2e7ae2d9e6308
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 .
21 #include "commonpicker.hxx"
22 #include <com/sun/star/beans/PropertyAttribute.hpp>
23 #include <com/sun/star/beans/NamedValue.hpp>
24 #include <vcl/svapp.hxx>
25 #include <osl/mutex.hxx>
26 #include <toolkit/helper/vclunohelper.hxx>
27 #include <comphelper/weakeventlistener.hxx>
28 #include <comphelper/types.hxx>
29 #include <vcl/msgbox.hxx>
30 #include "iodlg.hxx"
33 namespace svt
37 #define PROPERTY_ID_HELPURL 1
38 #define PROPERTY_ID_WINDOW 2
40 // using --------------------------------------------------------------
42 using namespace ::com::sun::star::lang;
43 using namespace ::com::sun::star::ui::dialogs;
44 using namespace ::com::sun::star::uno;
45 using namespace ::com::sun::star::beans;
46 using namespace ::comphelper;
49 OCommonPicker::OCommonPicker()
50 :OCommonPicker_Base( m_aMutex )
51 ,OPropertyContainer( GetBroadcastHelper() )
52 ,m_pDlg( nullptr )
53 ,m_nCancelEvent( nullptr )
54 ,m_bExecuting( false )
56 // the two properties we have
57 registerProperty(
58 "HelpURL", PROPERTY_ID_HELPURL,
59 PropertyAttribute::TRANSIENT,
60 &m_sHelpURL, cppu::UnoType<decltype(m_sHelpURL)>::get()
63 registerProperty(
64 "Window", PROPERTY_ID_WINDOW,
65 PropertyAttribute::TRANSIENT | PropertyAttribute::READONLY,
66 &m_xWindow, cppu::UnoType<decltype(m_xWindow)>::get()
71 OCommonPicker::~OCommonPicker()
73 if ( !GetBroadcastHelper().bDisposed )
75 acquire();
76 dispose();
81 // disambiguate XInterface
83 IMPLEMENT_FORWARD_XINTERFACE2( OCommonPicker, OCommonPicker_Base, OPropertyContainer )
86 // disambiguate XTypeProvider
88 IMPLEMENT_FORWARD_XTYPEPROVIDER2( OCommonPicker, OCommonPicker_Base, OPropertyContainer )
91 // XComponent related methods
93 void OCommonPicker::checkAlive() const
95 if ( GetBroadcastHelper().bInDispose || GetBroadcastHelper().bDisposed )
96 throw DisposedException();
99 void OCommonPicker::prepareDialog()
101 if(createPicker())
103 // set the title
104 if ( !m_aTitle.isEmpty() )
105 m_pDlg->SetText( m_aTitle );
110 void SAL_CALL OCommonPicker::disposing()
112 SolarMutexGuard aGuard;
114 stopWindowListening();
116 if ( m_nCancelEvent )
117 Application::RemoveUserEvent( m_nCancelEvent );
120 ::osl::MutexGuard aOwnGuard( m_aMutex );
121 if ( m_bExecuting && m_pDlg )
122 m_pDlg->EndDialog();
125 m_pDlg.disposeAndClear();
126 m_xWindow = nullptr;
127 m_xDialogParent = nullptr;
131 void OCommonPicker::stopWindowListening()
133 disposeComponent( m_xWindowListenerAdapter );
134 disposeComponent( m_xParentListenerAdapter );
138 // XEventListener
140 void SAL_CALL OCommonPicker::disposing( const EventObject& _rSource ) throw (RuntimeException, std::exception)
142 SolarMutexGuard aGuard;
143 bool bDialogDying = _rSource.Source == m_xWindow;
144 bool bParentDying = _rSource.Source == m_xDialogParent;
146 if ( bDialogDying || bParentDying )
148 stopWindowListening();
150 if ( !bDialogDying ) // it's the parent which is dying -> delete the dialog
151 m_pDlg.disposeAndClear();
152 else
153 m_pDlg.clear();
155 m_xWindow = nullptr;
156 m_xDialogParent = nullptr;
158 else
160 OSL_FAIL( "OCommonPicker::disposing: where did this come from?" );
165 // property set related methods
167 ::cppu::IPropertyArrayHelper* OCommonPicker::createArrayHelper( ) const
169 Sequence< Property > aProps;
170 describeProperties( aProps );
171 return new cppu::OPropertyArrayHelper( aProps );
175 ::cppu::IPropertyArrayHelper& SAL_CALL OCommonPicker::getInfoHelper()
177 return *getArrayHelper();
181 Reference< XPropertySetInfo > SAL_CALL OCommonPicker::getPropertySetInfo( ) throw(RuntimeException, std::exception)
183 return ::cppu::OPropertySetHelper::createPropertySetInfo( getInfoHelper() );
187 void SAL_CALL OCommonPicker::setFastPropertyValue_NoBroadcast( sal_Int32 _nHandle, const Any& _rValue ) throw (Exception, std::exception)
189 OPropertyContainer::setFastPropertyValue_NoBroadcast( _nHandle, _rValue );
191 // if the HelpURL changed, forward this to the dialog
192 if ( PROPERTY_ID_HELPURL == _nHandle )
193 if ( m_pDlg )
194 OControlAccess::setHelpURL( m_pDlg, m_sHelpURL, false );
198 bool OCommonPicker::createPicker()
200 if ( !m_pDlg )
202 m_pDlg.reset( implCreateDialog( VCLUnoHelper::GetWindow( m_xDialogParent ) ) );
203 SAL_WARN_IF( !m_pDlg, "fpicker.office", "OCommonPicker::createPicker: invalid dialog returned!" );
205 if ( m_pDlg )
207 // synchronize the help id of the dialog with out help URL property
208 if ( !m_sHelpURL.isEmpty() )
209 { // somebody already set the help URL while we had no dialog yet
210 OControlAccess::setHelpURL( m_pDlg, m_sHelpURL, false );
212 else
214 m_sHelpURL = OControlAccess::getHelpURL( m_pDlg, false );
217 m_xWindow = VCLUnoHelper::GetInterface( m_pDlg );
219 // add as event listener to the window
220 Reference< XComponent > xWindowComp( m_xWindow, UNO_QUERY );
221 OSL_ENSURE( xWindowComp.is(), "OCommonPicker::createFileDialog: invalid window component!" );
222 if ( xWindowComp.is() )
224 m_xWindowListenerAdapter = new OWeakEventListenerAdapter( this, xWindowComp );
225 // the adapter will add itself as listener, and forward notifications
228 // _and_ add as event listener to the parent - in case the parent is destroyed
229 // before we are disposed, our disposal would access dead VCL windows then ....
230 m_xDialogParent = VCLUnoHelper::GetInterface( m_pDlg->GetParent() );
231 xWindowComp.set(m_xDialogParent, css::uno::UNO_QUERY);
232 OSL_ENSURE( xWindowComp.is() || !m_pDlg->GetParent(), "OCommonPicker::createFileDialog: invalid window component (the parent this time)!" );
233 if ( xWindowComp.is() )
235 m_xParentListenerAdapter = new OWeakEventListenerAdapter( this, xWindowComp );
236 // the adapter will add itself as listener, and forward notifications
241 return nullptr != m_pDlg;
245 // XControlAccess functions
247 void SAL_CALL OCommonPicker::setControlProperty( const OUString& aControlName, const OUString& aControlProperty, const Any& aValue ) throw (IllegalArgumentException, RuntimeException, std::exception)
249 checkAlive();
251 SolarMutexGuard aGuard;
252 if ( createPicker() )
254 ::svt::OControlAccess aAccess( m_pDlg, m_pDlg->GetView() );
255 aAccess.setControlProperty( aControlName, aControlProperty, aValue );
260 Any SAL_CALL OCommonPicker::getControlProperty( const OUString& aControlName, const OUString& aControlProperty ) throw (IllegalArgumentException, RuntimeException, std::exception)
262 checkAlive();
264 SolarMutexGuard aGuard;
265 if ( createPicker() )
267 ::svt::OControlAccess aAccess( m_pDlg, m_pDlg->GetView() );
268 return aAccess.getControlProperty( aControlName, aControlProperty );
271 return Any();
275 // XControlInformation functions
277 Sequence< OUString > SAL_CALL OCommonPicker::getSupportedControls( ) throw (RuntimeException, std::exception)
279 checkAlive();
281 SolarMutexGuard aGuard;
282 if ( createPicker() )
284 ::svt::OControlAccess aAccess( m_pDlg, m_pDlg->GetView() );
285 return aAccess.getSupportedControls( );
288 return Sequence< OUString >();
292 sal_Bool SAL_CALL OCommonPicker::isControlSupported( const OUString& aControlName ) throw (RuntimeException, std::exception)
294 checkAlive();
296 SolarMutexGuard aGuard;
297 if ( createPicker() )
299 return svt::OControlAccess::isControlSupported( aControlName );
302 return false;
306 Sequence< OUString > SAL_CALL OCommonPicker::getSupportedControlProperties( const OUString& aControlName ) throw (IllegalArgumentException, RuntimeException, std::exception)
308 checkAlive();
310 SolarMutexGuard aGuard;
311 if ( createPicker() )
313 ::svt::OControlAccess aAccess( m_pDlg, m_pDlg->GetView() );
314 return aAccess.getSupportedControlProperties( aControlName );
317 return Sequence< OUString >();
321 sal_Bool SAL_CALL OCommonPicker::isControlPropertySupported( const OUString& aControlName, const OUString& aControlProperty ) throw (IllegalArgumentException, RuntimeException, std::exception)
323 checkAlive();
325 SolarMutexGuard aGuard;
326 if ( createPicker() )
328 ::svt::OControlAccess aAccess( m_pDlg, m_pDlg->GetView() );
329 return aAccess.isControlPropertySupported( aControlName, aControlProperty );
332 return false;
336 // XExecutableDialog functions
338 void SAL_CALL OCommonPicker::setTitle( const OUString& _rTitle ) throw( RuntimeException, std::exception )
340 SolarMutexGuard aGuard;
341 m_aTitle = _rTitle;
345 sal_Int16 OCommonPicker::execute() throw (RuntimeException, std::exception)
347 SolarMutexGuard aGuard;
349 prepareDialog();
352 ::osl::MutexGuard aOwnGuard( m_aMutex );
353 m_bExecuting = true;
355 sal_Int16 nResult = implExecutePicker();
357 ::osl::MutexGuard aOwnGuard( m_aMutex );
358 m_bExecuting = false;
361 return nResult;
365 // XCancellable functions
367 void SAL_CALL OCommonPicker::cancel( ) throw (RuntimeException, std::exception)
370 ::osl::MutexGuard aGuard( m_aMutex );
371 if ( m_nCancelEvent )
372 // nothing to do - the event for cancelling the dialog is already on the way
373 return;
376 // The thread which executes our dialog has locked the solar mutex for
377 // sure. Cancelling the dialog should be done with a locked solar mutex, too.
378 // Thus we post ourself a message for cancelling the dialog. This way, the message
379 // is either handled in the thread which opened the dialog (which may even be
380 // this thread here), or, if no dialog is open, in the thread doing scheduling
381 // currently. Both is okay for us ....
383 // Note that we could do check if we are really executing the dialog currently.
384 // but the information would be potentially obsolete at the moment our event
385 // arrives, so we need to check it there, anyway ...
386 m_nCancelEvent = Application::PostUserEvent( LINK( this, OCommonPicker, OnCancelPicker ) );
390 IMPL_LINK_NOARG(OCommonPicker, OnCancelPicker, void*, void)
392 // By definition, the solar mutex is locked when we arrive here. Note that this
393 // is important, as for instance the consistency of m_pDlg depends on this mutex.
394 ::osl::MutexGuard aGuard( m_aMutex );
395 m_nCancelEvent = nullptr;
397 if ( !m_bExecuting )
398 // nothing to do. This may be because the dialog was canceled after our cancel method
399 // posted this async event, or because somebody called cancel without the dialog
400 // being executed at this time.
401 return;
403 OSL_ENSURE( getDialog(), "OCommonPicker::OnCancelPicker: executing, but no dialog!" );
404 if ( getDialog() )
405 getDialog()->EndDialog();
409 // XInitialization functions
411 void SAL_CALL OCommonPicker::initialize( const Sequence< Any >& _rArguments )
412 throw ( Exception, RuntimeException, std::exception )
414 checkAlive();
416 OUString sSettingName;
417 Any aSettingValue;
419 PropertyValue aPropArg;
420 NamedValue aPairArg;
423 const Any* pArguments = _rArguments.getConstArray();
424 const Any* pArgumentsEnd = _rArguments.getConstArray() + _rArguments.getLength();
425 for ( const Any* pArgument = pArguments;
426 pArgument != pArgumentsEnd;
427 ++pArgument
430 if ( *pArgument >>= aPropArg )
432 if ( aPropArg.Name.isEmpty())
433 continue;
435 sSettingName = aPropArg.Name;
436 aSettingValue = aPropArg.Value;
438 else if ( *pArgument >>= aPairArg )
440 if ( aPairArg.Name.isEmpty())
441 continue;
443 sSettingName = aPairArg.Name;
444 aSettingValue = aPairArg.Value;
448 else
450 OSL_FAIL(
451 OString(
452 "OCommonPicker::initialize: unknown argument type at position "
453 + OString::number(pArguments - _rArguments.getConstArray())).getStr());
454 continue;
457 bool bKnownSetting =
458 implHandleInitializationArgument( sSettingName, aSettingValue );
459 DBG_ASSERT( bKnownSetting,
460 OString(
461 "OCommonPicker::initialize: unknown argument \""
462 + OString(sSettingName.getStr(), sSettingName.getLength(), osl_getThreadTextEncoding())
463 + "\"!").getStr() );
468 bool OCommonPicker::implHandleInitializationArgument( const OUString& _rName, const Any& _rValue )
470 bool bKnown = true;
471 if ( _rName == "ParentWindow" )
473 m_xDialogParent.clear();
474 OSL_VERIFY( _rValue >>= m_xDialogParent );
475 OSL_ENSURE( VCLUnoHelper::GetWindow( m_xDialogParent ), "OCommonPicker::implHandleInitializationArgument: invalid parent window given!" );
477 else
478 bKnown = false;
479 return bKnown;
483 } // namespace svt
486 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */