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