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