LCOV - code coverage report
Current view: top level - libreoffice/forms/source/component - ComboBox.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 363 0.0 %
Date: 2012-12-27 Functions: 0 34 0.0 %
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             : 
      21             : #include "ComboBox.hxx"
      22             : #include "property.hxx"
      23             : #include "property.hrc"
      24             : #include "services.hxx"
      25             : 
      26             : #include "frm_resource.hxx"
      27             : #include "frm_resource.hrc"
      28             : #include "BaseListBox.hxx"
      29             : 
      30             : #include <com/sun/star/sdb/SQLErrorEvent.hpp>
      31             : #include <com/sun/star/sdbc/XRowSet.hpp>
      32             : #include <com/sun/star/sdbc/DataType.hpp>
      33             : #include <com/sun/star/container/XIndexAccess.hpp>
      34             : #include <com/sun/star/sdb/XSQLQueryComposerFactory.hpp>
      35             : #include <com/sun/star/sdb/XQueriesSupplier.hpp>
      36             : #include <com/sun/star/util/NumberFormat.hpp>
      37             : #include <com/sun/star/sdbc/XConnection.hpp>
      38             : #include <com/sun/star/sdb/SQLContext.hpp>
      39             : #include <com/sun/star/sdb/CommandType.hpp>
      40             : 
      41             : #include <comphelper/numbers.hxx>
      42             : #include <comphelper/basicio.hxx>
      43             : #include <connectivity/dbtools.hxx>
      44             : #include <connectivity/dbconversion.hxx>
      45             : #include <cppuhelper/queryinterface.hxx>
      46             : #include <rtl/ustrbuf.hxx>
      47             : #include <tools/debug.hxx>
      48             : #include <tools/diagnose_ex.h>
      49             : #include <unotools/sharedunocomponent.hxx>
      50             : 
      51             : #include <limits.h>
      52             : 
      53             : using namespace dbtools;
      54             : 
      55             : //.........................................................................
      56             : namespace frm
      57             : {
      58             : using namespace ::com::sun::star::uno;
      59             : using namespace ::com::sun::star::sdb;
      60             : using namespace ::com::sun::star::sdbc;
      61             : using namespace ::com::sun::star::sdbcx;
      62             : using namespace ::com::sun::star::beans;
      63             : using namespace ::com::sun::star::container;
      64             : using namespace ::com::sun::star::form;
      65             : using namespace ::com::sun::star::awt;
      66             : using namespace ::com::sun::star::io;
      67             : using namespace ::com::sun::star::lang;
      68             : using namespace ::com::sun::star::util;
      69             : using namespace ::com::sun::star::form::binding;
      70             : 
      71             : //========================================================================
      72             : // class OComboBoxModel
      73             : //========================================================================
      74             : //------------------------------------------------------------------
      75           0 : InterfaceRef SAL_CALL OComboBoxModel_CreateInstance(const Reference<XMultiServiceFactory>& _rxFactory) throw (RuntimeException)
      76             : {
      77           0 :     return (*new OComboBoxModel(_rxFactory));
      78             : }
      79             : 
      80             : //------------------------------------------------------------------------------
      81           0 : Sequence<Type> OComboBoxModel::_getTypes()
      82             : {
      83             :     return ::comphelper::concatSequences(
      84             :         OBoundControlModel::_getTypes(),
      85             :         OEntryListHelper::getTypes(),
      86             :         OErrorBroadcaster::getTypes()
      87           0 :     );
      88             : }
      89             : 
      90             : // XServiceInfo
      91             : //------------------------------------------------------------------------------
      92           0 : StringSequence SAL_CALL OComboBoxModel::getSupportedServiceNames() throw(RuntimeException)
      93             : {
      94           0 :     StringSequence aSupported = OBoundControlModel::getSupportedServiceNames();
      95             : 
      96           0 :     sal_Int32 nOldLen = aSupported.getLength();
      97           0 :     aSupported.realloc( nOldLen + 8 );
      98           0 :     ::rtl::OUString* pStoreTo = aSupported.getArray() + nOldLen;
      99             : 
     100           0 :     *pStoreTo++ = BINDABLE_CONTROL_MODEL;
     101           0 :     *pStoreTo++ = DATA_AWARE_CONTROL_MODEL;
     102           0 :     *pStoreTo++ = VALIDATABLE_CONTROL_MODEL;
     103             : 
     104           0 :     *pStoreTo++ = BINDABLE_DATA_AWARE_CONTROL_MODEL;
     105           0 :     *pStoreTo++ = VALIDATABLE_BINDABLE_CONTROL_MODEL;
     106             : 
     107           0 :     *pStoreTo++ = FRM_SUN_COMPONENT_COMBOBOX;
     108           0 :     *pStoreTo++ = FRM_SUN_COMPONENT_DATABASE_COMBOBOX;
     109           0 :     *pStoreTo++ = BINDABLE_DATABASE_COMBO_BOX;
     110             : 
     111           0 :     return aSupported;
     112             : }
     113             : 
     114             : //------------------------------------------------------------------------------
     115           0 : Any SAL_CALL OComboBoxModel::queryAggregation(const Type& _rType) throw (RuntimeException)
     116             : {
     117           0 :     Any aReturn = OBoundControlModel::queryAggregation( _rType );
     118           0 :     if ( !aReturn.hasValue() )
     119           0 :         aReturn = OEntryListHelper::queryInterface( _rType );
     120           0 :     if ( !aReturn.hasValue() )
     121           0 :         aReturn = OErrorBroadcaster::queryInterface( _rType );
     122           0 :     return aReturn;
     123             : }
     124             : 
     125             : //------------------------------------------------------------------
     126             : DBG_NAME( OComboBoxModel )
     127             : //------------------------------------------------------------------
     128           0 : OComboBoxModel::OComboBoxModel(const Reference<XMultiServiceFactory>& _rxFactory)
     129             :     :OBoundControlModel( _rxFactory, VCL_CONTROLMODEL_COMBOBOX, FRM_SUN_CONTROL_COMBOBOX, sal_True, sal_True, sal_True )
     130             :                     // use the old control name for compytibility reasons
     131             :     ,OEntryListHelper( (OControlModel&)*this )
     132             :     ,OErrorBroadcaster( OComponentHelper::rBHelper )
     133           0 :     ,m_aListRowSet( getContext() )
     134             :     ,m_eListSourceType(ListSourceType_TABLE)
     135           0 :     ,m_bEmptyIsNull(sal_True)
     136             : {
     137             :     DBG_CTOR( OComboBoxModel, NULL );
     138             : 
     139           0 :     m_nClassId = FormComponentType::COMBOBOX;
     140           0 :     initValueProperty( PROPERTY_TEXT, PROPERTY_ID_TEXT );
     141           0 : }
     142             : 
     143             : //------------------------------------------------------------------
     144           0 : OComboBoxModel::OComboBoxModel( const OComboBoxModel* _pOriginal, const Reference<XMultiServiceFactory>& _rxFactory )
     145             :     :OBoundControlModel( _pOriginal, _rxFactory )
     146             :     ,OEntryListHelper( *_pOriginal, (OControlModel&)*this )
     147             :     ,OErrorBroadcaster( OComponentHelper::rBHelper )
     148           0 :     ,m_aListRowSet( getContext() )
     149             :     ,m_aListSource( _pOriginal->m_aListSource )
     150             :     ,m_aDefaultText( _pOriginal->m_aDefaultText )
     151             :     ,m_eListSourceType( _pOriginal->m_eListSourceType )
     152           0 :     ,m_bEmptyIsNull( _pOriginal->m_bEmptyIsNull )
     153             : {
     154             :     DBG_CTOR( OComboBoxModel, NULL );
     155           0 : }
     156             : 
     157             : //------------------------------------------------------------------
     158           0 : OComboBoxModel::~OComboBoxModel()
     159             : {
     160           0 :     if (!OComponentHelper::rBHelper.bDisposed)
     161             :     {
     162           0 :         acquire();
     163           0 :         dispose();
     164             :     }
     165             : 
     166             :     DBG_DTOR( OComboBoxModel, NULL );
     167           0 : }
     168             : 
     169             : // XCloneable
     170             : //------------------------------------------------------------------------------
     171           0 : IMPLEMENT_DEFAULT_CLONING( OComboBoxModel )
     172             : 
     173             : //------------------------------------------------------------------------------
     174           0 : void OComboBoxModel::disposing()
     175             : {
     176           0 :     OBoundControlModel::disposing();
     177           0 :     OEntryListHelper::disposing();
     178           0 :     OErrorBroadcaster::disposing();
     179           0 :     m_xFormatter = NULL;
     180           0 : }
     181             : 
     182             : //------------------------------------------------------------------------------
     183           0 : void OComboBoxModel::getFastPropertyValue(Any& _rValue, sal_Int32 _nHandle) const
     184             : {
     185           0 :     switch (_nHandle)
     186             :     {
     187             :         case PROPERTY_ID_LISTSOURCETYPE:
     188           0 :             _rValue <<= m_eListSourceType;
     189           0 :             break;
     190             : 
     191             :         case PROPERTY_ID_LISTSOURCE:
     192           0 :             _rValue <<= m_aListSource;
     193           0 :             break;
     194             : 
     195             :         case PROPERTY_ID_EMPTY_IS_NULL:
     196           0 :             _rValue <<= m_bEmptyIsNull;
     197           0 :             break;
     198             : 
     199             :         case PROPERTY_ID_DEFAULT_TEXT:
     200           0 :             _rValue <<= m_aDefaultText;
     201           0 :             break;
     202             : 
     203             :         case PROPERTY_ID_STRINGITEMLIST:
     204           0 :             _rValue <<= getStringItemList();
     205           0 :             break;
     206             : 
     207             :         default:
     208           0 :             OBoundControlModel::getFastPropertyValue(_rValue, _nHandle);
     209             :     }
     210           0 : }
     211             : 
     212             : //------------------------------------------------------------------------------
     213           0 : void OComboBoxModel::setFastPropertyValue_NoBroadcast(sal_Int32 _nHandle, const Any& _rValue)
     214             :                         throw (Exception)
     215             : {
     216           0 :     switch (_nHandle)
     217             :     {
     218             :         case PROPERTY_ID_LISTSOURCETYPE :
     219             :             DBG_ASSERT(_rValue.getValueType().equals(::getCppuType(static_cast<ListSourceType*>(0))),
     220             :                 "OComboBoxModel::setFastPropertyValue_NoBroadcast : invalid type !" );
     221           0 :             _rValue >>= m_eListSourceType;
     222           0 :             break;
     223             : 
     224             :         case PROPERTY_ID_LISTSOURCE :
     225             :             DBG_ASSERT(_rValue.getValueType().getTypeClass() == TypeClass_STRING,
     226             :                 "OComboBoxModel::setFastPropertyValue_NoBroadcast : invalid type !" );
     227           0 :             _rValue >>= m_aListSource;
     228             :             // The ListSource has changed -> reload
     229           0 :             if (ListSourceType_VALUELIST != m_eListSourceType)
     230             :             {
     231           0 :                 if ( m_xCursor.is() && !hasField() && !hasExternalListSource() )
     232             :                     // combo box is already connected to a database, and no external list source
     233             :                     // data source changed -> refresh
     234           0 :                     loadData( false );
     235             :             }
     236           0 :             break;
     237             : 
     238             :         case PROPERTY_ID_EMPTY_IS_NULL :
     239             :             DBG_ASSERT(_rValue.getValueType().getTypeClass() == TypeClass_BOOLEAN,
     240             :                 "OComboBoxModel::setFastPropertyValue_NoBroadcast : invalid type !" );
     241           0 :             _rValue >>= m_bEmptyIsNull;
     242           0 :             break;
     243             : 
     244             :         case PROPERTY_ID_DEFAULT_TEXT :
     245             :             DBG_ASSERT(_rValue.getValueType().getTypeClass() == TypeClass_STRING,
     246             :                 "OComboBoxModel::setFastPropertyValue_NoBroadcast : invalid type !" );
     247           0 :             _rValue >>= m_aDefaultText;
     248           0 :             resetNoBroadcast();
     249           0 :             break;
     250             : 
     251             :         case PROPERTY_ID_STRINGITEMLIST:
     252             :         {
     253           0 :             ControlModelLock aLock( *this );
     254           0 :             setNewStringItemList( _rValue, aLock );
     255             :                 // TODO: this is bogus. setNewStringItemList expects a guard which has the *only*
     256             :                 // lock to the mutex, but setFastPropertyValue_NoBroadcast is already called with
     257             :                 // a lock - so we effectively has two locks here, of which setNewStringItemList can
     258             :                 // only control one.
     259             :         }
     260           0 :         break;
     261             : 
     262             :         default:
     263           0 :             OBoundControlModel::setFastPropertyValue_NoBroadcast(_nHandle, _rValue);
     264             :     }
     265           0 : }
     266             : 
     267             : //------------------------------------------------------------------------------
     268           0 : sal_Bool OComboBoxModel::convertFastPropertyValue(
     269             :                         Any& _rConvertedValue, Any& _rOldValue, sal_Int32 _nHandle, const Any& _rValue)
     270             :                         throw (IllegalArgumentException)
     271             : {
     272           0 :     sal_Bool bModified(sal_False);
     273           0 :     switch (_nHandle)
     274             :     {
     275             :         case PROPERTY_ID_LISTSOURCETYPE :
     276           0 :             bModified = tryPropertyValueEnum(_rConvertedValue, _rOldValue, _rValue, m_eListSourceType);
     277           0 :             break;
     278             : 
     279             :         case PROPERTY_ID_LISTSOURCE :
     280           0 :             bModified = tryPropertyValue(_rConvertedValue, _rOldValue, _rValue, m_aListSource);
     281           0 :             break;
     282             : 
     283             :         case PROPERTY_ID_EMPTY_IS_NULL :
     284           0 :             bModified = tryPropertyValue(_rConvertedValue, _rOldValue, _rValue, m_bEmptyIsNull);
     285           0 :             break;
     286             : 
     287             :         case PROPERTY_ID_DEFAULT_TEXT :
     288           0 :             bModified = tryPropertyValue(_rConvertedValue, _rOldValue, _rValue, m_aDefaultText);
     289           0 :             break;
     290             : 
     291             :         case PROPERTY_ID_STRINGITEMLIST:
     292           0 :             bModified = convertNewListSourceProperty( _rConvertedValue, _rOldValue, _rValue );
     293           0 :             break;
     294             : 
     295             :         default:
     296           0 :             bModified = OBoundControlModel::convertFastPropertyValue(_rConvertedValue, _rOldValue, _nHandle, _rValue);
     297           0 :             break;
     298             :     }
     299           0 :     return bModified;
     300             : }
     301             : 
     302             : //------------------------------------------------------------------------------
     303           0 : void OComboBoxModel::describeFixedProperties( Sequence< Property >& _rProps ) const
     304             : {
     305           0 :     BEGIN_DESCRIBE_PROPERTIES( 6, OBoundControlModel )
     306           0 :         DECL_PROP1(TABINDEX,            sal_Int16,                  BOUND);
     307           0 :         DECL_PROP1(LISTSOURCETYPE,      ListSourceType, BOUND);
     308           0 :         DECL_PROP1(LISTSOURCE,          ::rtl::OUString,            BOUND);
     309           0 :         DECL_BOOL_PROP1(EMPTY_IS_NULL,                              BOUND);
     310           0 :         DECL_PROP1(DEFAULT_TEXT,        ::rtl::OUString,            BOUND);
     311           0 :         DECL_PROP1(STRINGITEMLIST,      Sequence< ::rtl::OUString >,BOUND);
     312             :     END_DESCRIBE_PROPERTIES();
     313           0 : }
     314             : 
     315             : //------------------------------------------------------------------------------
     316           0 : void OComboBoxModel::describeAggregateProperties( Sequence< Property >& _rAggregateProps ) const
     317             : {
     318           0 :     OBoundControlModel::describeAggregateProperties( _rAggregateProps );
     319             : 
     320             :     // superseded properties:
     321           0 :     RemoveProperty( _rAggregateProps, PROPERTY_STRINGITEMLIST );
     322           0 : }
     323             : 
     324             : //------------------------------------------------------------------------------
     325           0 : ::rtl::OUString SAL_CALL OComboBoxModel::getServiceName() throw(RuntimeException)
     326             : {
     327           0 :     return FRM_COMPONENT_COMBOBOX;  // old (non-sun) name for compatibility !
     328             : }
     329             : 
     330             : //------------------------------------------------------------------------------
     331           0 : void SAL_CALL OComboBoxModel::write(const Reference<stario::XObjectOutputStream>& _rxOutStream)
     332             :         throw(stario::IOException, RuntimeException)
     333             : {
     334           0 :     OBoundControlModel::write(_rxOutStream);
     335             : 
     336             :     // Version
     337             :     // Version 0x0002:  EmptyIsNull
     338             :     // Version 0x0003:  ListSource->Seq
     339             :     // Version 0x0004:  DefaultText
     340             :     // Version 0x0005:  HelpText
     341           0 :     _rxOutStream->writeShort(0x0006);
     342             : 
     343             :     // Maskierung fuer any
     344           0 :     sal_uInt16 nAnyMask = 0;
     345           0 :     if (m_aBoundColumn.getValueType().getTypeClass() == TypeClass_SHORT)
     346           0 :         nAnyMask |= BOUNDCOLUMN;
     347           0 :     _rxOutStream << nAnyMask;
     348             : 
     349           0 :     StringSequence aListSourceSeq(&m_aListSource, 1);
     350           0 :     _rxOutStream << aListSourceSeq;
     351           0 :     _rxOutStream << (sal_Int16)m_eListSourceType;
     352             : 
     353           0 :     if ((nAnyMask & BOUNDCOLUMN) == BOUNDCOLUMN)
     354             :     {
     355           0 :         sal_Int16 nBoundColumn = 0;
     356           0 :         m_aBoundColumn >>= nBoundColumn;
     357           0 :         _rxOutStream << nBoundColumn;
     358             :     }
     359             : 
     360           0 :     _rxOutStream << (sal_Bool)m_bEmptyIsNull;
     361           0 :     _rxOutStream << m_aDefaultText;
     362           0 :     writeHelpTextCompatibly(_rxOutStream);
     363             : 
     364             :     // from version 0x0006 : common properties
     365           0 :     writeCommonProperties(_rxOutStream);
     366           0 : }
     367             : 
     368             : //------------------------------------------------------------------------------
     369           0 : void SAL_CALL OComboBoxModel::read(const Reference<stario::XObjectInputStream>& _rxInStream) throw(stario::IOException, RuntimeException)
     370             : {
     371           0 :     OBoundControlModel::read(_rxInStream);
     372           0 :     ControlModelLock aLock( *this );
     373             : 
     374             :     // since we are "overwriting" the StringItemList of our aggregate (means we have
     375             :     // an own place to store the value, instead of relying on our aggregate storing it),
     376             :     // we need to respect what the aggregate just read for the StringItemList property.
     377             :     try
     378             :     {
     379           0 :         if ( m_xAggregateSet.is() )
     380           0 :             setNewStringItemList( m_xAggregateSet->getPropertyValue( PROPERTY_STRINGITEMLIST ), aLock );
     381             :     }
     382           0 :     catch( const Exception& )
     383             :     {
     384             :         OSL_FAIL( "OComboBoxModel::read: caught an exception while examining the aggregate's string item list!" );
     385             :     }
     386             : 
     387             :     // Version
     388           0 :     sal_uInt16 nVersion = _rxInStream->readShort();
     389             :     DBG_ASSERT(nVersion > 0, "OComboBoxModel::read : version 0 ? this should never have been written !");
     390             : 
     391           0 :     if (nVersion > 0x0006)
     392             :     {
     393             :         OSL_FAIL("OComboBoxModel::read : invalid (means unknown) version !");
     394           0 :         m_aListSource = ::rtl::OUString();
     395           0 :         m_aBoundColumn <<= (sal_Int16)0;
     396           0 :         m_aDefaultText = ::rtl::OUString();
     397           0 :         m_eListSourceType = ListSourceType_TABLE;
     398           0 :         m_bEmptyIsNull = sal_True;
     399           0 :         defaultCommonProperties();
     400           0 :         return;
     401             :     }
     402             : 
     403             :     // Masking for any
     404             :     sal_uInt16 nAnyMask;
     405           0 :     _rxInStream >> nAnyMask;
     406             : 
     407             :     // ListSource
     408           0 :     if (nVersion < 0x0003)
     409             :     {
     410           0 :         _rxInStream >> m_aListSource;
     411             :     }
     412             :     else // nVersion == 4
     413             :     {
     414           0 :         m_aListSource = ::rtl::OUString();
     415           0 :         StringSequence aListSource;
     416           0 :         _rxInStream >> aListSource;
     417           0 :         const ::rtl::OUString* pToken = aListSource.getConstArray();
     418           0 :         sal_Int32 nLen = aListSource.getLength();
     419           0 :         for (sal_Int32 i = 0; i < nLen; ++i, ++pToken)
     420           0 :             m_aListSource += *pToken;
     421             :     }
     422             : 
     423             :     sal_Int16 nListSourceType;
     424           0 :     _rxInStream >> nListSourceType;
     425           0 :     m_eListSourceType = (ListSourceType)nListSourceType;
     426             : 
     427           0 :     if ((nAnyMask & BOUNDCOLUMN) == BOUNDCOLUMN)
     428             :     {
     429             :         sal_Int16 nValue;
     430           0 :         _rxInStream >> nValue;
     431           0 :         m_aBoundColumn <<= nValue;
     432             :     }
     433             : 
     434           0 :     if (nVersion > 0x0001)
     435             :     {
     436             :         sal_Bool bNull;
     437           0 :         _rxInStream >> bNull;
     438           0 :         m_bEmptyIsNull = bNull;
     439             :     }
     440             : 
     441           0 :     if (nVersion > 0x0003)  // nVersion == 4
     442           0 :         _rxInStream >> m_aDefaultText;
     443             : 
     444             :     // StringList must be emptied if a ListSource is set.
     445             :     // This can be the case if we save in alive mode.
     446           0 :     if  (   !m_aListSource.isEmpty()
     447           0 :         &&  !hasExternalListSource()
     448             :         )
     449             :     {
     450           0 :         setFastPropertyValue( PROPERTY_ID_STRINGITEMLIST, makeAny( StringSequence() ) );
     451             :     }
     452             : 
     453           0 :     if (nVersion > 0x0004)
     454           0 :         readHelpTextCompatibly(_rxInStream);
     455             : 
     456           0 :     if (nVersion > 0x0005)
     457           0 :         readCommonProperties(_rxInStream);
     458             : 
     459             :     // After reading in, display the default values
     460           0 :     if ( !getControlSource().isEmpty() )
     461             :     {
     462             :         // (not if we don't have a control source - the "State" property acts like it is persistent, then
     463           0 :         resetNoBroadcast();
     464           0 :     }
     465             : }
     466             : 
     467             : //------------------------------------------------------------------------------
     468           0 : void OComboBoxModel::loadData( bool _bForce )
     469             : {
     470             :     DBG_ASSERT(m_eListSourceType != ListSourceType_VALUELIST, "OComboBoxModel::loadData : do not call for a value list !");
     471             :     DBG_ASSERT( !hasExternalListSource(), "OComboBoxModel::loadData: cannot load from DB when I have an external list source!" );
     472             : 
     473           0 :     if ( hasExternalListSource() )
     474             :         return;
     475             : 
     476             :     // Get Connection
     477           0 :     Reference<XRowSet> xForm(m_xCursor, UNO_QUERY);
     478           0 :     if (!xForm.is())
     479             :         return;
     480           0 :     Reference<XConnection> xConnection = getConnection(xForm);
     481           0 :     if (!xConnection.is())
     482             :         return;
     483             : 
     484           0 :     Reference<XServiceInfo> xServiceInfo(xConnection, UNO_QUERY);
     485           0 :     if (!xServiceInfo.is() || !xServiceInfo->supportsService(SRV_SDB_CONNECTION))
     486             :     {
     487             :         OSL_FAIL("OComboBoxModel::loadData : invalid connection !");
     488             :         return;
     489             :     }
     490             : 
     491           0 :     if (m_aListSource.isEmpty() || m_eListSourceType == ListSourceType_VALUELIST)
     492             :         return;
     493             : 
     494           0 :     ::utl::SharedUNOComponent< XResultSet > xListCursor;
     495             :     try
     496             :     {
     497           0 :         m_aListRowSet.setConnection( xConnection );
     498             : 
     499           0 :         bool bExecuteRowSet( false );
     500           0 :         switch (m_eListSourceType)
     501             :         {
     502             :             case ListSourceType_TABLEFIELDS:
     503             :                 // don't work with a statement here, the fields will be collected below
     504           0 :                 break;
     505             :             case ListSourceType_TABLE:
     506             :             {
     507             :                 // does the bound field belong to the table ?
     508             :                 // if we use an alias for the bound field, we won't find it
     509             :                 // in that case we use the first field of the table
     510             : 
     511           0 :                 Reference<XNameAccess> xFieldsByName = getTableFields(xConnection, m_aListSource);
     512           0 :                 Reference<XIndexAccess> xFieldsByIndex(xFieldsByName, UNO_QUERY);
     513             : 
     514           0 :                 ::rtl::OUString aFieldName;
     515           0 :                 if ( xFieldsByName.is() && xFieldsByName->hasByName( getControlSource() ) )
     516             :                 {
     517           0 :                     aFieldName = getControlSource();
     518             :                 }
     519             :                 else
     520             :                 {
     521             :                     // otherwise look for the alias
     522           0 :                     Reference<XPropertySet> xFormProp(xForm,UNO_QUERY);
     523           0 :                     Reference< XColumnsSupplier > xSupplyFields;
     524           0 :                     xFormProp->getPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SingleSelectQueryComposer"))) >>= xSupplyFields;
     525             : 
     526             :                     // search the field
     527             :                     DBG_ASSERT(xSupplyFields.is(), "OComboBoxModel::loadData : invalid query composer !");
     528             : 
     529           0 :                     Reference< XNameAccess > xFieldNames = xSupplyFields->getColumns();
     530           0 :                     if ( xFieldNames->hasByName( getControlSource() ) )
     531             :                     {
     532           0 :                         Reference< XPropertySet > xComposerFieldAsSet;
     533           0 :                         xFieldNames->getByName( getControlSource() ) >>= xComposerFieldAsSet;
     534           0 :                         if (hasProperty(PROPERTY_FIELDSOURCE, xComposerFieldAsSet))
     535           0 :                             xComposerFieldAsSet->getPropertyValue(PROPERTY_FIELDSOURCE) >>= aFieldName;
     536           0 :                     }
     537             :                 }
     538             : 
     539           0 :                 if (aFieldName.isEmpty())
     540             :                     break;
     541             : 
     542           0 :                 Reference<XDatabaseMetaData> xMeta = xConnection->getMetaData();
     543             :                 OSL_ENSURE(xMeta.is(),"No database meta data!");
     544           0 :                 if ( xMeta.is() )
     545             :                 {
     546           0 :                     ::rtl::OUString aQuote = xMeta->getIdentifierQuoteString();
     547             : 
     548           0 :                     ::rtl::OUString sCatalog, sSchema, sTable;
     549           0 :                     qualifiedNameComponents( xMeta, m_aListSource, sCatalog, sSchema, sTable, eInDataManipulation );
     550             : 
     551           0 :                     ::rtl::OUStringBuffer aStatement;
     552           0 :                     aStatement.appendAscii( "SELECT DISTINCT " );
     553           0 :                     aStatement.append     ( quoteName( aQuote, aFieldName ) );
     554           0 :                     aStatement.appendAscii( " FROM " );
     555           0 :                     aStatement.append     ( composeTableNameForSelect( xConnection, sCatalog, sSchema, sTable ) );
     556             : 
     557           0 :                     m_aListRowSet.setEscapeProcessing( sal_False );
     558           0 :                     m_aListRowSet.setCommand( aStatement.makeStringAndClear() );
     559           0 :                     bExecuteRowSet = true;
     560           0 :                 }
     561           0 :             }   break;
     562             :             case ListSourceType_QUERY:
     563             :             {
     564           0 :                 m_aListRowSet.setCommandFromQuery( m_aListSource );
     565           0 :                 bExecuteRowSet = true;
     566             :             }
     567           0 :             break;
     568             : 
     569             :             default:
     570             :             {
     571           0 :                 m_aListRowSet.setEscapeProcessing( ListSourceType_SQLPASSTHROUGH != m_eListSourceType );
     572           0 :                 m_aListRowSet.setCommand( m_aListSource );
     573           0 :                 bExecuteRowSet = true;
     574             :             }
     575             :         }
     576             : 
     577           0 :         if ( bExecuteRowSet )
     578             :         {
     579           0 :             if ( !_bForce && !m_aListRowSet.isDirty() )
     580             :             {
     581             :                 // if none of the settings of the row set changed, compared to the last
     582             :                 // invocation of loadData, then don't re-fill the list. Instead, assume
     583             :                 // the list entries are the same.
     584             :                 return;
     585             :             }
     586           0 :             xListCursor.reset( m_aListRowSet.execute() );
     587             :         }
     588             :     }
     589           0 :     catch(const SQLException& eSQL)
     590             :     {
     591           0 :         onError(eSQL, FRM_RES_STRING(RID_BASELISTBOX_ERROR_FILLLIST));
     592             :         return;
     593             :     }
     594           0 :     catch( const Exception& )
     595             :     {
     596             :         DBG_UNHANDLED_EXCEPTION();
     597             :         return;
     598             :     }
     599             : 
     600           0 :     ::std::vector< ::rtl::OUString >    aStringList;
     601           0 :     aStringList.reserve(16);
     602             :     try
     603             :     {
     604             :         OSL_ENSURE( xListCursor.is() || ( ListSourceType_TABLEFIELDS == m_eListSourceType ),
     605             :             "OComboBoxModel::loadData: logic error!" );
     606           0 :         if ( !xListCursor.is() && ( ListSourceType_TABLEFIELDS != m_eListSourceType ) )
     607             :             return;
     608             : 
     609           0 :         switch (m_eListSourceType)
     610             :         {
     611             :             case ListSourceType_SQL:
     612             :             case ListSourceType_SQLPASSTHROUGH:
     613             :             case ListSourceType_TABLE:
     614             :             case ListSourceType_QUERY:
     615             :             {
     616             :                 // The XDatabaseVariant of the first column
     617           0 :                 Reference<XColumnsSupplier> xSupplyCols(xListCursor, UNO_QUERY);
     618             :                 DBG_ASSERT(xSupplyCols.is(), "OComboBoxModel::loadData : cursor supports the row set service but is no column supplier?!");
     619           0 :                 Reference<XIndexAccess> xColumns;
     620           0 :                 if (xSupplyCols.is())
     621             :                 {
     622           0 :                     xColumns = Reference<XIndexAccess>(xSupplyCols->getColumns(), UNO_QUERY);
     623             :                     DBG_ASSERT(xColumns.is(), "OComboBoxModel::loadData : no columns supplied by the row set !");
     624             :                 }
     625           0 :                 Reference< XPropertySet > xDataField;
     626           0 :                 if ( xColumns.is() )
     627           0 :                     xColumns->getByIndex(0) >>= xDataField;
     628           0 :                 if ( !xDataField.is() )
     629             :                     return;
     630             : 
     631           0 :                 ::dbtools::FormattedColumnValue aValueFormatter( getContext(), xForm, xDataField );
     632             : 
     633             :                 // Fill Lists
     634           0 :                 sal_Int16 i = 0;
     635             :                 // At the moment by definition the list cursor is positioned _before_ the first row
     636           0 :                 while (xListCursor->next() && (i++<SHRT_MAX)) // Set max. count
     637             :                 {
     638           0 :                     aStringList.push_back( aValueFormatter.getFormattedValue() );
     639           0 :                 }
     640             :             }
     641           0 :             break;
     642             :             case ListSourceType_TABLEFIELDS:
     643             :             {
     644           0 :                 Reference<XNameAccess> xFieldNames = getTableFields(xConnection, m_aListSource);
     645           0 :                 if (xFieldNames.is())
     646             :                 {
     647           0 :                     StringSequence seqNames = xFieldNames->getElementNames();
     648           0 :                     sal_Int32 nFieldsCount = seqNames.getLength();
     649           0 :                     const ::rtl::OUString* pustrNames = seqNames.getConstArray();
     650             : 
     651           0 :                     for (sal_Int32 k=0; k<nFieldsCount; ++k)
     652           0 :                         aStringList.push_back(pustrNames[k]);
     653           0 :                 }
     654             :             }
     655           0 :             break;
     656             :             default:
     657             :                 OSL_FAIL( "OComboBoxModel::loadData: unreachable!" );
     658           0 :                 break;
     659             :         }
     660             :     }
     661           0 :     catch(const SQLException& eSQL)
     662             :     {
     663           0 :         onError(eSQL, FRM_RES_STRING(RID_BASELISTBOX_ERROR_FILLLIST));
     664             :         return;
     665             :     }
     666           0 :     catch( const Exception& )
     667             :     {
     668             :         DBG_UNHANDLED_EXCEPTION();
     669             :         return;
     670             :     }
     671             : 
     672             :     // Create StringSequence for ListBox
     673           0 :     StringSequence aStringSeq(aStringList.size());
     674           0 :     ::rtl::OUString* pStringAry = aStringSeq.getArray();
     675           0 :     for (sal_Int32 i = 0; i<aStringSeq.getLength(); ++i)
     676           0 :         pStringAry[i] = aStringList[i];
     677             : 
     678             :     // Set String-Sequence at ListBox
     679           0 :     setFastPropertyValue( PROPERTY_ID_STRINGITEMLIST, makeAny( aStringSeq ) );
     680             : }
     681             : 
     682             : //------------------------------------------------------------------------------
     683           0 : void OComboBoxModel::onConnectedDbColumn( const Reference< XInterface >& _rxForm )
     684             : {
     685           0 :     Reference<XPropertySet> xField = getField();
     686           0 :     if ( xField.is() )
     687           0 :         m_pValueFormatter.reset( new ::dbtools::FormattedColumnValue( getContext(), Reference< XRowSet >( _rxForm, UNO_QUERY ), xField ) );
     688           0 :     getPropertyValue( PROPERTY_STRINGITEMLIST ) >>= m_aDesignModeStringItems;
     689             : 
     690             :     // Only load data if a ListSource was supplied
     691           0 :     if ( !m_aListSource.isEmpty() && m_xCursor.is() && !hasExternalListSource() )
     692           0 :         loadData( false );
     693           0 : }
     694             : 
     695             : //------------------------------------------------------------------------------
     696           0 : void OComboBoxModel::onDisconnectedDbColumn()
     697             : {
     698           0 :     m_pValueFormatter.reset();
     699             : 
     700             :     // reset the string item list
     701           0 :     if ( !hasExternalListSource() )
     702           0 :         setFastPropertyValue( PROPERTY_ID_STRINGITEMLIST, makeAny( m_aDesignModeStringItems ) );
     703             : 
     704           0 :     m_aListRowSet.dispose();
     705           0 : }
     706             : 
     707             : //------------------------------------------------------------------------------
     708           0 : void SAL_CALL OComboBoxModel::reloaded( const EventObject& aEvent ) throw(RuntimeException)
     709             : {
     710           0 :     OBoundControlModel::reloaded(aEvent);
     711             : 
     712             :     // reload data if we have a list source
     713           0 :     if ( !m_aListSource.isEmpty() && m_xCursor.is() && !hasExternalListSource() )
     714           0 :         loadData( false );
     715           0 : }
     716             : 
     717             : //------------------------------------------------------------------------------
     718           0 : void OComboBoxModel::resetNoBroadcast()
     719             : {
     720           0 :     OBoundControlModel::resetNoBroadcast();
     721           0 :     m_aLastKnownValue.clear();
     722           0 : }
     723             : 
     724             : //-----------------------------------------------------------------------------
     725           0 : sal_Bool OComboBoxModel::commitControlValueToDbColumn( bool _bPostReset )
     726             : {
     727           0 :     Any aNewValue( m_xAggregateFastSet->getFastPropertyValue( getValuePropertyAggHandle() ) );
     728             : 
     729           0 :     ::rtl::OUString sNewValue;
     730           0 :     aNewValue >>= sNewValue;
     731             : 
     732           0 :     bool bModified = ( aNewValue != m_aLastKnownValue );
     733           0 :     if ( bModified )
     734             :     {
     735           0 :         if  (   !aNewValue.hasValue()
     736           0 :             ||  (   sNewValue.isEmpty()         // an empty string
     737             :                 &&  m_bEmptyIsNull              // which should be interpreted as NULL
     738             :                 )
     739             :             )
     740             :         {
     741           0 :             m_xColumnUpdate->updateNull();
     742             :         }
     743             :         else
     744             :         {
     745             :             try
     746             :             {
     747             :                 OSL_PRECOND( m_pValueFormatter.get(), "OComboBoxModel::commitControlValueToDbColumn: no value formatter!" );
     748           0 :                 if ( m_pValueFormatter.get() )
     749             :                 {
     750           0 :                     if ( !m_pValueFormatter->setFormattedValue( sNewValue ) )
     751           0 :                         return sal_False;
     752             :                 }
     753             :                 else
     754           0 :                     m_xColumnUpdate->updateString( sNewValue );
     755             :             }
     756           0 :             catch ( const Exception& )
     757             :             {
     758           0 :                 return sal_False;
     759             :             }
     760             :         }
     761             : 
     762           0 :         m_aLastKnownValue = aNewValue;
     763             :     }
     764             : 
     765             :     // add the new value to the list
     766           0 :     sal_Bool bAddToList = bModified && !_bPostReset;
     767             :         // (only if this is not the "commit" triggered by a "reset")
     768             : 
     769           0 :     if ( bAddToList )
     770             :     {
     771           0 :         StringSequence aStringItemList;
     772           0 :         if ( getPropertyValue( PROPERTY_STRINGITEMLIST ) >>= aStringItemList )
     773             :         {
     774           0 :             const ::rtl::OUString* pStringItems = aStringItemList.getConstArray();
     775             :             sal_Int32 i;
     776           0 :             for (i=0; i<aStringItemList.getLength(); ++i, ++pStringItems)
     777             :             {
     778           0 :                 if ( pStringItems->equals( sNewValue ) )
     779           0 :                     break;
     780             :             }
     781             : 
     782             :             // not found -> add
     783           0 :             if (i >= aStringItemList.getLength())
     784             :             {
     785           0 :                 sal_Int32 nOldLen = aStringItemList.getLength();
     786           0 :                 aStringItemList.realloc( nOldLen + 1 );
     787           0 :                 aStringItemList.getArray()[ nOldLen ] = sNewValue;
     788             : 
     789           0 :                 setFastPropertyValue( PROPERTY_ID_STRINGITEMLIST, makeAny( aStringItemList ) );
     790             :             }
     791           0 :         }
     792             :     }
     793             : 
     794           0 :     return sal_True;
     795             : }
     796             : 
     797             : // XPropertiesChangeListener
     798             : //------------------------------------------------------------------------------
     799           0 : Any OComboBoxModel::translateDbColumnToControlValue()
     800             : {
     801             :     OSL_PRECOND( m_pValueFormatter.get(), "OComboBoxModel::translateDbColumnToControlValue: no value formatter!" );
     802           0 :     if ( m_pValueFormatter.get() )
     803             :     {
     804           0 :         ::rtl::OUString sValue( m_pValueFormatter->getFormattedValue() );
     805           0 :         if  (   sValue.isEmpty()
     806           0 :             &&  m_pValueFormatter->getColumn().is()
     807           0 :             &&  m_pValueFormatter->getColumn()->wasNull()
     808             :             )
     809             :         {
     810           0 :             m_aLastKnownValue.clear();
     811             :         }
     812             :         else
     813             :         {
     814             : 
     815           0 :             m_aLastKnownValue <<= sValue;
     816           0 :         }
     817             :     }
     818             :     else
     819           0 :         m_aLastKnownValue.clear();
     820             : 
     821           0 :     return m_aLastKnownValue.hasValue() ? m_aLastKnownValue : makeAny( ::rtl::OUString() );
     822             :         // (m_aLastKnownValue is alllowed to be VOID, the control value isn't)
     823             : }
     824             : 
     825             : //------------------------------------------------------------------------------
     826           0 : Any OComboBoxModel::getDefaultForReset() const
     827             : {
     828           0 :     return makeAny( m_aDefaultText );
     829             : }
     830             : 
     831             : //--------------------------------------------------------------------
     832           0 : void OComboBoxModel::stringItemListChanged( ControlModelLock& /*_rInstanceLock*/ )
     833             : {
     834           0 :     if ( m_xAggregateSet.is() )
     835           0 :         m_xAggregateSet->setPropertyValue( PROPERTY_STRINGITEMLIST, makeAny( getStringItemList() ) );
     836           0 : }
     837             : 
     838             : //--------------------------------------------------------------------
     839           0 : void OComboBoxModel::connectedExternalListSource( )
     840             : {
     841             :     // TODO?
     842           0 : }
     843             : 
     844             : //--------------------------------------------------------------------
     845           0 : void OComboBoxModel::disconnectedExternalListSource( )
     846             : {
     847             :     // TODO?
     848           0 : }
     849             : 
     850             : //--------------------------------------------------------------------
     851           0 : void OComboBoxModel::refreshInternalEntryList()
     852             : {
     853             :     DBG_ASSERT( !hasExternalListSource(), "OComboBoxModel::refreshInternalEntryList: invalid call!" );
     854             : 
     855           0 :     if  (   !hasExternalListSource( )
     856             :         &&  ( m_eListSourceType != ListSourceType_VALUELIST )
     857           0 :         &&  ( m_xCursor.is() )
     858             :         )
     859             :     {
     860           0 :         loadData( true );
     861             :     }
     862           0 : }
     863             : 
     864             : //--------------------------------------------------------------------
     865           0 : void SAL_CALL OComboBoxModel::disposing( const EventObject& _rSource ) throw ( RuntimeException )
     866             : {
     867           0 :     if ( !OEntryListHelper::handleDisposing( _rSource ) )
     868           0 :         OBoundControlModel::disposing( _rSource );
     869           0 : }
     870             : 
     871             : //========================================================================
     872             : //= OComboBoxControl
     873             : //========================================================================
     874             : 
     875             : //------------------------------------------------------------------
     876           0 : InterfaceRef SAL_CALL OComboBoxControl_CreateInstance(const Reference<XMultiServiceFactory>& _rxFactory) throw (RuntimeException)
     877             : {
     878           0 :     return *(new OComboBoxControl(_rxFactory));
     879             : }
     880             : 
     881             : //------------------------------------------------------------------------------
     882           0 : OComboBoxControl::OComboBoxControl(const Reference<XMultiServiceFactory>& _rxFactory)
     883           0 :     :OBoundControl(_rxFactory, VCL_CONTROL_COMBOBOX)
     884             : {
     885           0 : }
     886             : 
     887             : //------------------------------------------------------------------------------
     888           0 : StringSequence SAL_CALL OComboBoxControl::getSupportedServiceNames() throw(RuntimeException)
     889             : {
     890           0 :     StringSequence aSupported = OBoundControl::getSupportedServiceNames();
     891           0 :     aSupported.realloc(aSupported.getLength() + 1);
     892             : 
     893           0 :     ::rtl::OUString* pArray = aSupported.getArray();
     894           0 :     pArray[aSupported.getLength()-1] = FRM_SUN_CONTROL_COMBOBOX;
     895           0 :     return aSupported;
     896             : }
     897             : 
     898             : //.........................................................................
     899             : }
     900             : //.........................................................................
     901             : 
     902             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10