Files
libreoffice/forms/source/component/clickableimage.cxx
Thomas Arnhold ba0a57702c remove OUString wrap for string literals
For some functions and all kinds of Exceptions.

CannotConvertException
CloseVetoException
DisposedException
EmptyUndoStackException
ErrorCodeIOException
Exception
GridInvalidDataException
GridInvalidModelException
IOException
IllegalAccessException
IllegalArgumentException
IllegalTypeException
IndexOutOfBoundsException
NoMasterException
NoSuchElementException
NoSupportException
PropertyVetoException
RuntimeException
SAXException
ScannerException
StorageWrappedTargetException
UnsupportedFlavorException
VetoException
WrappedTargetException
ZipIOException
throwGenericSQLException
throwIllegallArgumentException

createInstance
createInstanceWithContext
forName
getByName
getPackageManager
getPropertyValue
getUnpackedValueOrDefault
getValueByName
hasPropertyByName
openKey
setName
setPropertyValue
supportsService

bash command:

for i in `cat list`; do git grep "$i\s*(\s*OUString(\s*\"" -- '*.[hc]xx'
	| cut -d ':' -f1 | sort -u
	| xargs sed -i
		-e "s/\(\<$i\s*(\)\s*OUString(\s*\(\"[^\")\\]*\"\)\s*)\s*/\1\2/g"
		-e "s/\($i.*\)\"+ /\1\" + /g";
done

Change-Id: Iaf8e641b0abf28c082906014f87a183517630535
Reviewed-on: https://gerrit.libreoffice.org/4624
Tested-by: LibreOffice gerrit bot <gerrit@libreoffice.org>
Reviewed-by: Thomas Arnhold <thomas@arnhold.org>
Tested-by: Thomas Arnhold <thomas@arnhold.org>
2013-06-29 21:52:54 +00:00

