update dev300-m58
[ooovba.git] / forms / source / component / clickableimage.cxx
bloba4db2321168b14f368179e65d321e32712051b34
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: clickableimage.cxx,v $
10 * $Revision: 1.11 $
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_forms.hxx"
33 #include "clickableimage.hxx"
34 #include "controlfeatureinterception.hxx"
35 #include "urltransformer.hxx"
36 #include "componenttools.hxx"
37 #include <com/sun/star/form/XSubmit.hpp>
38 #include <com/sun/star/awt/SystemPointer.hpp>
39 #include <com/sun/star/form/FormComponentType.hpp>
40 #include <com/sun/star/frame/XDispatch.hpp>
41 #include <com/sun/star/frame/XDispatchProvider.hpp>
42 #include <com/sun/star/frame/FrameSearchFlag.hpp>
43 #include <com/sun/star/frame/XController.hpp>
44 #include <com/sun/star/frame/XFrame.hpp>
45 #include <com/sun/star/awt/ActionEvent.hpp>
46 #include <com/sun/star/awt/XActionListener.hpp>
47 #include <tools/urlobj.hxx>
48 #include <tools/debug.hxx>
49 #include <vcl/svapp.hxx>
50 #include <sfx2/docfile.hxx>
51 #include <sfx2/objsh.hxx>
52 #include <vos/mutex.hxx>
53 #include "services.hxx"
54 #include <comphelper/container.hxx>
55 #include <comphelper/listenernotification.hxx>
56 #include <svtools/imageresourceaccess.hxx>
57 #define LOCAL_URL_PREFIX '#'
59 //.........................................................................
60 namespace frm
62 //.........................................................................
64 using namespace ::com::sun::star::uno;
65 using namespace ::com::sun::star::sdb;
66 using namespace ::com::sun::star::sdbc;
67 using namespace ::com::sun::star::sdbcx;
68 using namespace ::com::sun::star::beans;
69 using namespace ::com::sun::star::container;
70 using namespace ::com::sun::star::form;
71 using namespace ::com::sun::star::awt;
72 using namespace ::com::sun::star::io;
73 using namespace ::com::sun::star::lang;
74 using namespace ::com::sun::star::util;
75 using namespace ::com::sun::star::frame;
76 using namespace ::com::sun::star::form::submission;
77 using ::com::sun::star::awt::MouseEvent;
78 using ::com::sun::star::task::XInteractionHandler;
80 //==================================================================
81 // OClickableImageBaseControl
82 //==================================================================
83 //------------------------------------------------------------------------------
84 Sequence<Type> OClickableImageBaseControl::_getTypes()
86 static Sequence<Type> aTypes;
87 if (!aTypes.getLength())
88 aTypes = concatSequences(OControl::_getTypes(), OClickableImageBaseControl_BASE::getTypes());
89 return aTypes;
92 //------------------------------------------------------------------------------
93 OClickableImageBaseControl::OClickableImageBaseControl(const Reference<XMultiServiceFactory>& _rxFactory, const ::rtl::OUString& _aService)
94 :OControl(_rxFactory, _aService)
95 ,m_pThread(NULL)
96 ,m_aSubmissionVetoListeners( m_aMutex )
97 ,m_aApproveActionListeners( m_aMutex )
98 ,m_aActionListeners( m_aMutex )
100 m_pFeatureInterception.reset( new ControlFeatureInterception( _rxFactory ) );
103 //------------------------------------------------------------------------------
104 OClickableImageBaseControl::~OClickableImageBaseControl()
106 if (!OComponentHelper::rBHelper.bDisposed)
108 acquire();
109 dispose();
113 // UNO Anbindung
114 //------------------------------------------------------------------------------
115 Any SAL_CALL OClickableImageBaseControl::queryAggregation(const Type& _rType) throw (RuntimeException)
117 Any aReturn = OControl::queryAggregation(_rType);
118 if (!aReturn.hasValue())
119 aReturn = OClickableImageBaseControl_BASE::queryInterface(_rType);
120 return aReturn;
123 // XApproveActionBroadcaster
124 //------------------------------------------------------------------------------
125 void OClickableImageBaseControl::addApproveActionListener(
126 const Reference<XApproveActionListener>& l) throw( RuntimeException )
128 m_aApproveActionListeners.addInterface(l);
131 //------------------------------------------------------------------------------
132 void OClickableImageBaseControl::removeApproveActionListener(
133 const Reference<XApproveActionListener>& l) throw( RuntimeException )
135 m_aApproveActionListeners.removeInterface(l);
138 //--------------------------------------------------------------------
139 void SAL_CALL OClickableImageBaseControl::registerDispatchProviderInterceptor( const Reference< XDispatchProviderInterceptor >& _rxInterceptor ) throw (RuntimeException)
141 m_pFeatureInterception->registerDispatchProviderInterceptor( _rxInterceptor );
144 //--------------------------------------------------------------------
145 void SAL_CALL OClickableImageBaseControl::releaseDispatchProviderInterceptor( const Reference< XDispatchProviderInterceptor >& _rxInterceptor ) throw (RuntimeException)
147 m_pFeatureInterception->releaseDispatchProviderInterceptor( _rxInterceptor );
150 // OComponentHelper
151 //------------------------------------------------------------------------------
152 void OClickableImageBaseControl::disposing()
154 EventObject aEvent( static_cast< XWeak* >( this ) );
155 m_aApproveActionListeners.disposeAndClear( aEvent );
156 m_aActionListeners.disposeAndClear( aEvent );
157 m_aSubmissionVetoListeners.disposeAndClear( aEvent );
158 m_pFeatureInterception->dispose();
161 ::osl::MutexGuard aGuard( m_aMutex );
162 if( m_pThread )
164 m_pThread->release();
165 m_pThread = NULL;
169 OControl::disposing();
172 //------------------------------------------------------------------------------
173 OImageProducerThread_Impl* OClickableImageBaseControl::getImageProducerThread()
175 if ( !m_pThread )
177 m_pThread = new OImageProducerThread_Impl( this );
178 m_pThread->acquire();
179 m_pThread->create();
181 return m_pThread;
184 //------------------------------------------------------------------------------
185 bool OClickableImageBaseControl::approveAction( )
187 sal_Bool bCancelled = sal_False;
188 EventObject aEvent( static_cast< XWeak* >( this ) );
190 ::cppu::OInterfaceIteratorHelper aIter( m_aApproveActionListeners );
191 while( !bCancelled && aIter.hasMoreElements() )
193 // Jede approveAction-Methode muss thread-safe sein!!!
194 if( !static_cast< XApproveActionListener* >( aIter.next() )->approveAction( aEvent ) )
195 bCancelled = sal_True;
198 return !bCancelled;
201 //------------------------------------------------------------------------------
202 // Diese Methode wird auch aus einem Thread gerufen und muss deshalb
203 // thread-safe sein.
204 void OClickableImageBaseControl::actionPerformed_Impl(sal_Bool bNotifyListener, const MouseEvent& rEvt)
206 if( bNotifyListener )
208 if ( !approveAction() )
209 return;
212 // Ob der Rest des Codes Thread-Safe ist weiss man nicht genau. Deshalb
213 // wird das meiste bei gelocktem Solar-Mutex erledigen.
214 Reference<XPropertySet> xSet;
215 Reference< XInterface > xModelsParent;
216 FormButtonType eButtonType = FormButtonType_PUSH;
218 ::vos::OGuard aGuard( Application::GetSolarMutex() );
220 // Parent holen
221 Reference<XFormComponent> xComp(getModel(), UNO_QUERY);
222 if (!xComp.is())
223 return;
225 xModelsParent = xComp->getParent();
226 if (!xModelsParent.is())
227 return;
229 // which button type?
230 xSet = xSet.query( xComp );
231 if ( !xSet.is() )
232 return;
233 xSet->getPropertyValue(PROPERTY_BUTTONTYPE) >>= eButtonType;
236 switch (eButtonType)
238 case FormButtonType_RESET:
240 // reset-Methoden muessen thread-safe sein!
241 Reference<XReset> xReset(xModelsParent, UNO_QUERY);
242 if (!xReset.is())
243 return;
245 xReset->reset();
247 break;
249 case FormButtonType_SUBMIT:
251 // if some outer component can provide an interaction handler, use it
252 Reference< XInteractionHandler > xHandler( m_pFeatureInterception->queryDispatch( "private:/InteractionHandler" ), UNO_QUERY );
255 implSubmit( rEvt, xHandler );
257 catch( const Exception& )
259 // ignore
262 break;
264 case FormButtonType_URL:
266 ::vos::OGuard aGuard( Application::GetSolarMutex() );
268 Reference< XModel > xModel = getXModel(xModelsParent);
269 if (!xModel.is())
270 return;
272 ///////////////////////////////////////////////////////////////////////
273 // Jetzt URL ausfuehren
274 Reference< XController > xController = xModel->getCurrentController();
275 if (!xController.is())
276 return;
278 Reference< XFrame > xFrame = xController->getFrame();
279 if( !xFrame.is() )
280 return;
282 URL aURL;
283 aURL.Complete =
284 getString(xSet->getPropertyValue(PROPERTY_TARGET_URL));
286 if (aURL.Complete.getLength() && (LOCAL_URL_PREFIX == aURL.Complete.getStr()[0]))
287 { // the URL contains a local URL only. Since the URLTransformer does not handle this case correctly
288 // (it can't: it does not know the document URL), we have to take care for this ourself.
289 // The real solution would be to not allow such relative URLs (there is a rule that at runtime, all
290 // URLs have to be absolute), but for compatibility reasons this is no option.
291 // The more as the user does not want to see a local URL as "file://<path>/<document>#mark" if it
292 // could be "#mark" as well.
293 // If we someday say that this hack (yes, it's kind of a hack) is not sustainable anymore, the complete
294 // solutiuon would be:
295 // * recognize URLs consisting of a mark only while _reading_ the document
296 // * for this, allow the INetURLObject (which at the moment is invoked when reading URLs) to
297 // transform such mark-only URLs into correct absolute URLs
298 // * at the UI, show only the mark
299 // * !!!! recognize every SAVEAS on the document, so the absolute URL can be adjusted. This seems
300 // rather impossible !!!
301 // 89752 - 23.07.2001 - frank.schoenheit@sun.com
302 aURL.Mark = aURL.Complete;
303 aURL.Complete = xModel->getURL();
304 aURL.Complete += aURL.Mark;
307 sal_Bool bDispatchUrlInternal = sal_False;
308 xSet->getPropertyValue(PROPERTY_DISPATCHURLINTERNAL) >>= bDispatchUrlInternal;
309 if ( bDispatchUrlInternal )
311 m_pFeatureInterception->getTransformer().parseSmartWithAsciiProtocol( aURL, INET_FILE_SCHEME );
313 ::rtl::OUString aTargetFrame;
314 xSet->getPropertyValue(PROPERTY_TARGET_FRAME) >>= aTargetFrame;
316 Reference< XDispatch > xDisp = Reference< XDispatchProvider > (xFrame,UNO_QUERY)->queryDispatch( aURL, aTargetFrame,
317 FrameSearchFlag::SELF | FrameSearchFlag::PARENT |
318 FrameSearchFlag::SIBLINGS | FrameSearchFlag::CREATE );
320 Sequence<PropertyValue> aArgs(1);
321 PropertyValue& rProp = aArgs.getArray()[0];
322 rProp.Name = ::rtl::OUString::createFromAscii("Referer");
323 rProp.Value <<= xModel->getURL();
325 if (xDisp.is())
326 xDisp->dispatch( aURL, aArgs );
328 else
330 URL aHyperLink = m_pFeatureInterception->getTransformer().getStrictURLFromAscii( ".uno:OpenHyperlink" );
332 Reference< XDispatch > xDisp = Reference< XDispatchProvider > (xFrame,UNO_QUERY)->queryDispatch(aHyperLink, ::rtl::OUString() , 0);
334 if ( xDisp.is() )
336 Sequence<PropertyValue> aProps(3);
337 aProps[0].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("URL"));
338 aProps[0].Value <<= aURL.Complete;
340 aProps[1].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("FrameName"));
341 aProps[1].Value = xSet->getPropertyValue(PROPERTY_TARGET_FRAME);
343 aProps[2].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Referer"));
344 aProps[2].Value <<= xModel->getURL();
346 xDisp->dispatch( aHyperLink, aProps );
349 } break;
350 default:
352 // notify the action listeners for a push button
353 ActionEvent aEvt(static_cast<XWeak*>(this), m_aActionCommand);
354 m_aActionListeners.notifyEach( &XActionListener::actionPerformed, aEvt );
360 //--------------------------------------------------------------------
361 void SAL_CALL OClickableImageBaseControl::addSubmissionVetoListener( const Reference< submission::XSubmissionVetoListener >& listener ) throw (NoSupportException, RuntimeException)
363 m_aSubmissionVetoListeners.addInterface( listener );
366 //--------------------------------------------------------------------
367 void SAL_CALL OClickableImageBaseControl::removeSubmissionVetoListener( const Reference< submission::XSubmissionVetoListener >& listener ) throw (NoSupportException, RuntimeException)
369 m_aSubmissionVetoListeners.removeInterface( listener );
372 //--------------------------------------------------------------------
373 void SAL_CALL OClickableImageBaseControl::submitWithInteraction( const Reference< XInteractionHandler >& _rxHandler ) throw (VetoException, WrappedTargetException, RuntimeException)
375 implSubmit( MouseEvent(), _rxHandler );
378 //--------------------------------------------------------------------
379 void SAL_CALL OClickableImageBaseControl::submit( ) throw (VetoException, WrappedTargetException, RuntimeException)
381 implSubmit( MouseEvent(), NULL );
384 //--------------------------------------------------------------------
385 Sequence< ::rtl::OUString > SAL_CALL OClickableImageBaseControl::getSupportedServiceNames( ) throw (RuntimeException)
387 Sequence< ::rtl::OUString > aSupported = OControl::getSupportedServiceNames();
388 aSupported.realloc( aSupported.getLength() + 1 );
390 ::rtl::OUString* pArray = aSupported.getArray();
391 pArray[ aSupported.getLength() - 1 ] = FRM_SUN_CONTROL_SUBMITBUTTON;
393 return aSupported;
396 //--------------------------------------------------------------------
397 void OClickableImageBaseControl::implSubmit( const MouseEvent& _rEvent, const Reference< XInteractionHandler >& _rxHandler ) SAL_THROW((VetoException, WrappedTargetException, RuntimeException))
401 // allow the veto listeners to join the game
402 m_aSubmissionVetoListeners.notifyEach( &XSubmissionVetoListener::submitting, EventObject( *this ) );
404 // see whether there's an "submit interceptor" set at our model
405 Reference< submission::XSubmissionSupplier > xSubmissionSupp( getModel(), UNO_QUERY );
406 Reference< XSubmission > xSubmission;
407 if ( xSubmissionSupp.is() )
408 xSubmission = xSubmissionSupp->getSubmission();
410 if ( xSubmission.is() )
412 if ( !_rxHandler.is() )
413 xSubmission->submit();
414 else
415 xSubmission->submitWithInteraction( _rxHandler );
417 else
419 // no "interceptor" -> ordinary (old-way) submission
420 Reference< XChild > xChild( getModel(), UNO_QUERY );
421 Reference< XSubmit > xParentSubmission;
422 if ( xChild.is() )
423 xParentSubmission = xParentSubmission.query( xChild->getParent() );
424 if ( xParentSubmission.is() )
425 xParentSubmission->submit( this, _rEvent );
428 catch( const VetoException& )
430 // allowed to leave
431 throw;
433 catch( const RuntimeException& )
435 // allowed to leave
436 throw;
438 catch( const Exception& e )
440 OSL_ENSURE( sal_False, "OClickableImageBaseControl::implSubmit: caught an unknown exception!" );
441 throw WrappedTargetException( ::rtl::OUString(), *this, makeAny( e ) );
445 //==================================================================
446 // OClickableImageBaseModel
447 //==================================================================
448 //------------------------------------------------------------------------------
449 Sequence<Type> OClickableImageBaseModel::_getTypes()
451 return concatSequences(
452 OControlModel::_getTypes(),
453 OClickableImageBaseModel_Base::getTypes()
457 //------------------------------------------------------------------
458 DBG_NAME( OClickableImageBaseModel )
459 //------------------------------------------------------------------
460 OClickableImageBaseModel::OClickableImageBaseModel( const Reference< XMultiServiceFactory >& _rxFactory, const ::rtl::OUString& _rUnoControlModelTypeName,
461 const ::rtl::OUString& rDefault )
462 :OControlModel( _rxFactory, _rUnoControlModelTypeName, rDefault )
463 ,OPropertyChangeListener(m_aMutex)
464 ,m_pMedium(NULL)
465 ,m_pProducer( NULL )
466 ,m_bDispatchUrlInternal(sal_False)
467 ,m_bDownloading(sal_False)
468 ,m_bProdStarted(sal_False)
470 DBG_CTOR( OClickableImageBaseModel, NULL );
471 implConstruct();
472 m_eButtonType = FormButtonType_PUSH;
475 //------------------------------------------------------------------
476 OClickableImageBaseModel::OClickableImageBaseModel( const OClickableImageBaseModel* _pOriginal, const Reference<XMultiServiceFactory>& _rxFactory )
477 :OControlModel( _pOriginal, _rxFactory )
478 ,OPropertyChangeListener( m_aMutex )
479 ,m_pMedium( NULL )
480 ,m_pProducer( NULL )
481 ,m_bDispatchUrlInternal(sal_False)
482 ,m_bDownloading( sal_False )
483 ,m_bProdStarted( sal_False )
485 DBG_CTOR( OClickableImageBaseModel, NULL );
486 implConstruct();
488 // copy properties
489 m_eButtonType = _pOriginal->m_eButtonType;
490 m_sTargetURL = _pOriginal->m_sTargetURL;
491 m_sTargetFrame = _pOriginal->m_sTargetFrame;
492 m_bDispatchUrlInternal = _pOriginal->m_bDispatchUrlInternal;
495 //------------------------------------------------------------------------------
496 void OClickableImageBaseModel::implInitializeImageURL( )
498 osl_incrementInterlockedCount( &m_refCount );
500 // simulate a propertyChanged event for the ImageURL
501 // 2003-05-15 - #109591# - fs@openoffice.org
502 Any aImageURL;
503 getFastPropertyValue( aImageURL, PROPERTY_ID_IMAGE_URL );
504 _propertyChanged( PropertyChangeEvent( *this, PROPERTY_IMAGE_URL, sal_False, PROPERTY_ID_IMAGE_URL, Any( ), aImageURL ) );
506 osl_decrementInterlockedCount( &m_refCount );
509 //------------------------------------------------------------------------------
510 void OClickableImageBaseModel::implConstruct()
512 m_pProducer = new ImageProducer;
513 increment( m_refCount );
515 m_xProducer = m_pProducer;
517 if ( m_xAggregateSet.is() )
519 OPropertyChangeMultiplexer* pMultiplexer = new OPropertyChangeMultiplexer( this, m_xAggregateSet );
520 pMultiplexer->addProperty( PROPERTY_IMAGE_URL );
523 decrement(m_refCount);
526 //------------------------------------------------------------------------------
527 OClickableImageBaseModel::~OClickableImageBaseModel()
529 if (!OComponentHelper::rBHelper.bDisposed)
531 acquire();
532 dispose();
534 DBG_ASSERT(m_pMedium == NULL, "OClickableImageBaseModel::~OClickableImageBaseModel : leaving a memory leak ...");
535 // spaetestens im dispose sollte das aufgeraeumt worden sein
537 DBG_DTOR( OClickableImageBaseModel, NULL );
540 // XImageProducer
541 //--------------------------------------------------------------------
542 void SAL_CALL OClickableImageBaseModel::addConsumer( const Reference< XImageConsumer >& _rxConsumer ) throw (RuntimeException)
544 ImageModelMethodGuard aGuard( *this );
545 GetImageProducer()->addConsumer( _rxConsumer );
548 //--------------------------------------------------------------------
549 void SAL_CALL OClickableImageBaseModel::removeConsumer( const Reference< XImageConsumer >& _rxConsumer ) throw (RuntimeException)
551 ImageModelMethodGuard aGuard( *this );
552 GetImageProducer()->removeConsumer( _rxConsumer );
555 //--------------------------------------------------------------------
556 void SAL_CALL OClickableImageBaseModel::startProduction( ) throw (RuntimeException)
558 ImageModelMethodGuard aGuard( *this );
559 GetImageProducer()->startProduction();
562 //--------------------------------------------------------------------
563 Reference< submission::XSubmission > SAL_CALL OClickableImageBaseModel::getSubmission() throw (RuntimeException)
565 return m_xSubmissionDelegate;
568 //--------------------------------------------------------------------
569 void SAL_CALL OClickableImageBaseModel::setSubmission( const Reference< submission::XSubmission >& _submission ) throw (RuntimeException)
571 m_xSubmissionDelegate = _submission;
574 //--------------------------------------------------------------------
575 Sequence< ::rtl::OUString > SAL_CALL OClickableImageBaseModel::getSupportedServiceNames( ) throw (RuntimeException)
577 Sequence< ::rtl::OUString > aSupported = OControlModel::getSupportedServiceNames();
578 aSupported.realloc( aSupported.getLength() + 1 );
580 ::rtl::OUString* pArray = aSupported.getArray();
581 pArray[ aSupported.getLength() - 1 ] = FRM_SUN_COMPONENT_SUBMITBUTTON;
583 return aSupported;
586 // OComponentHelper
587 //------------------------------------------------------------------------------
588 void OClickableImageBaseModel::disposing()
590 OControlModel::disposing();
591 if (m_pMedium)
593 delete m_pMedium;
594 m_pMedium = NULL;
597 m_xProducer = NULL;
598 m_pProducer = NULL;
601 //------------------------------------------------------------------------------
602 Any SAL_CALL OClickableImageBaseModel::queryAggregation(const Type& _rType) throw (RuntimeException)
604 // order matters:
605 // we definately want to "overload" the XImageProducer interface of our aggregate,
606 // thus check OClickableImageBaseModel_Base (which provides this) first
607 Any aReturn = OClickableImageBaseModel_Base::queryInterface( _rType );
609 // BUT: _don't_ let it feel responsible for the XTypeProvider interface
610 // (as this is implemented by our base class in the proper way)
611 if ( _rType.equals( ::getCppuType( static_cast< Reference< XTypeProvider >* >( NULL ) ) )
612 || !aReturn.hasValue()
614 aReturn = OControlModel::queryAggregation( _rType );
616 return aReturn;
619 //------------------------------------------------------------------------------
620 void OClickableImageBaseModel::getFastPropertyValue(Any& rValue, sal_Int32 nHandle) const
622 switch (nHandle)
624 case PROPERTY_ID_BUTTONTYPE : rValue <<= m_eButtonType; break;
625 case PROPERTY_ID_TARGET_URL : rValue <<= m_sTargetURL; break;
626 case PROPERTY_ID_TARGET_FRAME : rValue <<= m_sTargetFrame; break;
627 case PROPERTY_ID_DISPATCHURLINTERNAL : rValue <<= m_bDispatchUrlInternal; break;
628 default:
629 OControlModel::getFastPropertyValue(rValue, nHandle);
633 //------------------------------------------------------------------------------
634 void OClickableImageBaseModel::setFastPropertyValue_NoBroadcast(sal_Int32 nHandle, const Any& rValue) throw ( Exception)
636 switch (nHandle)
638 case PROPERTY_ID_BUTTONTYPE :
639 DBG_ASSERT(isA(rValue, static_cast<FormButtonType*>(NULL)), "OClickableImageBaseModel::setFastPropertyValue_NoBroadcast : invalid type !" );
640 rValue >>= m_eButtonType;
641 break;
643 case PROPERTY_ID_TARGET_URL :
644 DBG_ASSERT(rValue.getValueType().getTypeClass() == TypeClass_STRING, "OClickableImageBaseModel::setFastPropertyValue_NoBroadcast : invalid type !" );
645 rValue >>= m_sTargetURL;
646 break;
648 case PROPERTY_ID_TARGET_FRAME :
649 DBG_ASSERT(rValue.getValueType().getTypeClass() == TypeClass_STRING, "OClickableImageBaseModel::setFastPropertyValue_NoBroadcast : invalid type !" );
650 rValue >>= m_sTargetFrame;
651 break;
653 case PROPERTY_ID_DISPATCHURLINTERNAL:
654 DBG_ASSERT(rValue.getValueType().getTypeClass() == TypeClass_BOOLEAN, "OClickableImageBaseModel::setFastPropertyValue_NoBroadcast : invalid type !" );
655 rValue >>= m_bDispatchUrlInternal;
656 break;
658 default:
659 OControlModel::setFastPropertyValue_NoBroadcast(nHandle, rValue);
663 //------------------------------------------------------------------------------
664 sal_Bool OClickableImageBaseModel::convertFastPropertyValue(Any& rConvertedValue, Any& rOldValue, sal_Int32 nHandle, const Any& rValue)
665 throw( IllegalArgumentException )
667 switch (nHandle)
669 case PROPERTY_ID_BUTTONTYPE :
670 return tryPropertyValueEnum( rConvertedValue, rOldValue, rValue, m_eButtonType );
672 case PROPERTY_ID_TARGET_URL :
673 return tryPropertyValue(rConvertedValue, rOldValue, rValue, m_sTargetURL);
675 case PROPERTY_ID_TARGET_FRAME :
676 return tryPropertyValue(rConvertedValue, rOldValue, rValue, m_sTargetFrame);
678 case PROPERTY_ID_DISPATCHURLINTERNAL :
679 return tryPropertyValue(rConvertedValue, rOldValue, rValue, m_bDispatchUrlInternal);
681 default:
682 return OControlModel::convertFastPropertyValue(rConvertedValue, rOldValue, nHandle, rValue);
686 //------------------------------------------------------------------------------
687 void OClickableImageBaseModel::StartProduction()
689 ImageProducer *pImgProd = GetImageProducer();
690 // grab the ImageURL
691 rtl::OUString sURL;
692 getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ImageURL") ) ) >>= sURL;
693 if (!m_pMedium)
695 if ( ::svt::GraphicAccess::isSupportedURL( sURL ) )
696 pImgProd->SetImage( sURL );
697 else
698 // caution: the medium may be NULL if somebody gave us a invalid URL to work with
699 // 11/24/2000 - 79667 - FS
700 pImgProd->SetImage(String());
701 m_bDownloading = sal_False;
702 return;
704 if (m_pMedium->GetErrorCode()==0)
706 SvStream* pStream = m_pMedium->GetInStream();
708 pImgProd->SetImage(*pStream);
709 pImgProd->startProduction();
710 m_bProdStarted = sal_True;
712 else
714 pImgProd->SetImage(String());
715 delete m_pMedium;
716 m_pMedium = 0;
717 m_bDownloading = sal_False;
721 //------------------------------------------------------------------------------
722 void OClickableImageBaseModel::SetURL( const ::rtl::OUString& rURL )
724 if (m_pMedium || !rURL.getLength())
726 // Den Stream am Producer freigeben, bevor das Medium geloscht wird.
727 GetImageProducer()->SetImage(String());
728 delete m_pMedium;
729 m_pMedium = NULL;
732 // the SfxMedium is not allowed to be created with an invalid URL, so we have to check this first
733 // 23.01.2001 - 81927 - FS
734 INetURLObject aUrl(rURL);
735 if (INET_PROT_NOT_VALID == aUrl.GetProtocol())
736 // we treat an invalid URL like we would treat no URL
737 return;
739 if (rURL.getLength() && !::svt::GraphicAccess::isSupportedURL( rURL ) )
741 if (m_pMedium)
742 delete m_pMedium;
744 m_pMedium = new SfxMedium(rURL, STREAM_STD_READ, sal_False);
745 m_pMedium->SetDataAvailableLink(
746 STATIC_LINK(this, OClickableImageBaseModel, DataAvailableLink));
748 // Das XModel suchen, um an die Object-Shell oder zumindest den
749 // Referer zu gelangen.
750 // Das Model findet man allerdings nur beim Laden von HTML-Dokumenten
751 // und dann, wenn die URL in einem bereits geladenen Dokument
752 // geaendert wird. Waehrend des Ladens kommt man nicht an das
753 // Model ran.
754 Reference< XModel > xModel;
755 InterfaceRef xIfc( *this );
756 while( !xModel.is() && xIfc.is() )
758 Reference<XChild> xChild( xIfc, UNO_QUERY );
759 xIfc = xChild->getParent();
760 query_interface(xIfc, xModel);
763 // Die Object-Shell suchen, indem wir
764 // ueber alle Object-Shells iterieren und deren XModel mit dem
765 // eigenen vergleichen. Als Optimierung probieren wir aber erstmal
766 // die aktuelle Object-Shell.
767 // wir unser XModel mit dem aller Object
768 SfxObjectShell *pObjSh = 0;
770 if( xModel.is() )
772 SfxObjectShell *pTestObjSh = SfxObjectShell::Current();
773 if( pTestObjSh )
775 Reference< XModel > xTestModel = pTestObjSh->GetModel();
776 if( xTestModel == xModel )
777 pObjSh = pTestObjSh;
779 if( !pObjSh )
781 pTestObjSh = SfxObjectShell::GetFirst();
782 while( !pObjSh && pTestObjSh )
784 Reference< XModel > xTestModel = pTestObjSh->GetModel();
785 if( xTestModel == xModel )
786 pObjSh = pTestObjSh;
787 else
788 pTestObjSh = SfxObjectShell::GetNext( *pTestObjSh );
793 #ifdef USE_REGISTER_TRANSFER
794 if( pObjSh )
796 // Medium registrieren, damit abgebrochen werden kann
797 pObjSh->RegisterTransfer( *m_pMedium );
799 // Target-Frame uebertragen, damit auch javascript:-URLs
800 // "geladen" werden koennen.
801 const SfxMedium *pShMedium = pObjSh->GetMedium();
802 if( pShMedium )
803 m_pMedium->SetLoadTargetFrame(pShMedium->GetLoadTargetFrame());
805 else
807 // Keine Object-Shell, aber ein Medium? Dann uebernehmen wir
808 // zumindest den Referer.
809 if( xModel.is() )
811 ::rtl::OUString sReferer( xModel->getURL() );
812 if( sReferer.getLength() )
813 m_pMedium->SetReferer( OUStringToString(sReferer, CHARSET_SYSTEM) );
816 // Keinen Eintrag im Roter Button Menu
817 m_pMedium->SetDontCreateCancellable();
819 #else
820 if( pObjSh )
822 // Target-Frame uebertragen, damit auch javascript:-URLs
823 // "geladen" werden koennen.
824 const SfxMedium *pShMedium = pObjSh->GetMedium();
825 if( pShMedium )
826 m_pMedium->SetLoadTargetFrame(pShMedium->GetLoadTargetFrame());
829 if( xModel.is() )
831 ::rtl::OUString sReferer( xModel->getURL() );
832 if( sReferer.getLength() )
833 m_pMedium->SetReferer( sReferer );
836 // Keinen Eintrag im Roter Button Menu
837 m_pMedium->SetDontCreateCancellable();
838 #endif
840 // Downloading-Flag auf sal_True setzen. Es werden dann auch
841 // Data-Available-Links, wenn wir in den Pending-Staus gelangen.
842 m_bDownloading = sal_True;
843 m_bProdStarted = sal_False;
845 // Download anstossen (Achtung: Kann auch synchron sein).
846 m_pMedium->DownLoad(STATIC_LINK(this, OClickableImageBaseModel, DownloadDoneLink));
848 else
850 if ( ::svt::GraphicAccess::isSupportedURL( rURL ) )
851 GetImageProducer()->SetImage( rURL );
852 GetImageProducer()->startProduction();
856 //------------------------------------------------------------------------------
857 void OClickableImageBaseModel::DataAvailable()
859 if (!m_bProdStarted)
860 StartProduction();
862 GetImageProducer()->NewDataAvailable();
865 //------------------------------------------------------------------------------
866 void OClickableImageBaseModel::DownloadDone()
868 DataAvailable();
869 m_bDownloading = sal_False;
872 //------------------------------------------------------------------------------
873 IMPL_STATIC_LINK( OClickableImageBaseModel, DownloadDoneLink, void*, EMPTYARG )
875 ::osl::MutexGuard aGuard( pThis->m_aMutex );
876 pThis->DownloadDone();
877 return 0;
880 //------------------------------------------------------------------------------
881 IMPL_STATIC_LINK( OClickableImageBaseModel, DataAvailableLink, void*, EMPTYARG )
883 ::osl::MutexGuard aGuard( pThis->m_aMutex );
884 pThis->DataAvailable();
885 return 0;
888 //------------------------------------------------------------------------------
889 void OClickableImageBaseModel::_propertyChanged( const PropertyChangeEvent& rEvt )
890 throw( RuntimeException )
892 // Wenn eine URL gesetzt worden ist, muss die noch an den ImageProducer
893 // weitergereicht werden.
894 ::osl::MutexGuard aGuard(m_aMutex);
895 SetURL( getString(rEvt.NewValue) );
898 // -----------------------------------------------------------------------------
899 Any OClickableImageBaseModel::getPropertyDefaultByHandle( sal_Int32 nHandle ) const
901 switch (nHandle)
903 case PROPERTY_ID_BUTTONTYPE : return makeAny( FormButtonType_PUSH );
904 case PROPERTY_ID_TARGET_URL :
905 case PROPERTY_ID_TARGET_FRAME : return makeAny( ::rtl::OUString() );
906 case PROPERTY_ID_DISPATCHURLINTERNAL : return makeAny( sal_False );
907 default:
908 return OControlModel::getPropertyDefaultByHandle(nHandle);
912 //==================================================================
913 // OImageProducerThread_Impl
914 //==================================================================
915 //------------------------------------------------------------------
916 EventObject* OImageProducerThread_Impl::cloneEvent( const EventObject* _pEvt ) const
918 return new EventObject( *_pEvt );
921 //------------------------------------------------------------------
922 void OImageProducerThread_Impl::processEvent( ::cppu::OComponentHelper *pCompImpl,
923 const EventObject* pEvt,
924 const Reference<XControl>&,
925 sal_Bool )
927 ((OClickableImageBaseControl *)pCompImpl)->actionPerformed_Impl( sal_True, *(MouseEvent *)pEvt );
930 //.........................................................................
931 } // namespace frm
932 //.........................................................................