1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 .
20 #include "clickableimage.hxx"
21 #include "controlfeatureinterception.hxx"
22 #include "urltransformer.hxx"
23 #include "componenttools.hxx"
24 #include <com/sun/star/form/XSubmit.hpp>
25 #include <com/sun/star/awt/SystemPointer.hpp>
26 #include <com/sun/star/form/FormComponentType.hpp>
27 #include <com/sun/star/frame/XDispatch.hpp>
28 #include <com/sun/star/frame/XDispatchProvider.hpp>
29 #include <com/sun/star/frame/FrameSearchFlag.hpp>
30 #include <com/sun/star/frame/XController.hpp>
31 #include <com/sun/star/frame/XFrame.hpp>
32 #include <com/sun/star/awt/ActionEvent.hpp>
33 #include <com/sun/star/awt/XActionListener.hpp>
34 #include <tools/urlobj.hxx>
35 #include <tools/debug.hxx>
36 #include <vcl/svapp.hxx>
37 #include <sfx2/docfile.hxx>
38 #include <sfx2/objsh.hxx>
39 #include <osl/mutex.hxx>
40 #include "services.hxx"
41 #include <comphelper/container.hxx>
42 #include <comphelper/listenernotification.hxx>
43 #include <svtools/imageresourceaccess.hxx>
44 #define LOCAL_URL_PREFIX '#'
46 //.........................................................................
49 //.........................................................................
51 using namespace ::com::sun::star::uno
;
52 using namespace ::com::sun::star::sdb
;
53 using namespace ::com::sun::star::sdbc
;
54 using namespace ::com::sun::star::sdbcx
;
55 using namespace ::com::sun::star::beans
;
56 using namespace ::com::sun::star::container
;
57 using namespace ::com::sun::star::form
;
58 using namespace ::com::sun::star::awt
;
59 using namespace ::com::sun::star::io
;
60 using namespace ::com::sun::star::lang
;
61 using namespace ::com::sun::star::util
;
62 using namespace ::com::sun::star::frame
;
63 using namespace ::com::sun::star::form::submission
;
64 using ::com::sun::star::awt::MouseEvent
;
65 using ::com::sun::star::task::XInteractionHandler
;
67 //==================================================================
68 // OClickableImageBaseControl
69 //==================================================================
70 //------------------------------------------------------------------------------
71 Sequence
<Type
> OClickableImageBaseControl::_getTypes()
73 static Sequence
<Type
> aTypes
;
74 if (!aTypes
.getLength())
75 aTypes
= concatSequences(OControl::_getTypes(), OClickableImageBaseControl_BASE::getTypes());
79 //------------------------------------------------------------------------------
80 OClickableImageBaseControl::OClickableImageBaseControl(const Reference
<XMultiServiceFactory
>& _rxFactory
, const OUString
& _aService
)
81 :OControl(_rxFactory
, _aService
)
83 ,m_aSubmissionVetoListeners( m_aMutex
)
84 ,m_aApproveActionListeners( m_aMutex
)
85 ,m_aActionListeners( m_aMutex
)
87 m_pFeatureInterception
.reset( new ControlFeatureInterception( _rxFactory
) );
90 //------------------------------------------------------------------------------
91 OClickableImageBaseControl::~OClickableImageBaseControl()
93 if (!OComponentHelper::rBHelper
.bDisposed
)
101 //------------------------------------------------------------------------------
102 Any SAL_CALL
OClickableImageBaseControl::queryAggregation(const Type
& _rType
) throw (RuntimeException
)
104 Any aReturn
= OControl::queryAggregation(_rType
);
105 if (!aReturn
.hasValue())
106 aReturn
= OClickableImageBaseControl_BASE::queryInterface(_rType
);
110 // XApproveActionBroadcaster
111 //------------------------------------------------------------------------------
112 void OClickableImageBaseControl::addApproveActionListener(
113 const Reference
<XApproveActionListener
>& l
) throw( RuntimeException
)
115 m_aApproveActionListeners
.addInterface(l
);
118 //------------------------------------------------------------------------------
119 void OClickableImageBaseControl::removeApproveActionListener(
120 const Reference
<XApproveActionListener
>& l
) throw( RuntimeException
)
122 m_aApproveActionListeners
.removeInterface(l
);
125 //--------------------------------------------------------------------
126 void SAL_CALL
OClickableImageBaseControl::registerDispatchProviderInterceptor( const Reference
< XDispatchProviderInterceptor
>& _rxInterceptor
) throw (RuntimeException
)
128 m_pFeatureInterception
->registerDispatchProviderInterceptor( _rxInterceptor
);
131 //--------------------------------------------------------------------
132 void SAL_CALL
OClickableImageBaseControl::releaseDispatchProviderInterceptor( const Reference
< XDispatchProviderInterceptor
>& _rxInterceptor
) throw (RuntimeException
)
134 m_pFeatureInterception
->releaseDispatchProviderInterceptor( _rxInterceptor
);
138 //------------------------------------------------------------------------------
139 void OClickableImageBaseControl::disposing()
141 EventObject
aEvent( static_cast< XWeak
* >( this ) );
142 m_aApproveActionListeners
.disposeAndClear( aEvent
);
143 m_aActionListeners
.disposeAndClear( aEvent
);
144 m_aSubmissionVetoListeners
.disposeAndClear( aEvent
);
145 m_pFeatureInterception
->dispose();
148 ::osl::MutexGuard
aGuard( m_aMutex
);
151 m_pThread
->release();
156 OControl::disposing();
159 //------------------------------------------------------------------------------
160 OImageProducerThread_Impl
* OClickableImageBaseControl::getImageProducerThread()
164 m_pThread
= new OImageProducerThread_Impl( this );
165 m_pThread
->acquire();
171 //------------------------------------------------------------------------------
172 bool OClickableImageBaseControl::approveAction( )
174 sal_Bool bCancelled
= sal_False
;
175 EventObject
aEvent( static_cast< XWeak
* >( this ) );
177 ::cppu::OInterfaceIteratorHelper
aIter( m_aApproveActionListeners
);
178 while( !bCancelled
&& aIter
.hasMoreElements() )
180 // Jede approveAction-Methode muss thread-safe sein!!!
181 if( !static_cast< XApproveActionListener
* >( aIter
.next() )->approveAction( aEvent
) )
182 bCancelled
= sal_True
;
188 //------------------------------------------------------------------------------
189 // Diese Methode wird auch aus einem Thread gerufen und muss deshalb
191 void OClickableImageBaseControl::actionPerformed_Impl(sal_Bool bNotifyListener
, const MouseEvent
& rEvt
)
193 if( bNotifyListener
)
195 if ( !approveAction() )
199 // Ob der Rest des Codes Thread-Safe ist weiss man nicht genau. Deshalb
200 // wird das meiste bei gelocktem Solar-Mutex erledigen.
201 Reference
<XPropertySet
> xSet
;
202 Reference
< XInterface
> xModelsParent
;
203 FormButtonType eButtonType
= FormButtonType_PUSH
;
205 SolarMutexGuard aGuard
;
208 Reference
<XFormComponent
> xComp(getModel(), UNO_QUERY
);
212 xModelsParent
= xComp
->getParent();
213 if (!xModelsParent
.is())
216 // which button type?
217 xSet
= xSet
.query( xComp
);
220 xSet
->getPropertyValue(PROPERTY_BUTTONTYPE
) >>= eButtonType
;
225 case FormButtonType_RESET
:
227 // reset-Methoden muessen thread-safe sein!
228 Reference
<XReset
> xReset(xModelsParent
, UNO_QUERY
);
236 case FormButtonType_SUBMIT
:
238 // if some outer component can provide an interaction handler, use it
239 Reference
< XInteractionHandler
> xHandler( m_pFeatureInterception
->queryDispatch( "private:/InteractionHandler" ), UNO_QUERY
);
242 implSubmit( rEvt
, xHandler
);
244 catch( const Exception
& )
251 case FormButtonType_URL
:
253 SolarMutexGuard aGuard
;
255 Reference
< XModel
> xModel
= getXModel(xModelsParent
);
259 ///////////////////////////////////////////////////////////////////////
260 // Jetzt URL ausfuehren
261 Reference
< XController
> xController
= xModel
->getCurrentController();
262 if (!xController
.is())
265 Reference
< XFrame
> xFrame
= xController
->getFrame();
271 getString(xSet
->getPropertyValue(PROPERTY_TARGET_URL
));
273 if (!aURL
.Complete
.isEmpty() && (LOCAL_URL_PREFIX
== aURL
.Complete
.getStr()[0]))
274 { // the URL contains a local URL only. Since the URLTransformer does not handle this case correctly
275 // (it can't: it does not know the document URL), we have to take care for this ourself.
276 // The real solution would be to not allow such relative URLs (there is a rule that at runtime, all
277 // URLs have to be absolute), but for compatibility reasons this is no option.
278 // The more as the user does not want to see a local URL as "file://<path>/<document>#mark" if it
279 // could be "#mark" as well.
280 // If we someday say that this hack (yes, it's kind of a hack) is not sustainable anymore, the complete
281 // solutiuon would be:
282 // * recognize URLs consisting of a mark only while _reading_ the document
283 // * for this, allow the INetURLObject (which at the moment is invoked when reading URLs) to
284 // transform such mark-only URLs into correct absolute URLs
285 // * at the UI, show only the mark
286 // * !!!! recognize every SAVEAS on the document, so the absolute URL can be adjusted. This seems
287 // rather impossible !!!
288 aURL
.Mark
= aURL
.Complete
;
289 aURL
.Complete
= xModel
->getURL();
290 aURL
.Complete
+= aURL
.Mark
;
293 sal_Bool bDispatchUrlInternal
= sal_False
;
294 xSet
->getPropertyValue(PROPERTY_DISPATCHURLINTERNAL
) >>= bDispatchUrlInternal
;
295 if ( bDispatchUrlInternal
)
297 m_pFeatureInterception
->getTransformer().parseSmartWithAsciiProtocol( aURL
, INET_FILE_SCHEME
);
299 OUString aTargetFrame
;
300 xSet
->getPropertyValue(PROPERTY_TARGET_FRAME
) >>= aTargetFrame
;
302 Reference
< XDispatch
> xDisp
= Reference
< XDispatchProvider
> (xFrame
,UNO_QUERY
)->queryDispatch( aURL
, aTargetFrame
,
303 FrameSearchFlag::SELF
| FrameSearchFlag::PARENT
|
304 FrameSearchFlag::SIBLINGS
| FrameSearchFlag::CREATE
);
306 Sequence
<PropertyValue
> aArgs(1);
307 PropertyValue
& rProp
= aArgs
.getArray()[0];
308 rProp
.Name
= OUString("Referer");
309 rProp
.Value
<<= xModel
->getURL();
312 xDisp
->dispatch( aURL
, aArgs
);
316 URL aHyperLink
= m_pFeatureInterception
->getTransformer().getStrictURLFromAscii( ".uno:OpenHyperlink" );
318 Reference
< XDispatch
> xDisp
= Reference
< XDispatchProvider
> (xFrame
,UNO_QUERY
)->queryDispatch(aHyperLink
, OUString() , 0);
322 Sequence
<PropertyValue
> aProps(3);
323 aProps
[0].Name
= OUString("URL");
324 aProps
[0].Value
<<= aURL
.Complete
;
326 aProps
[1].Name
= OUString("FrameName");
327 aProps
[1].Value
= xSet
->getPropertyValue(PROPERTY_TARGET_FRAME
);
329 aProps
[2].Name
= OUString("Referer");
330 aProps
[2].Value
<<= xModel
->getURL();
332 xDisp
->dispatch( aHyperLink
, aProps
);
338 // notify the action listeners for a push button
339 ActionEvent
aEvt(static_cast<XWeak
*>(this), m_aActionCommand
);
340 m_aActionListeners
.notifyEach( &XActionListener::actionPerformed
, aEvt
);
346 //--------------------------------------------------------------------
347 void SAL_CALL
OClickableImageBaseControl::addSubmissionVetoListener( const Reference
< submission::XSubmissionVetoListener
>& listener
) throw (NoSupportException
, RuntimeException
)
349 m_aSubmissionVetoListeners
.addInterface( listener
);
352 //--------------------------------------------------------------------
353 void SAL_CALL
OClickableImageBaseControl::removeSubmissionVetoListener( const Reference
< submission::XSubmissionVetoListener
>& listener
) throw (NoSupportException
, RuntimeException
)
355 m_aSubmissionVetoListeners
.removeInterface( listener
);
358 //--------------------------------------------------------------------
359 void SAL_CALL
OClickableImageBaseControl::submitWithInteraction( const Reference
< XInteractionHandler
>& _rxHandler
) throw (VetoException
, WrappedTargetException
, RuntimeException
)
361 implSubmit( MouseEvent(), _rxHandler
);
364 //--------------------------------------------------------------------
365 void SAL_CALL
OClickableImageBaseControl::submit( ) throw (VetoException
, WrappedTargetException
, RuntimeException
)
367 implSubmit( MouseEvent(), NULL
);
370 //--------------------------------------------------------------------
371 Sequence
< OUString
> SAL_CALL
OClickableImageBaseControl::getSupportedServiceNames( ) throw (RuntimeException
)
373 Sequence
< OUString
> aSupported
= OControl::getSupportedServiceNames();
374 aSupported
.realloc( aSupported
.getLength() + 1 );
376 OUString
* pArray
= aSupported
.getArray();
377 pArray
[ aSupported
.getLength() - 1 ] = FRM_SUN_CONTROL_SUBMITBUTTON
;
382 //--------------------------------------------------------------------
383 void OClickableImageBaseControl::implSubmit( const MouseEvent
& _rEvent
, const Reference
< XInteractionHandler
>& _rxHandler
) SAL_THROW((VetoException
, WrappedTargetException
, RuntimeException
))
387 // allow the veto listeners to join the game
388 m_aSubmissionVetoListeners
.notifyEach( &XSubmissionVetoListener::submitting
, EventObject( *this ) );
390 // see whether there's an "submit interceptor" set at our model
391 Reference
< submission::XSubmissionSupplier
> xSubmissionSupp( getModel(), UNO_QUERY
);
392 Reference
< XSubmission
> xSubmission
;
393 if ( xSubmissionSupp
.is() )
394 xSubmission
= xSubmissionSupp
->getSubmission();
396 if ( xSubmission
.is() )
398 if ( !_rxHandler
.is() )
399 xSubmission
->submit();
401 xSubmission
->submitWithInteraction( _rxHandler
);
405 // no "interceptor" -> ordinary (old-way) submission
406 Reference
< XChild
> xChild( getModel(), UNO_QUERY
);
407 Reference
< XSubmit
> xParentSubmission
;
409 xParentSubmission
= xParentSubmission
.query( xChild
->getParent() );
410 if ( xParentSubmission
.is() )
411 xParentSubmission
->submit( this, _rEvent
);
414 catch( const VetoException
& )
419 catch( const RuntimeException
& )
424 catch( const WrappedTargetException
& )
429 catch( const Exception
& e
)
431 OSL_FAIL( "OClickableImageBaseControl::implSubmit: caught an unknown exception!" );
432 throw WrappedTargetException( OUString(), *this, makeAny( e
) );
436 //==================================================================
437 // OClickableImageBaseModel
438 //==================================================================
439 //------------------------------------------------------------------------------
440 Sequence
<Type
> OClickableImageBaseModel::_getTypes()
442 return concatSequences(
443 OControlModel::_getTypes(),
444 OClickableImageBaseModel_Base::getTypes()
448 //------------------------------------------------------------------
449 DBG_NAME( OClickableImageBaseModel
)
450 //------------------------------------------------------------------
451 OClickableImageBaseModel::OClickableImageBaseModel( const Reference
< XMultiServiceFactory
>& _rxFactory
, const OUString
& _rUnoControlModelTypeName
,
452 const OUString
& rDefault
)
453 :OControlModel( _rxFactory
, _rUnoControlModelTypeName
, rDefault
)
454 ,OPropertyChangeListener(m_aMutex
)
457 ,m_bDispatchUrlInternal(sal_False
)
458 ,m_bDownloading(sal_False
)
459 ,m_bProdStarted(sal_False
)
461 DBG_CTOR( OClickableImageBaseModel
, NULL
);
463 m_eButtonType
= FormButtonType_PUSH
;
466 //------------------------------------------------------------------
467 OClickableImageBaseModel::OClickableImageBaseModel( const OClickableImageBaseModel
* _pOriginal
, const Reference
<XMultiServiceFactory
>& _rxFactory
)
468 :OControlModel( _pOriginal
, _rxFactory
)
469 ,OPropertyChangeListener( m_aMutex
)
472 ,m_bDispatchUrlInternal(sal_False
)
473 ,m_bDownloading( sal_False
)
474 ,m_bProdStarted( sal_False
)
476 DBG_CTOR( OClickableImageBaseModel
, NULL
);
480 m_eButtonType
= _pOriginal
->m_eButtonType
;
481 m_sTargetURL
= _pOriginal
->m_sTargetURL
;
482 m_sTargetFrame
= _pOriginal
->m_sTargetFrame
;
483 m_bDispatchUrlInternal
= _pOriginal
->m_bDispatchUrlInternal
;
486 //------------------------------------------------------------------------------
487 void OClickableImageBaseModel::implInitializeImageURL( )
489 osl_atomic_increment( &m_refCount
);
491 // simulate a propertyChanged event for the ImageURL
493 getFastPropertyValue( aImageURL
, PROPERTY_ID_IMAGE_URL
);
494 _propertyChanged( PropertyChangeEvent( *this, PROPERTY_IMAGE_URL
, sal_False
, PROPERTY_ID_IMAGE_URL
, Any( ), aImageURL
) );
496 osl_atomic_decrement( &m_refCount
);
499 //------------------------------------------------------------------------------
500 void OClickableImageBaseModel::implConstruct()
502 m_pProducer
= new ImageProducer
;
503 increment( m_refCount
);
505 m_xProducer
= m_pProducer
;
507 if ( m_xAggregateSet
.is() )
509 OPropertyChangeMultiplexer
* pMultiplexer
= new OPropertyChangeMultiplexer( this, m_xAggregateSet
);
510 pMultiplexer
->addProperty( PROPERTY_IMAGE_URL
);
513 decrement(m_refCount
);
516 //------------------------------------------------------------------------------
517 OClickableImageBaseModel::~OClickableImageBaseModel()
519 if (!OComponentHelper::rBHelper
.bDisposed
)
524 DBG_ASSERT(m_pMedium
== NULL
, "OClickableImageBaseModel::~OClickableImageBaseModel : leaving a memory leak ...");
525 // spaetestens im dispose sollte das aufgeraeumt worden sein
527 DBG_DTOR( OClickableImageBaseModel
, NULL
);
531 //--------------------------------------------------------------------
532 void SAL_CALL
OClickableImageBaseModel::addConsumer( const Reference
< XImageConsumer
>& _rxConsumer
) throw (RuntimeException
)
534 ImageModelMethodGuard
aGuard( *this );
535 GetImageProducer()->addConsumer( _rxConsumer
);
538 //--------------------------------------------------------------------
539 void SAL_CALL
OClickableImageBaseModel::removeConsumer( const Reference
< XImageConsumer
>& _rxConsumer
) throw (RuntimeException
)
541 ImageModelMethodGuard
aGuard( *this );
542 GetImageProducer()->removeConsumer( _rxConsumer
);
545 //--------------------------------------------------------------------
546 void SAL_CALL
OClickableImageBaseModel::startProduction( ) throw (RuntimeException
)
548 ImageModelMethodGuard
aGuard( *this );
549 GetImageProducer()->startProduction();
552 //--------------------------------------------------------------------
553 Reference
< submission::XSubmission
> SAL_CALL
OClickableImageBaseModel::getSubmission() throw (RuntimeException
)
555 return m_xSubmissionDelegate
;
558 //--------------------------------------------------------------------
559 void SAL_CALL
OClickableImageBaseModel::setSubmission( const Reference
< submission::XSubmission
>& _submission
) throw (RuntimeException
)
561 m_xSubmissionDelegate
= _submission
;
564 //--------------------------------------------------------------------
565 Sequence
< OUString
> SAL_CALL
OClickableImageBaseModel::getSupportedServiceNames( ) throw (RuntimeException
)
567 Sequence
< OUString
> aSupported
= OControlModel::getSupportedServiceNames();
568 aSupported
.realloc( aSupported
.getLength() + 1 );
570 OUString
* pArray
= aSupported
.getArray();
571 pArray
[ aSupported
.getLength() - 1 ] = FRM_SUN_COMPONENT_SUBMITBUTTON
;
577 //------------------------------------------------------------------------------
578 void OClickableImageBaseModel::disposing()
580 OControlModel::disposing();
591 //------------------------------------------------------------------------------
592 Any SAL_CALL
OClickableImageBaseModel::queryAggregation(const Type
& _rType
) throw (RuntimeException
)
595 // we definitely want to "overload" the XImageProducer interface of our aggregate,
596 // thus check OClickableImageBaseModel_Base (which provides this) first
597 Any aReturn
= OClickableImageBaseModel_Base::queryInterface( _rType
);
599 // BUT: _don't_ let it feel responsible for the XTypeProvider interface
600 // (as this is implemented by our base class in the proper way)
601 if ( _rType
.equals( ::getCppuType( static_cast< Reference
< XTypeProvider
>* >( NULL
) ) )
602 || !aReturn
.hasValue()
604 aReturn
= OControlModel::queryAggregation( _rType
);
609 //------------------------------------------------------------------------------
610 void OClickableImageBaseModel::getFastPropertyValue(Any
& rValue
, sal_Int32 nHandle
) const
614 case PROPERTY_ID_BUTTONTYPE
: rValue
<<= m_eButtonType
; break;
615 case PROPERTY_ID_TARGET_URL
: rValue
<<= m_sTargetURL
; break;
616 case PROPERTY_ID_TARGET_FRAME
: rValue
<<= m_sTargetFrame
; break;
617 case PROPERTY_ID_DISPATCHURLINTERNAL
: rValue
<<= m_bDispatchUrlInternal
; break;
619 OControlModel::getFastPropertyValue(rValue
, nHandle
);
623 //------------------------------------------------------------------------------
624 void OClickableImageBaseModel::setFastPropertyValue_NoBroadcast(sal_Int32 nHandle
, const Any
& rValue
) throw ( Exception
)
628 case PROPERTY_ID_BUTTONTYPE
:
629 DBG_ASSERT(isA(rValue
, static_cast<FormButtonType
*>(NULL
)), "OClickableImageBaseModel::setFastPropertyValue_NoBroadcast : invalid type !" );
630 rValue
>>= m_eButtonType
;
633 case PROPERTY_ID_TARGET_URL
:
634 DBG_ASSERT(rValue
.getValueType().getTypeClass() == TypeClass_STRING
, "OClickableImageBaseModel::setFastPropertyValue_NoBroadcast : invalid type !" );
635 rValue
>>= m_sTargetURL
;
638 case PROPERTY_ID_TARGET_FRAME
:
639 DBG_ASSERT(rValue
.getValueType().getTypeClass() == TypeClass_STRING
, "OClickableImageBaseModel::setFastPropertyValue_NoBroadcast : invalid type !" );
640 rValue
>>= m_sTargetFrame
;
643 case PROPERTY_ID_DISPATCHURLINTERNAL
:
644 DBG_ASSERT(rValue
.getValueType().getTypeClass() == TypeClass_BOOLEAN
, "OClickableImageBaseModel::setFastPropertyValue_NoBroadcast : invalid type !" );
645 rValue
>>= m_bDispatchUrlInternal
;
649 OControlModel::setFastPropertyValue_NoBroadcast(nHandle
, rValue
);
653 //------------------------------------------------------------------------------
654 sal_Bool
OClickableImageBaseModel::convertFastPropertyValue(Any
& rConvertedValue
, Any
& rOldValue
, sal_Int32 nHandle
, const Any
& rValue
)
655 throw( IllegalArgumentException
)
659 case PROPERTY_ID_BUTTONTYPE
:
660 return tryPropertyValueEnum( rConvertedValue
, rOldValue
, rValue
, m_eButtonType
);
662 case PROPERTY_ID_TARGET_URL
:
663 return tryPropertyValue(rConvertedValue
, rOldValue
, rValue
, m_sTargetURL
);
665 case PROPERTY_ID_TARGET_FRAME
:
666 return tryPropertyValue(rConvertedValue
, rOldValue
, rValue
, m_sTargetFrame
);
668 case PROPERTY_ID_DISPATCHURLINTERNAL
:
669 return tryPropertyValue(rConvertedValue
, rOldValue
, rValue
, m_bDispatchUrlInternal
);
672 return OControlModel::convertFastPropertyValue(rConvertedValue
, rOldValue
, nHandle
, rValue
);
676 //------------------------------------------------------------------------------
677 void OClickableImageBaseModel::StartProduction()
679 ImageProducer
*pImgProd
= GetImageProducer();
682 getPropertyValue( OUString("ImageURL") ) >>= sURL
;
685 if ( ::svt::GraphicAccess::isSupportedURL( sURL
) )
686 pImgProd
->SetImage( sURL
);
688 // caution: the medium may be NULL if somebody gave us a invalid URL to work with
689 pImgProd
->SetImage(String());
690 m_bDownloading
= sal_False
;
693 if (m_pMedium
->GetErrorCode()==0)
695 SvStream
* pStream
= m_pMedium
->GetInStream();
697 pImgProd
->SetImage(*pStream
);
698 pImgProd
->startProduction();
699 m_bProdStarted
= sal_True
;
703 pImgProd
->SetImage(String());
706 m_bDownloading
= sal_False
;
710 //------------------------------------------------------------------------------
711 void OClickableImageBaseModel::SetURL( const OUString
& rURL
)
713 if (m_pMedium
|| rURL
.isEmpty())
715 // Den Stream am Producer freigeben, bevor das Medium geloscht wird.
716 GetImageProducer()->SetImage(String());
721 // the SfxMedium is not allowed to be created with an invalid URL, so we have to check this first
722 INetURLObject
aUrl(rURL
);
723 if (INET_PROT_NOT_VALID
== aUrl
.GetProtocol())
724 // we treat an invalid URL like we would treat no URL
727 if (!rURL
.isEmpty() && !::svt::GraphicAccess::isSupportedURL( rURL
) )
732 m_pMedium
= new SfxMedium(rURL
, STREAM_STD_READ
);
734 // Das XModel suchen, um an die Object-Shell oder zumindest den
735 // Referer zu gelangen.
736 // Das Model findet man allerdings nur beim Laden von HTML-Dokumenten
737 // und dann, wenn die URL in einem bereits geladenen Dokument
738 // geaendert wird. Waehrend des Ladens kommt man nicht an das
740 Reference
< XModel
> xModel
;
741 InterfaceRef
xIfc( *this );
742 while( !xModel
.is() && xIfc
.is() )
744 Reference
<XChild
> xChild( xIfc
, UNO_QUERY
);
745 xIfc
= xChild
->getParent();
746 query_interface(xIfc
, xModel
);
749 // Die Object-Shell suchen, indem wir
750 // ueber alle Object-Shells iterieren und deren XModel mit dem
751 // eigenen vergleichen. Als Optimierung probieren wir aber erstmal
752 // die aktuelle Object-Shell.
753 // wir unser XModel mit dem aller Object
754 SfxObjectShell
*pObjSh
= 0;
758 SfxObjectShell
*pTestObjSh
= SfxObjectShell::Current();
761 Reference
< XModel
> xTestModel
= pTestObjSh
->GetModel();
762 if( xTestModel
== xModel
)
767 pTestObjSh
= SfxObjectShell::GetFirst();
768 while( !pObjSh
&& pTestObjSh
)
770 Reference
< XModel
> xTestModel
= pTestObjSh
->GetModel();
771 if( xTestModel
== xModel
)
774 pTestObjSh
= SfxObjectShell::GetNext( *pTestObjSh
);
779 #ifdef USE_REGISTER_TRANSFER
782 // Target-Frame uebertragen, damit auch javascript:-URLs
783 // "geladen" werden koennen.
784 const SfxMedium
*pShMedium
= pObjSh
->GetMedium();
786 m_pMedium
->SetLoadTargetFrame(pShMedium
->GetLoadTargetFrame());
791 // Target-Frame uebertragen, damit auch javascript:-URLs
792 // "geladen" werden koennen.
793 const SfxMedium
*pShMedium
= pObjSh
->GetMedium();
795 m_pMedium
->SetLoadTargetFrame(pShMedium
->GetLoadTargetFrame());
799 // Downloading-Flag auf sal_True setzen. Es werden dann auch
800 // Data-Available-Links, wenn wir in den Pending-Staus gelangen.
801 m_bDownloading
= sal_True
;
802 m_bProdStarted
= sal_False
;
804 // Download anstossen (Achtung: Kann auch synchron sein).
805 m_pMedium
->DownLoad(STATIC_LINK(this, OClickableImageBaseModel
, DownloadDoneLink
));
809 if ( ::svt::GraphicAccess::isSupportedURL( rURL
) )
810 GetImageProducer()->SetImage( rURL
);
811 GetImageProducer()->startProduction();
815 //------------------------------------------------------------------------------
816 void OClickableImageBaseModel::DataAvailable()
821 GetImageProducer()->NewDataAvailable();
824 //------------------------------------------------------------------------------
825 void OClickableImageBaseModel::DownloadDone()
828 m_bDownloading
= sal_False
;
831 //------------------------------------------------------------------------------
832 IMPL_STATIC_LINK( OClickableImageBaseModel
, DownloadDoneLink
, void*, EMPTYARG
)
834 ::osl::MutexGuard
aGuard( pThis
->m_aMutex
);
835 pThis
->DownloadDone();
839 //------------------------------------------------------------------------------
840 void OClickableImageBaseModel::_propertyChanged( const PropertyChangeEvent
& rEvt
)
841 throw( RuntimeException
)
843 // Wenn eine URL gesetzt worden ist, muss die noch an den ImageProducer
844 // weitergereicht werden.
845 ::osl::MutexGuard
aGuard(m_aMutex
);
846 SetURL( getString(rEvt
.NewValue
) );
849 // -----------------------------------------------------------------------------
850 Any
OClickableImageBaseModel::getPropertyDefaultByHandle( sal_Int32 nHandle
) const
854 case PROPERTY_ID_BUTTONTYPE
: return makeAny( FormButtonType_PUSH
);
855 case PROPERTY_ID_TARGET_URL
:
856 case PROPERTY_ID_TARGET_FRAME
: return makeAny( OUString() );
857 case PROPERTY_ID_DISPATCHURLINTERNAL
: return makeAny( sal_False
);
859 return OControlModel::getPropertyDefaultByHandle(nHandle
);
863 //==================================================================
864 // OImageProducerThread_Impl
865 //==================================================================
866 //------------------------------------------------------------------
867 EventObject
* OImageProducerThread_Impl::cloneEvent( const EventObject
* _pEvt
) const
869 return new EventObject( *_pEvt
);
872 //------------------------------------------------------------------
873 void OImageProducerThread_Impl::processEvent( ::cppu::OComponentHelper
*pCompImpl
,
874 const EventObject
* pEvt
,
875 const Reference
<XControl
>&,
878 ((OClickableImageBaseControl
*)pCompImpl
)->actionPerformed_Impl( sal_True
, *(MouseEvent
*)pEvt
);
881 //.........................................................................
883 //.........................................................................
885 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */