Commits

Frank Schoenheit [fs]  committed 8eecb7c Merge

merging in latest changes from CWS unoawt2

  • Participants
  • Parent commits 6fc312c, a9f046b

Comments (0)

Files changed (7)

File offapi/com/sun/star/awt/UnoControlComboBoxModel.idl

 #include <com/sun/star/util/Color.idl>
 #endif
  
+#include <com/sun/star/awt/XItemList.idl>
  
 //============================================================================= 
  
         this is possible.</p>
     */
     [optional, property] short MouseWheelBehavior;
+
+    /** allows mmanipulating the list of items in the combo box more fine-grained than the
+        <member>StringItemList</member> property.
+    */
+    [optional] interface XItemList;
 }; 
  
 //============================================================================= 

File toolkit/inc/toolkit/awt/vclxwindows.hxx

 //	----------------------------------------------------
 //	class VCLXComboBox
 //	----------------------------------------------------
-class VCLXComboBox :	public ::com::sun::star::awt::XComboBox,
-						public VCLXEdit
+typedef ::cppu::ImplInheritanceHelper2  <   VCLXEdit
+                                        ,   ::com::sun::star::awt::XComboBox
+                                        ,   ::com::sun::star::awt::XItemListListener > VCLXComboBox_Base;
+class VCLXComboBox :	public VCLXComboBox_Base
 {
 private:
 	ActionListenerMultiplexer	maActionListeners;
 						VCLXComboBox();
     ~VCLXComboBox();
 
-	// ::com::sun::star::uno::XInterface
-    ::com::sun::star::uno::Any					SAL_CALL queryInterface( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException);
-	void										SAL_CALL acquire() throw()	{ OWeakObject::acquire(); }
-	void										SAL_CALL release() throw()	{ OWeakObject::release(); }
-
-    // ::com::sun::star::lang::XTypeProvider
-	::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type >	SAL_CALL getTypes() throw(::com::sun::star::uno::RuntimeException);
-	::com::sun::star::uno::Sequence< sal_Int8 >						SAL_CALL getImplementationId() throw(::com::sun::star::uno::RuntimeException);
-
  	// ::com::sun::star::lang::XComponent
     void SAL_CALL dispose(  ) throw(::com::sun::star::uno::RuntimeException);
 
     void SAL_CALL setProperty( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Any& Value ) throw(::com::sun::star::uno::RuntimeException);
     ::com::sun::star::uno::Any SAL_CALL getProperty( const ::rtl::OUString& PropertyName ) throw(::com::sun::star::uno::RuntimeException);
 
+    // XItemListListener
+    virtual void SAL_CALL listItemInserted( const ::com::sun::star::awt::ItemListEvent& Event ) throw (::com::sun::star::uno::RuntimeException);
+    virtual void SAL_CALL listItemRemoved( const ::com::sun::star::awt::ItemListEvent& Event ) throw (::com::sun::star::uno::RuntimeException);
+    virtual void SAL_CALL listItemModified( const ::com::sun::star::awt::ItemListEvent& Event ) throw (::com::sun::star::uno::RuntimeException);
+    virtual void SAL_CALL allItemsRemoved( const ::com::sun::star::lang::EventObject& Event ) throw (::com::sun::star::uno::RuntimeException);
+    virtual void SAL_CALL itemListChanged( const ::com::sun::star::lang::EventObject& Event ) throw (::com::sun::star::uno::RuntimeException);
+    // XEventListener
+    virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& i_rEvent ) throw (::com::sun::star::uno::RuntimeException);
+
     static void     ImplGetPropertyIds( std::list< sal_uInt16 > &aIds );
     virtual void    GetPropertyIds( std::list< sal_uInt16 > &aIds ) { return ImplGetPropertyIds( aIds ); }
 };

File toolkit/inc/toolkit/controls/unocontrols.hxx

                                             >   UnoControlListBoxModel_Base;
 class TOOLKIT_DLLPUBLIC UnoControlListBoxModel    :public UnoControlListBoxModel_Base
 {
+protected:
+    UnoControlListBoxModel(bool asComboBox);
 public:
 						UnoControlListBoxModel();
 						UnoControlListBoxModel( const UnoControlListBoxModel& i_rSource );
     ::rtl::OUString SAL_CALL getServiceName() throw(::com::sun::star::uno::RuntimeException);
 
     // ::com::sun::star::lang::XServiceInfo
-	DECLIMPL_SERVICEINFO_DERIVED( UnoControlListBoxModel, UnoControlModel, szServiceName2_UnoControlListBoxModel )
+	//DECLIMPL_SERVICEINFO_DERIVED( UnoControlListBoxModel, UnoControlModel, szServiceName2_UnoControlListBoxModel )
+    ::rtl::OUString SAL_CALL getImplementationName(  ) throw(::com::sun::star::uno::RuntimeException);
+    ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException);
 
     // ::com::sun::star::awt::XItemList
     virtual ::sal_Int32 SAL_CALL getItemCount() throw (::com::sun::star::uno::RuntimeException);
     void    impl_getStringItemList( ::std::vector< ::rtl::OUString >& o_rStringItems ) const;
     void    impl_setStringItemList_nolck( const ::std::vector< ::rtl::OUString >& i_rStringItems );
 
