1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: clickableimage.cxx,v $
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 //.........................................................................
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());
92 //------------------------------------------------------------------------------
93 OClickableImageBaseControl::OClickableImageBaseControl(const Reference
<XMultiServiceFactory
>& _rxFactory
, const ::rtl::OUString
& _aService
)
94 :OControl(_rxFactory
, _aService
)
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
)
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
);
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
);
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
);
164 m_pThread
->release();
169 OControl::disposing();
172 //------------------------------------------------------------------------------
173 OImageProducerThread_Impl
* OClickableImageBaseControl::getImageProducerThread()
177 m_pThread
= new OImageProducerThread_Impl( this );
178 m_pThread
->acquire();
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
;
201 //------------------------------------------------------------------------------
202 // Diese Methode wird auch aus einem Thread gerufen und muss deshalb
204 void OClickableImageBaseControl::actionPerformed_Impl(sal_Bool bNotifyListener
, const MouseEvent
& rEvt
)
206 if( bNotifyListener
)
208 if ( !approveAction() )
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() );
221 Reference
<XFormComponent
> xComp(getModel(), UNO_QUERY
);
225 xModelsParent
= xComp
->getParent();
226 if (!xModelsParent
.is())
229 // which button type?
230 xSet
= xSet
.query( xComp
);
233 xSet
->getPropertyValue(PROPERTY_BUTTONTYPE
) >>= eButtonType
;
238 case FormButtonType_RESET
:
240 // reset-Methoden muessen thread-safe sein!
241 Reference
<XReset
> xReset(xModelsParent
, UNO_QUERY
);
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
& )
264 case FormButtonType_URL
:
266 ::vos::OGuard
aGuard( Application::GetSolarMutex() );
268 Reference
< XModel
> xModel
= getXModel(xModelsParent
);
272 ///////////////////////////////////////////////////////////////////////
273 // Jetzt URL ausfuehren
274 Reference
< XController
> xController
= xModel
->getCurrentController();
275 if (!xController
.is())
278 Reference
< XFrame
> xFrame
= xController
->getFrame();
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();
326 xDisp
->dispatch( aURL
, aArgs
);
330 URL aHyperLink
= m_pFeatureInterception
->getTransformer().getStrictURLFromAscii( ".uno:OpenHyperlink" );
332 Reference
< XDispatch
> xDisp
= Reference
< XDispatchProvider
> (xFrame
,UNO_QUERY
)->queryDispatch(aHyperLink
, ::rtl::OUString() , 0);
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
);
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
;
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();
415 xSubmission
->submitWithInteraction( _rxHandler
);
419 // no "interceptor" -> ordinary (old-way) submission
420 Reference
< XChild
> xChild( getModel(), UNO_QUERY
);
421 Reference
< XSubmit
> xParentSubmission
;
423 xParentSubmission
= xParentSubmission
.query( xChild
->getParent() );
424 if ( xParentSubmission
.is() )
425 xParentSubmission
->submit( this, _rEvent
);
428 catch( const VetoException
& )
433 catch( const RuntimeException
& )
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
)
466 ,m_bDispatchUrlInternal(sal_False
)
467 ,m_bDownloading(sal_False
)
468 ,m_bProdStarted(sal_False
)
470 DBG_CTOR( OClickableImageBaseModel
, NULL
);
472 m_eButtonType
= FormButtonType_PUSH
;
475 //------------------------------------------------------------------
476 OClickableImageBaseModel::OClickableImageBaseModel( const OClickableImageBaseModel
* _pOriginal
, const Reference
<XMultiServiceFactory
>& _rxFactory
)
477 :OControlModel( _pOriginal
, _rxFactory
)
478 ,OPropertyChangeListener( m_aMutex
)
481 ,m_bDispatchUrlInternal(sal_False
)
482 ,m_bDownloading( sal_False
)
483 ,m_bProdStarted( sal_False
)
485 DBG_CTOR( OClickableImageBaseModel
, NULL
);
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
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
)
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
);
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
;
587 //------------------------------------------------------------------------------
588 void OClickableImageBaseModel::disposing()
590 OControlModel::disposing();
601 //------------------------------------------------------------------------------
602 Any SAL_CALL
OClickableImageBaseModel::queryAggregation(const Type
& _rType
) throw (RuntimeException
)
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
);
619 //------------------------------------------------------------------------------
620 void OClickableImageBaseModel::getFastPropertyValue(Any
& rValue
, sal_Int32 nHandle
) const
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;
629 OControlModel::getFastPropertyValue(rValue
, nHandle
);
633 //------------------------------------------------------------------------------
634 void OClickableImageBaseModel::setFastPropertyValue_NoBroadcast(sal_Int32 nHandle
, const Any
& rValue
) throw ( Exception
)
638 case PROPERTY_ID_BUTTONTYPE
:
639 DBG_ASSERT(isA(rValue
, static_cast<FormButtonType
*>(NULL
)), "OClickableImageBaseModel::setFastPropertyValue_NoBroadcast : invalid type !" );
640 rValue
>>= m_eButtonType
;
643 case PROPERTY_ID_TARGET_URL
:
644 DBG_ASSERT(rValue
.getValueType().getTypeClass() == TypeClass_STRING
, "OClickableImageBaseModel::setFastPropertyValue_NoBroadcast : invalid type !" );
645 rValue
>>= m_sTargetURL
;
648 case PROPERTY_ID_TARGET_FRAME
:
649 DBG_ASSERT(rValue
.getValueType().getTypeClass() == TypeClass_STRING
, "OClickableImageBaseModel::setFastPropertyValue_NoBroadcast : invalid type !" );
650 rValue
>>= m_sTargetFrame
;
653 case PROPERTY_ID_DISPATCHURLINTERNAL
:
654 DBG_ASSERT(rValue
.getValueType().getTypeClass() == TypeClass_BOOLEAN
, "OClickableImageBaseModel::setFastPropertyValue_NoBroadcast : invalid type !" );
655 rValue
>>= m_bDispatchUrlInternal
;
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
)
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
);
682 return OControlModel::convertFastPropertyValue(rConvertedValue
, rOldValue
, nHandle
, rValue
);
686 //------------------------------------------------------------------------------
687 void OClickableImageBaseModel::StartProduction()
689 ImageProducer
*pImgProd
= GetImageProducer();
692 getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ImageURL") ) ) >>= sURL
;
695 if ( ::svt::GraphicAccess::isSupportedURL( sURL
) )
696 pImgProd
->SetImage( sURL
);
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
;
704 if (m_pMedium
->GetErrorCode()==0)
706 SvStream
* pStream
= m_pMedium
->GetInStream();
708 pImgProd
->SetImage(*pStream
);
709 pImgProd
->startProduction();
710 m_bProdStarted
= sal_True
;
714 pImgProd
->SetImage(String());
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());
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
739 if (rURL
.getLength() && !::svt::GraphicAccess::isSupportedURL( rURL
) )
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
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;
772 SfxObjectShell
*pTestObjSh
= SfxObjectShell::Current();
775 Reference
< XModel
> xTestModel
= pTestObjSh
->GetModel();
776 if( xTestModel
== xModel
)
781 pTestObjSh
= SfxObjectShell::GetFirst();
782 while( !pObjSh
&& pTestObjSh
)
784 Reference
< XModel
> xTestModel
= pTestObjSh
->GetModel();
785 if( xTestModel
== xModel
)
788 pTestObjSh
= SfxObjectShell::GetNext( *pTestObjSh
);
793 #ifdef USE_REGISTER_TRANSFER
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();
803 m_pMedium
->SetLoadTargetFrame(pShMedium
->GetLoadTargetFrame());
807 // Keine Object-Shell, aber ein Medium? Dann uebernehmen wir
808 // zumindest den Referer.
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();
822 // Target-Frame uebertragen, damit auch javascript:-URLs
823 // "geladen" werden koennen.
824 const SfxMedium
*pShMedium
= pObjSh
->GetMedium();
826 m_pMedium
->SetLoadTargetFrame(pShMedium
->GetLoadTargetFrame());
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();
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
));
850 if ( ::svt::GraphicAccess::isSupportedURL( rURL
) )
851 GetImageProducer()->SetImage( rURL
);
852 GetImageProducer()->startProduction();
856 //------------------------------------------------------------------------------
857 void OClickableImageBaseModel::DataAvailable()
862 GetImageProducer()->NewDataAvailable();
865 //------------------------------------------------------------------------------
866 void OClickableImageBaseModel::DownloadDone()
869 m_bDownloading
= sal_False
;
872 //------------------------------------------------------------------------------
873 IMPL_STATIC_LINK( OClickableImageBaseModel
, DownloadDoneLink
, void*, EMPTYARG
)
875 ::osl::MutexGuard
aGuard( pThis
->m_aMutex
);
876 pThis
->DownloadDone();
880 //------------------------------------------------------------------------------
881 IMPL_STATIC_LINK( OClickableImageBaseModel
, DataAvailableLink
, void*, EMPTYARG
)
883 ::osl::MutexGuard
aGuard( pThis
->m_aMutex
);
884 pThis
->DataAvailable();
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
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
);
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
>&,
927 ((OClickableImageBaseControl
*)pCompImpl
)->actionPerformed_Impl( sal_True
, *(MouseEvent
*)pEvt
);
930 //.........................................................................
932 //.........................................................................