LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/forms/source/component - ImageControl.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 197 418 47.1 %
Date: 2013-07-09 Functions: 34 55 61.8 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10