-private:
+protected:
     ::boost::scoped_ptr< UnoControlListBoxModel_Data >  m_pData;
     ::cppu::OInterfaceContainerHelper                   m_aItemListListeners;
 };
     virtual void SAL_CALL itemListChanged( const ::com::sun::star::lang::EventObject& Event ) throw (::com::sun::star::uno::RuntimeException);
 
 	// ::com::sun::star::lang::XServiceInfo
-	DECLIMPL_SERVICEINFO_DERIVED( UnoListBoxControl, UnoControlBase, szServiceName2_UnoControlListBox )
+	// DECLIMPL_SERVICEINFO_DERIVED( UnoListBoxControl, UnoControlBase, szServiceName2_UnoControlListBox )
+    ::rtl::OUString SAL_CALL getImplementationName(  ) throw(::com::sun::star::uno::RuntimeException);
+    ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException);
 
 protected:
     void                ImplUpdateSelectedItemsProperty();
 //	----------------------------------------------------
 //	class UnoControlComboBoxModel
 //	----------------------------------------------------
-class UnoControlComboBoxModel :	public UnoControlModel
+class UnoControlComboBoxModel :	public UnoControlListBoxModel
 {
 protected:
 	::com::sun::star::uno::Any 		ImplGetDefaultValue( sal_uInt16 nPropId ) const;
-	::cppu::IPropertyArrayHelper&	SAL_CALL getInfoHelper();
+    ::cppu::IPropertyArrayHelper&	SAL_CALL getInfoHelper();
 
 public:
 						UnoControlComboBoxModel();
-						UnoControlComboBoxModel( const UnoControlComboBoxModel& rModel ) : UnoControlModel( rModel ) {;}
+						UnoControlComboBoxModel( const UnoControlComboBoxModel& rModel ) : UnoControlListBoxModel( rModel ) {;}
 
 	UnoControlModel*	Clone() const { return new UnoControlComboBoxModel( *this ); }
 
 	// ::com::sun::star::io::XPersistObject
     ::rtl::OUString SAL_CALL getServiceName() throw(::com::sun::star::uno::RuntimeException);
 
-	// ::com::sun::star::beans::XMultiPropertySet
+    // ::com::sun::star::beans::XMultiPropertySet
     ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo(  ) throw(::com::sun::star::uno::RuntimeException);
+    // OPropertySetHelper
+	void SAL_CALL setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const ::com::sun::star::uno::Any& rValue ) throw (::com::sun::star::uno::Exception);
 
 	// ::com::sun::star::lang::XServiceInfo
-	DECLIMPL_SERVICEINFO_DERIVED( UnoControlComboBoxModel, UnoControlModel, szServiceName2_UnoControlComboBoxModel )
+    ::rtl::OUString SAL_CALL getImplementationName(  ) throw(::com::sun::star::uno::RuntimeException);
+    ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException);
+	// DECLIMPL_SERVICEINFO_DERIVED( UnoControlComboBoxModel, UnoControlModel, szServiceName2_UnoControlComboBoxModel )
 
 };
 
 //	----------------------------------------------------
 //	class UnoComboBoxControl
 //	----------------------------------------------------
-class UnoComboBoxControl :	public UnoEditControl,
-							public ::com::sun::star::awt::XComboBox
+class UnoComboBoxControl :	public UnoEditControl
+                        ,   public ::com::sun::star::awt::XComboBox
+		                ,   public ::com::sun::star::awt::XItemListener
+                        ,   public ::com::sun::star::awt::XItemListListener
 {
 private:
 	ActionListenerMultiplexer 	maActionListeners;
 				UnoComboBoxControl();
 	::rtl::OUString		GetComponentServiceName();
 
-	::com::sun::star::uno::Any	SAL_CALL queryInterface( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException) { return UnoEditControl::queryInterface(rType); }
+    void SAL_CALL createPeer( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XToolkit >& Toolkit, const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer >& Parent ) throw(::com::sun::star::uno::RuntimeException);
+    void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw(::com::sun::star::uno::RuntimeException) { UnoEditControl::disposing( Source ); }
+    void SAL_CALL dispose(  ) throw(::com::sun::star::uno::RuntimeException);
+
+    ::com::sun::star::uno::Any	SAL_CALL queryInterface( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException) { return UnoEditControl::queryInterface(rType); }
     ::com::sun::star::uno::Any	SAL_CALL queryAggregation( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException);
 	void						SAL_CALL acquire() throw()	{ OWeakAggObject::acquire(); }
 	void						SAL_CALL release() throw()	{ OWeakAggObject::release(); }
-    void SAL_CALL createPeer( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XToolkit >& Toolkit, const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer >& Parent ) throw(::com::sun::star::uno::RuntimeException);
-    void SAL_CALL dispose(  ) throw(::com::sun::star::uno::RuntimeException);
+    
 
     // ::com::sun::star::lang::XTypeProvider
 	::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type >	SAL_CALL getTypes() throw(::com::sun::star::uno::RuntimeException);
     sal_Int16 SAL_CALL getDropDownLineCount(  ) throw(::com::sun::star::uno::RuntimeException);
     void SAL_CALL setDropDownLineCount( sal_Int16 nLines ) throw(::com::sun::star::uno::RuntimeException);
 
+    // XUnoControl
+    virtual sal_Bool SAL_CALL setModel(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel >& Model) throw ( ::com::sun::star::uno::RuntimeException );
+
+    // XItemListListener
+    virtual void SAL_CALL listItemInserted( const ::com::sun::star::awt::ItemListEvent& Event ) throw (::com::sun::star::uno::RuntimeException);
+    virtual void SAL_CALL listItemRemoved( const ::com::sun::star::awt::ItemListEvent& Event ) throw (::com::sun::star::uno::RuntimeException);
+    virtual void SAL_CALL listItemModified( const ::com::sun::star::awt::ItemListEvent& Event ) throw (::com::sun::star::uno::RuntimeException);
+    virtual void SAL_CALL allItemsRemoved( const ::com::sun::star::lang::EventObject& Event ) throw (::com::sun::star::uno::RuntimeException);
+    virtual void SAL_CALL itemListChanged( const ::com::sun::star::lang::EventObject& Event ) throw (::com::sun::star::uno::RuntimeException);
+
+    // XItemListener
+    virtual void SAL_CALL itemStateChanged( const ::com::sun::star::awt::ItemEvent& rEvent ) throw (::com::sun::star::uno::RuntimeException);
+
 	// ::com::sun::star::lang::XServiceInfo
-	DECLIMPL_SERVICEINFO_DERIVED( UnoComboBoxControl, UnoEditControl, szServiceName2_UnoControlComboBox )
+    ::rtl::OUString SAL_CALL getImplementationName(  ) throw(::com::sun::star::uno::RuntimeException);
+    ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException);
+	//DECLIMPL_SERVICEINFO_DERIVED( UnoComboBoxControl, UnoEditControl, szServiceName2_UnoControlComboBox )
+protected:
+    virtual void        ImplSetPeerProperty( const ::rtl::OUString& rPropName, const ::com::sun::star::uno::Any& rVal );
+	virtual void        updateFromModel();
+    ActionListenerMultiplexer& 	getActionListeners();
+	ItemListenerMultiplexer& 	getItemListeners();
 
 };
 

File toolkit/source/awt/vclxwindows.cxx

 #endif
 }
 
-// ::com::sun::star::uno::XInterface
-::com::sun::star::uno::Any VCLXComboBox::queryInterface( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException)
-{
-	::com::sun::star::uno::Any aRet = ::cppu::queryInterface( rType,
-										SAL_STATIC_CAST( ::com::sun::star::awt::XComboBox*, this ) );
-	return (aRet.hasValue() ? aRet : VCLXEdit::queryInterface( rType ));
-}
-
-// ::com::sun::star::lang::XTypeProvider
-IMPL_XTYPEPROVIDER_START( VCLXComboBox )
-	getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XComboBox>* ) NULL ),
-	VCLXEdit::getTypes()
-IMPL_XTYPEPROVIDER_END
-
 ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext > VCLXComboBox::CreateAccessibleContext()
 {
 	::vos::OGuard aGuard( GetMutex() );
 		for ( sal_uInt16 n = 0; n < aItems.getLength(); n++ )
 		{
 			pBox->InsertEntry( aItems.getConstArray()[n], nP );
-			if ( (sal_uInt16)nPos < 0xFFFF )	// Nicht wenn 0xFFFF, weil LIST_APPEND
-				nP++;
+			if ( nP == 0xFFFF )
+            {
+                OSL_ENSURE( false, "VCLXComboBox::addItems: too many entries!" );
+                // skip remaining entries, list cannot hold them, anyway
+                break;
+            }
 		}
 	}
 }
 			break;
 			case BASEPROPERTY_STRINGITEMLIST:
 			{
-				::com::sun::star::uno::Sequence< ::rtl::OUString> aItems;
+                ::com::sun::star::uno::Sequence< ::rtl::OUString> aItems;
 				if ( Value >>= aItems )
 				{
-					sal_Bool bUpdate = pComboBox->IsUpdateMode();
-					pComboBox->SetUpdateMode( sal_False );
 					pComboBox->Clear();
-					const ::rtl::OUString* pStrings = aItems.getConstArray();
-					sal_Int32 nItems = aItems.getLength();
-					for ( sal_Int32 n = 0; n < nItems; n++ )
-						pComboBox->InsertEntry( pStrings[n], LISTBOX_APPEND );
-					pComboBox->SetUpdateMode( bUpdate );
+					addItems( aItems, 0 );
 				}
 			}
 			break;
 		nLines = nL;
 	}
 }
