bump product version to 4.1.6.2
[LibreOffice.git] / fpicker / source / office / commonpicker.cxx
blob06ccac4048f403ac4d4622f5238d97005f172ad7
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"
32 //.........................................................................
33 namespace svt
35 //.........................................................................
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;
48 //---------------------------------------------------------------------
49 OCommonPicker::OCommonPicker( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxFactory )
50 :OCommonPicker_Base( m_aMutex )
51 ,OPropertyContainer( GetBroadcastHelper() )
52 ,m_xORB( _rxFactory )
53 ,m_pDlg( NULL )
54 ,m_nCancelEvent( 0 )
55 ,m_bExecuting( sal_False )
57 // the two properties we have
58 registerProperty(
59 OUString( "HelpURL" ), PROPERTY_ID_HELPURL,
60 PropertyAttribute::TRANSIENT,
61 &m_sHelpURL, ::getCppuType( &m_sHelpURL )
64 registerProperty(
65 OUString( "Window" ), PROPERTY_ID_WINDOW,
66 PropertyAttribute::TRANSIENT | PropertyAttribute::READONLY,
67 &m_xWindow, ::getCppuType( &m_xWindow )
71 //---------------------------------------------------------------------
72 OCommonPicker::~OCommonPicker()
74 if ( !GetBroadcastHelper().bDisposed )
76 acquire();
77 dispose();
81 //---------------------------------------------------------------------
82 // disambiguate XInterface
83 //---------------------------------------------------------------------
84 IMPLEMENT_FORWARD_XINTERFACE2( OCommonPicker, OCommonPicker_Base, OPropertyContainer )
86 //---------------------------------------------------------------------
87 // disambiguate XTypeProvider
88 //---------------------------------------------------------------------
89 IMPLEMENT_FORWARD_XTYPEPROVIDER2( OCommonPicker, OCommonPicker_Base, OPropertyContainer )
91 //---------------------------------------------------------------------
92 // XComponent related methods
93 //---------------------------------------------------------------------
94 void OCommonPicker::checkAlive() const SAL_THROW( (DisposedException) )
96 if ( GetBroadcastHelper().bInDispose || GetBroadcastHelper().bDisposed )
97 throw DisposedException();
100 void OCommonPicker::prepareDialog()
102 if ( !getDialog() )
103 createPicker();
105 // set the title
106 if ( !m_aTitle.isEmpty() )
107 getDialog()->SetText( m_aTitle );
110 //---------------------------------------------------------------------
111 void SAL_CALL OCommonPicker::disposing()
113 SolarMutexGuard aGuard;
115 stopWindowListening();
117 if ( m_nCancelEvent )
118 Application::RemoveUserEvent( m_nCancelEvent );
121 ::osl::MutexGuard aOwnGuard( m_aMutex );
122 if ( m_bExecuting && m_pDlg )
123 m_pDlg->EndDialog( RET_CANCEL );
126 delete m_pDlg;
127 m_pDlg = NULL;
128 m_xWindow = NULL;
129 m_xDialogParent = NULL;
132 //---------------------------------------------------------------------
133 void OCommonPicker::stopWindowListening()
135 disposeComponent( m_xWindowListenerAdapter );
136 disposeComponent( m_xParentListenerAdapter );
139 //---------------------------------------------------------------------
140 // XEventListener
141 //---------------------------------------------------------------------
142 void SAL_CALL OCommonPicker::disposing( const EventObject& _rSource ) throw (RuntimeException)
144 SolarMutexGuard aGuard;
145 sal_Bool bDialogDying = _rSource.Source == m_xWindow;
146 sal_Bool bParentDying = _rSource.Source == m_xDialogParent;
148 if ( bDialogDying || bParentDying )
150 stopWindowListening();
152 if ( !bDialogDying ) // it's the parent which is dying -> delete the dialog
153 delete m_pDlg;
155 m_pDlg = NULL;
156 m_xWindow = NULL;
157 m_xDialogParent = NULL;
159 else
161 OSL_FAIL( "OCommonPicker::disposing: where did this come from?" );
165 //---------------------------------------------------------------------
166 // property set related methods
167 //---------------------------------------------------------------------
168 ::cppu::IPropertyArrayHelper* OCommonPicker::createArrayHelper( ) const
170 Sequence< Property > aProps;
171 describeProperties( aProps );
172 return new cppu::OPropertyArrayHelper( aProps );
175 //---------------------------------------------------------------------
176 ::cppu::IPropertyArrayHelper& SAL_CALL OCommonPicker::getInfoHelper()
178 return *const_cast< OCommonPicker* >( this )->getArrayHelper();
181 //---------------------------------------------------------------------
182 Reference< XPropertySetInfo > SAL_CALL OCommonPicker::getPropertySetInfo( ) throw(RuntimeException)
184 return ::cppu::OPropertySetHelper::createPropertySetInfo( getInfoHelper() );
187 //---------------------------------------------------------------------
188 void SAL_CALL OCommonPicker::setFastPropertyValue_NoBroadcast( sal_Int32 _nHandle, const Any& _rValue ) throw (Exception)
190 OPropertyContainer::setFastPropertyValue_NoBroadcast( _nHandle, _rValue );
192 // if the HelpURL changed, forward this to the dialog
193 if ( PROPERTY_ID_HELPURL == _nHandle )
194 if ( m_pDlg )
195 OControlAccess::setHelpURL( m_pDlg, m_sHelpURL, sal_False );
199 //---------------------------------------------------------------------
200 sal_Bool OCommonPicker::createPicker()
202 SolarMutexGuard aGuard;
204 if ( !m_pDlg )
206 m_pDlg = implCreateDialog( VCLUnoHelper::GetWindow( m_xDialogParent ) );
207 DBG_ASSERT( m_pDlg, "OCommonPicker::createPicker: invalid dialog returned!" );
209 if ( m_pDlg )
211 // synchronize the help id of the dialog with out help URL property
212 if ( !m_sHelpURL.isEmpty() )
213 { // somebody already set the help URL while we had no dialog yet
214 OControlAccess::setHelpURL( m_pDlg, m_sHelpURL, sal_False );
216 else
218 m_sHelpURL = OControlAccess::getHelpURL( m_pDlg, sal_False );
221 m_xWindow = VCLUnoHelper::GetInterface( m_pDlg );
223 // add as event listener to the window
224 Reference< XComponent > xWindowComp( m_xWindow, UNO_QUERY );
225 OSL_ENSURE( xWindowComp.is(), "OCommonPicker::createFileDialog: invalid window component!" );
226 if ( xWindowComp.is() )
228 m_xWindowListenerAdapter = new OWeakEventListenerAdapter( this, xWindowComp );
229 // the adapter will add itself as listener, and forward notifications
232 // _and_ add as event listener to the parent - in case the parent is destroyed
233 // before we are disposed, our disposal would access dead VCL windows then ....
234 m_xDialogParent = VCLUnoHelper::GetInterface( m_pDlg->GetParent() );
235 xWindowComp = xWindowComp.query( m_xDialogParent );
236 OSL_ENSURE( xWindowComp.is() || !m_pDlg->GetParent(), "OCommonPicker::createFileDialog: invalid window component (the parent this time)!" );
237 if ( xWindowComp.is() )
239 m_xParentListenerAdapter = new OWeakEventListenerAdapter( this, xWindowComp );
240 // the adapter will add itself as listener, and forward notifications
245 return NULL != m_pDlg;
248 //---------------------------------------------------------------------
249 // XControlAccess functions
250 //---------------------------------------------------------------------
251 void SAL_CALL OCommonPicker::setControlProperty( const OUString& aControlName, const OUString& aControlProperty, const Any& aValue ) throw (IllegalArgumentException, RuntimeException)
253 checkAlive();
255 SolarMutexGuard aGuard;
256 if ( createPicker() )
258 ::svt::OControlAccess aAccess( m_pDlg, m_pDlg->GetView() );
259 aAccess.setControlProperty( aControlName, aControlProperty, aValue );
263 //---------------------------------------------------------------------
264 Any SAL_CALL OCommonPicker::getControlProperty( const OUString& aControlName, const OUString& aControlProperty ) throw (IllegalArgumentException, RuntimeException)
266 checkAlive();
268 SolarMutexGuard aGuard;
269 if ( createPicker() )
271 ::svt::OControlAccess aAccess( m_pDlg, m_pDlg->GetView() );
272 return aAccess.getControlProperty( aControlName, aControlProperty );
275 return Any();
278 //---------------------------------------------------------------------
279 // XControlInformation functions
280 //---------------------------------------------------------------------
281 Sequence< OUString > SAL_CALL OCommonPicker::getSupportedControls( ) throw (RuntimeException)
283 checkAlive();
285 SolarMutexGuard aGuard;
286 if ( createPicker() )
288 ::svt::OControlAccess aAccess( m_pDlg, m_pDlg->GetView() );
289 return aAccess.getSupportedControls( );
292 return Sequence< OUString >();
295 //---------------------------------------------------------------------
296 sal_Bool SAL_CALL OCommonPicker::isControlSupported( const OUString& aControlName ) throw (RuntimeException)
298 checkAlive();
300 SolarMutexGuard aGuard;
301 if ( createPicker() )
303 ::svt::OControlAccess aAccess( m_pDlg, m_pDlg->GetView() );
304 return aAccess.isControlSupported( aControlName );
307 return sal_False;
310 //---------------------------------------------------------------------
311 Sequence< OUString > SAL_CALL OCommonPicker::getSupportedControlProperties( const OUString& aControlName ) throw (IllegalArgumentException, RuntimeException)
313 checkAlive();
315 SolarMutexGuard aGuard;
316 if ( createPicker() )
318 ::svt::OControlAccess aAccess( m_pDlg, m_pDlg->GetView() );
319 return aAccess.getSupportedControlProperties( aControlName );
322 return Sequence< OUString >();
325 //---------------------------------------------------------------------
326 sal_Bool SAL_CALL OCommonPicker::isControlPropertySupported( const OUString& aControlName, const OUString& aControlProperty ) throw (IllegalArgumentException, RuntimeException)
328 checkAlive();
330 SolarMutexGuard aGuard;
331 if ( createPicker() )
333 ::svt::OControlAccess aAccess( m_pDlg, m_pDlg->GetView() );
334 return aAccess.isControlPropertySupported( aControlName, aControlProperty );
337 return sal_False;
340 //---------------------------------------------------------------------
341 // XExecutableDialog functions
342 //---------------------------------------------------------------------
343 void SAL_CALL OCommonPicker::setTitle( const OUString& _rTitle ) throw( RuntimeException )
345 SolarMutexGuard aGuard;
346 m_aTitle = _rTitle;
349 //---------------------------------------------------------------------
350 sal_Int16 OCommonPicker::execute() throw (RuntimeException)
352 SolarMutexGuard aGuard;
354 prepareDialog();
357 ::osl::MutexGuard aOwnGuard( m_aMutex );
358 m_bExecuting = sal_True;
360 sal_Int16 nResult = implExecutePicker();
362 ::osl::MutexGuard aOwnGuard( m_aMutex );
363 m_bExecuting = sal_False;
366 return nResult;
369 //---------------------------------------------------------------------
370 // XCancellable functions
371 //---------------------------------------------------------------------
372 void SAL_CALL OCommonPicker::cancel( ) throw (RuntimeException)
375 ::osl::MutexGuard aGuard( m_aMutex );
376 if ( m_nCancelEvent )
377 // nothing to do - the event for cancelling the dialog is already on the way
378 return;
381 // The thread which executes our dialog has locked the solar mutex for
382 // sure. Cancelling the dialog should be done with a locked solar mutex, too.
383 // Thus we post ourself a message for cancelling the dialog. This way, the message
384 // is either handled in the thread which opened the dialog (which may even be
385 // this thread here), or, if no dialog is open, in the thread doing scheduling
386 // currently. Both is okay for us ....
388 // Note that we could do check if we are really executing the dialog currently.
389 // but the information would be potentially obsolete at the moment our event
390 // arrives, so we need to check it there, anyway ...
391 m_nCancelEvent = Application::PostUserEvent( LINK( this, OCommonPicker, OnCancelPicker ) );
394 //---------------------------------------------------------------------
395 IMPL_LINK_NOARG(OCommonPicker, OnCancelPicker)
397 // By definition, the solar mutex is locked when we arrive here. Note that this
398 // is important, as for instance the consistency of m_pDlg depends on this mutex.
399 ::osl::MutexGuard aGuard( m_aMutex );
400 m_nCancelEvent = 0;
402 if ( !m_bExecuting )
403 // nothing to do. This may be because the dialog was canceled after our cancel method
404 // posted this async event, or because somebody called cancel without the dialog
405 // being executed at this time.
406 return 0;
408 OSL_ENSURE( getDialog(), "OCommonPicker::OnCancelPicker: executing, but no dialog!" );
409 if ( getDialog() )
410 getDialog()->EndDialog( RET_CANCEL );
412 return 0L;
415 //------------------------------------------------------------------------------------
416 // XInitialization functions
417 //------------------------------------------------------------------------------------
418 void SAL_CALL OCommonPicker::initialize( const Sequence< Any >& _rArguments )
419 throw ( Exception, RuntimeException )
421 checkAlive();
423 OUString sSettingName;
424 Any aSettingValue;
426 PropertyValue aPropArg;
427 NamedValue aPairArg;
430 const Any* pArguments = _rArguments.getConstArray();
431 const Any* pArgumentsEnd = _rArguments.getConstArray() + _rArguments.getLength();
432 for ( const Any* pArgument = pArguments;
433 pArgument != pArgumentsEnd;
434 ++pArgument
437 if ( *pArgument >>= aPropArg )
439 if ( aPropArg.Name.isEmpty())
440 continue;
442 sSettingName = aPropArg.Name;
443 aSettingValue = aPropArg.Value;
445 else if ( *pArgument >>= aPairArg )
447 if ( aPairArg.Name.isEmpty())
448 continue;
450 sSettingName = aPairArg.Name;
451 aSettingValue = aPairArg.Value;
455 else
457 OSL_FAIL(
458 ( OString( "OCommonPicker::initialize: unknown argument type at position " )
459 += OString::valueOf( (sal_Int32)( pArguments - _rArguments.getConstArray() ) )
460 ).getStr()
462 continue;
465 #ifdef DBG_UTIL
466 sal_Bool bKnownSetting =
467 #endif
468 implHandleInitializationArgument( sSettingName, aSettingValue );
469 DBG_ASSERT( bKnownSetting,
470 ( OString( "OCommonPicker::initialize: unknown argument \"" )
471 += OString( sSettingName.getStr(), sSettingName.getLength(), osl_getThreadTextEncoding() )
472 += OString( "\"!" )
473 ).getStr()
478 //---------------------------------------------------------------------
479 sal_Bool OCommonPicker::implHandleInitializationArgument( const OUString& _rName, const Any& _rValue ) SAL_THROW( ( Exception, RuntimeException ) )
481 sal_Bool bKnown = sal_True;
482 if ( _rName == "ParentWindow" )
484 m_xDialogParent.clear();
485 OSL_VERIFY( _rValue >>= m_xDialogParent );
486 OSL_ENSURE( VCLUnoHelper::GetWindow( m_xDialogParent ), "OCommonPicker::implHandleInitializationArgument: invalid parent window given!" );
488 else
489 bKnown = sal_False;
490 return bKnown;
493 //.........................................................................
494 } // namespace svt
495 //.........................................................................
497 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */