1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 29*cdf0e10cSrcweir #include "precompiled_forms.hxx" 30*cdf0e10cSrcweir #include "ImageControl.hxx" 31*cdf0e10cSrcweir 32*cdf0e10cSrcweir #include "property.hrc" 33*cdf0e10cSrcweir #include "frm_resource.hrc" 34*cdf0e10cSrcweir #include "frm_resource.hxx" 35*cdf0e10cSrcweir #include "services.hxx" 36*cdf0e10cSrcweir #include "componenttools.hxx" 37*cdf0e10cSrcweir 38*cdf0e10cSrcweir #include <svtools/imageresourceaccess.hxx> 39*cdf0e10cSrcweir #include <unotools/ucblockbytes.hxx> 40*cdf0e10cSrcweir #include <sfx2/filedlghelper.hxx> 41*cdf0e10cSrcweir #include <com/sun/star/awt/XPopupMenu.hpp> 42*cdf0e10cSrcweir #include <com/sun/star/awt/PopupMenuDirection.hpp> 43*cdf0e10cSrcweir #include <com/sun/star/ui/dialogs/TemplateDescription.hpp> 44*cdf0e10cSrcweir #include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp> 45*cdf0e10cSrcweir #include <com/sun/star/ui/dialogs/XFilePickerControlAccess.hpp> 46*cdf0e10cSrcweir #include <com/sun/star/ui/dialogs/XFilePicker.hpp> 47*cdf0e10cSrcweir #include <com/sun/star/sdbc/DataType.hpp> 48*cdf0e10cSrcweir #include <com/sun/star/awt/MouseButton.hpp> 49*cdf0e10cSrcweir #include <com/sun/star/awt/XWindow.hpp> 50*cdf0e10cSrcweir #include <com/sun/star/awt/XDialog.hpp> 51*cdf0e10cSrcweir #include <com/sun/star/io/XActiveDataSink.hpp> 52*cdf0e10cSrcweir #include <com/sun/star/io/NotConnectedException.hpp> 53*cdf0e10cSrcweir #include <com/sun/star/beans/PropertyValue.hpp> 54*cdf0e10cSrcweir #include <com/sun/star/graphic/XGraphic.hpp> 55*cdf0e10cSrcweir #include <com/sun/star/graphic/GraphicObject.hpp> 56*cdf0e10cSrcweir #include <tools/urlobj.hxx> 57*cdf0e10cSrcweir #include <tools/stream.hxx> 58*cdf0e10cSrcweir #include <tools/debug.hxx> 59*cdf0e10cSrcweir #include <tools/diagnose_ex.h> 60*cdf0e10cSrcweir #include <vcl/svapp.hxx> 61*cdf0e10cSrcweir #include <unotools/streamhelper.hxx> 62*cdf0e10cSrcweir #include <comphelper/extract.hxx> 63*cdf0e10cSrcweir #include <comphelper/guarding.hxx> 64*cdf0e10cSrcweir #include <unotools/ucbstreamhelper.hxx> 65*cdf0e10cSrcweir #include <svl/urihelper.hxx> 66*cdf0e10cSrcweir 67*cdf0e10cSrcweir #include <memory> 68*cdf0e10cSrcweir 69*cdf0e10cSrcweir #define ID_OPEN_GRAPHICS 1 70*cdf0e10cSrcweir #define ID_CLEAR_GRAPHICS 2 71*cdf0e10cSrcweir 72*cdf0e10cSrcweir //......................................................................... 73*cdf0e10cSrcweir namespace frm 74*cdf0e10cSrcweir { 75*cdf0e10cSrcweir //......................................................................... 76*cdf0e10cSrcweir using namespace ::com::sun::star; 77*cdf0e10cSrcweir using namespace ::com::sun::star::uno; 78*cdf0e10cSrcweir using namespace ::com::sun::star::sdb; 79*cdf0e10cSrcweir using namespace ::com::sun::star::sdbc; 80*cdf0e10cSrcweir using namespace ::com::sun::star::sdbcx; 81*cdf0e10cSrcweir using namespace ::com::sun::star::beans; 82*cdf0e10cSrcweir using namespace ::com::sun::star::container; 83*cdf0e10cSrcweir using namespace ::com::sun::star::form; 84*cdf0e10cSrcweir using namespace ::com::sun::star::awt; 85*cdf0e10cSrcweir using namespace ::com::sun::star::io; 86*cdf0e10cSrcweir using namespace ::com::sun::star::ui::dialogs; 87*cdf0e10cSrcweir using namespace ::com::sun::star::lang; 88*cdf0e10cSrcweir using namespace ::com::sun::star::util; 89*cdf0e10cSrcweir using namespace ::com::sun::star::graphic; 90*cdf0e10cSrcweir using namespace ::com::sun::star::frame; 91*cdf0e10cSrcweir 92*cdf0e10cSrcweir //============================================================================== 93*cdf0e10cSrcweir //= OImageControlModel 94*cdf0e10cSrcweir //============================================================================== 95*cdf0e10cSrcweir namespace 96*cdf0e10cSrcweir { 97*cdf0e10cSrcweir enum ImageStoreType 98*cdf0e10cSrcweir { 99*cdf0e10cSrcweir ImageStoreBinary, 100*cdf0e10cSrcweir ImageStoreLink, 101*cdf0e10cSrcweir 102*cdf0e10cSrcweir ImageStoreInvalid 103*cdf0e10cSrcweir }; 104*cdf0e10cSrcweir 105*cdf0e10cSrcweir ImageStoreType lcl_getImageStoreType( const sal_Int32 _nFieldType ) 106*cdf0e10cSrcweir { 107*cdf0e10cSrcweir // binary/longvarchar types could be used to store images in binary representation 108*cdf0e10cSrcweir if ( ( _nFieldType == DataType::BINARY ) 109*cdf0e10cSrcweir || ( _nFieldType == DataType::VARBINARY ) 110*cdf0e10cSrcweir || ( _nFieldType == DataType::LONGVARBINARY ) 111*cdf0e10cSrcweir || ( _nFieldType == DataType::OTHER ) 112*cdf0e10cSrcweir || ( _nFieldType == DataType::OBJECT ) 113*cdf0e10cSrcweir || ( _nFieldType == DataType::BLOB ) 114*cdf0e10cSrcweir || ( _nFieldType == DataType::LONGVARCHAR ) 115*cdf0e10cSrcweir || ( _nFieldType == DataType::CLOB ) 116*cdf0e10cSrcweir ) 117*cdf0e10cSrcweir return ImageStoreBinary; 118*cdf0e10cSrcweir 119*cdf0e10cSrcweir // char types could be used to store links to images 120*cdf0e10cSrcweir if ( ( _nFieldType == DataType::CHAR ) 121*cdf0e10cSrcweir || ( _nFieldType == DataType::VARCHAR ) 122*cdf0e10cSrcweir ) 123*cdf0e10cSrcweir return ImageStoreLink; 124*cdf0e10cSrcweir 125*cdf0e10cSrcweir return ImageStoreInvalid; 126*cdf0e10cSrcweir } 127*cdf0e10cSrcweir } 128*cdf0e10cSrcweir 129*cdf0e10cSrcweir //============================================================================== 130*cdf0e10cSrcweir // OImageControlModel 131*cdf0e10cSrcweir //============================================================================== 132*cdf0e10cSrcweir 133*cdf0e10cSrcweir //------------------------------------------------------------------------------ 134*cdf0e10cSrcweir InterfaceRef SAL_CALL OImageControlModel_CreateInstance(const Reference<XMultiServiceFactory>& _rxFactory) 135*cdf0e10cSrcweir { 136*cdf0e10cSrcweir return *(new OImageControlModel(_rxFactory)); 137*cdf0e10cSrcweir } 138*cdf0e10cSrcweir 139*cdf0e10cSrcweir //------------------------------------------------------------------------------ 140*cdf0e10cSrcweir Sequence<Type> OImageControlModel::_getTypes() 141*cdf0e10cSrcweir { 142*cdf0e10cSrcweir return concatSequences( 143*cdf0e10cSrcweir OBoundControlModel::_getTypes(), 144*cdf0e10cSrcweir OImageControlModel_Base::getTypes() 145*cdf0e10cSrcweir ); 146*cdf0e10cSrcweir } 147*cdf0e10cSrcweir 148*cdf0e10cSrcweir DBG_NAME(OImageControlModel) 149*cdf0e10cSrcweir //------------------------------------------------------------------ 150*cdf0e10cSrcweir OImageControlModel::OImageControlModel(const Reference<XMultiServiceFactory>& _rxFactory) 151*cdf0e10cSrcweir :OBoundControlModel( _rxFactory, VCL_CONTROLMODEL_IMAGECONTROL, FRM_SUN_CONTROL_IMAGECONTROL, sal_False, sal_False, sal_False ) 152*cdf0e10cSrcweir // use the old control name for compytibility reasons 153*cdf0e10cSrcweir ,m_pImageProducer( NULL ) 154*cdf0e10cSrcweir ,m_bExternalGraphic( true ) 155*cdf0e10cSrcweir ,m_bReadOnly( sal_False ) 156*cdf0e10cSrcweir ,m_sImageURL() 157*cdf0e10cSrcweir ,m_xGraphicObject() 158*cdf0e10cSrcweir { 159*cdf0e10cSrcweir DBG_CTOR( OImageControlModel, NULL ); 160*cdf0e10cSrcweir m_nClassId = FormComponentType::IMAGECONTROL; 161*cdf0e10cSrcweir initOwnValueProperty( PROPERTY_IMAGE_URL ); 162*cdf0e10cSrcweir 163*cdf0e10cSrcweir implConstruct(); 164*cdf0e10cSrcweir } 165*cdf0e10cSrcweir 166*cdf0e10cSrcweir //------------------------------------------------------------------ 167*cdf0e10cSrcweir OImageControlModel::OImageControlModel( const OImageControlModel* _pOriginal, const Reference< XMultiServiceFactory >& _rxFactory ) 168*cdf0e10cSrcweir :OBoundControlModel( _pOriginal, _rxFactory ) 169*cdf0e10cSrcweir // use the old control name for compytibility reasons 170*cdf0e10cSrcweir ,m_pImageProducer( NULL ) 171*cdf0e10cSrcweir ,m_bExternalGraphic( true ) 172*cdf0e10cSrcweir ,m_bReadOnly( _pOriginal->m_bReadOnly ) 173*cdf0e10cSrcweir ,m_sImageURL( _pOriginal->m_sImageURL ) 174*cdf0e10cSrcweir ,m_xGraphicObject( _pOriginal->m_xGraphicObject ) 175*cdf0e10cSrcweir { 176*cdf0e10cSrcweir DBG_CTOR( OImageControlModel, NULL ); 177*cdf0e10cSrcweir implConstruct(); 178*cdf0e10cSrcweir 179*cdf0e10cSrcweir osl_incrementInterlockedCount( &m_refCount ); 180*cdf0e10cSrcweir { 181*cdf0e10cSrcweir // simulate a propertyChanged event for the ImageURL 182*cdf0e10cSrcweir // 2003-05-15 - #109591# - fs@openoffice.org 183*cdf0e10cSrcweir ::osl::MutexGuard aGuard( m_aMutex ); 184*cdf0e10cSrcweir impl_handleNewImageURL_lck( eOther ); 185*cdf0e10cSrcweir } 186*cdf0e10cSrcweir osl_decrementInterlockedCount( &m_refCount ); 187*cdf0e10cSrcweir } 188*cdf0e10cSrcweir 189*cdf0e10cSrcweir //------------------------------------------------------------------ 190*cdf0e10cSrcweir void OImageControlModel::implConstruct() 191*cdf0e10cSrcweir { 192*cdf0e10cSrcweir m_pImageProducer = new ImageProducer; 193*cdf0e10cSrcweir m_xImageProducer = m_pImageProducer; 194*cdf0e10cSrcweir m_pImageProducer->SetDoneHdl( LINK( this, OImageControlModel, OnImageImportDone ) ); 195*cdf0e10cSrcweir } 196*cdf0e10cSrcweir 197*cdf0e10cSrcweir //------------------------------------------------------------------ 198*cdf0e10cSrcweir OImageControlModel::~OImageControlModel() 199*cdf0e10cSrcweir { 200*cdf0e10cSrcweir if (!OComponentHelper::rBHelper.bDisposed) 201*cdf0e10cSrcweir { 202*cdf0e10cSrcweir acquire(); 203*cdf0e10cSrcweir dispose(); 204*cdf0e10cSrcweir } 205*cdf0e10cSrcweir 206*cdf0e10cSrcweir DBG_DTOR(OImageControlModel,NULL); 207*cdf0e10cSrcweir } 208*cdf0e10cSrcweir 209*cdf0e10cSrcweir // XCloneable 210*cdf0e10cSrcweir //------------------------------------------------------------------------------ 211*cdf0e10cSrcweir IMPLEMENT_DEFAULT_CLONING( OImageControlModel ) 212*cdf0e10cSrcweir 213*cdf0e10cSrcweir // XServiceInfo 214*cdf0e10cSrcweir //------------------------------------------------------------------------------ 215*cdf0e10cSrcweir StringSequence OImageControlModel::getSupportedServiceNames() throw() 216*cdf0e10cSrcweir { 217*cdf0e10cSrcweir StringSequence aSupported = OBoundControlModel::getSupportedServiceNames(); 218*cdf0e10cSrcweir aSupported.realloc(aSupported.getLength() + 1); 219*cdf0e10cSrcweir 220*cdf0e10cSrcweir ::rtl::OUString*pArray = aSupported.getArray(); 221*cdf0e10cSrcweir pArray[aSupported.getLength()-1] = FRM_SUN_COMPONENT_IMAGECONTROL; 222*cdf0e10cSrcweir return aSupported; 223*cdf0e10cSrcweir } 224*cdf0e10cSrcweir 225*cdf0e10cSrcweir //------------------------------------------------------------------------------ 226*cdf0e10cSrcweir Any SAL_CALL OImageControlModel::queryAggregation(const Type& _rType) throw (RuntimeException) 227*cdf0e10cSrcweir { 228*cdf0e10cSrcweir // oder matters: we want to "override" the XImageProducer interface of the aggreate with out 229*cdf0e10cSrcweir // own XImageProducer interface, thus we need to query OImageControlModel_Base first 230*cdf0e10cSrcweir Any aReturn = OImageControlModel_Base::queryInterface( _rType ); 231*cdf0e10cSrcweir 232*cdf0e10cSrcweir // BUT: _don't_ let it feel responsible for the XTypeProvider interface 233*cdf0e10cSrcweir // (as this is implemented by our base class in the proper way) 234*cdf0e10cSrcweir if ( _rType.equals( ::getCppuType( static_cast< Reference< XTypeProvider >* >( NULL ) ) ) 235*cdf0e10cSrcweir || !aReturn.hasValue() 236*cdf0e10cSrcweir ) 237*cdf0e10cSrcweir aReturn = OBoundControlModel::queryAggregation( _rType ); 238*cdf0e10cSrcweir 239*cdf0e10cSrcweir return aReturn; 240*cdf0e10cSrcweir } 241*cdf0e10cSrcweir 242*cdf0e10cSrcweir //------------------------------------------------------------------------------ 243*cdf0e10cSrcweir sal_Bool OImageControlModel::approveDbColumnType( sal_Int32 _nColumnType ) 244*cdf0e10cSrcweir { 245*cdf0e10cSrcweir return ImageStoreInvalid != lcl_getImageStoreType( _nColumnType ); 246*cdf0e10cSrcweir } 247*cdf0e10cSrcweir 248*cdf0e10cSrcweir //------------------------------------------------------------------------------ 249*cdf0e10cSrcweir void OImageControlModel::getFastPropertyValue(Any& rValue, sal_Int32 nHandle) const 250*cdf0e10cSrcweir { 251*cdf0e10cSrcweir switch (nHandle) 252*cdf0e10cSrcweir { 253*cdf0e10cSrcweir case PROPERTY_ID_READONLY: 254*cdf0e10cSrcweir rValue <<= (sal_Bool)m_bReadOnly; 255*cdf0e10cSrcweir break; 256*cdf0e10cSrcweir case PROPERTY_ID_IMAGE_URL: 257*cdf0e10cSrcweir rValue <<= m_sImageURL; 258*cdf0e10cSrcweir break; 259*cdf0e10cSrcweir case PROPERTY_ID_GRAPHIC: 260*cdf0e10cSrcweir rValue <<= m_xGraphicObject.is() ? m_xGraphicObject->getGraphic() : Reference< XGraphic >(); 261*cdf0e10cSrcweir break; 262*cdf0e10cSrcweir default: 263*cdf0e10cSrcweir OBoundControlModel::getFastPropertyValue(rValue, nHandle); 264*cdf0e10cSrcweir } 265*cdf0e10cSrcweir } 266*cdf0e10cSrcweir 267*cdf0e10cSrcweir //------------------------------------------------------------------------------ 268*cdf0e10cSrcweir void OImageControlModel::setFastPropertyValue_NoBroadcast(sal_Int32 nHandle, const Any& rValue) throw ( ::com::sun::star::uno::Exception) 269*cdf0e10cSrcweir { 270*cdf0e10cSrcweir switch (nHandle) 271*cdf0e10cSrcweir { 272*cdf0e10cSrcweir case PROPERTY_ID_READONLY : 273*cdf0e10cSrcweir DBG_ASSERT(rValue.getValueType().getTypeClass() == TypeClass_BOOLEAN, "OImageControlModel::setFastPropertyValue_NoBroadcast : invalid type !" ); 274*cdf0e10cSrcweir m_bReadOnly = getBOOL(rValue); 275*cdf0e10cSrcweir break; 276*cdf0e10cSrcweir 277*cdf0e10cSrcweir case PROPERTY_ID_IMAGE_URL: 278*cdf0e10cSrcweir OSL_VERIFY( rValue >>= m_sImageURL ); 279*cdf0e10cSrcweir impl_handleNewImageURL_lck( eOther ); 280*cdf0e10cSrcweir { 281*cdf0e10cSrcweir ControlModelLock aLock( *this ); 282*cdf0e10cSrcweir // that's a fake ... onValuePropertyChange expects to receive the only lock to our instance, 283*cdf0e10cSrcweir // but we're already called with our mutex locked ... 284*cdf0e10cSrcweir onValuePropertyChange( aLock ); 285*cdf0e10cSrcweir } 286*cdf0e10cSrcweir break; 287*cdf0e10cSrcweir 288*cdf0e10cSrcweir case PROPERTY_ID_GRAPHIC: 289*cdf0e10cSrcweir { 290*cdf0e10cSrcweir Reference< XGraphic > xGraphic; 291*cdf0e10cSrcweir OSL_VERIFY( rValue >>= xGraphic ); 292*cdf0e10cSrcweir if ( !xGraphic.is() ) 293*cdf0e10cSrcweir m_xGraphicObject.clear(); 294*cdf0e10cSrcweir else 295*cdf0e10cSrcweir { 296*cdf0e10cSrcweir m_xGraphicObject = GraphicObject::create( m_aContext.getUNOContext() ); 297*cdf0e10cSrcweir m_xGraphicObject->setGraphic( xGraphic ); 298*cdf0e10cSrcweir } 299*cdf0e10cSrcweir 300*cdf0e10cSrcweir if ( m_bExternalGraphic ) 301*cdf0e10cSrcweir { 302*cdf0e10cSrcweir // if that's an external graphic, i.e. one which has not been loaded by ourselves in response to a 303*cdf0e10cSrcweir // new image URL, then also adjust our ImageURL. 304*cdf0e10cSrcweir ::rtl::OUString sNewImageURL; 305*cdf0e10cSrcweir if ( m_xGraphicObject.is() ) 306*cdf0e10cSrcweir { 307*cdf0e10cSrcweir sNewImageURL = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "vnd.sun.star.GraphicObject:" ) ); 308*cdf0e10cSrcweir sNewImageURL = sNewImageURL + m_xGraphicObject->getUniqueID(); 309*cdf0e10cSrcweir } 310*cdf0e10cSrcweir m_sImageURL = sNewImageURL; 311*cdf0e10cSrcweir // TODO: speaking strictly, this would need to be notified, since ImageURL is a bound property. However, 312*cdf0e10cSrcweir // this method here is called with a locked mutex, so we cannot simply call listeners ... 313*cdf0e10cSrcweir // I think the missing notification (and thus clients which potentially cannot observe the change) 314*cdf0e10cSrcweir // is less severe than the potential deadlock ... 315*cdf0e10cSrcweir } 316*cdf0e10cSrcweir } 317*cdf0e10cSrcweir break; 318*cdf0e10cSrcweir 319*cdf0e10cSrcweir default: 320*cdf0e10cSrcweir OBoundControlModel::setFastPropertyValue_NoBroadcast(nHandle, rValue); 321*cdf0e10cSrcweir break; 322*cdf0e10cSrcweir } 323*cdf0e10cSrcweir } 324*cdf0e10cSrcweir 325*cdf0e10cSrcweir //------------------------------------------------------------------------------ 326*cdf0e10cSrcweir sal_Bool OImageControlModel::convertFastPropertyValue(Any& rConvertedValue, Any& rOldValue, sal_Int32 nHandle, const Any& rValue) 327*cdf0e10cSrcweir throw( IllegalArgumentException ) 328*cdf0e10cSrcweir { 329*cdf0e10cSrcweir switch (nHandle) 330*cdf0e10cSrcweir { 331*cdf0e10cSrcweir case PROPERTY_ID_READONLY : 332*cdf0e10cSrcweir return tryPropertyValue(rConvertedValue, rOldValue, rValue, m_bReadOnly); 333*cdf0e10cSrcweir 334*cdf0e10cSrcweir case PROPERTY_ID_IMAGE_URL: 335*cdf0e10cSrcweir return tryPropertyValue( rConvertedValue, rOldValue, rValue, m_sImageURL ); 336*cdf0e10cSrcweir 337*cdf0e10cSrcweir case PROPERTY_ID_GRAPHIC: 338*cdf0e10cSrcweir { 339*cdf0e10cSrcweir const Reference< XGraphic > xGraphic( getFastPropertyValue( PROPERTY_ID_GRAPHIC ), UNO_QUERY ); 340*cdf0e10cSrcweir return tryPropertyValue( rConvertedValue, rOldValue, rValue, xGraphic ); 341*cdf0e10cSrcweir } 342*cdf0e10cSrcweir 343*cdf0e10cSrcweir default: 344*cdf0e10cSrcweir return OBoundControlModel::convertFastPropertyValue(rConvertedValue, rOldValue, nHandle, rValue); 345*cdf0e10cSrcweir } 346*cdf0e10cSrcweir } 347*cdf0e10cSrcweir 348*cdf0e10cSrcweir //------------------------------------------------------------------------------ 349*cdf0e10cSrcweir void OImageControlModel::describeFixedProperties( Sequence< Property >& _rProps ) const 350*cdf0e10cSrcweir { 351*cdf0e10cSrcweir BEGIN_DESCRIBE_PROPERTIES( 4, OBoundControlModel ) 352*cdf0e10cSrcweir DECL_IFACE_PROP2( GRAPHIC, XGraphic, BOUND, TRANSIENT ); 353*cdf0e10cSrcweir DECL_PROP1 ( IMAGE_URL, ::rtl::OUString, BOUND ); 354*cdf0e10cSrcweir DECL_BOOL_PROP1 ( READONLY, BOUND ); 355*cdf0e10cSrcweir DECL_PROP1 ( TABINDEX, sal_Int16, BOUND ); 356*cdf0e10cSrcweir END_DESCRIBE_PROPERTIES(); 357*cdf0e10cSrcweir } 358*cdf0e10cSrcweir 359*cdf0e10cSrcweir //------------------------------------------------------------------------------ 360*cdf0e10cSrcweir void OImageControlModel::describeAggregateProperties( Sequence< Property >& /* [out] */ o_rAggregateProperties ) const 361*cdf0e10cSrcweir { 362*cdf0e10cSrcweir OBoundControlModel::describeAggregateProperties( o_rAggregateProperties ); 363*cdf0e10cSrcweir // remove ImageULR and Graphic properties, we "overload" them. This is because our aggregate synchronizes those 364*cdf0e10cSrcweir // two, but we have an own sychronization mechanism. 365*cdf0e10cSrcweir RemoveProperty( o_rAggregateProperties, PROPERTY_IMAGE_URL ); 366*cdf0e10cSrcweir RemoveProperty( o_rAggregateProperties, PROPERTY_GRAPHIC ); 367*cdf0e10cSrcweir } 368*cdf0e10cSrcweir 369*cdf0e10cSrcweir //------------------------------------------------------------------------------ 370*cdf0e10cSrcweir ::rtl::OUString OImageControlModel::getServiceName() throw ( ::com::sun::star::uno::RuntimeException) 371*cdf0e10cSrcweir { 372*cdf0e10cSrcweir return FRM_COMPONENT_IMAGECONTROL; // old (non-sun) name for compatibility ! 373*cdf0e10cSrcweir } 374*cdf0e10cSrcweir 375*cdf0e10cSrcweir //------------------------------------------------------------------------------ 376*cdf0e10cSrcweir void OImageControlModel::write(const Reference<XObjectOutputStream>& _rxOutStream) throw ( ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException) 377*cdf0e10cSrcweir { 378*cdf0e10cSrcweir // Basisklasse 379*cdf0e10cSrcweir OBoundControlModel::write(_rxOutStream); 380*cdf0e10cSrcweir // Version 381*cdf0e10cSrcweir _rxOutStream->writeShort(0x0003); 382*cdf0e10cSrcweir // Name 383*cdf0e10cSrcweir _rxOutStream->writeBoolean(m_bReadOnly); 384*cdf0e10cSrcweir writeHelpTextCompatibly(_rxOutStream); 385*cdf0e10cSrcweir // from version 0x0003 : common properties 386*cdf0e10cSrcweir writeCommonProperties(_rxOutStream); 387*cdf0e10cSrcweir } 388*cdf0e10cSrcweir 389*cdf0e10cSrcweir //------------------------------------------------------------------------------ 390*cdf0e10cSrcweir void OImageControlModel::read(const Reference<XObjectInputStream>& _rxInStream) throw ( ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException) 391*cdf0e10cSrcweir { 392*cdf0e10cSrcweir OBoundControlModel::read(_rxInStream); 393*cdf0e10cSrcweir 394*cdf0e10cSrcweir // Version 395*cdf0e10cSrcweir sal_uInt16 nVersion = _rxInStream->readShort(); 396*cdf0e10cSrcweir switch (nVersion) 397*cdf0e10cSrcweir { 398*cdf0e10cSrcweir case 0x0001: 399*cdf0e10cSrcweir m_bReadOnly = _rxInStream->readBoolean(); 400*cdf0e10cSrcweir break; 401*cdf0e10cSrcweir case 0x0002: 402*cdf0e10cSrcweir m_bReadOnly = _rxInStream->readBoolean(); 403*cdf0e10cSrcweir readHelpTextCompatibly(_rxInStream); 404*cdf0e10cSrcweir break; 405*cdf0e10cSrcweir case 0x0003: 406*cdf0e10cSrcweir m_bReadOnly = _rxInStream->readBoolean(); 407*cdf0e10cSrcweir readHelpTextCompatibly(_rxInStream); 408*cdf0e10cSrcweir readCommonProperties(_rxInStream); 409*cdf0e10cSrcweir break; 410*cdf0e10cSrcweir default : 411*cdf0e10cSrcweir DBG_ERROR("OImageControlModel::read : unknown version !"); 412*cdf0e10cSrcweir m_bReadOnly = sal_False; 413*cdf0e10cSrcweir defaultCommonProperties(); 414*cdf0e10cSrcweir break; 415*cdf0e10cSrcweir } 416*cdf0e10cSrcweir // Nach dem Lesen die Defaultwerte anzeigen 417*cdf0e10cSrcweir if ( getControlSource().getLength() ) 418*cdf0e10cSrcweir { // (not if we don't have a control source - the "State" property acts like it is persistent, then 419*cdf0e10cSrcweir ::osl::MutexGuard aGuard(m_aMutex); // resetNoBroadcast expects this mutex guarding 420*cdf0e10cSrcweir resetNoBroadcast(); 421*cdf0e10cSrcweir } 422*cdf0e10cSrcweir } 423*cdf0e10cSrcweir 424*cdf0e10cSrcweir //------------------------------------------------------------------------------ 425*cdf0e10cSrcweir sal_Bool OImageControlModel::impl_updateStreamForURL_lck( const ::rtl::OUString& _rURL, ValueChangeInstigator _eInstigator ) 426*cdf0e10cSrcweir { 427*cdf0e10cSrcweir // create a stream for the image specified by the URL 428*cdf0e10cSrcweir ::std::auto_ptr< SvStream > pImageStream; 429*cdf0e10cSrcweir Reference< XInputStream > xImageStream; 430*cdf0e10cSrcweir 431*cdf0e10cSrcweir if ( ::svt::GraphicAccess::isSupportedURL( _rURL ) ) 432*cdf0e10cSrcweir { 433*cdf0e10cSrcweir xImageStream = ::svt::GraphicAccess::getImageXStream( getContext().getLegacyServiceFactory(), _rURL ); 434*cdf0e10cSrcweir } 435*cdf0e10cSrcweir else 436*cdf0e10cSrcweir { 437*cdf0e10cSrcweir pImageStream.reset( ::utl::UcbStreamHelper::CreateStream( _rURL, STREAM_READ ) ); 438*cdf0e10cSrcweir sal_Bool bSetNull = ( pImageStream.get() == NULL ) || ( ERRCODE_NONE != pImageStream->GetErrorCode() ); 439*cdf0e10cSrcweir 440*cdf0e10cSrcweir if ( !bSetNull ) 441*cdf0e10cSrcweir { 442*cdf0e10cSrcweir // get the size of the stream 443*cdf0e10cSrcweir pImageStream->Seek(STREAM_SEEK_TO_END); 444*cdf0e10cSrcweir sal_Int32 nSize = (sal_Int32)pImageStream->Tell(); 445*cdf0e10cSrcweir if (pImageStream->GetBufferSize() < 8192) 446*cdf0e10cSrcweir pImageStream->SetBufferSize(8192); 447*cdf0e10cSrcweir pImageStream->Seek(STREAM_SEEK_TO_BEGIN); 448*cdf0e10cSrcweir 449*cdf0e10cSrcweir xImageStream = new ::utl::OInputStreamHelper( new SvLockBytes( pImageStream.get(), sal_False ), nSize ); 450*cdf0e10cSrcweir } 451*cdf0e10cSrcweir } 452*cdf0e10cSrcweir 453*cdf0e10cSrcweir if ( xImageStream.is() ) 454*cdf0e10cSrcweir { 455*cdf0e10cSrcweir if ( m_xColumnUpdate.is() ) 456*cdf0e10cSrcweir m_xColumnUpdate->updateBinaryStream( xImageStream, xImageStream->available() ); 457*cdf0e10cSrcweir else 458*cdf0e10cSrcweir setControlValue( makeAny( xImageStream ), _eInstigator ); 459*cdf0e10cSrcweir xImageStream->closeInput(); 460*cdf0e10cSrcweir return sal_True; 461*cdf0e10cSrcweir } 462*cdf0e10cSrcweir 463*cdf0e10cSrcweir return sal_False; 464*cdf0e10cSrcweir } 465*cdf0e10cSrcweir 466*cdf0e10cSrcweir //------------------------------------------------------------------------------ 467*cdf0e10cSrcweir sal_Bool OImageControlModel::impl_handleNewImageURL_lck( ValueChangeInstigator _eInstigator ) 468*cdf0e10cSrcweir { 469*cdf0e10cSrcweir switch ( lcl_getImageStoreType( getFieldType() ) ) 470*cdf0e10cSrcweir { 471*cdf0e10cSrcweir case ImageStoreBinary: 472*cdf0e10cSrcweir if ( impl_updateStreamForURL_lck( m_sImageURL, _eInstigator ) ) 473*cdf0e10cSrcweir return sal_True; 474*cdf0e10cSrcweir break; 475*cdf0e10cSrcweir 476*cdf0e10cSrcweir case ImageStoreLink: 477*cdf0e10cSrcweir { 478*cdf0e10cSrcweir ::rtl::OUString sCommitURL( m_sImageURL ); 479*cdf0e10cSrcweir if ( m_sDocumentURL.getLength() ) 480*cdf0e10cSrcweir sCommitURL = URIHelper::simpleNormalizedMakeRelative( m_sDocumentURL, sCommitURL ); 481*cdf0e10cSrcweir OSL_ENSURE( m_xColumnUpdate.is(), "OImageControlModel::impl_handleNewImageURL_lck: no bound field, but ImageStoreLink?!" ); 482*cdf0e10cSrcweir if ( m_xColumnUpdate.is() ) 483*cdf0e10cSrcweir { 484*cdf0e10cSrcweir m_xColumnUpdate->updateString( sCommitURL ); 485*cdf0e10cSrcweir return sal_True; 486*cdf0e10cSrcweir } 487*cdf0e10cSrcweir } 488*cdf0e10cSrcweir break; 489*cdf0e10cSrcweir 490*cdf0e10cSrcweir case ImageStoreInvalid: 491*cdf0e10cSrcweir OSL_ENSURE( false, "OImageControlModel::impl_handleNewImageURL_lck: image storage type type!" ); 492*cdf0e10cSrcweir break; 493*cdf0e10cSrcweir } 494*cdf0e10cSrcweir 495*cdf0e10cSrcweir // if we're here, then the above code was unable to update our field/control from the given URL 496*cdf0e10cSrcweir // => fall back to NULL/VOID 497*cdf0e10cSrcweir if ( m_xColumnUpdate.is() ) 498*cdf0e10cSrcweir m_xColumnUpdate->updateNull(); 499*cdf0e10cSrcweir else 500*cdf0e10cSrcweir setControlValue( Any(), _eInstigator ); 501*cdf0e10cSrcweir 502*cdf0e10cSrcweir return sal_True; 503*cdf0e10cSrcweir } 504*cdf0e10cSrcweir 505*cdf0e10cSrcweir //------------------------------------------------------------------------------ 506*cdf0e10cSrcweir sal_Bool OImageControlModel::commitControlValueToDbColumn( bool _bPostReset ) 507*cdf0e10cSrcweir { 508*cdf0e10cSrcweir if ( _bPostReset ) 509*cdf0e10cSrcweir { 510*cdf0e10cSrcweir // since this is a "commit after reset", we can simply update the column 511*cdf0e10cSrcweir // with null - this is our "default" which we were just reset to 512*cdf0e10cSrcweir if ( m_xColumnUpdate.is() ) 513*cdf0e10cSrcweir m_xColumnUpdate->updateNull(); 514*cdf0e10cSrcweir } 515*cdf0e10cSrcweir else 516*cdf0e10cSrcweir { 517*cdf0e10cSrcweir ::osl::MutexGuard aGuard(m_aMutex); 518*cdf0e10cSrcweir return impl_handleNewImageURL_lck( eDbColumnBinding ); 519*cdf0e10cSrcweir } 520*cdf0e10cSrcweir 521*cdf0e10cSrcweir return sal_True; 522*cdf0e10cSrcweir } 523*cdf0e10cSrcweir 524*cdf0e10cSrcweir //------------------------------------------------------------------------------ 525*cdf0e10cSrcweir namespace 526*cdf0e10cSrcweir { 527*cdf0e10cSrcweir bool lcl_isValidDocumentURL( const ::rtl::OUString& _rDocURL ) 528*cdf0e10cSrcweir { 529*cdf0e10cSrcweir return ( _rDocURL.getLength() && !_rDocURL.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "private:object" ) ) ); 530*cdf0e10cSrcweir } 531*cdf0e10cSrcweir } 532*cdf0e10cSrcweir 533*cdf0e10cSrcweir //------------------------------------------------------------------------------ 534*cdf0e10cSrcweir void OImageControlModel::onConnectedDbColumn( const Reference< XInterface >& _rxForm ) 535*cdf0e10cSrcweir { 536*cdf0e10cSrcweir OBoundControlModel::onConnectedDbColumn( _rxForm ); 537*cdf0e10cSrcweir 538*cdf0e10cSrcweir try 539*cdf0e10cSrcweir { 540*cdf0e10cSrcweir Reference< XModel > xDocument( getXModel( *this ) ); 541*cdf0e10cSrcweir if ( xDocument.is() ) 542*cdf0e10cSrcweir { 543*cdf0e10cSrcweir m_sDocumentURL = xDocument->getURL(); 544*cdf0e10cSrcweir if ( !lcl_isValidDocumentURL( m_sDocumentURL ) ) 545*cdf0e10cSrcweir { 546*cdf0e10cSrcweir Reference< XChild > xAsChild( xDocument, UNO_QUERY ); 547*cdf0e10cSrcweir while ( xAsChild.is() && !lcl_isValidDocumentURL( m_sDocumentURL ) ) 548*cdf0e10cSrcweir { 549*cdf0e10cSrcweir xDocument.set( xAsChild->getParent(), UNO_QUERY ); 550*cdf0e10cSrcweir if ( xDocument.is() ) 551*cdf0e10cSrcweir m_sDocumentURL = xDocument->getURL(); 552*cdf0e10cSrcweir xAsChild.set( xDocument, UNO_QUERY ); 553*cdf0e10cSrcweir } 554*cdf0e10cSrcweir } 555*cdf0e10cSrcweir } 556*cdf0e10cSrcweir } 557*cdf0e10cSrcweir catch( const Exception& ) 558*cdf0e10cSrcweir { 559*cdf0e10cSrcweir DBG_UNHANDLED_EXCEPTION(); 560*cdf0e10cSrcweir } 561*cdf0e10cSrcweir } 562*cdf0e10cSrcweir 563*cdf0e10cSrcweir //------------------------------------------------------------------------------ 564*cdf0e10cSrcweir void OImageControlModel::onDisconnectedDbColumn() 565*cdf0e10cSrcweir { 566*cdf0e10cSrcweir OBoundControlModel::onDisconnectedDbColumn(); 567*cdf0e10cSrcweir 568*cdf0e10cSrcweir m_sDocumentURL = ::rtl::OUString(); 569*cdf0e10cSrcweir } 570*cdf0e10cSrcweir 571*cdf0e10cSrcweir //------------------------------------------------------------------------------ 572*cdf0e10cSrcweir Any OImageControlModel::translateDbColumnToControlValue() 573*cdf0e10cSrcweir { 574*cdf0e10cSrcweir switch ( lcl_getImageStoreType( getFieldType() ) ) 575*cdf0e10cSrcweir { 576*cdf0e10cSrcweir case ImageStoreBinary: 577*cdf0e10cSrcweir { 578*cdf0e10cSrcweir Reference< XInputStream > xImageStream( m_xColumn->getBinaryStream() ); 579*cdf0e10cSrcweir if ( m_xColumn->wasNull() ) 580*cdf0e10cSrcweir xImageStream.clear(); 581*cdf0e10cSrcweir return makeAny( xImageStream ); 582*cdf0e10cSrcweir } 583*cdf0e10cSrcweir case ImageStoreLink: 584*cdf0e10cSrcweir { 585*cdf0e10cSrcweir ::rtl::OUString sImageLink( m_xColumn->getString() ); 586*cdf0e10cSrcweir if ( m_sDocumentURL.getLength() ) 587*cdf0e10cSrcweir sImageLink = INetURLObject::GetAbsURL( m_sDocumentURL, sImageLink ); 588*cdf0e10cSrcweir return makeAny( sImageLink ); 589*cdf0e10cSrcweir } 590*cdf0e10cSrcweir case ImageStoreInvalid: 591*cdf0e10cSrcweir OSL_ENSURE( false, "OImageControlModel::translateDbColumnToControlValue: invalid field type!" ); 592*cdf0e10cSrcweir break; 593*cdf0e10cSrcweir } 594*cdf0e10cSrcweir return Any(); 595*cdf0e10cSrcweir } 596*cdf0e10cSrcweir 597*cdf0e10cSrcweir //------------------------------------------------------------------------------ 598*cdf0e10cSrcweir Any OImageControlModel::getControlValue( ) const 599*cdf0e10cSrcweir { 600*cdf0e10cSrcweir return makeAny( m_sImageURL ); 601*cdf0e10cSrcweir } 602*cdf0e10cSrcweir 603*cdf0e10cSrcweir //------------------------------------------------------------------------------ 604*cdf0e10cSrcweir void OImageControlModel::doSetControlValue( const Any& _rValue ) 605*cdf0e10cSrcweir { 606*cdf0e10cSrcweir DBG_ASSERT( GetImageProducer() && m_xImageProducer.is(), "OImageControlModel::doSetControlValue: no image producer!" ); 607*cdf0e10cSrcweir if ( !GetImageProducer() || !m_xImageProducer.is() ) 608*cdf0e10cSrcweir return; 609*cdf0e10cSrcweir 610*cdf0e10cSrcweir bool bStartProduction = false; 611*cdf0e10cSrcweir switch ( lcl_getImageStoreType( getFieldType() ) ) 612*cdf0e10cSrcweir { 613*cdf0e10cSrcweir case ImageStoreBinary: 614*cdf0e10cSrcweir { 615*cdf0e10cSrcweir // give the image producer the stream 616*cdf0e10cSrcweir Reference< XInputStream > xInStream; 617*cdf0e10cSrcweir _rValue >>= xInStream; 618*cdf0e10cSrcweir GetImageProducer()->setImage( xInStream ); 619*cdf0e10cSrcweir bStartProduction = true; 620*cdf0e10cSrcweir } 621*cdf0e10cSrcweir break; 622*cdf0e10cSrcweir 623*cdf0e10cSrcweir case ImageStoreLink: 624*cdf0e10cSrcweir { 625*cdf0e10cSrcweir ::rtl::OUString sImageURL; 626*cdf0e10cSrcweir _rValue >>= sImageURL; 627*cdf0e10cSrcweir GetImageProducer()->SetImage( sImageURL ); 628*cdf0e10cSrcweir bStartProduction = true; 629*cdf0e10cSrcweir } 630*cdf0e10cSrcweir break; 631*cdf0e10cSrcweir 632*cdf0e10cSrcweir case ImageStoreInvalid: 633*cdf0e10cSrcweir OSL_ENSURE( false, "OImageControlModel::doSetControlValue: invalid field type!" ); 634*cdf0e10cSrcweir break; 635*cdf0e10cSrcweir 636*cdf0e10cSrcweir } // switch ( lcl_getImageStoreType( getFieldType() ) ) 637*cdf0e10cSrcweir 638*cdf0e10cSrcweir if ( bStartProduction ) 639*cdf0e10cSrcweir { 640*cdf0e10cSrcweir // start production 641*cdf0e10cSrcweir Reference< XImageProducer > xProducer = m_xImageProducer; 642*cdf0e10cSrcweir { 643*cdf0e10cSrcweir // release our mutex once (it's acquired in the calling method!), as starting the image production may 644*cdf0e10cSrcweir // result in the locking of the solar mutex (unfortunally the default implementation of our aggregate, 645*cdf0e10cSrcweir // VCLXImageControl, does this locking) 646*cdf0e10cSrcweir // FS - 74438 - 30.03.00 647*cdf0e10cSrcweir MutexRelease aRelease(m_aMutex); 648*cdf0e10cSrcweir xProducer->startProduction(); 649*cdf0e10cSrcweir } 650*cdf0e10cSrcweir } 651*cdf0e10cSrcweir } 652*cdf0e10cSrcweir 653*cdf0e10cSrcweir // OComponentHelper 654*cdf0e10cSrcweir //------------------------------------------------------------------ 655*cdf0e10cSrcweir void SAL_CALL OImageControlModel::disposing() 656*cdf0e10cSrcweir { 657*cdf0e10cSrcweir OBoundControlModel::disposing(); 658*cdf0e10cSrcweir } 659*cdf0e10cSrcweir 660*cdf0e10cSrcweir //------------------------------------------------------------------------------ 661*cdf0e10cSrcweir void OImageControlModel::resetNoBroadcast() 662*cdf0e10cSrcweir { 663*cdf0e10cSrcweir if ( hasField() ) // only reset when we are connected to a column 664*cdf0e10cSrcweir OBoundControlModel::resetNoBroadcast( ); 665*cdf0e10cSrcweir } 666*cdf0e10cSrcweir 667*cdf0e10cSrcweir //-------------------------------------------------------------------- 668*cdf0e10cSrcweir Reference< XImageProducer > SAL_CALL OImageControlModel::getImageProducer() throw ( RuntimeException) 669*cdf0e10cSrcweir { 670*cdf0e10cSrcweir return this; 671*cdf0e10cSrcweir } 672*cdf0e10cSrcweir 673*cdf0e10cSrcweir //-------------------------------------------------------------------- 674*cdf0e10cSrcweir void SAL_CALL OImageControlModel::addConsumer( const Reference< XImageConsumer >& _rxConsumer ) throw (RuntimeException) 675*cdf0e10cSrcweir { 676*cdf0e10cSrcweir GetImageProducer()->addConsumer( _rxConsumer ); 677*cdf0e10cSrcweir } 678*cdf0e10cSrcweir 679*cdf0e10cSrcweir //-------------------------------------------------------------------- 680*cdf0e10cSrcweir void SAL_CALL OImageControlModel::removeConsumer( const Reference< XImageConsumer >& _rxConsumer ) throw (RuntimeException) 681*cdf0e10cSrcweir { 682*cdf0e10cSrcweir GetImageProducer()->removeConsumer( _rxConsumer ); 683*cdf0e10cSrcweir } 684*cdf0e10cSrcweir 685*cdf0e10cSrcweir //-------------------------------------------------------------------- 686*cdf0e10cSrcweir void SAL_CALL OImageControlModel::startProduction( ) throw (RuntimeException) 687*cdf0e10cSrcweir { 688*cdf0e10cSrcweir GetImageProducer()->startProduction(); 689*cdf0e10cSrcweir } 690*cdf0e10cSrcweir 691*cdf0e10cSrcweir //------------------------------------------------------------------------------ 692*cdf0e10cSrcweir IMPL_LINK( OImageControlModel, OnImageImportDone, ::Graphic*, i_pGraphic ) 693*cdf0e10cSrcweir { 694*cdf0e10cSrcweir const Reference< XGraphic > xGraphic( i_pGraphic != NULL ? Image( i_pGraphic->GetBitmapEx() ).GetXGraphic() : NULL ); 695*cdf0e10cSrcweir m_bExternalGraphic = false; 696*cdf0e10cSrcweir try 697*cdf0e10cSrcweir { 698*cdf0e10cSrcweir setPropertyValue( PROPERTY_GRAPHIC, makeAny( xGraphic ) ); 699*cdf0e10cSrcweir } 700*cdf0e10cSrcweir catch ( const Exception& ) 701*cdf0e10cSrcweir { 702*cdf0e10cSrcweir DBG_UNHANDLED_EXCEPTION(); 703*cdf0e10cSrcweir } 704*cdf0e10cSrcweir m_bExternalGraphic = true; 705*cdf0e10cSrcweir return 1L; 706*cdf0e10cSrcweir } 707*cdf0e10cSrcweir 708*cdf0e10cSrcweir //================================================================== 709*cdf0e10cSrcweir // OImageControlControl 710*cdf0e10cSrcweir //================================================================== 711*cdf0e10cSrcweir 712*cdf0e10cSrcweir //------------------------------------------------------------------ 713*cdf0e10cSrcweir InterfaceRef SAL_CALL OImageControlControl_CreateInstance(const Reference<XMultiServiceFactory>& _rxFactory) 714*cdf0e10cSrcweir { 715*cdf0e10cSrcweir return *(new OImageControlControl(_rxFactory)); 716*cdf0e10cSrcweir } 717*cdf0e10cSrcweir 718*cdf0e10cSrcweir //------------------------------------------------------------------------------ 719*cdf0e10cSrcweir Sequence<Type> OImageControlControl::_getTypes() 720*cdf0e10cSrcweir { 721*cdf0e10cSrcweir return concatSequences( 722*cdf0e10cSrcweir OBoundControl::_getTypes(), 723*cdf0e10cSrcweir OImageControlControl_Base::getTypes() 724*cdf0e10cSrcweir ); 725*cdf0e10cSrcweir } 726*cdf0e10cSrcweir 727*cdf0e10cSrcweir //------------------------------------------------------------------------------ 728*cdf0e10cSrcweir OImageControlControl::OImageControlControl(const Reference<XMultiServiceFactory>& _rxFactory) 729*cdf0e10cSrcweir :OBoundControl(_rxFactory, VCL_CONTROL_IMAGECONTROL) 730*cdf0e10cSrcweir ,m_aModifyListeners( m_aMutex ) 731*cdf0e10cSrcweir { 732*cdf0e10cSrcweir increment(m_refCount); 733*cdf0e10cSrcweir { 734*cdf0e10cSrcweir // als Focus- und MouseListener anmelden 735*cdf0e10cSrcweir Reference< XWindow > xComp; 736*cdf0e10cSrcweir query_aggregation( m_xAggregate, xComp ); 737*cdf0e10cSrcweir if ( xComp.is() ) 738*cdf0e10cSrcweir xComp->addMouseListener( this ); 739*cdf0e10cSrcweir } 740*cdf0e10cSrcweir decrement(m_refCount); 741*cdf0e10cSrcweir } 742*cdf0e10cSrcweir 743*cdf0e10cSrcweir //------------------------------------------------------------------------------ 744*cdf0e10cSrcweir Any SAL_CALL OImageControlControl::queryAggregation(const Type& _rType) throw (RuntimeException) 745*cdf0e10cSrcweir { 746*cdf0e10cSrcweir Any aReturn = OBoundControl::queryAggregation( _rType ); 747*cdf0e10cSrcweir if ( !aReturn.hasValue() ) 748*cdf0e10cSrcweir aReturn = ::cppu::queryInterface( 749*cdf0e10cSrcweir _rType, 750*cdf0e10cSrcweir static_cast< XMouseListener* >( this ), 751*cdf0e10cSrcweir static_cast< XModifyBroadcaster* >( this ) 752*cdf0e10cSrcweir ); 753*cdf0e10cSrcweir 754*cdf0e10cSrcweir return aReturn; 755*cdf0e10cSrcweir } 756*cdf0e10cSrcweir 757*cdf0e10cSrcweir //------------------------------------------------------------------------------ 758*cdf0e10cSrcweir StringSequence OImageControlControl::getSupportedServiceNames() throw() 759*cdf0e10cSrcweir { 760*cdf0e10cSrcweir StringSequence aSupported = OBoundControl::getSupportedServiceNames(); 761*cdf0e10cSrcweir aSupported.realloc(aSupported.getLength() + 1); 762*cdf0e10cSrcweir 763*cdf0e10cSrcweir ::rtl::OUString*pArray = aSupported.getArray(); 764*cdf0e10cSrcweir pArray[aSupported.getLength()-1] = FRM_SUN_CONTROL_IMAGECONTROL; 765*cdf0e10cSrcweir return aSupported; 766*cdf0e10cSrcweir } 767*cdf0e10cSrcweir 768*cdf0e10cSrcweir //------------------------------------------------------------------------------ 769*cdf0e10cSrcweir void SAL_CALL OImageControlControl::addModifyListener( const Reference< XModifyListener >& _Listener ) throw (RuntimeException) 770*cdf0e10cSrcweir { 771*cdf0e10cSrcweir m_aModifyListeners.addInterface( _Listener ); 772*cdf0e10cSrcweir } 773*cdf0e10cSrcweir 774*cdf0e10cSrcweir //------------------------------------------------------------------------------ 775*cdf0e10cSrcweir void SAL_CALL OImageControlControl::removeModifyListener( const Reference< XModifyListener >& _Listener ) throw (RuntimeException) 776*cdf0e10cSrcweir { 777*cdf0e10cSrcweir m_aModifyListeners.removeInterface( _Listener ); 778*cdf0e10cSrcweir } 779*cdf0e10cSrcweir 780*cdf0e10cSrcweir //------------------------------------------------------------------------------ 781*cdf0e10cSrcweir void SAL_CALL OImageControlControl::disposing() 782*cdf0e10cSrcweir { 783*cdf0e10cSrcweir EventObject aEvent( *this ); 784*cdf0e10cSrcweir m_aModifyListeners.disposeAndClear( aEvent ); 785*cdf0e10cSrcweir 786*cdf0e10cSrcweir OBoundControl::disposing(); 787*cdf0e10cSrcweir } 788*cdf0e10cSrcweir 789*cdf0e10cSrcweir //------------------------------------------------------------------------------ 790*cdf0e10cSrcweir void SAL_CALL OImageControlControl::disposing( const EventObject& _Event ) throw(RuntimeException) 791*cdf0e10cSrcweir { 792*cdf0e10cSrcweir OBoundControl::disposing( _Event ); 793*cdf0e10cSrcweir } 794*cdf0e10cSrcweir 795*cdf0e10cSrcweir //------------------------------------------------------------------------------ 796*cdf0e10cSrcweir void OImageControlControl::implClearGraphics( sal_Bool _bForce ) 797*cdf0e10cSrcweir { 798*cdf0e10cSrcweir Reference< XPropertySet > xSet( getModel(), UNO_QUERY ); 799*cdf0e10cSrcweir if ( xSet.is() ) 800*cdf0e10cSrcweir { 801*cdf0e10cSrcweir if ( _bForce ) 802*cdf0e10cSrcweir { 803*cdf0e10cSrcweir ::rtl::OUString sOldImageURL; 804*cdf0e10cSrcweir xSet->getPropertyValue( PROPERTY_IMAGE_URL ) >>= sOldImageURL; 805*cdf0e10cSrcweir 806*cdf0e10cSrcweir if ( !sOldImageURL.getLength() ) 807*cdf0e10cSrcweir // the ImageURL is already empty, so simply setting a new empty one would not suffice 808*cdf0e10cSrcweir // (since it would be ignored) 809*cdf0e10cSrcweir xSet->setPropertyValue( PROPERTY_IMAGE_URL, makeAny( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:emptyImage" ) ) ) ); 810*cdf0e10cSrcweir // (the concrete URL we're passing here doens't matter. It's important that 811*cdf0e10cSrcweir // the model cannot resolve it to a a valid resource describing an image stream 812*cdf0e10cSrcweir } 813*cdf0e10cSrcweir 814*cdf0e10cSrcweir xSet->setPropertyValue( PROPERTY_IMAGE_URL, makeAny( ::rtl::OUString() ) ); 815*cdf0e10cSrcweir } 816*cdf0e10cSrcweir } 817*cdf0e10cSrcweir 818*cdf0e10cSrcweir //------------------------------------------------------------------------------ 819*cdf0e10cSrcweir bool OImageControlControl::implInsertGraphics() 820*cdf0e10cSrcweir { 821*cdf0e10cSrcweir Reference< XPropertySet > xSet( getModel(), UNO_QUERY ); 822*cdf0e10cSrcweir if ( !xSet.is() ) 823*cdf0e10cSrcweir return false; 824*cdf0e10cSrcweir 825*cdf0e10cSrcweir ::rtl::OUString sTitle = FRM_RES_STRING(RID_STR_IMPORT_GRAPHIC); 826*cdf0e10cSrcweir // build some arguments for the upcoming dialog 827*cdf0e10cSrcweir try 828*cdf0e10cSrcweir { 829*cdf0e10cSrcweir ::sfx2::FileDialogHelper aDialog( TemplateDescription::FILEOPEN_LINK_PREVIEW, SFXWB_GRAPHIC ); 830*cdf0e10cSrcweir aDialog.SetTitle( sTitle ); 831*cdf0e10cSrcweir 832*cdf0e10cSrcweir Reference< XFilePickerControlAccess > xController( aDialog.GetFilePicker(), UNO_QUERY_THROW ); 833*cdf0e10cSrcweir xController->setValue(ExtendedFilePickerElementIds::CHECKBOX_PREVIEW, 0, ::cppu::bool2any(sal_True)); 834*cdf0e10cSrcweir 835*cdf0e10cSrcweir Reference<XPropertySet> xBoundField; 836*cdf0e10cSrcweir if ( hasProperty( PROPERTY_BOUNDFIELD, xSet ) ) 837*cdf0e10cSrcweir xSet->getPropertyValue( PROPERTY_BOUNDFIELD ) >>= xBoundField; 838*cdf0e10cSrcweir sal_Bool bHasField = xBoundField.is(); 839*cdf0e10cSrcweir 840*cdf0e10cSrcweir // if the control is bound to a DB field, then it's not possible to decide whether or not to link 841*cdf0e10cSrcweir xController->enableControl(ExtendedFilePickerElementIds::CHECKBOX_LINK, !bHasField ); 842*cdf0e10cSrcweir 843*cdf0e10cSrcweir // if the control is bound to a DB field, then linking of the image depends on the type of the field 844*cdf0e10cSrcweir sal_Bool bImageIsLinked = sal_True; 845*cdf0e10cSrcweir if ( bHasField ) 846*cdf0e10cSrcweir { 847*cdf0e10cSrcweir sal_Int32 nFieldType = DataType::OTHER; 848*cdf0e10cSrcweir OSL_VERIFY( xBoundField->getPropertyValue( PROPERTY_FIELDTYPE ) >>= nFieldType ); 849*cdf0e10cSrcweir bImageIsLinked = ( lcl_getImageStoreType( nFieldType ) == ImageStoreLink ); 850*cdf0e10cSrcweir } 851*cdf0e10cSrcweir xController->setValue(ExtendedFilePickerElementIds::CHECKBOX_LINK, 0, makeAny( bImageIsLinked ) ); 852*cdf0e10cSrcweir 853*cdf0e10cSrcweir if ( ERRCODE_NONE == aDialog.Execute() ) 854*cdf0e10cSrcweir { 855*cdf0e10cSrcweir // reset the url property in case it already has the value we're about to set - in this case 856*cdf0e10cSrcweir // our propertyChanged would not get called without this. 857*cdf0e10cSrcweir implClearGraphics( sal_False ); 858*cdf0e10cSrcweir sal_Bool bIsLink = sal_False; 859*cdf0e10cSrcweir xController->getValue(ExtendedFilePickerElementIds::CHECKBOX_LINK, 0) >>= bIsLink; 860*cdf0e10cSrcweir // Force bIsLink to be sal_True if we're bound to a field. Though we initialized the file picker with IsLink=TRUE 861*cdf0e10cSrcweir // in this case, and disabled the respective control, there might be picker implementations which do not 862*cdf0e10cSrcweir // respect this, and return IsLink=FALSE here. In this case, "normalize" the flag. 863*cdf0e10cSrcweir // #i112659# / 2010-08-26 / frank.schoenheit@oracle.com 864*cdf0e10cSrcweir bIsLink |= bHasField; 865*cdf0e10cSrcweir if ( !bIsLink ) 866*cdf0e10cSrcweir { 867*cdf0e10cSrcweir Graphic aGraphic; 868*cdf0e10cSrcweir aDialog.GetGraphic( aGraphic ); 869*cdf0e10cSrcweir xSet->setPropertyValue( PROPERTY_GRAPHIC, makeAny( aGraphic.GetXGraphic() ) ); 870*cdf0e10cSrcweir } 871*cdf0e10cSrcweir else 872*cdf0e10cSrcweir xSet->setPropertyValue( PROPERTY_IMAGE_URL, makeAny( ::rtl::OUString( aDialog.GetPath() ) ) ); 873*cdf0e10cSrcweir 874*cdf0e10cSrcweir return true; 875*cdf0e10cSrcweir } 876*cdf0e10cSrcweir } 877*cdf0e10cSrcweir catch(Exception&) 878*cdf0e10cSrcweir { 879*cdf0e10cSrcweir DBG_ERROR("OImageControlControl::implInsertGraphics: caught an exception while attempting to execute the FilePicker!"); 880*cdf0e10cSrcweir } 881*cdf0e10cSrcweir return false; 882*cdf0e10cSrcweir } 883*cdf0e10cSrcweir 884*cdf0e10cSrcweir //------------------------------------------------------------------------------ 885*cdf0e10cSrcweir bool OImageControlControl::impl_isEmptyGraphics_nothrow() const 886*cdf0e10cSrcweir { 887*cdf0e10cSrcweir bool bIsEmpty = true; 888*cdf0e10cSrcweir 889*cdf0e10cSrcweir try 890*cdf0e10cSrcweir { 891*cdf0e10cSrcweir Reference< XPropertySet > xModelProps( const_cast< OImageControlControl* >( this )->getModel(), UNO_QUERY_THROW ); 892*cdf0e10cSrcweir Reference< XGraphic > xGraphic; 893*cdf0e10cSrcweir OSL_VERIFY( xModelProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Graphic" ) ) ) >>= xGraphic ); 894*cdf0e10cSrcweir bIsEmpty = !xGraphic.is(); 895*cdf0e10cSrcweir } 896*cdf0e10cSrcweir catch( const Exception& ) 897*cdf0e10cSrcweir { 898*cdf0e10cSrcweir DBG_UNHANDLED_EXCEPTION(); 899*cdf0e10cSrcweir } 900*cdf0e10cSrcweir 901*cdf0e10cSrcweir return bIsEmpty; 902*cdf0e10cSrcweir } 903*cdf0e10cSrcweir 904*cdf0e10cSrcweir // MouseListener 905*cdf0e10cSrcweir //------------------------------------------------------------------------------ 906*cdf0e10cSrcweir void OImageControlControl::mousePressed(const ::com::sun::star::awt::MouseEvent& e) throw ( ::com::sun::star::uno::RuntimeException) 907*cdf0e10cSrcweir { 908*cdf0e10cSrcweir ::vos::OGuard aGuard( Application::GetSolarMutex() ); 909*cdf0e10cSrcweir 910*cdf0e10cSrcweir if (e.Buttons != MouseButton::LEFT) 911*cdf0e10cSrcweir return; 912*cdf0e10cSrcweir 913*cdf0e10cSrcweir bool bModified = false; 914*cdf0e10cSrcweir // is this a request for a context menu? 915*cdf0e10cSrcweir if ( e.PopupTrigger ) 916*cdf0e10cSrcweir { 917*cdf0e10cSrcweir Reference< XPopupMenu > xMenu( m_aContext.createComponent( "com.sun.star.awt.PopupMenu" ), UNO_QUERY ); 918*cdf0e10cSrcweir DBG_ASSERT( xMenu.is(), "OImageControlControl::mousePressed: could not create a popup menu!" ); 919*cdf0e10cSrcweir 920*cdf0e10cSrcweir Reference< XWindowPeer > xWindowPeer = getPeer(); 921*cdf0e10cSrcweir DBG_ASSERT( xWindowPeer.is(), "OImageControlControl::mousePressed: no window!" ); 922*cdf0e10cSrcweir 923*cdf0e10cSrcweir if ( xMenu.is() && xWindowPeer.is() ) 924*cdf0e10cSrcweir { 925*cdf0e10cSrcweir xMenu->insertItem( ID_OPEN_GRAPHICS, FRM_RES_STRING( RID_STR_OPEN_GRAPHICS ), 0, 0 ); 926*cdf0e10cSrcweir xMenu->insertItem( ID_CLEAR_GRAPHICS, FRM_RES_STRING( RID_STR_CLEAR_GRAPHICS ), 0, 1 ); 927*cdf0e10cSrcweir 928*cdf0e10cSrcweir // check if the ImageURL is empty 929*cdf0e10cSrcweir if ( impl_isEmptyGraphics_nothrow() ) 930*cdf0e10cSrcweir xMenu->enableItem( ID_CLEAR_GRAPHICS, sal_False ); 931*cdf0e10cSrcweir 932*cdf0e10cSrcweir awt::Rectangle aRect( e.X, e.Y, 0, 0 ); 933*cdf0e10cSrcweir if ( ( e.X < 0 ) || ( e.Y < 0 ) ) 934*cdf0e10cSrcweir { // context menu triggered by keyboard 935*cdf0e10cSrcweir // position it in the center of the control 936*cdf0e10cSrcweir // 102205 - 16.08.2002 - fs@openoffice.org 937*cdf0e10cSrcweir Reference< XWindow > xWindow( static_cast< ::cppu::OWeakObject* >( this ), UNO_QUERY ); 938*cdf0e10cSrcweir OSL_ENSURE( xWindow.is(), "OImageControlControl::mousePressed: me not a window? How this?" ); 939*cdf0e10cSrcweir if ( xWindow.is() ) 940*cdf0e10cSrcweir { 941*cdf0e10cSrcweir awt::Rectangle aPosSize = xWindow->getPosSize(); 942*cdf0e10cSrcweir aRect.X = aPosSize.Width / 2; 943*cdf0e10cSrcweir aRect.Y = aPosSize.Height / 2; 944*cdf0e10cSrcweir } 945*cdf0e10cSrcweir } 946*cdf0e10cSrcweir 947*cdf0e10cSrcweir const sal_Int16 nResult = xMenu->execute( xWindowPeer, aRect, PopupMenuDirection::EXECUTE_DEFAULT ); 948*cdf0e10cSrcweir 949*cdf0e10cSrcweir switch ( nResult ) 950*cdf0e10cSrcweir { 951*cdf0e10cSrcweir case ID_OPEN_GRAPHICS: 952*cdf0e10cSrcweir implInsertGraphics(); 953*cdf0e10cSrcweir bModified = true; 954*cdf0e10cSrcweir break; 955*cdf0e10cSrcweir 956*cdf0e10cSrcweir case ID_CLEAR_GRAPHICS: 957*cdf0e10cSrcweir implClearGraphics( sal_True ); 958*cdf0e10cSrcweir bModified = true; 959*cdf0e10cSrcweir break; 960*cdf0e10cSrcweir } 961*cdf0e10cSrcweir } 962*cdf0e10cSrcweir } 963*cdf0e10cSrcweir else 964*cdf0e10cSrcweir { 965*cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////// 966*cdf0e10cSrcweir // Doppelclick 967*cdf0e10cSrcweir if (e.ClickCount == 2) 968*cdf0e10cSrcweir { 969*cdf0e10cSrcweir 970*cdf0e10cSrcweir Reference<XPropertySet> xSet(getModel(), UNO_QUERY); 971*cdf0e10cSrcweir if (!xSet.is()) 972*cdf0e10cSrcweir return; 973*cdf0e10cSrcweir 974*cdf0e10cSrcweir // wenn Control nicht gebunden ist, kein Dialog (da die zu schickende URL hinterher sowieso 975*cdf0e10cSrcweir // versanden wuerde) 976*cdf0e10cSrcweir // FS - #64946# - 19.04.99 977*cdf0e10cSrcweir Reference<XPropertySet> xBoundField; 978*cdf0e10cSrcweir if (hasProperty(PROPERTY_BOUNDFIELD, xSet)) 979*cdf0e10cSrcweir ::cppu::extractInterface(xBoundField, xSet->getPropertyValue(PROPERTY_BOUNDFIELD)); 980*cdf0e10cSrcweir if (!xBoundField.is()) 981*cdf0e10cSrcweir { 982*cdf0e10cSrcweir // but only if our IMAGE_URL property is handled as if it is transient, which is equivalent to 983*cdf0e10cSrcweir // an empty control source 984*cdf0e10cSrcweir if (!hasProperty(PROPERTY_CONTROLSOURCE, xSet) || (::comphelper::getString(xSet->getPropertyValue(PROPERTY_CONTROLSOURCE)).getLength() != 0)) 985*cdf0e10cSrcweir return; 986*cdf0e10cSrcweir } 987*cdf0e10cSrcweir 988*cdf0e10cSrcweir sal_Bool bReadOnly = false; 989*cdf0e10cSrcweir xSet->getPropertyValue(PROPERTY_READONLY) >>= bReadOnly; 990*cdf0e10cSrcweir if (bReadOnly) 991*cdf0e10cSrcweir return; 992*cdf0e10cSrcweir 993*cdf0e10cSrcweir if ( implInsertGraphics() ) 994*cdf0e10cSrcweir bModified = true; 995*cdf0e10cSrcweir } 996*cdf0e10cSrcweir } 997*cdf0e10cSrcweir 998*cdf0e10cSrcweir if ( bModified ) 999*cdf0e10cSrcweir { 1000*cdf0e10cSrcweir EventObject aEvent( *this ); 1001*cdf0e10cSrcweir m_aModifyListeners.notifyEach( &XModifyListener::modified, aEvent ); 1002*cdf0e10cSrcweir } 1003*cdf0e10cSrcweir } 1004*cdf0e10cSrcweir 1005*cdf0e10cSrcweir //------------------------------------------------------------------------------ 1006*cdf0e10cSrcweir void SAL_CALL OImageControlControl::mouseReleased(const awt::MouseEvent& /*e*/) throw ( RuntimeException ) 1007*cdf0e10cSrcweir { 1008*cdf0e10cSrcweir } 1009*cdf0e10cSrcweir 1010*cdf0e10cSrcweir //------------------------------------------------------------------------------ 1011*cdf0e10cSrcweir void SAL_CALL OImageControlControl::mouseEntered(const awt::MouseEvent& /*e*/) throw ( RuntimeException ) 1012*cdf0e10cSrcweir { 1013*cdf0e10cSrcweir } 1014*cdf0e10cSrcweir 1015*cdf0e10cSrcweir //------------------------------------------------------------------------------ 1016*cdf0e10cSrcweir void SAL_CALL OImageControlControl::mouseExited(const awt::MouseEvent& /*e*/) throw ( RuntimeException ) 1017*cdf0e10cSrcweir { 1018*cdf0e10cSrcweir } 1019*cdf0e10cSrcweir 1020*cdf0e10cSrcweir //......................................................................... 1021*cdf0e10cSrcweir } // namespace frm 1022*cdf0e10cSrcweir //......................................................................... 1023*cdf0e10cSrcweir 1024