+void SAL_CALL VCLXComboBox::listItemInserted( const ItemListEvent& i_rEvent ) throw (RuntimeException)
+{
+	::vos::OGuard aGuard( GetMutex() );
+
+    ComboBox* pComboBox = dynamic_cast< ComboBox* >( GetWindow() );
+
+    ENSURE_OR_RETURN_VOID( pComboBox, "VCLXComboBox::listItemInserted: no ComboBox?!" );
+    ENSURE_OR_RETURN_VOID( ( i_rEvent.ItemPosition >= 0 ) && ( i_rEvent.ItemPosition <= sal_Int32( pComboBox->GetEntryCount() ) ),
+        "VCLXComboBox::listItemInserted: illegal (inconsistent) item position!" );
+    pComboBox->InsertEntry(
+        i_rEvent.ItemText.IsPresent ? i_rEvent.ItemText.Value : ::rtl::OUString(),
+        i_rEvent.ItemImageURL.IsPresent ? lcl_getImageFromURL( i_rEvent.ItemImageURL.Value ) : Image(),
+        i_rEvent.ItemPosition );
+}
+
+void SAL_CALL VCLXComboBox::listItemRemoved( const ItemListEvent& i_rEvent ) throw (RuntimeException)
+{
+	::vos::OGuard aGuard( GetMutex() );
+
+    ComboBox* pComboBox = dynamic_cast< ComboBox* >( GetWindow() );
+
+    ENSURE_OR_RETURN_VOID( pComboBox, "VCLXComboBox::listItemRemoved: no ComboBox?!" );
+    ENSURE_OR_RETURN_VOID( ( i_rEvent.ItemPosition >= 0 ) && ( i_rEvent.ItemPosition < sal_Int32( pComboBox->GetEntryCount() ) ),
+        "VCLXComboBox::listItemRemoved: illegal (inconsistent) item position!" );
+
+    pComboBox->RemoveEntry( i_rEvent.ItemPosition );
+}
+
+void SAL_CALL VCLXComboBox::listItemModified( const ItemListEvent& i_rEvent ) throw (RuntimeException)
+{
+	::vos::OGuard aGuard( GetMutex() );
+
+    ComboBox* pComboBox = dynamic_cast< ComboBox* >( GetWindow() );
+
+    ENSURE_OR_RETURN_VOID( pComboBox, "VCLXComboBox::listItemModified: no ComboBox?!" );
+    ENSURE_OR_RETURN_VOID( ( i_rEvent.ItemPosition >= 0 ) && ( i_rEvent.ItemPosition < sal_Int32( pComboBox->GetEntryCount() ) ),
+        "VCLXComboBox::listItemModified: illegal (inconsistent) item position!" );
+
+    // VCL's ComboBox does not support changing an entry's text or image, so remove and re-insert
+
+    const ::rtl::OUString sNewText = i_rEvent.ItemText.IsPresent ? i_rEvent.ItemText.Value : ::rtl::OUString( pComboBox->GetEntry( i_rEvent.ItemPosition ) );
+    const Image aNewImage( i_rEvent.ItemImageURL.IsPresent ? lcl_getImageFromURL( i_rEvent.ItemImageURL.Value ) : pComboBox->GetEntryImage( i_rEvent.ItemPosition  ) );
+
+    pComboBox->RemoveEntry( i_rEvent.ItemPosition );
+    pComboBox->InsertEntry( sNewText, aNewImage, i_rEvent.ItemPosition );
+}
+
+void SAL_CALL VCLXComboBox::allItemsRemoved( const EventObject& i_rEvent ) throw (RuntimeException)
+{
+	::vos::OGuard aGuard( GetMutex() );
+
+    ComboBox* pComboBox = dynamic_cast< ComboBox* >( GetWindow() );
+    ENSURE_OR_RETURN_VOID( pComboBox, "VCLXComboBox::listItemModified: no ComboBox?!" );
+
+    pComboBox->Clear();
+
+    (void)i_rEvent;
+}
+
+void SAL_CALL VCLXComboBox::itemListChanged( const EventObject& i_rEvent ) throw (RuntimeException)
+{
+	::vos::OGuard aGuard( GetMutex() );
+
+    ComboBox* pComboBox = dynamic_cast< ComboBox* >( GetWindow() );
+    ENSURE_OR_RETURN_VOID( pComboBox, "VCLXComboBox::listItemModified: no ComboBox?!" );
+
+    pComboBox->Clear();
+
+    uno::Reference< beans::XPropertySet > xPropSet( i_rEvent.Source, uno::UNO_QUERY_THROW );
+    uno::Reference< beans::XPropertySetInfo > xPSI( xPropSet->getPropertySetInfo(), uno::UNO_QUERY_THROW );
+    // bool localize = xPSI->hasPropertyByName( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ResourceResolver" ) ) );
+    uno::Reference< resource::XStringResourceResolver > xStringResourceResolver;
+    if ( xPSI->hasPropertyByName( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ResourceResolver" ) ) ) )
+    {
+        xStringResourceResolver.set(
+            xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ResourceResolver" ) ) ),
+            uno::UNO_QUERY
+        );
+    }
+    
+
+    Reference< XItemList > xItemList( i_rEvent.Source, uno::UNO_QUERY_THROW );
+    uno::Sequence< beans::Pair< ::rtl::OUString, ::rtl::OUString > > aItems = xItemList->getAllItems();
+    for ( sal_Int32 i=0; i<aItems.getLength(); ++i )
+    {
+        ::rtl::OUString aLocalizationKey( aItems[i].First );
+        if ( xStringResourceResolver.is() && aLocalizationKey.getLength() != 0 && aLocalizationKey[0] == '&' )
+        {
+            aLocalizationKey = xStringResourceResolver->resolveString(aLocalizationKey.copy( 1 ));
+        }
+        pComboBox->InsertEntry( aLocalizationKey, lcl_getImageFromURL( aItems[i].Second ) );
+    }
+}
+void SAL_CALL VCLXComboBox::disposing( const EventObject& i_rEvent ) throw (RuntimeException)
+{
+    // just disambiguate
+    VCLXEdit::disposing( i_rEvent );
+}
 
 //	----------------------------------------------------
 //	class VCLXFormattedSpinField

File toolkit/source/controls/unocontrols.cxx

 using ::com::sun::star::uno::Reference;
 using namespace ::toolkit;
 
+#define IMPL_SERVICEINFO_DERIVED( ImplName, BaseClass, ServiceName ) \
+    ::rtl::OUString SAL_CALL ImplName::getImplementationName(  ) throw(::com::sun::star::uno::RuntimeException) { return ::rtl::OUString::createFromAscii( "stardiv.Toolkit." #ImplName ); } \
+    ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL ImplName::getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException)	\
+							{ \
+								::com::sun::star::uno::Sequence< ::rtl::OUString > aNames = BaseClass::getSupportedServiceNames( ); \
+								aNames.realloc( aNames.getLength() + 1 ); \
+								aNames[ aNames.getLength() - 1 ] = ::rtl::OUString::createFromAscii( ServiceName ); \
+								return aNames; \
+							} \
+
+
+
 //	----------------------------------------------------
 //	class UnoControlEditModel
 //	----------------------------------------------------
 {
     UNO_CONTROL_MODEL_REGISTER_PROPERTIES( VCLXListBox );
 }
+// ---------------------------------------------------------------------------------------------------------------------
+UnoControlListBoxModel::UnoControlListBoxModel(bool)
+    :UnoControlListBoxModel_Base()
+    ,m_pData( new UnoControlListBoxModel_Data( *this ) )
+    ,m_aItemListListeners( GetMutex() )
+{
+}
 
 // ---------------------------------------------------------------------------------------------------------------------
 UnoControlListBoxModel::UnoControlListBoxModel( const UnoControlListBoxModel& i_rSource )
 UnoControlListBoxModel::~UnoControlListBoxModel()
 {
 }
+IMPL_SERVICEINFO_DERIVED( UnoControlListBoxModel, UnoControlModel, szServiceName2_UnoControlListBoxModel )
 // ---------------------------------------------------------------------------------------------------------------------
 ::rtl::OUString UnoControlListBoxModel::getServiceName() throw(::com::sun::star::uno::RuntimeException)
 {
 	return ::rtl::OUString::createFromAscii( szServiceName_UnoControlListBoxModel );
 }
-
 // ---------------------------------------------------------------------------------------------------------------------
 uno::Any UnoControlListBoxModel::ImplGetDefaultValue( sal_uInt16 nPropId ) const
 {
 {
 	return ::rtl::OUString::createFromAscii( "listbox" );
 }
+IMPL_SERVICEINFO_DERIVED( UnoListBoxControl, UnoControlBase, szServiceName2_UnoControlListBox )
 
 void UnoListBoxControl::dispose() throw(uno::RuntimeException)
 {
 //	----------------------------------------------------
 //	class UnoControlComboBoxModel
 //	----------------------------------------------------
-UnoControlComboBoxModel::UnoControlComboBoxModel()
+UnoControlComboBoxModel::UnoControlComboBoxModel() : UnoControlListBoxModel(true)
 {
     UNO_CONTROL_MODEL_REGISTER_PROPERTIES( VCLXComboBox );
 }
 
+IMPL_SERVICEINFO_DERIVED( UnoControlComboBoxModel, UnoControlModel, szServiceName2_UnoControlComboBoxModel )
+
+uno::Reference< beans::XPropertySetInfo > UnoControlComboBoxModel::getPropertySetInfo(  ) throw(uno::RuntimeException)
+{
+	static uno::Reference< beans::XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) );
+	return xInfo;
+}
+// ---------------------------------------------------------------------------------------------------------------------
+::cppu::IPropertyArrayHelper& UnoControlComboBoxModel::getInfoHelper()
+{
+	static UnoPropertyArrayHelper* pHelper = NULL;
+	if ( !pHelper )
+	{
+		uno::Sequence<sal_Int32>	aIDs = ImplGetPropertyIds();
+		pHelper = new UnoPropertyArrayHelper( aIDs );
+	}
+	return *pHelper;
+}
+
+
 ::rtl::OUString UnoControlComboBoxModel::getServiceName() throw(::com::sun::star::uno::RuntimeException)
 {
 	return ::rtl::OUString::createFromAscii( szServiceName_UnoControlComboBoxModel );
 }
+void SAL_CALL UnoControlComboBoxModel::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const uno::Any& rValue ) throw (uno::Exception)
+{
+    UnoControlModel::setFastPropertyValue_NoBroadcast( nHandle, rValue );
+
+    if ( nHandle == BASEPROPERTY_STRINGITEMLIST && !m_pData->m_bSettingLegacyProperty)
+	{
+        // synchronize the legacy StringItemList property with our list items
+        Sequence< ::rtl::OUString > aStringItemList;
+        Any aPropValue;
+        getFastPropertyValue( aPropValue, BASEPROPERTY_STRINGITEMLIST );
+        OSL_VERIFY( aPropValue >>= aStringItemList );
+
+        ::std::vector< ListItem > aItems( aStringItemList.getLength() );
+        ::std::transform(
+            aStringItemList.getConstArray(),
+            aStringItemList.getConstArray() + aStringItemList.getLength(),
+            aItems.begin(),
+            CreateListItem()
+        );
+        m_pData->setAllItems( aItems );
+
+        // since an XItemListListener does not have a "all items modified" or some such method,
+        // we simulate this by notifying removal of all items, followed by insertion of all new
+        // items
+        lang::EventObject aEvent;
+        aEvent.Source = *this;
+        m_aItemListListeners.notifyEach( &XItemListListener::itemListChanged, aEvent );
+        // TODO: OPropertySetHelper calls into this method with the mutex locked ...
+        // which is wrong for the above notifications ...
+	}
+}
 
 uno::Any UnoControlComboBoxModel::ImplGetDefaultValue( sal_uInt16 nPropId ) const
 {
 	return UnoControlModel::ImplGetDefaultValue( nPropId );
 }
 
-
-::cppu::IPropertyArrayHelper& UnoControlComboBoxModel::getInfoHelper()
-{
-	static UnoPropertyArrayHelper* pHelper = NULL;
-	if ( !pHelper )
-	{
-		uno::Sequence<sal_Int32>	aIDs = ImplGetPropertyIds();
-		pHelper = new UnoPropertyArrayHelper( aIDs );
-	}
-	return *pHelper;
-}
-
-// beans::XMultiPropertySet
-uno::Reference< beans::XPropertySetInfo > UnoControlComboBoxModel::getPropertySetInfo(  ) throw(uno::RuntimeException)
-{
-	static uno::Reference< beans::XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) );
-	return xInfo;
-}
-
-
-
 //	----------------------------------------------------
 //	class UnoComboBoxControl
 //	----------------------------------------------------
 	maComponentInfos.nWidth = 100;
 	maComponentInfos.nHeight = 12;
 }