887 lines
36 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#include "clickableimage.hxx"
#include "controlfeatureinterception.hxx"
#include "urltransformer.hxx"
#include "componenttools.hxx"
#include <com/sun/star/form/XSubmit.hpp>
#include <com/sun/star/awt/SystemPointer.hpp>
#include <com/sun/star/form/FormComponentType.hpp>
#include <com/sun/star/frame/XDispatch.hpp>
#include <com/sun/star/frame/XDispatchProvider.hpp>
#include <com/sun/star/frame/FrameSearchFlag.hpp>
#include <com/sun/star/frame/XController.hpp>
#include <com/sun/star/frame/XFrame.hpp>
#include <com/sun/star/awt/ActionEvent.hpp>
#include <com/sun/star/awt/XActionListener.hpp>
#include <tools/urlobj.hxx>
#include <tools/debug.hxx>
#include <vcl/svapp.hxx>
#include <sfx2/docfile.hxx>
#include <sfx2/objsh.hxx>
#include <osl/mutex.hxx>
#include "services.hxx"
#include <comphelper/container.hxx>
#include <comphelper/listenernotification.hxx>
#include <comphelper/processfactory.hxx>
#include <svtools/imageresourceaccess.hxx>
#define LOCAL_URL_PREFIX '#'
//.........................................................................
namespace frm
{
//.........................................................................
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::sdb;
using namespace ::com::sun::star::sdbc;
using namespace ::com::sun::star::sdbcx;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::form;
using namespace ::com::sun::star::awt;
using namespace ::com::sun::star::io;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::util;
using namespace ::com::sun::star::frame;
using namespace ::com::sun::star::form::submission;
using ::com::sun::star::awt::MouseEvent;
using ::com::sun::star::task::XInteractionHandler;
//==================================================================
// OClickableImageBaseControl
//==================================================================
//------------------------------------------------------------------------------
Sequence<Type> OClickableImageBaseControl::_getTypes()
{
static Sequence<Type> aTypes;
if (!aTypes.getLength())
aTypes = concatSequences(OControl::_getTypes(), OClickableImageBaseControl_BASE::getTypes());
return aTypes;
}
//------------------------------------------------------------------------------
OClickableImageBaseControl::OClickableImageBaseControl(const Reference<XComponentContext>& _rxFactory, const OUString& _aService)
:OControl(_rxFactory, _aService)
,m_pThread(NULL)
,m_aSubmissionVetoListeners( m_aMutex )
,m_aApproveActionListeners( m_aMutex )
,m_aActionListeners( m_aMutex )
{
m_pFeatureInterception.reset( new ControlFeatureInterception( _rxFactory ) );
}
//------------------------------------------------------------------------------
OClickableImageBaseControl::~OClickableImageBaseControl()
{
if (!OComponentHelper::rBHelper.bDisposed)
{
acquire();
dispose();
}
}
// UNO Anbindung
//------------------------------------------------------------------------------
Any SAL_CALL OClickableImageBaseControl::queryAggregation(const Type& _rType) throw (RuntimeException)
{
Any aReturn = OControl::queryAggregation(_rType);
if (!aReturn.hasValue())
aReturn = OClickableImageBaseControl_BASE::queryInterface(_rType);
return aReturn;
}
// XApproveActionBroadcaster
//------------------------------------------------------------------------------
void OClickableImageBaseControl::addApproveActionListener(
const Reference<XApproveActionListener>& l) throw( RuntimeException )
{
m_aApproveActionListeners.addInterface(l);
}
//------------------------------------------------------------------------------
void OClickableImageBaseControl::removeApproveActionListener(
const Reference<XApproveActionListener>& l) throw( RuntimeException )
{
m_aApproveActionListeners.removeInterface(l);
}
//--------------------------------------------------------------------
void SAL_CALL OClickableImageBaseControl::registerDispatchProviderInterceptor( const Reference< XDispatchProviderInterceptor >& _rxInterceptor ) throw (RuntimeException)
{
m_pFeatureInterception->registerDispatchProviderInterceptor( _rxInterceptor );
}
//--------------------------------------------------------------------
void SAL_CALL OClickableImageBaseControl::releaseDispatchProviderInterceptor( const Reference< XDispatchProviderInterceptor >& _rxInterceptor ) throw (RuntimeException)
{
m_pFeatureInterception->releaseDispatchProviderInterceptor( _rxInterceptor );
}
// OComponentHelper
//------------------------------------------------------------------------------
void OClickableImageBaseControl::disposing()
{
EventObject aEvent( static_cast< XWeak* >( this ) );
m_aApproveActionListeners.disposeAndClear( aEvent );
m_aActionListeners.disposeAndClear( aEvent );
m_aSubmissionVetoListeners.disposeAndClear( aEvent );
m_pFeatureInterception->dispose();
{
::osl::MutexGuard aGuard( m_aMutex );
if( m_pThread )
{
m_pThread->release();
m_pThread = NULL;
}
}
OControl::disposing();
}
//------------------------------------------------------------------------------
OImageProducerThread_Impl* OClickableImageBaseControl::getImageProducerThread()
{
if ( !m_pThread )
{
m_pThread = new OImageProducerThread_Impl( this );
m_pThread->acquire();
m_pThread->create();
}
return m_pThread;
}
//------------------------------------------------------------------------------
bool OClickableImageBaseControl::approveAction( )
{
sal_Bool bCancelled = sal_False;
EventObject aEvent( static_cast< XWeak* >( this ) );
::cppu::OInterfaceIteratorHelper aIter( m_aApproveActionListeners );
while( !bCancelled && aIter.hasMoreElements() )
{
// Jede approveAction-Methode muss thread-safe sein!!!
if( !static_cast< XApproveActionListener* >( aIter.next() )->approveAction( aEvent ) )
bCancelled = sal_True;
}
return !bCancelled;
}
//------------------------------------------------------------------------------
// Diese Methode wird auch aus einem Thread gerufen und muss deshalb
// thread-safe sein.
void OClickableImageBaseControl::actionPerformed_Impl(sal_Bool bNotifyListener, const MouseEvent& rEvt)
{
if( bNotifyListener )
{
if ( !approveAction() )
return;
}
// Ob der Rest des Codes Thread-Safe ist weiss man nicht genau. Deshalb
// wird das meiste bei gelocktem Solar-Mutex erledigen.
Reference<XPropertySet> xSet;
Reference< XInterface > xModelsParent;
FormButtonType eButtonType = FormButtonType_PUSH;
{
SolarMutexGuard aGuard;
// Parent holen
Reference<XFormComponent> xComp(getModel(), UNO_QUERY);
if (!xComp.is())
return;
xModelsParent = xComp->getParent();
if (!xModelsParent.is())
return;
// which button type?
xSet = xSet.query( xComp );
if ( !xSet.is() )
return;
xSet->getPropertyValue(PROPERTY_BUTTONTYPE) >>= eButtonType;
}
switch (eButtonType)
{
case FormButtonType_RESET:
{
// reset-Methoden muessen thread-safe sein!
Reference<XReset> xReset(xModelsParent, UNO_QUERY);
if (!xReset.is())
return;
xReset->reset();
}
break;
case FormButtonType_SUBMIT:
{
// if some outer component can provide an interaction handler, use it
Reference< XInteractionHandler > xHandler( m_pFeatureInterception->queryDispatch( "private:/InteractionHandler" ), UNO_QUERY );
try
{
implSubmit( rEvt, xHandler );
}
catch( const Exception& )
{
// ignore
}
}
break;
case FormButtonType_URL:
{
SolarMutexGuard aGuard;
Reference< XModel > xModel = getXModel(xModelsParent);
if (!xModel.is())
return;
///////////////////////////////////////////////////////////////////////
// Jetzt URL ausfuehren
Reference< XController > xController = xModel->getCurrentController();
if (!xController.is())
return;
Reference< XFrame > xFrame = xController->getFrame();
if( !xFrame.is() )
return;
URL aURL;
aURL.Complete =
getString(xSet->getPropertyValue(PROPERTY_TARGET_URL));
if (!aURL.Complete.isEmpty() && (LOCAL_URL_PREFIX == aURL.Complete.getStr()[0]))
{ // the URL contains a local URL only. Since the URLTransformer does not handle this case correctly
// (it can't: it does not know the document URL), we have to take care for this ourself.
// The real solution would be to not allow such relative URLs (there is a rule that at runtime, all
// URLs have to be absolute), but for compatibility reasons this is no option.
// The more as the user does not want to see a local URL as "file://<path>/<document>#mark" if it
// could be "#mark" as well.
// If we someday say that this hack (yes, it's kind of a hack) is not sustainable anymore, the complete
// solutiuon would be:
// * recognize URLs consisting of a mark only while _reading_ the document
// * for this, allow the INetURLObject (which at the moment is invoked when reading URLs) to
// transform such mark-only URLs into correct absolute URLs
// * at the UI, show only the mark
// * !!!! recognize every SAVEAS on the document, so the absolute URL can be adjusted. This seems
// rather impossible !!!
aURL.Mark = aURL.Complete;
aURL.Complete = xModel->getURL();
aURL.Complete += aURL.Mark;
}
sal_Bool bDispatchUrlInternal = sal_False;
xSet->getPropertyValue(PROPERTY_DISPATCHURLINTERNAL) >>= bDispatchUrlInternal;
if ( bDispatchUrlInternal )
{
m_pFeatureInterception->getTransformer().parseSmartWithAsciiProtocol( aURL, INET_FILE_SCHEME );
OUString aTargetFrame;
xSet->getPropertyValue(PROPERTY_TARGET_FRAME) >>= aTargetFrame;
Reference< XDispatch > xDisp = Reference< XDispatchProvider > (xFrame,UNO_QUERY)->queryDispatch( aURL, aTargetFrame,
FrameSearchFlag::SELF | FrameSearchFlag::PARENT |
FrameSearchFlag::SIBLINGS | FrameSearchFlag::CREATE );
Sequence<PropertyValue> aArgs(1);
PropertyValue& rProp = aArgs.getArray()[0];
rProp.Name = OUString("Referer");
rProp.Value <<= xModel->getURL();
if (xDisp.is())
xDisp->dispatch( aURL, aArgs );
}
else
{
URL aHyperLink = m_pFeatureInterception->getTransformer().getStrictURLFromAscii( ".uno:OpenHyperlink" );
Reference< XDispatch > xDisp = Reference< XDispatchProvider > (xFrame,UNO_QUERY)->queryDispatch(aHyperLink, OUString() , 0);
if ( xDisp.is() )
{
Sequence<PropertyValue> aProps(3);
aProps[0].Name = OUString("URL");
aProps[0].Value <<= aURL.Complete;
aProps[1].Name = OUString("FrameName");
aProps[1].Value = xSet->getPropertyValue(PROPERTY_TARGET_FRAME);
aProps[2].Name = OUString("Referer");
aProps[2].Value <<= xModel->getURL();
xDisp->dispatch( aHyperLink, aProps );
}
}
} break;
default:
{
// notify the action listeners for a push button
ActionEvent aEvt(static_cast<XWeak*>(this), m_aActionCommand);
m_aActionListeners.notifyEach( &XActionListener::actionPerformed, aEvt );
}
}
}
//--------------------------------------------------------------------
void SAL_CALL OClickableImageBaseControl::addSubmissionVetoListener( const Reference< submission::XSubmissionVetoListener >& listener ) throw (NoSupportException, RuntimeException)
{
m_aSubmissionVetoListeners.addInterface( listener );
}
//--------------------------------------------------------------------
void SAL_CALL OClickableImageBaseControl::removeSubmissionVetoListener( const Reference< submission::XSubmissionVetoListener >& listener ) throw (NoSupportException, RuntimeException)
{
m_aSubmissionVetoListeners.removeInterface( listener );
}
//--------------------------------------------------------------------
void SAL_CALL OClickableImageBaseControl::submitWithInteraction( const Reference< XInteractionHandler >& _rxHandler ) throw (VetoException, WrappedTargetException, RuntimeException)
{
implSubmit( MouseEvent(), _rxHandler );
}
//--------------------------------------------------------------------
void SAL_CALL OClickableImageBaseControl::submit( ) throw (VetoException, WrappedTargetException, RuntimeException)
{
implSubmit( MouseEvent(), NULL );
}
//--------------------------------------------------------------------
Sequence< OUString > SAL_CALL OClickableImageBaseControl::getSupportedServiceNames( ) throw (RuntimeException)
{
Sequence< OUString > aSupported = OControl::getSupportedServiceNames();
aSupported.realloc( aSupported.getLength() + 1 );
OUString* pArray = aSupported.getArray();
pArray[ aSupported.getLength() - 1 ] = FRM_SUN_CONTROL_SUBMITBUTTON;
return aSupported;
}
//--------------------------------------------------------------------
void OClickableImageBaseControl::implSubmit( const MouseEvent& _rEvent, const Reference< XInteractionHandler >& _rxHandler ) SAL_THROW((VetoException, WrappedTargetException, RuntimeException))
{
try
{
// allow the veto listeners to join the game
m_aSubmissionVetoListeners.notifyEach( &XSubmissionVetoListener::submitting, EventObject( *this ) );
// see whether there's an "submit interceptor" set at our model
Reference< submission::XSubmissionSupplier > xSubmissionSupp( getModel(), UNO_QUERY );
Reference< XSubmission > xSubmission;
if ( xSubmissionSupp.is() )
xSubmission = xSubmissionSupp->getSubmission();
if ( xSubmission.is() )
{
if ( !_rxHandler.is() )
xSubmission->submit();
else
xSubmission->submitWithInteraction( _rxHandler );
}
else
{
// no "interceptor" -> ordinary (old-way) submission
Reference< XChild > xChild( getModel(), UNO_QUERY );
Reference< XSubmit > xParentSubmission;
if ( xChild.is() )
xParentSubmission = xParentSubmission.query( xChild->getParent() );
if ( xParentSubmission.is() )
xParentSubmission->submit( this, _rEvent );
}
}
catch( const VetoException& )
{
// allowed to leave
throw;
}
catch( const RuntimeException& )
{
// allowed to leave
throw;
}
catch( const WrappedTargetException& )
{
// allowed to leave
throw;
}
catch( const Exception& e )
{
OSL_FAIL( "OClickableImageBaseControl::implSubmit: caught an unknown exception!" );
throw WrappedTargetException( OUString(), *this, makeAny( e ) );
}
}
//==================================================================
// OClickableImageBaseModel
//==================================================================
//------------------------------------------------------------------------------
Sequence<Type> OClickableImageBaseModel::_getTypes()
{
return concatSequences(
OControlModel::_getTypes(),
OClickableImageBaseModel_Base::getTypes()
);
}
//------------------------------------------------------------------
DBG_NAME( OClickableImageBaseModel )
//------------------------------------------------------------------
OClickableImageBaseModel::OClickableImageBaseModel( const Reference< XComponentContext >& _rxFactory, const OUString& _rUnoControlModelTypeName,
const OUString& rDefault )
:OControlModel( _rxFactory, _rUnoControlModelTypeName, rDefault )
,OPropertyChangeListener(m_aMutex)
,m_pMedium(NULL)
,m_pProducer( NULL )
,m_bDispatchUrlInternal(sal_False)
,m_bDownloading(sal_False)
,m_bProdStarted(sal_False)
{
DBG_CTOR( OClickableImageBaseModel, NULL );
implConstruct();
m_eButtonType = FormButtonType_PUSH;
}
//------------------------------------------------------------------
OClickableImageBaseModel::OClickableImageBaseModel( const OClickableImageBaseModel* _pOriginal, const Reference<XComponentContext>& _rxFactory )
:OControlModel( _pOriginal, _rxFactory )
,OPropertyChangeListener( m_aMutex )
,m_pMedium( NULL )
,m_pProducer( NULL )
,m_bDispatchUrlInternal(sal_False)
,m_bDownloading( sal_False )
,m_bProdStarted( sal_False )
{
DBG_CTOR( OClickableImageBaseModel, NULL );
implConstruct();
// copy properties
m_eButtonType = _pOriginal->m_eButtonType;
m_sTargetURL = _pOriginal->m_sTargetURL;
m_sTargetFrame = _pOriginal->m_sTargetFrame;
m_bDispatchUrlInternal = _pOriginal->m_bDispatchUrlInternal;
}
//------------------------------------------------------------------------------
void OClickableImageBaseModel::implInitializeImageURL( )
{
osl_atomic_increment( &m_refCount );
{
// simulate a propertyChanged event for the ImageURL
Any aImageURL;
getFastPropertyValue( aImageURL, PROPERTY_ID_IMAGE_URL );
_propertyChanged( PropertyChangeEvent( *this, PROPERTY_IMAGE_URL, sal_False, PROPERTY_ID_IMAGE_URL, Any( ), aImageURL ) );
}
osl_atomic_decrement( &m_refCount );
}
//------------------------------------------------------------------------------
void OClickableImageBaseModel::implConstruct()
{
m_pProducer = new ImageProducer;
increment( m_refCount );
{
m_xProducer = m_pProducer;
if ( m_xAggregateSet.is() )
{
OPropertyChangeMultiplexer* pMultiplexer = new OPropertyChangeMultiplexer( this, m_xAggregateSet );
pMultiplexer->addProperty( PROPERTY_IMAGE_URL );
}
}
decrement(m_refCount);
}
//------------------------------------------------------------------------------
OClickableImageBaseModel::~OClickableImageBaseModel()
{
if (!OComponentHelper::rBHelper.bDisposed)
{
acquire();
dispose();
}
DBG_ASSERT(m_pMedium == NULL, "OClickableImageBaseModel::~OClickableImageBaseModel : leaving a memory leak ...");
// spaetestens im dispose sollte das aufgeraeumt worden sein
DBG_DTOR( OClickableImageBaseModel, NULL );
}
// XImageProducer
//--------------------------------------------------------------------
void SAL_CALL OClickableImageBaseModel::addConsumer( const Reference< XImageConsumer >& _rxConsumer ) throw (RuntimeException)
{
ImageModelMethodGuard aGuard( *this );
GetImageProducer()->addConsumer( _rxConsumer );
}
//--------------------------------------------------------------------
void SAL_CALL OClickableImageBaseModel::removeConsumer( const Reference< XImageConsumer >& _rxConsumer ) throw (RuntimeException)
{
ImageModelMethodGuard aGuard( *this );
GetImageProducer()->removeConsumer( _rxConsumer );
}
//--------------------------------------------------------------------
void SAL_CALL OClickableImageBaseModel::startProduction( ) throw (RuntimeException)
{
ImageModelMethodGuard aGuard( *this );
GetImageProducer()->startProduction();
}
//--------------------------------------------------------------------
Reference< submission::XSubmission > SAL_CALL OClickableImageBaseModel::getSubmission() throw (RuntimeException)
{
return m_xSubmissionDelegate;
}
//--------------------------------------------------------------------
void SAL_CALL OClickableImageBaseModel::setSubmission( const Reference< submission::XSubmission >& _submission ) throw (RuntimeException)
{
m_xSubmissionDelegate = _submission;
}
//--------------------------------------------------------------------
Sequence< OUString > SAL_CALL OClickableImageBaseModel::getSupportedServiceNames( ) throw (RuntimeException)
{
Sequence< OUString > aSupported = OControlModel::getSupportedServiceNames();
aSupported.realloc( aSupported.getLength() + 1 );
OUString* pArray = aSupported.getArray();
pArray[ aSupported.getLength() - 1 ] = FRM_SUN_COMPONENT_SUBMITBUTTON;
return aSupported;
}
// OComponentHelper
//------------------------------------------------------------------------------
void OClickableImageBaseModel::disposing()
{
OControlModel::disposing();
if (m_pMedium)
{
delete m_pMedium;
m_pMedium = NULL;
}
m_xProducer = NULL;
m_pProducer = NULL;
}
//------------------------------------------------------------------------------
Any SAL_CALL OClickableImageBaseModel::queryAggregation(const Type& _rType) throw (RuntimeException)
{
// order matters:
// we definitely want to "overload" the XImageProducer interface of our aggregate,
// thus check OClickableImageBaseModel_Base (which provides this) first
Any aReturn = OClickableImageBaseModel_Base::queryInterface( _rType );
// BUT: _don't_ let it feel responsible for the XTypeProvider interface
// (as this is implemented by our base class in the proper way)
if ( _rType.equals( ::getCppuType( static_cast< Reference< XTypeProvider >* >( NULL ) ) )
|| !aReturn.hasValue()
)
aReturn = OControlModel::queryAggregation( _rType );
return aReturn;
}
//------------------------------------------------------------------------------
void OClickableImageBaseModel::getFastPropertyValue(Any& rValue, sal_Int32 nHandle) const
{
switch (nHandle)
{
case PROPERTY_ID_BUTTONTYPE : rValue <<= m_eButtonType; break;
case PROPERTY_ID_TARGET_URL : rValue <<= m_sTargetURL; break;
case PROPERTY_ID_TARGET_FRAME : rValue <<= m_sTargetFrame; break;
case PROPERTY_ID_DISPATCHURLINTERNAL : rValue <<= m_bDispatchUrlInternal; break;
default:
OControlModel::getFastPropertyValue(rValue, nHandle);
}
}
//------------------------------------------------------------------------------
void OClickableImageBaseModel::setFastPropertyValue_NoBroadcast(sal_Int32 nHandle, const Any& rValue) throw ( Exception)
{
switch (nHandle)
{
case PROPERTY_ID_BUTTONTYPE :
DBG_ASSERT(isA(rValue, static_cast<FormButtonType*>(NULL)), "OClickableImageBaseModel::setFastPropertyValue_NoBroadcast : invalid type !" );
rValue >>= m_eButtonType;
break;
case PROPERTY_ID_TARGET_URL :
DBG_ASSERT(rValue.getValueType().getTypeClass() == TypeClass_STRING, "OClickableImageBaseModel::setFastPropertyValue_NoBroadcast : invalid type !" );
rValue >>= m_sTargetURL;
break;
case PROPERTY_ID_TARGET_FRAME :
DBG_ASSERT(rValue.getValueType().getTypeClass() == TypeClass_STRING, "OClickableImageBaseModel::setFastPropertyValue_NoBroadcast : invalid type !" );
rValue >>= m_sTargetFrame;
break;
case PROPERTY_ID_DISPATCHURLINTERNAL:
DBG_ASSERT(rValue.getValueType().getTypeClass() == TypeClass_BOOLEAN, "OClickableImageBaseModel::setFastPropertyValue_NoBroadcast : invalid type !" );
rValue >>= m_bDispatchUrlInternal;
break;
default:
OControlModel::setFastPropertyValue_NoBroadcast(nHandle, rValue);
}
}
//------------------------------------------------------------------------------
sal_Bool OClickableImageBaseModel::convertFastPropertyValue(Any& rConvertedValue, Any& rOldValue, sal_Int32 nHandle, const Any& rValue)
throw( IllegalArgumentException )
{
switch (nHandle)
{
case PROPERTY_ID_BUTTONTYPE :
return tryPropertyValueEnum( rConvertedValue, rOldValue, rValue, m_eButtonType );
case PROPERTY_ID_TARGET_URL :
return tryPropertyValue(rConvertedValue, rOldValue, rValue, m_sTargetURL);
case PROPERTY_ID_TARGET_FRAME :
return tryPropertyValue(rConvertedValue, rOldValue, rValue, m_sTargetFrame);
case PROPERTY_ID_DISPATCHURLINTERNAL :
return tryPropertyValue(rConvertedValue, rOldValue, rValue, m_bDispatchUrlInternal);
default:
return OControlModel::convertFastPropertyValue(rConvertedValue, rOldValue, nHandle, rValue);
}
}
//------------------------------------------------------------------------------
void OClickableImageBaseModel::StartProduction()
{
ImageProducer *pImgProd = GetImageProducer();
// grab the ImageURL
OUString sURL;
getPropertyValue("ImageURL") >>= sURL;
if (!m_pMedium)
{
if ( ::svt::GraphicAccess::isSupportedURL( sURL ) )
pImgProd->SetImage( sURL );
else
// caution: the medium may be NULL if somebody gave us a invalid URL to work with
pImgProd->SetImage(String());
m_bDownloading = sal_False;
return;
}
if (m_pMedium->GetErrorCode()==0)
{
SvStream* pStream = m_pMedium->GetInStream();
pImgProd->SetImage(*pStream);
pImgProd->startProduction();
m_bProdStarted = sal_True;
}
else
{
pImgProd->SetImage(String());
delete m_pMedium;
m_pMedium = 0;
m_bDownloading = sal_False;
}
}
//------------------------------------------------------------------------------
void OClickableImageBaseModel::SetURL( const OUString& rURL )
{
if (m_pMedium || rURL.isEmpty())
{
// Den Stream am Producer freigeben, bevor das Medium geloscht wird.
GetImageProducer()->SetImage(String());
delete m_pMedium;
m_pMedium = NULL;
}
// the SfxMedium is not allowed to be created with an invalid URL, so we have to check this first
INetURLObject aUrl(rURL);
if (INET_PROT_NOT_VALID == aUrl.GetProtocol())
// we treat an invalid URL like we would treat no URL
return;
if (!rURL.isEmpty() && !::svt::GraphicAccess::isSupportedURL( rURL ) )
{
if (m_pMedium)
delete m_pMedium;
m_pMedium = new SfxMedium(rURL, STREAM_STD_READ);
// Das XModel suchen, um an die Object-Shell oder zumindest den
// Referer zu gelangen.
// Das Model findet man allerdings nur beim Laden von HTML-Dokumenten
// und dann, wenn die URL in einem bereits geladenen Dokument
// geaendert wird. Waehrend des Ladens kommt man nicht an das
// Model ran.
Reference< XModel > xModel;
InterfaceRef xIfc( *this );
while( !xModel.is() && xIfc.is() )
{
Reference<XChild> xChild( xIfc, UNO_QUERY );
xIfc = xChild->getParent();
query_interface(xIfc, xModel);
}
// Die Object-Shell suchen, indem wir
// ueber alle Object-Shells iterieren und deren XModel mit dem
// eigenen vergleichen. Als Optimierung probieren wir aber erstmal
// die aktuelle Object-Shell.
// wir unser XModel mit dem aller Object
SfxObjectShell *pObjSh = 0;
if( xModel.is() )
{
SfxObjectShell *pTestObjSh = SfxObjectShell::Current();
if( pTestObjSh )
{
Reference< XModel > xTestModel = pTestObjSh->GetModel();
if( xTestModel == xModel )
pObjSh = pTestObjSh;
}
if( !pObjSh )
{
pTestObjSh = SfxObjectShell::GetFirst();
while( !pObjSh && pTestObjSh )
{
Reference< XModel > xTestModel = pTestObjSh->GetModel();
if( xTestModel == xModel )
pObjSh = pTestObjSh;
else
pTestObjSh = SfxObjectShell::GetNext( *pTestObjSh );
}
}
}
#ifdef USE_REGISTER_TRANSFER
if( pObjSh )
{
// Target-Frame uebertragen, damit auch javascript:-URLs
// "geladen" werden koennen.
const SfxMedium *pShMedium = pObjSh->GetMedium();
if( pShMedium )
m_pMedium->SetLoadTargetFrame(pShMedium->GetLoadTargetFrame());
}
#else
if( pObjSh )
{
// Target-Frame uebertragen, damit auch javascript:-URLs
// "geladen" werden koennen.
const SfxMedium *pShMedium = pObjSh->GetMedium();
if( pShMedium )
m_pMedium->SetLoadTargetFrame(pShMedium->GetLoadTargetFrame());
}
#endif
// Downloading-Flag auf sal_True setzen. Es werden dann auch
// Data-Available-Links, wenn wir in den Pending-Staus gelangen.
m_bDownloading = sal_True;
m_bProdStarted = sal_False;
// Download anstossen (Achtung: Kann auch synchron sein).
m_pMedium->DownLoad(STATIC_LINK(this, OClickableImageBaseModel, DownloadDoneLink));
}
else
{
if ( ::svt::GraphicAccess::isSupportedURL( rURL ) )
GetImageProducer()->SetImage( rURL );
GetImageProducer()->startProduction();
}
}
//------------------------------------------------------------------------------
void OClickableImageBaseModel::DataAvailable()
{
if (!m_bProdStarted)
StartProduction();
GetImageProducer()->NewDataAvailable();
}
//------------------------------------------------------------------------------
void OClickableImageBaseModel::DownloadDone()
{
DataAvailable();
m_bDownloading = sal_False;
}
//------------------------------------------------------------------------------
IMPL_STATIC_LINK( OClickableImageBaseModel, DownloadDoneLink, void*, EMPTYARG )
{
::osl::MutexGuard aGuard( pThis->m_aMutex );
pThis->DownloadDone();
return 0;
}
//------------------------------------------------------------------------------
void OClickableImageBaseModel::_propertyChanged( const PropertyChangeEvent& rEvt )
throw( RuntimeException )
{
// Wenn eine URL gesetzt worden ist, muss die noch an den ImageProducer
// weitergereicht werden.
::osl::MutexGuard aGuard(m_aMutex);
SetURL( getString(rEvt.NewValue) );
}
// -----------------------------------------------------------------------------
Any OClickableImageBaseModel::getPropertyDefaultByHandle( sal_Int32 nHandle ) const
{
switch (nHandle)
{
case PROPERTY_ID_BUTTONTYPE : return makeAny( FormButtonType_PUSH );
case PROPERTY_ID_TARGET_URL :
case PROPERTY_ID_TARGET_FRAME : return makeAny( OUString() );
case PROPERTY_ID_DISPATCHURLINTERNAL : return makeAny( sal_False );
default:
return OControlModel::getPropertyDefaultByHandle(nHandle);
}
}
//==================================================================
// OImageProducerThread_Impl
//==================================================================
//------------------------------------------------------------------
EventObject* OImageProducerThread_Impl::cloneEvent( const EventObject* _pEvt ) const
{
return new EventObject( *_pEvt );
}
//------------------------------------------------------------------
void OImageProducerThread_Impl::processEvent( ::cppu::OComponentHelper *pCompImpl,
const EventObject* pEvt,
const Reference<XControl>&,
sal_Bool )
{
((OClickableImageBaseControl *)pCompImpl)->actionPerformed_Impl( sal_True, *(MouseEvent *)pEvt );
}
//.........................................................................
} // namespace frm
//.........................................................................
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */