1*24acc546SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3*24acc546SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*24acc546SAndrew Rist * or more contributor license agreements. See the NOTICE file 5*24acc546SAndrew Rist * distributed with this work for additional information 6*24acc546SAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*24acc546SAndrew Rist * to you under the Apache License, Version 2.0 (the 8*24acc546SAndrew Rist * "License"); you may not use this file except in compliance 9*24acc546SAndrew Rist * with the License. You may obtain a copy of the License at 10*24acc546SAndrew Rist * 11*24acc546SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12*24acc546SAndrew Rist * 13*24acc546SAndrew Rist * Unless required by applicable law or agreed to in writing, 14*24acc546SAndrew Rist * software distributed under the License is distributed on an 15*24acc546SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*24acc546SAndrew Rist * KIND, either express or implied. See the License for the 17*24acc546SAndrew Rist * specific language governing permissions and limitations 18*24acc546SAndrew Rist * under the License. 19*24acc546SAndrew Rist * 20*24acc546SAndrew Rist *************************************************************/ 21*24acc546SAndrew Rist 22*24acc546SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 25cdf0e10cSrcweir #include "precompiled_forms.hxx" 26cdf0e10cSrcweir #include "entrylisthelper.hxx" 27cdf0e10cSrcweir #include "FormComponent.hxx" 28cdf0e10cSrcweir 29cdf0e10cSrcweir #include <osl/diagnose.h> 30cdf0e10cSrcweir #include <comphelper/sequence.hxx> 31cdf0e10cSrcweir #include <comphelper/property.hxx> 32cdf0e10cSrcweir #include <algorithm> 33cdf0e10cSrcweir 34cdf0e10cSrcweir //......................................................................... 35cdf0e10cSrcweir namespace frm 36cdf0e10cSrcweir { 37cdf0e10cSrcweir //......................................................................... 38cdf0e10cSrcweir 39cdf0e10cSrcweir using namespace ::com::sun::star::uno; 40cdf0e10cSrcweir using namespace ::com::sun::star::lang; 41cdf0e10cSrcweir using namespace ::com::sun::star::util; 42cdf0e10cSrcweir using namespace ::com::sun::star::form::binding; 43cdf0e10cSrcweir 44cdf0e10cSrcweir //===================================================================== 45cdf0e10cSrcweir //= OEntryListHelper 46cdf0e10cSrcweir //===================================================================== 47cdf0e10cSrcweir //--------------------------------------------------------------------- OEntryListHelper(OControlModel & _rControlModel)48cdf0e10cSrcweir OEntryListHelper::OEntryListHelper( OControlModel& _rControlModel ) 49cdf0e10cSrcweir :m_rControlModel( _rControlModel ) 50cdf0e10cSrcweir ,m_aRefreshListeners( _rControlModel.getInstanceMutex() ) 51cdf0e10cSrcweir { 52cdf0e10cSrcweir } 53cdf0e10cSrcweir 54cdf0e10cSrcweir //--------------------------------------------------------------------- OEntryListHelper(const OEntryListHelper & _rSource,OControlModel & _rControlModel)55cdf0e10cSrcweir OEntryListHelper::OEntryListHelper( const OEntryListHelper& _rSource, OControlModel& _rControlModel ) 56cdf0e10cSrcweir :m_rControlModel( _rControlModel ) 57cdf0e10cSrcweir ,m_xListSource ( _rSource.m_xListSource ) 58cdf0e10cSrcweir ,m_aStringItems( _rSource.m_aStringItems ) 59cdf0e10cSrcweir ,m_aRefreshListeners( _rControlModel.getInstanceMutex() ) 60cdf0e10cSrcweir { 61cdf0e10cSrcweir } 62cdf0e10cSrcweir 63cdf0e10cSrcweir //--------------------------------------------------------------------- ~OEntryListHelper()64cdf0e10cSrcweir OEntryListHelper::~OEntryListHelper( ) 65cdf0e10cSrcweir { 66cdf0e10cSrcweir } 67cdf0e10cSrcweir 68cdf0e10cSrcweir //--------------------------------------------------------------------- setListEntrySource(const Reference<XListEntrySource> & _rxSource)69cdf0e10cSrcweir void SAL_CALL OEntryListHelper::setListEntrySource( const Reference< XListEntrySource >& _rxSource ) throw (RuntimeException) 70cdf0e10cSrcweir { 71cdf0e10cSrcweir ControlModelLock aLock( m_rControlModel ); 72cdf0e10cSrcweir 73cdf0e10cSrcweir // disconnect from the current external list source 74cdf0e10cSrcweir disconnectExternalListSource(); 75cdf0e10cSrcweir 76cdf0e10cSrcweir // and connect to the new one 77cdf0e10cSrcweir if ( _rxSource.is() ) 78cdf0e10cSrcweir connectExternalListSource( _rxSource, aLock ); 79cdf0e10cSrcweir } 80cdf0e10cSrcweir 81cdf0e10cSrcweir //--------------------------------------------------------------------- getListEntrySource()82cdf0e10cSrcweir Reference< XListEntrySource > SAL_CALL OEntryListHelper::getListEntrySource( ) throw (RuntimeException) 83cdf0e10cSrcweir { 84cdf0e10cSrcweir return m_xListSource; 85cdf0e10cSrcweir } 86cdf0e10cSrcweir 87cdf0e10cSrcweir 88cdf0e10cSrcweir //--------------------------------------------------------------------- entryChanged(const ListEntryEvent & _rEvent)89cdf0e10cSrcweir void SAL_CALL OEntryListHelper::entryChanged( const ListEntryEvent& _rEvent ) throw (RuntimeException) 90cdf0e10cSrcweir { 91cdf0e10cSrcweir ControlModelLock aLock( m_rControlModel ); 92cdf0e10cSrcweir 93cdf0e10cSrcweir OSL_ENSURE( _rEvent.Source == m_xListSource, 94cdf0e10cSrcweir "OEntryListHelper::entryChanged: where did this come from?" ); 95cdf0e10cSrcweir OSL_ENSURE( ( _rEvent.Position >= 0 ) && ( _rEvent.Position < m_aStringItems.getLength() ), 96cdf0e10cSrcweir "OEntryListHelper::entryChanged: invalid index!" ); 97cdf0e10cSrcweir OSL_ENSURE( _rEvent.Entries.getLength() == 1, 98cdf0e10cSrcweir "OEntryListHelper::entryChanged: invalid string list!" ); 99cdf0e10cSrcweir 100cdf0e10cSrcweir if ( ( _rEvent.Position >= 0 ) 101cdf0e10cSrcweir && ( _rEvent.Position < m_aStringItems.getLength() ) 102cdf0e10cSrcweir && ( _rEvent.Entries.getLength() > 0 ) 103cdf0e10cSrcweir ) 104cdf0e10cSrcweir { 105cdf0e10cSrcweir m_aStringItems[ _rEvent.Position ] = _rEvent.Entries[ 0 ]; 106cdf0e10cSrcweir stringItemListChanged( aLock ); 107cdf0e10cSrcweir } 108cdf0e10cSrcweir } 109cdf0e10cSrcweir 110cdf0e10cSrcweir //--------------------------------------------------------------------- entryRangeInserted(const ListEntryEvent & _rEvent)111cdf0e10cSrcweir void SAL_CALL OEntryListHelper::entryRangeInserted( const ListEntryEvent& _rEvent ) throw (RuntimeException) 112cdf0e10cSrcweir { 113cdf0e10cSrcweir ControlModelLock aLock( m_rControlModel ); 114cdf0e10cSrcweir 115cdf0e10cSrcweir OSL_ENSURE( _rEvent.Source == m_xListSource, 116cdf0e10cSrcweir "OEntryListHelper::entryRangeInserted: where did this come from?" ); 117cdf0e10cSrcweir OSL_ENSURE( ( _rEvent.Position > 0 ) && ( _rEvent.Position < m_aStringItems.getLength() ) && ( _rEvent.Entries.getLength() > 0 ), 118cdf0e10cSrcweir "OEntryListHelper::entryRangeRemoved: invalid count and/or position!" ); 119cdf0e10cSrcweir 120cdf0e10cSrcweir if ( ( _rEvent.Position > 0 ) 121cdf0e10cSrcweir && ( _rEvent.Position < m_aStringItems.getLength() ) 122cdf0e10cSrcweir && ( _rEvent.Entries.getLength() > 0 ) 123cdf0e10cSrcweir ) 124cdf0e10cSrcweir { 125cdf0e10cSrcweir // the entries *before* the insertion pos 126cdf0e10cSrcweir Sequence< ::rtl::OUString > aKeepEntries( 127cdf0e10cSrcweir m_aStringItems.getConstArray(), 128cdf0e10cSrcweir _rEvent.Position 129cdf0e10cSrcweir ); 130cdf0e10cSrcweir // the entries *behind* the insertion pos 131cdf0e10cSrcweir Sequence< ::rtl::OUString > aMovedEntries( 132cdf0e10cSrcweir m_aStringItems.getConstArray() + _rEvent.Position, 133cdf0e10cSrcweir m_aStringItems.getLength() - _rEvent.Position 134cdf0e10cSrcweir ); 135cdf0e10cSrcweir 136cdf0e10cSrcweir // concat all three parts 137cdf0e10cSrcweir m_aStringItems = ::comphelper::concatSequences( 138cdf0e10cSrcweir aKeepEntries, 139cdf0e10cSrcweir _rEvent.Entries, 140cdf0e10cSrcweir aMovedEntries 141cdf0e10cSrcweir ); 142cdf0e10cSrcweir 143cdf0e10cSrcweir stringItemListChanged( aLock ); 144cdf0e10cSrcweir } 145cdf0e10cSrcweir } 146cdf0e10cSrcweir 147cdf0e10cSrcweir //--------------------------------------------------------------------- entryRangeRemoved(const ListEntryEvent & _rEvent)148cdf0e10cSrcweir void SAL_CALL OEntryListHelper::entryRangeRemoved( const ListEntryEvent& _rEvent ) throw (RuntimeException) 149cdf0e10cSrcweir { 150cdf0e10cSrcweir ControlModelLock aLock( m_rControlModel ); 151cdf0e10cSrcweir 152cdf0e10cSrcweir OSL_ENSURE( _rEvent.Source == m_xListSource, 153cdf0e10cSrcweir "OEntryListHelper::entryRangeRemoved: where did this come from?" ); 154cdf0e10cSrcweir OSL_ENSURE( ( _rEvent.Position > 0 ) && ( _rEvent.Count > 0 ) && ( _rEvent.Position + _rEvent.Count <= m_aStringItems.getLength() ), 155cdf0e10cSrcweir "OEntryListHelper::entryRangeRemoved: invalid count and/or position!" ); 156cdf0e10cSrcweir 157cdf0e10cSrcweir if ( ( _rEvent.Position > 0 ) 158cdf0e10cSrcweir && ( _rEvent.Count > 0 ) 159cdf0e10cSrcweir && ( _rEvent.Position + _rEvent.Count <= m_aStringItems.getLength() ) 160cdf0e10cSrcweir ) 161cdf0e10cSrcweir { 162cdf0e10cSrcweir // copy all items after the removed ones 163cdf0e10cSrcweir ::std::copy( 164cdf0e10cSrcweir m_aStringItems.getConstArray() + _rEvent.Position + _rEvent.Count, 165cdf0e10cSrcweir m_aStringItems.getConstArray() + m_aStringItems.getLength(), 166cdf0e10cSrcweir m_aStringItems.getArray( ) + _rEvent.Position 167cdf0e10cSrcweir ); 168cdf0e10cSrcweir // shrink the array 169cdf0e10cSrcweir m_aStringItems.realloc( m_aStringItems.getLength() - _rEvent.Count ); 170cdf0e10cSrcweir 171cdf0e10cSrcweir stringItemListChanged( aLock ); 172cdf0e10cSrcweir } 173cdf0e10cSrcweir } 174cdf0e10cSrcweir 175cdf0e10cSrcweir //--------------------------------------------------------------------- allEntriesChanged(const EventObject & _rEvent)176cdf0e10cSrcweir void SAL_CALL OEntryListHelper::allEntriesChanged( const EventObject& _rEvent ) throw (RuntimeException) 177cdf0e10cSrcweir { 178cdf0e10cSrcweir ControlModelLock aLock( m_rControlModel ); 179cdf0e10cSrcweir 180cdf0e10cSrcweir OSL_ENSURE( _rEvent.Source == m_xListSource, 181cdf0e10cSrcweir "OEntryListHelper::allEntriesChanged: where did this come from?" ); 182cdf0e10cSrcweir 183cdf0e10cSrcweir Reference< XListEntrySource > xSource( _rEvent.Source, UNO_QUERY ); 184cdf0e10cSrcweir if ( _rEvent.Source == m_xListSource ) 185cdf0e10cSrcweir { 186cdf0e10cSrcweir impl_lock_refreshList( aLock ); 187cdf0e10cSrcweir } 188cdf0e10cSrcweir } 189cdf0e10cSrcweir 190cdf0e10cSrcweir // XRefreshable 191cdf0e10cSrcweir //------------------------------------------------------------------------------ addRefreshListener(const Reference<XRefreshListener> & _rxListener)192cdf0e10cSrcweir void SAL_CALL OEntryListHelper::addRefreshListener(const Reference<XRefreshListener>& _rxListener) throw(RuntimeException) 193cdf0e10cSrcweir { 194cdf0e10cSrcweir if ( _rxListener.is() ) 195cdf0e10cSrcweir m_aRefreshListeners.addInterface( _rxListener ); 196cdf0e10cSrcweir } 197cdf0e10cSrcweir 198cdf0e10cSrcweir //------------------------------------------------------------------------------ removeRefreshListener(const Reference<XRefreshListener> & _rxListener)199cdf0e10cSrcweir void SAL_CALL OEntryListHelper::removeRefreshListener(const Reference<XRefreshListener>& _rxListener) throw(RuntimeException) 200cdf0e10cSrcweir { 201cdf0e10cSrcweir if ( _rxListener.is() ) 202cdf0e10cSrcweir m_aRefreshListeners.removeInterface( _rxListener ); 203cdf0e10cSrcweir } 204cdf0e10cSrcweir 205cdf0e10cSrcweir //------------------------------------------------------------------------------ refresh()206cdf0e10cSrcweir void SAL_CALL OEntryListHelper::refresh() throw(RuntimeException) 207cdf0e10cSrcweir { 208cdf0e10cSrcweir { 209cdf0e10cSrcweir ControlModelLock aLock( m_rControlModel ); 210cdf0e10cSrcweir impl_lock_refreshList( aLock ); 211cdf0e10cSrcweir } 212cdf0e10cSrcweir 213cdf0e10cSrcweir EventObject aEvt( static_cast< XRefreshable* >( this ) ); 214cdf0e10cSrcweir m_aRefreshListeners.notifyEach( &XRefreshListener::refreshed, aEvt ); 215cdf0e10cSrcweir } 216cdf0e10cSrcweir 217cdf0e10cSrcweir //--------------------------------------------------------------------- impl_lock_refreshList(ControlModelLock & _rInstanceLock)218cdf0e10cSrcweir void OEntryListHelper::impl_lock_refreshList( ControlModelLock& _rInstanceLock ) 219cdf0e10cSrcweir { 220cdf0e10cSrcweir if ( hasExternalListSource() ) 221cdf0e10cSrcweir { 222cdf0e10cSrcweir m_aStringItems = m_xListSource->getAllListEntries( ); 223cdf0e10cSrcweir stringItemListChanged( _rInstanceLock ); 224cdf0e10cSrcweir } 225cdf0e10cSrcweir else 226cdf0e10cSrcweir refreshInternalEntryList(); 227cdf0e10cSrcweir } 228cdf0e10cSrcweir 229cdf0e10cSrcweir //--------------------------------------------------------------------- handleDisposing(const EventObject & _rEvent)230cdf0e10cSrcweir bool OEntryListHelper::handleDisposing( const EventObject& _rEvent ) 231cdf0e10cSrcweir { 232cdf0e10cSrcweir if ( m_xListSource .is() && ( _rEvent.Source == m_xListSource ) ) 233cdf0e10cSrcweir { 234cdf0e10cSrcweir disconnectExternalListSource( ); 235cdf0e10cSrcweir return true; 236cdf0e10cSrcweir } 237cdf0e10cSrcweir return false; 238cdf0e10cSrcweir } 239cdf0e10cSrcweir 240cdf0e10cSrcweir //--------------------------------------------------------------------- disposing()241cdf0e10cSrcweir void OEntryListHelper::disposing( ) 242cdf0e10cSrcweir { 243cdf0e10cSrcweir EventObject aEvt( static_cast< XRefreshable* >( this ) ); 244cdf0e10cSrcweir m_aRefreshListeners.disposeAndClear(aEvt); 245cdf0e10cSrcweir 246cdf0e10cSrcweir if ( hasExternalListSource( ) ) 247cdf0e10cSrcweir disconnectExternalListSource( ); 248cdf0e10cSrcweir } 249cdf0e10cSrcweir 250cdf0e10cSrcweir //--------------------------------------------------------------------- disconnectExternalListSource()251cdf0e10cSrcweir void OEntryListHelper::disconnectExternalListSource( ) 252cdf0e10cSrcweir { 253cdf0e10cSrcweir if ( m_xListSource.is() ) 254cdf0e10cSrcweir m_xListSource->removeListEntryListener( this ); 255cdf0e10cSrcweir 256cdf0e10cSrcweir m_xListSource.clear(); 257cdf0e10cSrcweir 258cdf0e10cSrcweir disconnectedExternalListSource(); 259cdf0e10cSrcweir } 260cdf0e10cSrcweir 261cdf0e10cSrcweir //--------------------------------------------------------------------- connectedExternalListSource()262cdf0e10cSrcweir void OEntryListHelper::connectedExternalListSource( ) 263cdf0e10cSrcweir { 264cdf0e10cSrcweir // nothing to do here 265cdf0e10cSrcweir } 266cdf0e10cSrcweir 267cdf0e10cSrcweir //--------------------------------------------------------------------- disconnectedExternalListSource()268cdf0e10cSrcweir void OEntryListHelper::disconnectedExternalListSource( ) 269cdf0e10cSrcweir { 270cdf0e10cSrcweir // nothing to do here 271cdf0e10cSrcweir } 272cdf0e10cSrcweir 273cdf0e10cSrcweir //--------------------------------------------------------------------- connectExternalListSource(const Reference<XListEntrySource> & _rxSource,ControlModelLock & _rInstanceLock)274cdf0e10cSrcweir void OEntryListHelper::connectExternalListSource( const Reference< XListEntrySource >& _rxSource, ControlModelLock& _rInstanceLock ) 275cdf0e10cSrcweir { 276cdf0e10cSrcweir OSL_ENSURE( !hasExternalListSource(), "OEntryListHelper::connectExternalListSource: only to be called if no external source is active!" ); 277cdf0e10cSrcweir OSL_ENSURE( _rxSource.is(), "OEntryListHelper::connectExternalListSource: invalid list source!" ); 278cdf0e10cSrcweir 279cdf0e10cSrcweir // remember it 280cdf0e10cSrcweir m_xListSource = _rxSource; 281cdf0e10cSrcweir 282cdf0e10cSrcweir // initially fill our item list 283cdf0e10cSrcweir if ( m_xListSource.is() ) 284cdf0e10cSrcweir { 285cdf0e10cSrcweir // be notified when the list changes ... 286cdf0e10cSrcweir m_xListSource->addListEntryListener( this ); 287cdf0e10cSrcweir 288cdf0e10cSrcweir m_aStringItems = m_xListSource->getAllListEntries( ); 289cdf0e10cSrcweir stringItemListChanged( _rInstanceLock ); 290cdf0e10cSrcweir 291cdf0e10cSrcweir // let derivees react on the new list source 292cdf0e10cSrcweir connectedExternalListSource(); 293cdf0e10cSrcweir } 294cdf0e10cSrcweir } 295cdf0e10cSrcweir 296cdf0e10cSrcweir //--------------------------------------------------------------------- convertNewListSourceProperty(Any & _rConvertedValue,Any & _rOldValue,const Any & _rValue)297cdf0e10cSrcweir sal_Bool OEntryListHelper::convertNewListSourceProperty( Any& _rConvertedValue, 298cdf0e10cSrcweir Any& _rOldValue, const Any& _rValue ) SAL_THROW( ( IllegalArgumentException ) ) 299cdf0e10cSrcweir { 300cdf0e10cSrcweir if ( hasExternalListSource() ) 301cdf0e10cSrcweir throw IllegalArgumentException( ); 302cdf0e10cSrcweir // TODO: error message 303cdf0e10cSrcweir 304cdf0e10cSrcweir return ::comphelper::tryPropertyValue( _rConvertedValue, _rOldValue, _rValue, m_aStringItems ); 305cdf0e10cSrcweir } 306cdf0e10cSrcweir 307cdf0e10cSrcweir //--------------------------------------------------------------------- setNewStringItemList(const::com::sun::star::uno::Any & _rValue,ControlModelLock & _rInstanceLock)308cdf0e10cSrcweir void OEntryListHelper::setNewStringItemList( const ::com::sun::star::uno::Any& _rValue, ControlModelLock& _rInstanceLock ) 309cdf0e10cSrcweir { 310cdf0e10cSrcweir OSL_PRECOND( !hasExternalListSource(), "OEntryListHelper::setNewStringItemList: this should never have survived convertNewListSourceProperty!" ); 311cdf0e10cSrcweir OSL_VERIFY( _rValue >>= m_aStringItems ); 312cdf0e10cSrcweir stringItemListChanged( _rInstanceLock ); 313cdf0e10cSrcweir } 314cdf0e10cSrcweir 315cdf0e10cSrcweir //......................................................................... 316cdf0e10cSrcweir } // namespace frm 317cdf0e10cSrcweir //......................................................................... 318