+IMPL_SERVICEINFO_DERIVED( UnoComboBoxControl, UnoEditControl, szServiceName2_UnoControlComboBox )
 
 ::rtl::OUString UnoComboBoxControl::GetComponentServiceName()
 {
 	return ::rtl::OUString::createFromAscii( "combobox" );
 }
 
-// uno::XInterface
-uno::Any UnoComboBoxControl::queryAggregation( const uno::Type & rType ) throw(uno::RuntimeException)
-{
-	uno::Any aRet = ::cppu::queryInterface( rType,
-										SAL_STATIC_CAST( awt::XComboBox*, this ) );
-	return (aRet.hasValue() ? aRet : UnoEditControl::queryAggregation( rType ));
-}
-
-// lang::XTypeProvider
-IMPL_XTYPEPROVIDER_START( UnoComboBoxControl )
-	getCppuType( ( uno::Reference< awt::XComboBox>* ) NULL ),
-	UnoEditControl::getTypes()
-IMPL_XTYPEPROVIDER_END
-
 void UnoComboBoxControl::dispose() throw(uno::RuntimeException)
 {
 	lang::EventObject aEvt;
 	maItemListeners.disposeAndClear( aEvt );
 	UnoControl::dispose();
 }
-
+uno::Any UnoComboBoxControl::queryAggregation( const uno::Type & rType ) throw(uno::RuntimeException)
+{
+	uno::Any aRet = ::cppu::queryInterface( rType,
+										SAL_STATIC_CAST( awt::XComboBox*, this ) );
+    if ( !aRet.hasValue() )
+    {
+        aRet = ::cppu::queryInterface( rType,
+										SAL_STATIC_CAST( awt::XItemListener*, this ) );
+        if ( !aRet.hasValue() )
+        {
+            aRet = ::cppu::queryInterface( rType,
+										    SAL_STATIC_CAST( awt::XItemListListener*, this ) );
+        }
+    }
+	return (aRet.hasValue() ? aRet : UnoEditControl::queryAggregation( rType ));
+}
+// lang::XTypeProvider
+IMPL_XTYPEPROVIDER_START( UnoComboBoxControl )
+	getCppuType( ( uno::Reference< awt::XComboBox>* ) NULL ),
+    getCppuType( ( uno::Reference< awt::XItemListener>* ) NULL ),
+    getCppuType( ( uno::Reference< awt::XItemListListener>* ) NULL ),
+	UnoEditControl::getTypes()
+IMPL_XTYPEPROVIDER_END
+
+void UnoComboBoxControl::updateFromModel()
+{
+    UnoEditControl::updateFromModel();
+
+    Reference< XItemListListener > xItemListListener( getPeer(), UNO_QUERY );
+    ENSURE_OR_RETURN_VOID( xItemListListener.is(), "UnoComboBoxControl::updateFromModel: a peer which is no ItemListListener?!" );
+
+    EventObject aEvent( getModel() );
+    xItemListListener->itemListChanged( aEvent );
+}
+void UnoComboBoxControl::ImplSetPeerProperty( const ::rtl::OUString& rPropName, const uno::Any& rVal )
+{
+    if ( rPropName == GetPropertyName( BASEPROPERTY_STRINGITEMLIST ) )
+        // do not forward this to our peer. We are a XItemListListener at our model, and changes in the string item
+        // list (which is a legacy property) will, later, arrive as changes in the ItemList. Those latter changes
+        // will be forwarded to the peer, which will update itself accordingly.
+        return;
+
+	UnoEditControl::ImplSetPeerProperty( rPropName, rVal );
+}
 void UnoComboBoxControl::createPeer( const uno::Reference< awt::XToolkit > & rxToolkit, const uno::Reference< awt::XWindowPeer >  & rParentPeer ) throw(uno::RuntimeException)
 {
 	UnoEditControl::createPeer( rxToolkit, rParentPeer );
 	}
 	maItemListeners.removeInterface( l );
 }
