update dev300-m58
[ooovba.git] / fpicker / source / office / commonpicker.cxx
blob8fa1ac31f45731ceed004254ed297b092b24bb10
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: commonpicker.cxx,v $
10 * $Revision: 1.9.12.1 $
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_fpicker.hxx"
34 #include "commonpicker.hxx"
35 #include <com/sun/star/beans/PropertyAttribute.hpp>
36 #include <com/sun/star/beans/NamedValue.hpp>
37 #include <vcl/svapp.hxx>
38 #include <vos/mutex.hxx>
39 #include <toolkit/helper/vclunohelper.hxx>
40 #include <comphelper/weakeventlistener.hxx>
41 #include <comphelper/types.hxx>
42 #include <vcl/msgbox.hxx>
43 #include "iodlg.hxx"
45 //.........................................................................
46 namespace svt
48 //.........................................................................
50 #define PROPERTY_ID_HELPURL 1
51 #define PROPERTY_ID_WINDOW 2
53 // using --------------------------------------------------------------
55 using namespace ::com::sun::star::lang;
56 using namespace ::com::sun::star::ui::dialogs;
57 using namespace ::com::sun::star::uno;
58 using namespace ::com::sun::star::beans;
59 using namespace ::comphelper;
61 //---------------------------------------------------------------------
62 OCommonPicker::OCommonPicker( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxFactory )
63 :OCommonPicker_Base( m_aMutex )
64 ,OPropertyContainer( GetBroadcastHelper() )
65 ,m_xORB( _rxFactory )
66 ,m_pDlg( NULL )
67 ,m_nCancelEvent( 0 )
68 ,m_bExecuting( sal_False )
70 // the two properties we have
71 registerProperty(
72 ::rtl::OUString::createFromAscii( "HelpURL" ), PROPERTY_ID_HELPURL,
73 PropertyAttribute::TRANSIENT,
74 &m_sHelpURL, ::getCppuType( &m_sHelpURL )
77 registerProperty(
78 ::rtl::OUString::createFromAscii( "Window" ), PROPERTY_ID_WINDOW,
79 PropertyAttribute::TRANSIENT | PropertyAttribute::READONLY,
80 &m_xWindow, ::getCppuType( &m_xWindow )
84 //---------------------------------------------------------------------
85 OCommonPicker::~OCommonPicker()
87 if ( !GetBroadcastHelper().bDisposed )
89 acquire();
90 dispose();
94 //---------------------------------------------------------------------
95 // disambiguate XInterface
96 //---------------------------------------------------------------------
97 IMPLEMENT_FORWARD_XINTERFACE2( OCommonPicker, OCommonPicker_Base, OPropertyContainer )
99 //---------------------------------------------------------------------
100 // disambiguate XTypeProvider
101 //---------------------------------------------------------------------
102 IMPLEMENT_FORWARD_XTYPEPROVIDER2( OCommonPicker, OCommonPicker_Base, OPropertyContainer )
104 //---------------------------------------------------------------------
105 // XComponent related methods
106 //---------------------------------------------------------------------
107 void OCommonPicker::checkAlive() const SAL_THROW( (DisposedException) )
109 if ( GetBroadcastHelper().bInDispose || GetBroadcastHelper().bDisposed )
110 throw DisposedException();
113 void OCommonPicker::prepareDialog()
115 if ( !getDialog() )
116 createPicker();
118 // set the title
119 if ( m_aTitle.getLength() > 0 )
120 getDialog()->SetText( m_aTitle );
123 //---------------------------------------------------------------------
124 void SAL_CALL OCommonPicker::disposing()
126 ::vos::OGuard aGuard( Application::GetSolarMutex() );
128 stopWindowListening();
130 if ( m_nCancelEvent )
131 Application::RemoveUserEvent( m_nCancelEvent );
134 ::osl::MutexGuard aOwnGuard( m_aMutex );
135 if ( m_bExecuting && m_pDlg )
136 m_pDlg->EndDialog( RET_CANCEL );
139 delete m_pDlg;
140 m_pDlg = NULL;
141 m_xWindow = NULL;
142 m_xDialogParent = NULL;
145 //---------------------------------------------------------------------
146 void OCommonPicker::stopWindowListening()
148 disposeComponent( m_xWindowListenerAdapter );
149 disposeComponent( m_xParentListenerAdapter );
152 //---------------------------------------------------------------------
153 // XEventListener
154 //---------------------------------------------------------------------
155 void SAL_CALL OCommonPicker::disposing( const EventObject& _rSource ) throw (RuntimeException)
157 ::vos::OGuard aGuard( Application::GetSolarMutex() );
158 sal_Bool bDialogDying = _rSource.Source == m_xWindow;
159 sal_Bool bParentDying = _rSource.Source == m_xDialogParent;
161 if ( bDialogDying || bParentDying )
163 stopWindowListening();
165 if ( !bDialogDying ) // it's the parent which is dying -> delete the dialog
166 delete m_pDlg;
168 m_pDlg = NULL;
169 m_xWindow = NULL;
170 m_xDialogParent = NULL;
172 else
174 DBG_ERROR( "OCommonPicker::disposing: where did this come from?" );
178 //---------------------------------------------------------------------
179 // property set related methods
180 //---------------------------------------------------------------------
181 ::cppu::IPropertyArrayHelper* OCommonPicker::createArrayHelper( ) const
183 Sequence< Property > aProps;
184 describeProperties( aProps );
185 return new cppu::OPropertyArrayHelper( aProps );
188 //---------------------------------------------------------------------
189 ::cppu::IPropertyArrayHelper& SAL_CALL OCommonPicker::getInfoHelper()
191 return *const_cast< OCommonPicker* >( this )->getArrayHelper();
194 //---------------------------------------------------------------------
195 Reference< XPropertySetInfo > SAL_CALL OCommonPicker::getPropertySetInfo( ) throw(RuntimeException)
197 return ::cppu::OPropertySetHelper::createPropertySetInfo( getInfoHelper() );
200 //---------------------------------------------------------------------
201 void SAL_CALL OCommonPicker::setFastPropertyValue_NoBroadcast( sal_Int32 _nHandle, const Any& _rValue ) throw (Exception)
203 OPropertyContainer::setFastPropertyValue_NoBroadcast( _nHandle, _rValue );
205 // if the HelpURL changed, forward this to the dialog
206 if ( PROPERTY_ID_HELPURL == _nHandle )
207 if ( m_pDlg )
208 OControlAccess::setHelpURL( m_pDlg, m_sHelpURL, sal_False );
212 //---------------------------------------------------------------------
213 sal_Bool OCommonPicker::createPicker()
215 ::vos::OGuard aGuard( Application::GetSolarMutex() );
217 if ( !m_pDlg )
219 m_pDlg = implCreateDialog( VCLUnoHelper::GetWindow( m_xDialogParent ) );
220 DBG_ASSERT( m_pDlg, "OCommonPicker::createPicker: invalid dialog returned!" );
222 if ( m_pDlg )
224 // synchronize the help id of the dialog with out help URL property
225 if ( m_sHelpURL.getLength() )
226 { // somebody already set the help URL while we had no dialog yet
227 OControlAccess::setHelpURL( m_pDlg, m_sHelpURL, sal_False );
229 else
231 m_sHelpURL = OControlAccess::getHelpURL( m_pDlg, sal_False );
234 m_xWindow = VCLUnoHelper::GetInterface( m_pDlg );
236 // add as event listener to the window
237 Reference< XComponent > xWindowComp( m_xWindow, UNO_QUERY );
238 OSL_ENSURE( xWindowComp.is(), "OCommonPicker::createFileDialog: invalid window component!" );
239 if ( xWindowComp.is() )
241 m_xWindowListenerAdapter = new OWeakEventListenerAdapter( this, xWindowComp );
242 // the adapter will add itself as listener, and forward notifications
245 // _and_ add as event listener to the parent - in case the parent is destroyed
246 // before we are disposed, our disposal would access dead VCL windows then ....
247 m_xDialogParent = VCLUnoHelper::GetInterface( m_pDlg->GetParent() );
248 xWindowComp = xWindowComp.query( m_xDialogParent );
249 OSL_ENSURE( xWindowComp.is() || !m_pDlg->GetParent(), "OCommonPicker::createFileDialog: invalid window component (the parent this time)!" );
250 if ( xWindowComp.is() )
252 m_xParentListenerAdapter = new OWeakEventListenerAdapter( this, xWindowComp );
253 // the adapter will add itself as listener, and forward notifications
258 return NULL != m_pDlg;
261 //---------------------------------------------------------------------
262 // XControlAccess functions
263 //---------------------------------------------------------------------
264 void SAL_CALL OCommonPicker::setControlProperty( const ::rtl::OUString& aControlName, const ::rtl::OUString& aControlProperty, const Any& aValue ) throw (IllegalArgumentException, RuntimeException)
266 checkAlive();
268 ::vos::OGuard aGuard( Application::GetSolarMutex() );
269 if ( createPicker() )
271 ::svt::OControlAccess aAccess( m_pDlg, m_pDlg->GetView() );
272 aAccess.setControlProperty( aControlName, aControlProperty, aValue );
276 //---------------------------------------------------------------------
277 Any SAL_CALL OCommonPicker::getControlProperty( const ::rtl::OUString& aControlName, const ::rtl::OUString& aControlProperty ) throw (IllegalArgumentException, RuntimeException)
279 checkAlive();
281 ::vos::OGuard aGuard( Application::GetSolarMutex() );
282 if ( createPicker() )
284 ::svt::OControlAccess aAccess( m_pDlg, m_pDlg->GetView() );
285 return aAccess.getControlProperty( aControlName, aControlProperty );
288 return Any();
291 //---------------------------------------------------------------------
292 // XControlInformation functions
293 //---------------------------------------------------------------------
294 Sequence< ::rtl::OUString > SAL_CALL OCommonPicker::getSupportedControls( ) throw (RuntimeException)
296 checkAlive();
298 ::vos::OGuard aGuard( Application::GetSolarMutex() );
299 if ( createPicker() )
301 ::svt::OControlAccess aAccess( m_pDlg, m_pDlg->GetView() );
302 return aAccess.getSupportedControls( );
305 return Sequence< ::rtl::OUString >();
308 //---------------------------------------------------------------------
309 sal_Bool SAL_CALL OCommonPicker::isControlSupported( const ::rtl::OUString& aControlName ) throw (RuntimeException)
311 checkAlive();
313 ::vos::OGuard aGuard( Application::GetSolarMutex() );
314 if ( createPicker() )
316 ::svt::OControlAccess aAccess( m_pDlg, m_pDlg->GetView() );
317 return aAccess.isControlSupported( aControlName );
320 return sal_False;
323 //---------------------------------------------------------------------
324 Sequence< ::rtl::OUString > SAL_CALL OCommonPicker::getSupportedControlProperties( const ::rtl::OUString& aControlName ) throw (IllegalArgumentException, RuntimeException)
326 checkAlive();
328 ::vos::OGuard aGuard( Application::GetSolarMutex() );
329 if ( createPicker() )
331 ::svt::OControlAccess aAccess( m_pDlg, m_pDlg->GetView() );
332 return aAccess.getSupportedControlProperties( aControlName );
335 return Sequence< ::rtl::OUString >();
338 //---------------------------------------------------------------------
339 sal_Bool SAL_CALL OCommonPicker::isControlPropertySupported( const ::rtl::OUString& aControlName, const ::rtl::OUString& aControlProperty ) throw (IllegalArgumentException, RuntimeException)
341 checkAlive();
343 ::vos::OGuard aGuard( Application::GetSolarMutex() );
344 if ( createPicker() )
346 ::svt::OControlAccess aAccess( m_pDlg, m_pDlg->GetView() );
347 return aAccess.isControlPropertySupported( aControlName, aControlProperty );
350 return sal_False;
353 //---------------------------------------------------------------------
354 // XExecutableDialog functions
355 //---------------------------------------------------------------------
356 void SAL_CALL OCommonPicker::setTitle( const rtl::OUString& _rTitle ) throw( RuntimeException )
358 ::vos::OGuard aGuard( Application::GetSolarMutex() );
359 m_aTitle = _rTitle;
362 //---------------------------------------------------------------------
363 sal_Int16 OCommonPicker::execute() throw (RuntimeException)
365 ::vos::OGuard aGuard( Application::GetSolarMutex() );
367 prepareDialog();
370 ::osl::MutexGuard aOwnGuard( m_aMutex );
371 m_bExecuting = sal_True;
373 sal_Int16 nResult = implExecutePicker();
375 ::osl::MutexGuard aOwnGuard( m_aMutex );
376 m_bExecuting = sal_False;
379 return nResult;
382 //---------------------------------------------------------------------
383 // XCancellable functions
384 //---------------------------------------------------------------------
385 void SAL_CALL OCommonPicker::cancel( ) throw (RuntimeException)
388 ::osl::MutexGuard aGuard( m_aMutex );
389 if ( m_nCancelEvent )
390 // nothing to do - the event for cancelling the dialog is already on the way
391 return;
394 // The thread which executes our dialog has locked the solar mutex for
395 // sure. Cancelling the dialog should be done with a locked solar mutex, too.
396 // Thus we post ourself a message for cancelling the dialog. This way, the message
397 // is either handled in the thread which opened the dialog (which may even be
398 // this thread here), or, if no dialog is open, in the thread doing scheduling
399 // currently. Both is okay for us ....
401 // Note that we could do check if we are really executing the dialog currently.
402 // but the information would be potentially obsolete at the moment our event
403 // arrives, so we need to check it there, anyway ...
404 m_nCancelEvent = Application::PostUserEvent( LINK( this, OCommonPicker, OnCancelPicker ) );
407 //---------------------------------------------------------------------
408 IMPL_LINK( OCommonPicker, OnCancelPicker, void*, EMPTYARG )
410 // By definition, the solar mutex is locked when we arrive here. Note that this
411 // is important, as for instance the consistency of m_pDlg depends on this mutex.
412 ::osl::MutexGuard aGuard( m_aMutex );
413 m_nCancelEvent = 0;
415 if ( !m_bExecuting )
416 // nothing to do. This may be because the dialog was cancelled after our cancel method
417 // posted this async event, or because somebody called cancel without the dialog
418 // being executed at this time.
419 return 0;
421 OSL_ENSURE( getDialog(), "OCommonPicker::OnCancelPicker: executing, but no dialog!" );
422 if ( getDialog() )
423 getDialog()->EndDialog( RET_CANCEL );
425 return 0L;
428 //------------------------------------------------------------------------------------
429 // XInitialization functions
430 //------------------------------------------------------------------------------------
431 void SAL_CALL OCommonPicker::initialize( const Sequence< Any >& _rArguments )
432 throw ( Exception, RuntimeException )
434 checkAlive();
436 ::rtl::OUString sSettingName;
437 Any aSettingValue;
439 PropertyValue aPropArg;
440 NamedValue aPairArg;
443 const Any* pArguments = _rArguments.getConstArray();
444 const Any* pArgumentsEnd = _rArguments.getConstArray() + _rArguments.getLength();
445 for ( const Any* pArgument = pArguments;
446 pArgument != pArgumentsEnd;
447 ++pArgument
450 if ( *pArgument >>= aPropArg )
452 if ( aPropArg.Name.getLength() <= 0)
453 continue;
455 sSettingName = aPropArg.Name;
456 aSettingValue = aPropArg.Value;
458 else if ( *pArgument >>= aPairArg )
460 if ( aPairArg.Name.getLength() <= 0)
461 continue;
463 sSettingName = aPairArg.Name;
464 aSettingValue = aPairArg.Value;
468 else
470 DBG_ERROR(
471 ( ::rtl::OString( "OCommonPicker::initialize: unknown argument type at position " )
472 += ::rtl::OString::valueOf( (sal_Int32)( pArguments - _rArguments.getConstArray() ) )
473 ).getStr()
475 continue;
478 #ifdef DBG_UTIL
479 sal_Bool bKnownSetting =
480 #endif
481 implHandleInitializationArgument( sSettingName, aSettingValue );
482 DBG_ASSERT( bKnownSetting,
483 ( ::rtl::OString( "OCommonPicker::initialize: unknown argument \"" )
484 += ::rtl::OString( sSettingName.getStr(), sSettingName.getLength(), osl_getThreadTextEncoding() )
485 += ::rtl::OString( "\"!" )
486 ).getStr()
491 //---------------------------------------------------------------------
492 sal_Bool OCommonPicker::implHandleInitializationArgument( const ::rtl::OUString& _rName, const Any& _rValue ) SAL_THROW( ( Exception, RuntimeException ) )
494 sal_Bool bKnown = sal_True;
495 if ( _rName.equalsAscii( "ParentWindow" ) )
497 m_xDialogParent.clear();
498 OSL_VERIFY( _rValue >>= m_xDialogParent );
499 OSL_ENSURE( VCLUnoHelper::GetWindow( m_xDialogParent ), "OCommonPicker::implHandleInitializationArgument: invalid parent window given!" );
501 else
502 bKnown = sal_False;
503 return bKnown;
506 //.........................................................................
507 } // namespace svt
508 //.........................................................................