+void UnoComboBoxControl::itemStateChanged( const awt::ItemEvent& rEvent ) throw(uno::RuntimeException)
+{
+	if ( maItemListeners.getLength() )
+    {
+        try
+        {
+		    maItemListeners.itemStateChanged( rEvent );
+        }
+        catch( const Exception& e )
+        {
+#if OSL_DEBUG_LEVEL == 0
+            (void) e; // suppress warning
+#else
+            ::rtl::OString sMessage( "UnoComboBoxControl::itemStateChanged: caught an exception:\n" );
+            sMessage += ::rtl::OString( e.Message.getStr(), e.Message.getLength(), RTL_TEXTENCODING_ASCII_US );
+        	OSL_ENSURE( sal_False, sMessage.getStr() );
+#endif
+        }
+    }
+}
+sal_Bool SAL_CALL UnoComboBoxControl::setModel( const uno::Reference< awt::XControlModel >& i_rModel ) throw ( uno::RuntimeException )
+{
+	::osl::MutexGuard aGuard( GetMutex() );
+
+    const Reference< XItemList > xOldItems( getModel(), UNO_QUERY );
+    OSL_ENSURE( xOldItems.is() || !getModel().is(), "UnoComboBoxControl::setModel: illegal old model!" );
+    const Reference< XItemList > xNewItems( i_rModel, UNO_QUERY );
+    OSL_ENSURE( xNewItems.is() || !i_rModel.is(), "UnoComboBoxControl::setModel: illegal new model!" );
+
+    if ( !UnoEditControl::setModel( i_rModel ) )
+        return sal_False;
+
+    if ( xOldItems.is() )
+        xOldItems->removeItemListListener( this );
+    if ( xNewItems.is() )
+        xNewItems->addItemListListener( this );
+
+    return sal_True;
+}
+
+void SAL_CALL UnoComboBoxControl::listItemInserted( const awt::ItemListEvent& i_rEvent ) throw (uno::RuntimeException)
+{
+    const Reference< XItemListListener > xPeerListener( getPeer(), UNO_QUERY );
+    OSL_ENSURE( xPeerListener.is() || !getPeer().is(), "UnoComboBoxControl::listItemInserted: invalid peer!" );
+    if ( xPeerListener.is() )
+        xPeerListener->listItemInserted( i_rEvent );
+}
+
+void SAL_CALL UnoComboBoxControl::listItemRemoved( const awt::ItemListEvent& i_rEvent ) throw (uno::RuntimeException)
+{
+    const Reference< XItemListListener > xPeerListener( getPeer(), UNO_QUERY );
+    OSL_ENSURE( xPeerListener.is() || !getPeer().is(), "UnoComboBoxControl::listItemRemoved: invalid peer!" );
+    if ( xPeerListener.is() )
+        xPeerListener->listItemRemoved( i_rEvent );
+}
+
+void SAL_CALL UnoComboBoxControl::listItemModified( const awt::ItemListEvent& i_rEvent ) throw (uno::RuntimeException)
+{
+    const Reference< XItemListListener > xPeerListener( getPeer(), UNO_QUERY );
+    OSL_ENSURE( xPeerListener.is() || !getPeer().is(), "UnoComboBoxControl::listItemModified: invalid peer!" );
+    if ( xPeerListener.is() )
+        xPeerListener->listItemModified( i_rEvent );
+}
+
+void SAL_CALL UnoComboBoxControl::allItemsRemoved( const lang::EventObject& i_rEvent ) throw (uno::RuntimeException)
+{
+    const Reference< XItemListListener > xPeerListener( getPeer(), UNO_QUERY );
+    OSL_ENSURE( xPeerListener.is() || !getPeer().is(), "UnoComboBoxControl::allItemsRemoved: invalid peer!" );
+    if ( xPeerListener.is() )
+        xPeerListener->allItemsRemoved( i_rEvent );
+}
+
+void SAL_CALL UnoComboBoxControl::itemListChanged( const lang::EventObject& i_rEvent ) throw (uno::RuntimeException)
+{
+    const Reference< XItemListListener > xPeerListener( getPeer(), UNO_QUERY );
+    OSL_ENSURE( xPeerListener.is() || !getPeer().is(), "UnoComboBoxControl::itemListChanged: invalid peer!" );
+    if ( xPeerListener.is() )
+        xPeerListener->itemListChanged( i_rEvent );
+}
+ActionListenerMultiplexer& 	UnoComboBoxControl::getActionListeners()
+{
+    return maActionListeners;
+}
+ItemListenerMultiplexer& 	UnoComboBoxControl::getItemListeners()
+{
+    return maItemListeners;
+}
 
 void UnoComboBoxControl::addItem( const ::rtl::OUString& aItem, sal_Int16 nPos ) throw(uno::RuntimeException)
 {

File vcl/inc/vcl/combobox.hxx

 
     USHORT          GetEntryPos( const XubString& rStr ) const;
     USHORT          GetEntryPos( const void* pData ) const;
+    Image           GetEntryImage( USHORT nPos ) const;
     XubString       GetEntry( USHORT nPos ) const;
     USHORT          GetEntryCount() const;
 

File vcl/source/control/combobox.cxx

 	mpImplLB->Clear();
     CallEventListeners( VCLEVENT_COMBOBOX_ITEMREMOVED, (void*) sal_IntPtr(-1) );
 }
+// -----------------------------------------------------------------------
+
+Image ComboBox::GetEntryImage( USHORT nPos ) const
+{
+    if ( mpImplLB->GetEntryList()->HasEntryImage( nPos ) )
+        return mpImplLB->GetEntryList()->GetEntryImage( nPos );
+    return Image();
+}
 
 // -----------------------------------------------------------------------