1*2a97ec55SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3*2a97ec55SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*2a97ec55SAndrew Rist * or more contributor license agreements. See the NOTICE file 5*2a97ec55SAndrew Rist * distributed with this work for additional information 6*2a97ec55SAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*2a97ec55SAndrew Rist * to you under the Apache License, Version 2.0 (the 8*2a97ec55SAndrew Rist * "License"); you may not use this file except in compliance 9*2a97ec55SAndrew Rist * with the License. You may obtain a copy of the License at 10cdf0e10cSrcweir * 11*2a97ec55SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12cdf0e10cSrcweir * 13*2a97ec55SAndrew Rist * Unless required by applicable law or agreed to in writing, 14*2a97ec55SAndrew Rist * software distributed under the License is distributed on an 15*2a97ec55SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*2a97ec55SAndrew Rist * KIND, either express or implied. See the License for the 17*2a97ec55SAndrew Rist * specific language governing permissions and limitations 18*2a97ec55SAndrew Rist * under the License. 19cdf0e10cSrcweir * 20*2a97ec55SAndrew Rist *************************************************************/ 21*2a97ec55SAndrew Rist 22*2a97ec55SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 25cdf0e10cSrcweir #include "precompiled_extensions.hxx" 26cdf0e10cSrcweir #include "browserlistbox.hxx" 27cdf0e10cSrcweir #ifndef EXTENSIONS_PROPRESID_HRC 28cdf0e10cSrcweir #include "propresid.hrc" 29cdf0e10cSrcweir #endif 30cdf0e10cSrcweir #include "proplinelistener.hxx" 31cdf0e10cSrcweir #include "propcontrolobserver.hxx" 32cdf0e10cSrcweir #include "linedescriptor.hxx" 33cdf0e10cSrcweir #include "inspectorhelpwindow.hxx" 34cdf0e10cSrcweir 35cdf0e10cSrcweir /** === begin UNO includes === **/ 36cdf0e10cSrcweir #include <com/sun/star/lang/DisposedException.hpp> 37cdf0e10cSrcweir #include <com/sun/star/lang/XComponent.hpp> 38cdf0e10cSrcweir #include <com/sun/star/inspection/PropertyControlType.hpp> 39cdf0e10cSrcweir /** === end UNO includes === **/ 40cdf0e10cSrcweir #include <tools/debug.hxx> 41cdf0e10cSrcweir #include <tools/diagnose_ex.h> 42cdf0e10cSrcweir #include <comphelper/asyncnotification.hxx> 43cdf0e10cSrcweir #include <cppuhelper/implbase1.hxx> 44cdf0e10cSrcweir #include <vcl/svapp.hxx> 45cdf0e10cSrcweir #include <vos/mutex.hxx> 46cdf0e10cSrcweir 47cdf0e10cSrcweir //............................................................................ 48cdf0e10cSrcweir namespace pcr 49cdf0e10cSrcweir { 50cdf0e10cSrcweir //............................................................................ 51cdf0e10cSrcweir 52cdf0e10cSrcweir #define FRAME_OFFSET 4 53cdf0e10cSrcweir // TODO: find out what this is really for ... and check if it does make sense in the new 54cdf0e10cSrcweir // browser environment 55cdf0e10cSrcweir #define LAYOUT_HELP_WINDOW_DISTANCE_APPFONT 3 56cdf0e10cSrcweir 57cdf0e10cSrcweir /** === begin UNO using === **/ 58cdf0e10cSrcweir using ::com::sun::star::uno::Any; 59cdf0e10cSrcweir using ::com::sun::star::uno::Exception; 60cdf0e10cSrcweir using ::com::sun::star::inspection::XPropertyControlContext; 61cdf0e10cSrcweir using ::com::sun::star::uno::Reference; 62cdf0e10cSrcweir using ::com::sun::star::inspection::XPropertyControl; 63cdf0e10cSrcweir using ::com::sun::star::uno::RuntimeException; 64cdf0e10cSrcweir using ::com::sun::star::lang::DisposedException; 65cdf0e10cSrcweir using ::com::sun::star::lang::XComponent; 66cdf0e10cSrcweir using ::com::sun::star::uno::UNO_QUERY; 67cdf0e10cSrcweir using ::com::sun::star::graphic::XGraphic; 68cdf0e10cSrcweir /** === end UNO using === **/ 69cdf0e10cSrcweir namespace PropertyControlType = ::com::sun::star::inspection::PropertyControlType; 70cdf0e10cSrcweir 71cdf0e10cSrcweir //================================================================== 72cdf0e10cSrcweir //= ControlEvent 73cdf0e10cSrcweir //================================================================== 74cdf0e10cSrcweir enum ControlEventType 75cdf0e10cSrcweir { 76cdf0e10cSrcweir FOCUS_GAINED, 77cdf0e10cSrcweir VALUE_CHANGED, 78cdf0e10cSrcweir ACTIVATE_NEXT 79cdf0e10cSrcweir }; 80cdf0e10cSrcweir 81cdf0e10cSrcweir struct ControlEvent : public ::comphelper::AnyEvent 82cdf0e10cSrcweir { 83cdf0e10cSrcweir Reference< XPropertyControl > xControl; 84cdf0e10cSrcweir ControlEventType eType; 85cdf0e10cSrcweir ControlEventpcr::ControlEvent86cdf0e10cSrcweir ControlEvent( const Reference< XPropertyControl >& _rxControl, ControlEventType _eType ) 87cdf0e10cSrcweir :xControl( _rxControl ) 88cdf0e10cSrcweir ,eType( _eType ) 89cdf0e10cSrcweir { 90cdf0e10cSrcweir } 91cdf0e10cSrcweir }; 92cdf0e10cSrcweir 93cdf0e10cSrcweir //================================================================== 94cdf0e10cSrcweir //= SharedNotifier 95cdf0e10cSrcweir //================================================================== 96cdf0e10cSrcweir class SharedNotifier 97cdf0e10cSrcweir { 98cdf0e10cSrcweir private: 99cdf0e10cSrcweir static ::osl::Mutex& getMutex(); 100cdf0e10cSrcweir static ::rtl::Reference< ::comphelper::AsyncEventNotifier > s_pNotifier; 101cdf0e10cSrcweir 102cdf0e10cSrcweir public: 103cdf0e10cSrcweir static const ::rtl::Reference< ::comphelper::AsyncEventNotifier >& 104cdf0e10cSrcweir getNotifier(); 105cdf0e10cSrcweir 106cdf0e10cSrcweir private: 107cdf0e10cSrcweir SharedNotifier(); // never implemented 108cdf0e10cSrcweir SharedNotifier( const SharedNotifier& ); // never implemented 109cdf0e10cSrcweir SharedNotifier& operator=( const SharedNotifier& ); // never implemented 110cdf0e10cSrcweir }; 111cdf0e10cSrcweir 112cdf0e10cSrcweir //------------------------------------------------------------------ 113cdf0e10cSrcweir ::rtl::Reference< ::comphelper::AsyncEventNotifier > SharedNotifier::s_pNotifier; 114cdf0e10cSrcweir 115cdf0e10cSrcweir //------------------------------------------------------------------ getMutex()116cdf0e10cSrcweir ::osl::Mutex& SharedNotifier::getMutex() 117cdf0e10cSrcweir { 118cdf0e10cSrcweir static ::osl::Mutex s_aMutex; 119cdf0e10cSrcweir return s_aMutex; 120cdf0e10cSrcweir } 121cdf0e10cSrcweir 122cdf0e10cSrcweir //------------------------------------------------------------------ getNotifier()123cdf0e10cSrcweir const ::rtl::Reference< ::comphelper::AsyncEventNotifier >& SharedNotifier::getNotifier() 124cdf0e10cSrcweir { 125cdf0e10cSrcweir ::osl::MutexGuard aGuard( getMutex() ); 126cdf0e10cSrcweir if ( !s_pNotifier.is() ) 127cdf0e10cSrcweir { 128cdf0e10cSrcweir s_pNotifier.set( new ::comphelper::AsyncEventNotifier ); 129cdf0e10cSrcweir s_pNotifier->create(); 130cdf0e10cSrcweir } 131cdf0e10cSrcweir return s_pNotifier; 132cdf0e10cSrcweir } 133cdf0e10cSrcweir 134cdf0e10cSrcweir //================================================================== 135cdf0e10cSrcweir //= PropertyControlContext_Impl 136cdf0e10cSrcweir //================================================================== 137cdf0e10cSrcweir /** implementation for of <type scope="com::sun::star::inspection">XPropertyControlContext</type> 138cdf0e10cSrcweir which forwards all events to a non-UNO version of this interface 139cdf0e10cSrcweir */ 140cdf0e10cSrcweir typedef ::cppu::WeakImplHelper1< XPropertyControlContext > PropertyControlContext_Impl_Base; 141cdf0e10cSrcweir class PropertyControlContext_Impl :public PropertyControlContext_Impl_Base 142cdf0e10cSrcweir ,public ::comphelper::IEventProcessor 143cdf0e10cSrcweir { 144cdf0e10cSrcweir public: 145cdf0e10cSrcweir enum NotifcationMode 146cdf0e10cSrcweir { 147cdf0e10cSrcweir eSynchronously, 148cdf0e10cSrcweir eAsynchronously 149cdf0e10cSrcweir }; 150cdf0e10cSrcweir 151cdf0e10cSrcweir private: 152cdf0e10cSrcweir IControlContext* m_pContext; 153cdf0e10cSrcweir NotifcationMode m_eMode; 154cdf0e10cSrcweir 155cdf0e10cSrcweir public: 156cdf0e10cSrcweir /** creates an instance 157cdf0e10cSrcweir @param _rContextImpl 158cdf0e10cSrcweir the instance to delegate events to 159cdf0e10cSrcweir */ 160cdf0e10cSrcweir PropertyControlContext_Impl( IControlContext& _rContextImpl ); 161cdf0e10cSrcweir 162cdf0e10cSrcweir /** disposes the context. 163cdf0e10cSrcweir 164cdf0e10cSrcweir When you call this method, all subsequent callbacks to the 165cdf0e10cSrcweir <type scope="com::sun::star::inspection">XPropertyControlContext</type> methods 166cdf0e10cSrcweir will throw a <type scope="com::sun::star::lang">DisposedException</type>. 167cdf0e10cSrcweir */ 168cdf0e10cSrcweir void SAL_CALL dispose(); 169cdf0e10cSrcweir 170cdf0e10cSrcweir /** sets the notification mode, so that notifications recieved from the controls are 171cdf0e10cSrcweir forwarded to our IControlContext either synchronously or asynchronously 172cdf0e10cSrcweir @param _eMode 173cdf0e10cSrcweir the new notification mode 174cdf0e10cSrcweir */ 175cdf0e10cSrcweir void setNotificationMode( NotifcationMode _eMode ); 176cdf0e10cSrcweir 177cdf0e10cSrcweir virtual void SAL_CALL acquire() throw(); 178cdf0e10cSrcweir virtual void SAL_CALL release() throw(); 179cdf0e10cSrcweir 180cdf0e10cSrcweir protected: 181cdf0e10cSrcweir ~PropertyControlContext_Impl(); 182cdf0e10cSrcweir 183cdf0e10cSrcweir // XPropertyControlObserver 184cdf0e10cSrcweir virtual void SAL_CALL focusGained( const Reference< XPropertyControl >& Control ) throw (RuntimeException); 185cdf0e10cSrcweir virtual void SAL_CALL valueChanged( const Reference< XPropertyControl >& Control ) throw (RuntimeException); 186cdf0e10cSrcweir // XPropertyControlContext 187cdf0e10cSrcweir virtual void SAL_CALL activateNextControl( const Reference< XPropertyControl >& CurrentControl ) throw (RuntimeException); 188cdf0e10cSrcweir 189cdf0e10cSrcweir // IEventProcessor 190cdf0e10cSrcweir virtual void processEvent( const ::comphelper::AnyEvent& _rEvent ); 191cdf0e10cSrcweir 192cdf0e10cSrcweir private: 193cdf0e10cSrcweir /** processes the given event, i.e. notifies it to our IControlContext 194cdf0e10cSrcweir @param _rEvent 195cdf0e10cSrcweir the event no notify 196cdf0e10cSrcweir @precond 197cdf0e10cSrcweir our mutex (well, the SolarMutex) is locked 198cdf0e10cSrcweir */ 199cdf0e10cSrcweir void impl_processEvent_throw( const ::comphelper::AnyEvent& _rEvent ); 200cdf0e10cSrcweir 201cdf0e10cSrcweir /** checks whether we're alive 202cdf0e10cSrcweir 203cdf0e10cSrcweir @throws DisposedException 204cdf0e10cSrcweir if the instance is already disposed 205cdf0e10cSrcweir */ 206cdf0e10cSrcweir void impl_checkAlive_throw() const; 207cdf0e10cSrcweir 208cdf0e10cSrcweir /** checks whether the instance is already disposed 209cdf0e10cSrcweir */ impl_isDisposed_nothrow() const210cdf0e10cSrcweir bool impl_isDisposed_nothrow() const { return m_pContext == NULL; } 211cdf0e10cSrcweir 212cdf0e10cSrcweir /** notifies the given event originating from the given control 213cdf0e10cSrcweir @throws DisposedException 214cdf0e10cSrcweir @param _rxControl 215cdf0e10cSrcweir @param _eType 216cdf0e10cSrcweir */ 217cdf0e10cSrcweir void impl_notify_throw( const Reference< XPropertyControl >& _rxControl, ControlEventType _eType ); 218cdf0e10cSrcweir }; 219cdf0e10cSrcweir 220cdf0e10cSrcweir //-------------------------------------------------------------------- PropertyControlContext_Impl(IControlContext & _rContextImpl)221cdf0e10cSrcweir PropertyControlContext_Impl::PropertyControlContext_Impl( IControlContext& _rContextImpl ) 222cdf0e10cSrcweir :m_pContext( &_rContextImpl ) 223cdf0e10cSrcweir ,m_eMode( eAsynchronously ) 224cdf0e10cSrcweir { 225cdf0e10cSrcweir } 226cdf0e10cSrcweir 227cdf0e10cSrcweir //-------------------------------------------------------------------- ~PropertyControlContext_Impl()228cdf0e10cSrcweir PropertyControlContext_Impl::~PropertyControlContext_Impl() 229cdf0e10cSrcweir { 230cdf0e10cSrcweir if ( !impl_isDisposed_nothrow() ) 231cdf0e10cSrcweir dispose(); 232cdf0e10cSrcweir } 233cdf0e10cSrcweir 234cdf0e10cSrcweir //-------------------------------------------------------------------- impl_checkAlive_throw() const235cdf0e10cSrcweir void PropertyControlContext_Impl::impl_checkAlive_throw() const 236cdf0e10cSrcweir { 237cdf0e10cSrcweir if ( impl_isDisposed_nothrow() ) 238cdf0e10cSrcweir throw DisposedException( ::rtl::OUString(), *const_cast< PropertyControlContext_Impl* >( this ) ); 239cdf0e10cSrcweir } 240cdf0e10cSrcweir 241cdf0e10cSrcweir //-------------------------------------------------------------------- dispose()242cdf0e10cSrcweir void SAL_CALL PropertyControlContext_Impl::dispose() 243cdf0e10cSrcweir { 244cdf0e10cSrcweir ::vos::OGuard aGuard( Application::GetSolarMutex() ); 245cdf0e10cSrcweir if ( impl_isDisposed_nothrow() ) 246cdf0e10cSrcweir return; 247cdf0e10cSrcweir 248cdf0e10cSrcweir SharedNotifier::getNotifier()->removeEventsForProcessor( this ); 249cdf0e10cSrcweir m_pContext = NULL; 250cdf0e10cSrcweir } 251cdf0e10cSrcweir 252cdf0e10cSrcweir //-------------------------------------------------------------------- setNotificationMode(NotifcationMode _eMode)253cdf0e10cSrcweir void PropertyControlContext_Impl::setNotificationMode( NotifcationMode _eMode ) 254cdf0e10cSrcweir { 255cdf0e10cSrcweir ::vos::OGuard aGuard( Application::GetSolarMutex() ); 256cdf0e10cSrcweir m_eMode = _eMode; 257cdf0e10cSrcweir } 258cdf0e10cSrcweir 259cdf0e10cSrcweir //-------------------------------------------------------------------- impl_notify_throw(const Reference<XPropertyControl> & _rxControl,ControlEventType _eType)260cdf0e10cSrcweir void PropertyControlContext_Impl::impl_notify_throw( const Reference< XPropertyControl >& _rxControl, ControlEventType _eType ) 261cdf0e10cSrcweir { 262cdf0e10cSrcweir ::comphelper::AnyEventRef pEvent; 263cdf0e10cSrcweir 264cdf0e10cSrcweir { 265cdf0e10cSrcweir ::vos::OGuard aGuard( Application::GetSolarMutex() ); 266cdf0e10cSrcweir impl_checkAlive_throw(); 267cdf0e10cSrcweir pEvent = new ControlEvent( _rxControl, _eType ); 268cdf0e10cSrcweir 269cdf0e10cSrcweir if ( m_eMode == eSynchronously ) 270cdf0e10cSrcweir { 271cdf0e10cSrcweir impl_processEvent_throw( *pEvent ); 272cdf0e10cSrcweir return; 273cdf0e10cSrcweir } 274cdf0e10cSrcweir } 275cdf0e10cSrcweir 276cdf0e10cSrcweir SharedNotifier::getNotifier()->addEvent( pEvent, this ); 277cdf0e10cSrcweir } 278cdf0e10cSrcweir 279cdf0e10cSrcweir //-------------------------------------------------------------------- focusGained(const Reference<XPropertyControl> & Control)280cdf0e10cSrcweir void SAL_CALL PropertyControlContext_Impl::focusGained( const Reference< XPropertyControl >& Control ) throw (RuntimeException) 281cdf0e10cSrcweir { 282cdf0e10cSrcweir DBG_TRACE( "PropertyControlContext_Impl: FOCUS_GAINED" ); 283cdf0e10cSrcweir impl_notify_throw( Control, FOCUS_GAINED ); 284cdf0e10cSrcweir } 285cdf0e10cSrcweir 286cdf0e10cSrcweir //-------------------------------------------------------------------- valueChanged(const Reference<XPropertyControl> & Control)287cdf0e10cSrcweir void SAL_CALL PropertyControlContext_Impl::valueChanged( const Reference< XPropertyControl >& Control ) throw (RuntimeException) 288cdf0e10cSrcweir { 289cdf0e10cSrcweir DBG_TRACE( "PropertyControlContext_Impl: VALUE_CHANGED" ); 290cdf0e10cSrcweir impl_notify_throw( Control, VALUE_CHANGED ); 291cdf0e10cSrcweir } 292cdf0e10cSrcweir 293cdf0e10cSrcweir //-------------------------------------------------------------------- activateNextControl(const Reference<XPropertyControl> & CurrentControl)294cdf0e10cSrcweir void SAL_CALL PropertyControlContext_Impl::activateNextControl( const Reference< XPropertyControl >& CurrentControl ) throw (RuntimeException) 295cdf0e10cSrcweir { 296cdf0e10cSrcweir DBG_TRACE( "PropertyControlContext_Impl: ACTIVATE_NEXT" ); 297cdf0e10cSrcweir impl_notify_throw( CurrentControl, ACTIVATE_NEXT ); 298cdf0e10cSrcweir } 299cdf0e10cSrcweir 300cdf0e10cSrcweir //-------------------------------------------------------------------- acquire()301cdf0e10cSrcweir void SAL_CALL PropertyControlContext_Impl::acquire() throw() 302cdf0e10cSrcweir { 303cdf0e10cSrcweir PropertyControlContext_Impl_Base::acquire(); 304cdf0e10cSrcweir } 305cdf0e10cSrcweir 306cdf0e10cSrcweir //-------------------------------------------------------------------- release()307cdf0e10cSrcweir void SAL_CALL PropertyControlContext_Impl::release() throw() 308cdf0e10cSrcweir { 309cdf0e10cSrcweir PropertyControlContext_Impl_Base::release(); 310cdf0e10cSrcweir } 311cdf0e10cSrcweir 312cdf0e10cSrcweir //-------------------------------------------------------------------- processEvent(const::comphelper::AnyEvent & _rEvent)313cdf0e10cSrcweir void PropertyControlContext_Impl::processEvent( const ::comphelper::AnyEvent& _rEvent ) 314cdf0e10cSrcweir { 315cdf0e10cSrcweir ::vos::OGuard aGuard( Application::GetSolarMutex() ); 316cdf0e10cSrcweir if ( impl_isDisposed_nothrow() ) 317cdf0e10cSrcweir return; 318cdf0e10cSrcweir 319cdf0e10cSrcweir try 320cdf0e10cSrcweir { 321cdf0e10cSrcweir impl_processEvent_throw( _rEvent ); 322cdf0e10cSrcweir } 323cdf0e10cSrcweir catch( const Exception& ) 324cdf0e10cSrcweir { 325cdf0e10cSrcweir // can't handle otherwise, since our caller (the notification thread) does not allow 326cdf0e10cSrcweir // for exceptions (it could itself abort only) 327cdf0e10cSrcweir DBG_UNHANDLED_EXCEPTION(); 328cdf0e10cSrcweir } 329cdf0e10cSrcweir } 330cdf0e10cSrcweir 331cdf0e10cSrcweir //-------------------------------------------------------------------- impl_processEvent_throw(const::comphelper::AnyEvent & _rEvent)332cdf0e10cSrcweir void PropertyControlContext_Impl::impl_processEvent_throw( const ::comphelper::AnyEvent& _rEvent ) 333cdf0e10cSrcweir { 334cdf0e10cSrcweir const ControlEvent& rControlEvent = static_cast< const ControlEvent& >( _rEvent ); 335cdf0e10cSrcweir switch ( rControlEvent.eType ) 336cdf0e10cSrcweir { 337cdf0e10cSrcweir case FOCUS_GAINED: 338cdf0e10cSrcweir DBG_TRACE( "PropertyControlContext_Impl::processEvent: FOCUS_GAINED" ); 339cdf0e10cSrcweir m_pContext->focusGained( rControlEvent.xControl ); 340cdf0e10cSrcweir break; 341cdf0e10cSrcweir case VALUE_CHANGED: 342cdf0e10cSrcweir DBG_TRACE( "PropertyControlContext_Impl::processEvent: VALUE_CHANGED" ); 343cdf0e10cSrcweir m_pContext->valueChanged( rControlEvent.xControl ); 344cdf0e10cSrcweir break; 345cdf0e10cSrcweir case ACTIVATE_NEXT: 346cdf0e10cSrcweir DBG_TRACE( "PropertyControlContext_Impl::processEvent: ACTIVATE_NEXT" ); 347cdf0e10cSrcweir m_pContext->activateNextControl( rControlEvent.xControl ); 348cdf0e10cSrcweir break; 349cdf0e10cSrcweir } 350cdf0e10cSrcweir } 351cdf0e10cSrcweir 352cdf0e10cSrcweir //================================================================== 353cdf0e10cSrcweir //= OBrowserListBox 354cdf0e10cSrcweir //================================================================== DBG_NAME(OBrowserListBox)355cdf0e10cSrcweir DBG_NAME(OBrowserListBox) 356cdf0e10cSrcweir //------------------------------------------------------------------ 357cdf0e10cSrcweir OBrowserListBox::OBrowserListBox( Window* pParent, WinBits nWinStyle) 358cdf0e10cSrcweir :Control(pParent, nWinStyle| WB_CLIPCHILDREN) 359cdf0e10cSrcweir ,m_aLinesPlayground(this,WB_DIALOGCONTROL | WB_CLIPCHILDREN) 360cdf0e10cSrcweir ,m_aVScroll(this,WB_VSCROLL|WB_REPEAT|WB_DRAG) 361cdf0e10cSrcweir ,m_pHelpWindow( new InspectorHelpWindow( this ) ) 362cdf0e10cSrcweir ,m_pLineListener(NULL) 363cdf0e10cSrcweir ,m_pControlObserver( NULL ) 364cdf0e10cSrcweir ,m_nYOffset(0) 365cdf0e10cSrcweir ,m_nCurrentPreferredHelpHeight(0) 366cdf0e10cSrcweir ,m_nTheNameSize(0) 367cdf0e10cSrcweir ,m_bIsActive(sal_False) 368cdf0e10cSrcweir ,m_bUpdate(sal_True) 369cdf0e10cSrcweir ,m_pControlContextImpl( new PropertyControlContext_Impl( *this ) ) 370cdf0e10cSrcweir { 371cdf0e10cSrcweir DBG_CTOR(OBrowserListBox,NULL); 372cdf0e10cSrcweir 373cdf0e10cSrcweir ListBox aListBox(this,WB_DROPDOWN); 374cdf0e10cSrcweir aListBox.SetPosSizePixel(Point(0,0),Size(100,100)); 375cdf0e10cSrcweir m_nRowHeight = (sal_uInt16)aListBox.GetSizePixel().Height()+2; 376cdf0e10cSrcweir SetBackground( pParent->GetBackground() ); 377cdf0e10cSrcweir m_aLinesPlayground.SetBackground( GetBackground() ); 378cdf0e10cSrcweir 379cdf0e10cSrcweir m_aLinesPlayground.SetPosPixel(Point(0,0)); 380cdf0e10cSrcweir m_aLinesPlayground.SetPaintTransparent(sal_True); 381cdf0e10cSrcweir m_aLinesPlayground.Show(); 382cdf0e10cSrcweir m_aVScroll.Hide(); 383cdf0e10cSrcweir m_aVScroll.SetScrollHdl(LINK(this, OBrowserListBox, ScrollHdl)); 384cdf0e10cSrcweir } 385cdf0e10cSrcweir 386cdf0e10cSrcweir //------------------------------------------------------------------ ~OBrowserListBox()387cdf0e10cSrcweir OBrowserListBox::~OBrowserListBox() 388cdf0e10cSrcweir { 389cdf0e10cSrcweir OSL_ENSURE( !IsModified(), "OBrowserListBox::~OBrowserListBox: still modified - should have been committed before!" ); 390cdf0e10cSrcweir // doing the commit here, while we, as well as our owner, as well as some other components, 391cdf0e10cSrcweir // are already "half dead" (means within their dtor) is potentially dangerous. 392cdf0e10cSrcweir // By definition, CommitModified has to be called (if necessary) before destruction 393cdf0e10cSrcweir // #105868# - 2002-12-13 - fs@openoffice.org 394cdf0e10cSrcweir 395cdf0e10cSrcweir m_pControlContextImpl->dispose(); 396cdf0e10cSrcweir m_pControlContextImpl.clear(); 397cdf0e10cSrcweir 398cdf0e10cSrcweir Hide(); 399cdf0e10cSrcweir Clear(); 400cdf0e10cSrcweir 401cdf0e10cSrcweir DBG_DTOR(OBrowserListBox,NULL); 402cdf0e10cSrcweir } 403cdf0e10cSrcweir 404cdf0e10cSrcweir //------------------------------------------------------------------ IsModified() const405cdf0e10cSrcweir sal_Bool OBrowserListBox::IsModified( ) const 406cdf0e10cSrcweir { 407cdf0e10cSrcweir sal_Bool bModified = sal_False; 408cdf0e10cSrcweir 409cdf0e10cSrcweir if ( m_bIsActive && m_xActiveControl.is() ) 410cdf0e10cSrcweir bModified = m_xActiveControl->isModified(); 411cdf0e10cSrcweir 412cdf0e10cSrcweir return bModified; 413cdf0e10cSrcweir } 414cdf0e10cSrcweir 415cdf0e10cSrcweir //------------------------------------------------------------------ CommitModified()416cdf0e10cSrcweir void OBrowserListBox::CommitModified( ) 417cdf0e10cSrcweir { 418cdf0e10cSrcweir if ( IsModified() && m_xActiveControl.is() ) 419cdf0e10cSrcweir { 420cdf0e10cSrcweir // for the time of this commit, notify all events synchronously 421cdf0e10cSrcweir // #i63814# / 2006-03-31 / frank.schoenheit@sun.com 422cdf0e10cSrcweir m_pControlContextImpl->setNotificationMode( PropertyControlContext_Impl::eSynchronously ); 423cdf0e10cSrcweir try 424cdf0e10cSrcweir { 425cdf0e10cSrcweir m_xActiveControl->notifyModifiedValue(); 426cdf0e10cSrcweir } 427cdf0e10cSrcweir catch( const Exception& ) 428cdf0e10cSrcweir { 429cdf0e10cSrcweir DBG_UNHANDLED_EXCEPTION(); 430cdf0e10cSrcweir } 431cdf0e10cSrcweir m_pControlContextImpl->setNotificationMode( PropertyControlContext_Impl::eAsynchronously ); 432cdf0e10cSrcweir } 433cdf0e10cSrcweir } 434cdf0e10cSrcweir 435cdf0e10cSrcweir //------------------------------------------------------------------ ActivateListBox(sal_Bool _bActive)436cdf0e10cSrcweir void OBrowserListBox::ActivateListBox(sal_Bool _bActive) 437cdf0e10cSrcweir { 438cdf0e10cSrcweir m_bIsActive = _bActive; 439cdf0e10cSrcweir if (m_bIsActive) 440cdf0e10cSrcweir { 441cdf0e10cSrcweir // TODO: what's the sense of this? 442cdf0e10cSrcweir m_aVScroll.SetThumbPos(100); 443cdf0e10cSrcweir MoveThumbTo(0); 444cdf0e10cSrcweir Resize(); 445cdf0e10cSrcweir } 446cdf0e10cSrcweir } 447cdf0e10cSrcweir 448cdf0e10cSrcweir //------------------------------------------------------------------ impl_getPrefererredHelpHeight()449cdf0e10cSrcweir long OBrowserListBox::impl_getPrefererredHelpHeight() 450cdf0e10cSrcweir { 451cdf0e10cSrcweir return HasHelpSection() ? m_pHelpWindow->GetOptimalHeightPixel() : 0; 452cdf0e10cSrcweir } 453cdf0e10cSrcweir 454cdf0e10cSrcweir //------------------------------------------------------------------ Resize()455cdf0e10cSrcweir void OBrowserListBox::Resize() 456cdf0e10cSrcweir { 457cdf0e10cSrcweir Rectangle aPlayground( Point( 0, 0 ), GetOutputSizePixel() ); 458cdf0e10cSrcweir Size aHelpWindowDistance( LogicToPixel( Size( 0, LAYOUT_HELP_WINDOW_DISTANCE_APPFONT ), MAP_APPFONT ) ); 459cdf0e10cSrcweir 460cdf0e10cSrcweir long nHelpWindowHeight = m_nCurrentPreferredHelpHeight = impl_getPrefererredHelpHeight(); 461cdf0e10cSrcweir bool bPositionHelpWindow = ( nHelpWindowHeight != 0 ); 462cdf0e10cSrcweir 463cdf0e10cSrcweir Rectangle aLinesArea( aPlayground ); 464cdf0e10cSrcweir if ( bPositionHelpWindow ) 465cdf0e10cSrcweir { 466cdf0e10cSrcweir aLinesArea.Bottom() -= nHelpWindowHeight; 467cdf0e10cSrcweir aLinesArea.Bottom() -= aHelpWindowDistance.Height(); 468cdf0e10cSrcweir } 469cdf0e10cSrcweir m_aLinesPlayground.SetPosSizePixel( aLinesArea.TopLeft(), aLinesArea.GetSize() ); 470cdf0e10cSrcweir 471cdf0e10cSrcweir UpdateVScroll(); 472cdf0e10cSrcweir 473cdf0e10cSrcweir sal_Bool bNeedScrollbar = m_aOrderedLines.size() > (sal_uInt32)CalcVisibleLines(); 474cdf0e10cSrcweir if ( !bNeedScrollbar ) 475cdf0e10cSrcweir { 476cdf0e10cSrcweir if ( m_aVScroll.IsVisible() ) 477cdf0e10cSrcweir m_aVScroll.Hide(); 478cdf0e10cSrcweir // scroll to top 479cdf0e10cSrcweir m_nYOffset = 0; 480cdf0e10cSrcweir m_aVScroll.SetThumbPos( 0 ); 481cdf0e10cSrcweir } 482cdf0e10cSrcweir else 483cdf0e10cSrcweir { 484cdf0e10cSrcweir Size aVScrollSize( m_aVScroll.GetSizePixel() ); 485cdf0e10cSrcweir 486cdf0e10cSrcweir // adjust the playground's width 487cdf0e10cSrcweir aLinesArea.Right() -= aVScrollSize.Width(); 488cdf0e10cSrcweir m_aLinesPlayground.SetPosSizePixel( aLinesArea.TopLeft(), aLinesArea.GetSize() ); 489cdf0e10cSrcweir 490cdf0e10cSrcweir // position the scrollbar 491cdf0e10cSrcweir aVScrollSize.Height() = aLinesArea.GetHeight(); 492cdf0e10cSrcweir Point aVScrollPos( aLinesArea.GetWidth(), 0 ); 493cdf0e10cSrcweir m_aVScroll.SetPosSizePixel( aVScrollPos, aVScrollSize ); 494cdf0e10cSrcweir } 495cdf0e10cSrcweir 496cdf0e10cSrcweir for ( sal_uInt16 i = 0; i < m_aOrderedLines.size(); ++i ) 497cdf0e10cSrcweir m_aOutOfDateLines.insert( i ); 498cdf0e10cSrcweir 499cdf0e10cSrcweir // repaint 500cdf0e10cSrcweir EnablePaint(sal_False); 501cdf0e10cSrcweir UpdatePlayGround(); 502cdf0e10cSrcweir EnablePaint(sal_True); 503cdf0e10cSrcweir 504cdf0e10cSrcweir // show the scrollbar 505cdf0e10cSrcweir if ( bNeedScrollbar ) 506cdf0e10cSrcweir m_aVScroll.Show(); 507cdf0e10cSrcweir 508cdf0e10cSrcweir // position the help window 509cdf0e10cSrcweir if ( bPositionHelpWindow ) 510cdf0e10cSrcweir { 511cdf0e10cSrcweir Rectangle aHelpArea( aPlayground ); 512cdf0e10cSrcweir aHelpArea.Top() = aLinesArea.Bottom() + aHelpWindowDistance.Height(); 513cdf0e10cSrcweir m_pHelpWindow->SetPosSizePixel( aHelpArea.TopLeft(), aHelpArea.GetSize() ); 514cdf0e10cSrcweir } 515cdf0e10cSrcweir } 516cdf0e10cSrcweir 517cdf0e10cSrcweir //------------------------------------------------------------------ SetListener(IPropertyLineListener * _pListener)518cdf0e10cSrcweir void OBrowserListBox::SetListener( IPropertyLineListener* _pListener ) 519cdf0e10cSrcweir { 520cdf0e10cSrcweir m_pLineListener = _pListener; 521cdf0e10cSrcweir } 522cdf0e10cSrcweir 523cdf0e10cSrcweir //------------------------------------------------------------------ SetObserver(IPropertyControlObserver * _pObserver)524cdf0e10cSrcweir void OBrowserListBox::SetObserver( IPropertyControlObserver* _pObserver ) 525cdf0e10cSrcweir { 526cdf0e10cSrcweir m_pControlObserver = _pObserver; 527cdf0e10cSrcweir } 528cdf0e10cSrcweir 529cdf0e10cSrcweir //------------------------------------------------------------------ EnableHelpSection(bool _bEnable)530cdf0e10cSrcweir void OBrowserListBox::EnableHelpSection( bool _bEnable ) 531cdf0e10cSrcweir { 532cdf0e10cSrcweir m_pHelpWindow->Show( _bEnable ); 533cdf0e10cSrcweir Resize(); 534cdf0e10cSrcweir } 535cdf0e10cSrcweir 536cdf0e10cSrcweir //------------------------------------------------------------------ HasHelpSection() const537cdf0e10cSrcweir bool OBrowserListBox::HasHelpSection() const 538cdf0e10cSrcweir { 539cdf0e10cSrcweir return m_pHelpWindow->IsVisible(); 540cdf0e10cSrcweir } 541cdf0e10cSrcweir 542cdf0e10cSrcweir //------------------------------------------------------------------ SetHelpText(const::rtl::OUString & _rHelpText)543cdf0e10cSrcweir void OBrowserListBox::SetHelpText( const ::rtl::OUString& _rHelpText ) 544cdf0e10cSrcweir { 545cdf0e10cSrcweir OSL_ENSURE( HasHelpSection(), "OBrowserListBox::SetHelpText: help section not visible!" ); 546cdf0e10cSrcweir m_pHelpWindow->SetText( _rHelpText ); 547cdf0e10cSrcweir if ( m_nCurrentPreferredHelpHeight != impl_getPrefererredHelpHeight() ) 548cdf0e10cSrcweir Resize(); 549cdf0e10cSrcweir } 550cdf0e10cSrcweir 551cdf0e10cSrcweir //------------------------------------------------------------------ SetHelpLineLimites(sal_Int32 _nMinLines,sal_Int32 _nMaxLines)552cdf0e10cSrcweir void OBrowserListBox::SetHelpLineLimites( sal_Int32 _nMinLines, sal_Int32 _nMaxLines ) 553cdf0e10cSrcweir { 554cdf0e10cSrcweir m_pHelpWindow->SetLimits( _nMinLines, _nMaxLines ); 555cdf0e10cSrcweir } 556cdf0e10cSrcweir 557cdf0e10cSrcweir //------------------------------------------------------------------ CalcVisibleLines()558cdf0e10cSrcweir sal_uInt16 OBrowserListBox::CalcVisibleLines() 559cdf0e10cSrcweir { 560cdf0e10cSrcweir Size aSize(m_aLinesPlayground.GetOutputSizePixel()); 561cdf0e10cSrcweir sal_uInt16 nResult = 0; 562cdf0e10cSrcweir if (0 != m_nRowHeight) 563cdf0e10cSrcweir nResult = (sal_uInt16) aSize.Height()/m_nRowHeight; 564cdf0e10cSrcweir 565cdf0e10cSrcweir return nResult; 566cdf0e10cSrcweir } 567cdf0e10cSrcweir 568cdf0e10cSrcweir //------------------------------------------------------------------ UpdateVScroll()569cdf0e10cSrcweir void OBrowserListBox::UpdateVScroll() 570cdf0e10cSrcweir { 571cdf0e10cSrcweir sal_uInt16 nLines = CalcVisibleLines(); 572cdf0e10cSrcweir m_aVScroll.SetPageSize(nLines-1); 573cdf0e10cSrcweir m_aVScroll.SetVisibleSize(nLines-1); 574cdf0e10cSrcweir 575cdf0e10cSrcweir size_t nCount = m_aLines.size(); 576cdf0e10cSrcweir if (nCount>0) 577cdf0e10cSrcweir { 578cdf0e10cSrcweir m_aVScroll.SetRange(Range(0,nCount-1)); 579cdf0e10cSrcweir m_nYOffset = -m_aVScroll.GetThumbPos()*m_nRowHeight; 580cdf0e10cSrcweir } 581cdf0e10cSrcweir else 582cdf0e10cSrcweir { 583cdf0e10cSrcweir m_aVScroll.SetRange(Range(0,0)); 584cdf0e10cSrcweir m_nYOffset = 0; 585cdf0e10cSrcweir } 586cdf0e10cSrcweir } 587cdf0e10cSrcweir 588cdf0e10cSrcweir //------------------------------------------------------------------ PositionLine(sal_uInt16 _nIndex)589cdf0e10cSrcweir void OBrowserListBox::PositionLine( sal_uInt16 _nIndex ) 590cdf0e10cSrcweir { 591cdf0e10cSrcweir Size aSize(m_aLinesPlayground.GetOutputSizePixel()); 592cdf0e10cSrcweir Point aPos(0, m_nYOffset); 593cdf0e10cSrcweir 594cdf0e10cSrcweir aSize.Height() = m_nRowHeight; 595cdf0e10cSrcweir 596cdf0e10cSrcweir aPos.Y() += _nIndex * m_nRowHeight; 597cdf0e10cSrcweir 598cdf0e10cSrcweir if ( _nIndex < m_aOrderedLines.size() ) 599cdf0e10cSrcweir { 600cdf0e10cSrcweir m_aOrderedLines[ _nIndex ]->second.pLine->SetPosSizePixel( aPos, aSize ); 601cdf0e10cSrcweir 602cdf0e10cSrcweir m_aOrderedLines[ _nIndex ]->second.pLine->SetTitleWidth( m_nTheNameSize + 2 * FRAME_OFFSET ); 603cdf0e10cSrcweir 604cdf0e10cSrcweir // show the line if necessary 605cdf0e10cSrcweir if ( !m_aOrderedLines[ _nIndex ]->second.pLine->IsVisible() ) 606cdf0e10cSrcweir m_aOrderedLines[ _nIndex ]->second.pLine->Show(); 607cdf0e10cSrcweir } 608cdf0e10cSrcweir } 609cdf0e10cSrcweir 610cdf0e10cSrcweir //------------------------------------------------------------------ UpdatePosNSize()611cdf0e10cSrcweir void OBrowserListBox::UpdatePosNSize() 612cdf0e10cSrcweir { 613cdf0e10cSrcweir for ( ::std::set< sal_uInt16 >::const_iterator aLoop = m_aOutOfDateLines.begin(); 614cdf0e10cSrcweir aLoop != m_aOutOfDateLines.end(); 615cdf0e10cSrcweir ++aLoop 616cdf0e10cSrcweir ) 617cdf0e10cSrcweir { 618cdf0e10cSrcweir DBG_ASSERT( *aLoop < m_aOrderedLines.size(), "OBrowserListBox::UpdatePosNSize: invalid line index!" ); 619cdf0e10cSrcweir if ( *aLoop < m_aOrderedLines.size() ) 620cdf0e10cSrcweir PositionLine( *aLoop ); 621cdf0e10cSrcweir } 622cdf0e10cSrcweir m_aOutOfDateLines.clear(); 623cdf0e10cSrcweir } 624cdf0e10cSrcweir 625cdf0e10cSrcweir //------------------------------------------------------------------ UpdatePlayGround()626cdf0e10cSrcweir void OBrowserListBox::UpdatePlayGround() 627cdf0e10cSrcweir { 628cdf0e10cSrcweir sal_Int32 nThumbPos = m_aVScroll.GetThumbPos(); 629cdf0e10cSrcweir sal_Int32 nLines = CalcVisibleLines(); 630cdf0e10cSrcweir 631cdf0e10cSrcweir sal_uInt16 nEnd = (sal_uInt16)(nThumbPos + nLines); 632cdf0e10cSrcweir if (nEnd >= m_aOrderedLines.size()) 633cdf0e10cSrcweir nEnd = (sal_uInt16)m_aOrderedLines.size()-1; 634cdf0e10cSrcweir 635cdf0e10cSrcweir if ( !m_aOrderedLines.empty() ) 636cdf0e10cSrcweir { 637cdf0e10cSrcweir for ( sal_uInt16 i = (sal_uInt16)nThumbPos; i <= nEnd; ++i ) 638cdf0e10cSrcweir m_aOutOfDateLines.insert( i ); 639cdf0e10cSrcweir UpdatePosNSize(); 640cdf0e10cSrcweir } 641cdf0e10cSrcweir } 642cdf0e10cSrcweir 643cdf0e10cSrcweir //------------------------------------------------------------------ UpdateAll()644cdf0e10cSrcweir void OBrowserListBox::UpdateAll() 645cdf0e10cSrcweir { 646cdf0e10cSrcweir Resize(); 647cdf0e10cSrcweir } 648cdf0e10cSrcweir 649cdf0e10cSrcweir //------------------------------------------------------------------ DisableUpdate()650cdf0e10cSrcweir void OBrowserListBox::DisableUpdate() 651cdf0e10cSrcweir { 652cdf0e10cSrcweir m_bUpdate = sal_False; 653cdf0e10cSrcweir } 654cdf0e10cSrcweir 655cdf0e10cSrcweir //------------------------------------------------------------------ EnableUpdate()656cdf0e10cSrcweir void OBrowserListBox::EnableUpdate() 657cdf0e10cSrcweir { 658cdf0e10cSrcweir m_bUpdate = sal_True; 659cdf0e10cSrcweir UpdateAll(); 660cdf0e10cSrcweir } 661cdf0e10cSrcweir 662cdf0e10cSrcweir //------------------------------------------------------------------ SetPropertyValue(const::rtl::OUString & _rEntryName,const Any & _rValue,bool _bUnknownValue)663cdf0e10cSrcweir void OBrowserListBox::SetPropertyValue(const ::rtl::OUString& _rEntryName, const Any& _rValue, bool _bUnknownValue ) 664cdf0e10cSrcweir { 665cdf0e10cSrcweir ListBoxLines::iterator line = m_aLines.find( _rEntryName ); 666cdf0e10cSrcweir if ( line != m_aLines.end() ) 667cdf0e10cSrcweir { 668cdf0e10cSrcweir if ( _bUnknownValue ) 669cdf0e10cSrcweir { 670cdf0e10cSrcweir Reference< XPropertyControl > xControl( line->second.pLine->getControl() ); 671cdf0e10cSrcweir OSL_ENSURE( xControl.is(), "OBrowserListBox::SetPropertyValue: illegal control!" ); 672cdf0e10cSrcweir if ( xControl.is() ) 673cdf0e10cSrcweir xControl->setValue( Any() ); 674cdf0e10cSrcweir } 675cdf0e10cSrcweir else 676cdf0e10cSrcweir impl_setControlAsPropertyValue( line->second, _rValue ); 677cdf0e10cSrcweir } 678cdf0e10cSrcweir } 679cdf0e10cSrcweir 680cdf0e10cSrcweir //------------------------------------------------------------------------ GetPropertyPos(const::rtl::OUString & _rEntryName) const681cdf0e10cSrcweir sal_uInt16 OBrowserListBox::GetPropertyPos( const ::rtl::OUString& _rEntryName ) const 682cdf0e10cSrcweir { 683cdf0e10cSrcweir sal_uInt16 nRet = LISTBOX_ENTRY_NOTFOUND; 684cdf0e10cSrcweir for ( OrderedListBoxLines::const_iterator linePos = m_aOrderedLines.begin(); 685cdf0e10cSrcweir linePos != m_aOrderedLines.end(); 686cdf0e10cSrcweir ++linePos 687cdf0e10cSrcweir ) 688cdf0e10cSrcweir { 689cdf0e10cSrcweir if ( (*linePos)->first == _rEntryName ) 690cdf0e10cSrcweir { 691cdf0e10cSrcweir nRet = (sal_uInt16)( linePos - m_aOrderedLines.begin() ); 692cdf0e10cSrcweir break; 693cdf0e10cSrcweir } 694cdf0e10cSrcweir } 695cdf0e10cSrcweir 696cdf0e10cSrcweir return nRet; 697cdf0e10cSrcweir } 698cdf0e10cSrcweir 699cdf0e10cSrcweir //------------------------------------------------------------------------ impl_getBrowserLineForName(const::rtl::OUString & _rEntryName,BrowserLinePointer & _out_rpLine) const700cdf0e10cSrcweir bool OBrowserListBox::impl_getBrowserLineForName( const ::rtl::OUString& _rEntryName, BrowserLinePointer& _out_rpLine ) const 701cdf0e10cSrcweir { 702cdf0e10cSrcweir ListBoxLines::const_iterator line = m_aLines.find( _rEntryName ); 703cdf0e10cSrcweir if ( line != m_aLines.end() ) 704cdf0e10cSrcweir _out_rpLine = line->second.pLine; 705cdf0e10cSrcweir else 706cdf0e10cSrcweir _out_rpLine.reset(); 707cdf0e10cSrcweir return ( NULL != _out_rpLine.get() ); 708cdf0e10cSrcweir } 709cdf0e10cSrcweir 710cdf0e10cSrcweir //------------------------------------------------------------------------ EnablePropertyControls(const::rtl::OUString & _rEntryName,sal_Int16 _nControls,bool _bEnable)711cdf0e10cSrcweir void OBrowserListBox::EnablePropertyControls( const ::rtl::OUString& _rEntryName, sal_Int16 _nControls, bool _bEnable ) 712cdf0e10cSrcweir { 713cdf0e10cSrcweir BrowserLinePointer pLine; 714cdf0e10cSrcweir if ( impl_getBrowserLineForName( _rEntryName, pLine ) ) 715cdf0e10cSrcweir pLine->EnablePropertyControls( _nControls, _bEnable ); 716cdf0e10cSrcweir } 717cdf0e10cSrcweir 718cdf0e10cSrcweir //------------------------------------------------------------------------ EnablePropertyLine(const::rtl::OUString & _rEntryName,bool _bEnable)719cdf0e10cSrcweir void OBrowserListBox::EnablePropertyLine( const ::rtl::OUString& _rEntryName, bool _bEnable ) 720cdf0e10cSrcweir { 721cdf0e10cSrcweir BrowserLinePointer pLine; 722cdf0e10cSrcweir if ( impl_getBrowserLineForName( _rEntryName, pLine ) ) 723cdf0e10cSrcweir pLine->EnablePropertyLine( _bEnable ); 724cdf0e10cSrcweir } 725cdf0e10cSrcweir 726cdf0e10cSrcweir //------------------------------------------------------------------------ GetPropertyControl(const::rtl::OUString & _rEntryName)727cdf0e10cSrcweir Reference< XPropertyControl > OBrowserListBox::GetPropertyControl( const ::rtl::OUString& _rEntryName ) 728cdf0e10cSrcweir { 729cdf0e10cSrcweir BrowserLinePointer pLine; 730cdf0e10cSrcweir if ( impl_getBrowserLineForName( _rEntryName, pLine ) ) 731cdf0e10cSrcweir return pLine->getControl(); 732cdf0e10cSrcweir return NULL; 733cdf0e10cSrcweir } 734cdf0e10cSrcweir 735cdf0e10cSrcweir //------------------------------------------------------------------ InsertEntry(const OLineDescriptor & _rPropertyData,sal_uInt16 _nPos)736cdf0e10cSrcweir sal_uInt16 OBrowserListBox::InsertEntry(const OLineDescriptor& _rPropertyData, sal_uInt16 _nPos) 737cdf0e10cSrcweir { 738cdf0e10cSrcweir // create a new line 739cdf0e10cSrcweir BrowserLinePointer pBrowserLine( new OBrowserLine( _rPropertyData.sName, &m_aLinesPlayground ) ); 740cdf0e10cSrcweir 741cdf0e10cSrcweir ListBoxLine aNewLine( pBrowserLine, _rPropertyData.xPropertyHandler ); 742cdf0e10cSrcweir ::std::pair< ListBoxLines::iterator, bool > insertPoint = 743cdf0e10cSrcweir m_aLines.insert( ListBoxLines::value_type( _rPropertyData.sName, aNewLine ) ); 744cdf0e10cSrcweir OSL_ENSURE( insertPoint.second, "OBrowserListBox::InsertEntry: already have another line for this name!" ); 745cdf0e10cSrcweir 746cdf0e10cSrcweir sal_uInt16 nInsertPos = _nPos; 747cdf0e10cSrcweir if ( nInsertPos > m_aOrderedLines.size() ) 748cdf0e10cSrcweir nInsertPos = EDITOR_LIST_APPEND; 749cdf0e10cSrcweir if ( EDITOR_LIST_APPEND == nInsertPos ) 750cdf0e10cSrcweir { 751cdf0e10cSrcweir nInsertPos = (sal_uInt16)m_aOrderedLines.size(); 752cdf0e10cSrcweir m_aOrderedLines.push_back( insertPoint.first ); 753cdf0e10cSrcweir } 754cdf0e10cSrcweir else 755cdf0e10cSrcweir m_aOrderedLines.insert( m_aOrderedLines.begin() + nInsertPos, insertPoint.first ); 756cdf0e10cSrcweir 757cdf0e10cSrcweir pBrowserLine->SetTitleWidth(m_nTheNameSize); 758cdf0e10cSrcweir if (m_bUpdate) 759cdf0e10cSrcweir { 760cdf0e10cSrcweir UpdateVScroll(); 761cdf0e10cSrcweir Invalidate(); 762cdf0e10cSrcweir } 763cdf0e10cSrcweir 764cdf0e10cSrcweir // initialize the entry 765cdf0e10cSrcweir ChangeEntry(_rPropertyData, nInsertPos); 766cdf0e10cSrcweir 767cdf0e10cSrcweir // update the positions of possibly affected lines 768cdf0e10cSrcweir sal_uInt16 nUpdatePos = nInsertPos; 769cdf0e10cSrcweir while ( nUpdatePos < m_aOrderedLines.size() ) 770cdf0e10cSrcweir m_aOutOfDateLines.insert( nUpdatePos++ ); 771cdf0e10cSrcweir UpdatePosNSize( ); 772cdf0e10cSrcweir 773cdf0e10cSrcweir return nInsertPos; 774cdf0e10cSrcweir } 775cdf0e10cSrcweir 776cdf0e10cSrcweir //------------------------------------------------------------------ GetMinimumWidth()777cdf0e10cSrcweir sal_Int32 OBrowserListBox::GetMinimumWidth() 778cdf0e10cSrcweir { 779cdf0e10cSrcweir return m_nTheNameSize + 2 * FRAME_OFFSET + (m_nRowHeight - 4) * 8; 780cdf0e10cSrcweir } 781cdf0e10cSrcweir 782cdf0e10cSrcweir //------------------------------------------------------------------ GetMinimumHeight()783cdf0e10cSrcweir sal_Int32 OBrowserListBox::GetMinimumHeight() 784cdf0e10cSrcweir { 785cdf0e10cSrcweir // assume that we want to display 5 rows, at least 786cdf0e10cSrcweir sal_Int32 nMinHeight = m_nRowHeight * 5; 787cdf0e10cSrcweir 788cdf0e10cSrcweir if ( HasHelpSection() ) 789cdf0e10cSrcweir { 790cdf0e10cSrcweir Size aHelpWindowDistance( LogicToPixel( Size( 0, LAYOUT_HELP_WINDOW_DISTANCE_APPFONT ), MAP_APPFONT ) ); 791cdf0e10cSrcweir nMinHeight += aHelpWindowDistance.Height(); 792cdf0e10cSrcweir 793cdf0e10cSrcweir nMinHeight += m_pHelpWindow->GetMinimalHeightPixel(); 794cdf0e10cSrcweir } 795cdf0e10cSrcweir 796cdf0e10cSrcweir return nMinHeight; 797cdf0e10cSrcweir } 798cdf0e10cSrcweir 799cdf0e10cSrcweir //------------------------------------------------------------------ ShowEntry(sal_uInt16 _nPos)800cdf0e10cSrcweir void OBrowserListBox::ShowEntry(sal_uInt16 _nPos) 801cdf0e10cSrcweir { 802cdf0e10cSrcweir if ( _nPos < m_aOrderedLines.size() ) 803cdf0e10cSrcweir { 804cdf0e10cSrcweir sal_Int32 nThumbPos = m_aVScroll.GetThumbPos(); 805cdf0e10cSrcweir 806cdf0e10cSrcweir if (_nPos < nThumbPos) 807cdf0e10cSrcweir MoveThumbTo(_nPos); 808cdf0e10cSrcweir else 809cdf0e10cSrcweir { 810cdf0e10cSrcweir sal_Int32 nLines = CalcVisibleLines(); 811cdf0e10cSrcweir if (_nPos >= nThumbPos + nLines) 812cdf0e10cSrcweir MoveThumbTo(_nPos - nLines + 1); 813cdf0e10cSrcweir } 814cdf0e10cSrcweir } 815cdf0e10cSrcweir 816cdf0e10cSrcweir } 817cdf0e10cSrcweir 818cdf0e10cSrcweir //------------------------------------------------------------------ MoveThumbTo(sal_Int32 _nNewThumbPos)819cdf0e10cSrcweir void OBrowserListBox::MoveThumbTo(sal_Int32 _nNewThumbPos) 820cdf0e10cSrcweir { 821cdf0e10cSrcweir // disable painting to prevent flicker 822cdf0e10cSrcweir m_aLinesPlayground.EnablePaint(sal_False); 823cdf0e10cSrcweir 824cdf0e10cSrcweir sal_Int32 nDelta = _nNewThumbPos - m_aVScroll.GetThumbPos(); 825cdf0e10cSrcweir // adjust the scrollbar 826cdf0e10cSrcweir m_aVScroll.SetThumbPos(_nNewThumbPos); 827cdf0e10cSrcweir sal_Int32 nThumbPos = _nNewThumbPos; 828cdf0e10cSrcweir 829cdf0e10cSrcweir m_nYOffset = -m_aVScroll.GetThumbPos() * m_nRowHeight; 830cdf0e10cSrcweir 831cdf0e10cSrcweir sal_Int32 nLines = CalcVisibleLines(); 832cdf0e10cSrcweir sal_uInt16 nEnd = (sal_uInt16)(nThumbPos + nLines); 833cdf0e10cSrcweir 834cdf0e10cSrcweir m_aLinesPlayground.Scroll(0, -nDelta * m_nRowHeight, SCROLL_CHILDREN); 835cdf0e10cSrcweir 836cdf0e10cSrcweir if (1 == nDelta) 837cdf0e10cSrcweir { 838cdf0e10cSrcweir // TODO: what's the sense of this two PositionLines? Why not just one call? 839cdf0e10cSrcweir PositionLine(nEnd-1); 840cdf0e10cSrcweir PositionLine(nEnd); 841cdf0e10cSrcweir } 842cdf0e10cSrcweir else if (-1 == nDelta) 843cdf0e10cSrcweir { 844cdf0e10cSrcweir PositionLine((sal_uInt16)nThumbPos); 845cdf0e10cSrcweir } 846cdf0e10cSrcweir else if (0 != nDelta) 847cdf0e10cSrcweir { 848cdf0e10cSrcweir UpdatePlayGround(); 849cdf0e10cSrcweir } 850cdf0e10cSrcweir 851cdf0e10cSrcweir m_aLinesPlayground.EnablePaint(sal_True); 852cdf0e10cSrcweir m_aLinesPlayground.Invalidate(INVALIDATE_CHILDREN); 853cdf0e10cSrcweir } 854cdf0e10cSrcweir 855cdf0e10cSrcweir //------------------------------------------------------------------ IMPL_LINK(OBrowserListBox,ScrollHdl,ScrollBar *,_pScrollBar)856cdf0e10cSrcweir IMPL_LINK(OBrowserListBox, ScrollHdl, ScrollBar*, _pScrollBar ) 857cdf0e10cSrcweir { 858cdf0e10cSrcweir DBG_ASSERT(_pScrollBar == &m_aVScroll, "OBrowserListBox::ScrollHdl: where does this come from?"); 859cdf0e10cSrcweir (void)_pScrollBar; 860cdf0e10cSrcweir 861cdf0e10cSrcweir // disable painting to prevent flicker 862cdf0e10cSrcweir m_aLinesPlayground.EnablePaint(sal_False); 863cdf0e10cSrcweir 864cdf0e10cSrcweir sal_Int32 nThumbPos = m_aVScroll.GetThumbPos(); 865cdf0e10cSrcweir 866cdf0e10cSrcweir sal_Int32 nDelta = m_aVScroll.GetDelta(); 867cdf0e10cSrcweir m_nYOffset = -nThumbPos * m_nRowHeight; 868cdf0e10cSrcweir 869cdf0e10cSrcweir sal_uInt16 nEnd = (sal_uInt16)(nThumbPos + CalcVisibleLines()); 870cdf0e10cSrcweir 871cdf0e10cSrcweir m_aLinesPlayground.Scroll(0, -nDelta * m_nRowHeight, SCROLL_CHILDREN); 872cdf0e10cSrcweir 873cdf0e10cSrcweir if (1 == nDelta) 874cdf0e10cSrcweir { 875cdf0e10cSrcweir PositionLine(nEnd-1); 876cdf0e10cSrcweir PositionLine(nEnd); 877cdf0e10cSrcweir } 878cdf0e10cSrcweir else if (nDelta==-1) 879cdf0e10cSrcweir { 880cdf0e10cSrcweir PositionLine((sal_uInt16)nThumbPos); 881cdf0e10cSrcweir } 882cdf0e10cSrcweir else if (nDelta!=0 || m_aVScroll.GetType() == SCROLL_DONTKNOW) 883cdf0e10cSrcweir { 884cdf0e10cSrcweir UpdatePlayGround(); 885cdf0e10cSrcweir } 886cdf0e10cSrcweir 887cdf0e10cSrcweir m_aLinesPlayground.EnablePaint(sal_True); 888cdf0e10cSrcweir return 0; 889cdf0e10cSrcweir } 890cdf0e10cSrcweir 891cdf0e10cSrcweir //------------------------------------------------------------------ buttonClicked(OBrowserLine * _pLine,sal_Bool _bPrimary)892cdf0e10cSrcweir void OBrowserListBox::buttonClicked( OBrowserLine* _pLine, sal_Bool _bPrimary ) 893cdf0e10cSrcweir { 894cdf0e10cSrcweir DBG_ASSERT( _pLine, "OBrowserListBox::buttonClicked: invalid browser line!" ); 895cdf0e10cSrcweir if ( _pLine && m_pLineListener ) 896cdf0e10cSrcweir { 897cdf0e10cSrcweir m_pLineListener->Clicked( _pLine->GetEntryName(), _bPrimary ); 898cdf0e10cSrcweir } 899cdf0e10cSrcweir } 900cdf0e10cSrcweir 901cdf0e10cSrcweir //------------------------------------------------------------------ impl_setControlAsPropertyValue(const ListBoxLine & _rLine,const Any & _rPropertyValue)902cdf0e10cSrcweir void OBrowserListBox::impl_setControlAsPropertyValue( const ListBoxLine& _rLine, const Any& _rPropertyValue ) 903cdf0e10cSrcweir { 904cdf0e10cSrcweir Reference< XPropertyControl > xControl( _rLine.pLine->getControl() ); 905cdf0e10cSrcweir try 906cdf0e10cSrcweir { 907cdf0e10cSrcweir if ( _rPropertyValue.getValueType().equals( _rLine.pLine->getControl()->getValueType() ) ) 908cdf0e10cSrcweir { 909cdf0e10cSrcweir xControl->setValue( _rPropertyValue ); 910cdf0e10cSrcweir } 911cdf0e10cSrcweir else 912cdf0e10cSrcweir { 913cdf0e10cSrcweir #ifdef DBG_UTIL 914cdf0e10cSrcweir if ( !_rLine.xHandler.is() ) 915cdf0e10cSrcweir { 916cdf0e10cSrcweir ::rtl::OString sMessage( "OBrowserListBox::impl_setControlAsPropertyValue: no handler -> no conversion (property: '" ); 917cdf0e10cSrcweir ::rtl::OUString sPropertyName( _rLine.pLine->GetEntryName() ); 918cdf0e10cSrcweir sMessage += ::rtl::OString( sPropertyName.getStr(), sPropertyName.getLength(), RTL_TEXTENCODING_ASCII_US ); 919cdf0e10cSrcweir sMessage += ::rtl::OString( "')!" ); 920cdf0e10cSrcweir DBG_ERROR( sMessage ); 921cdf0e10cSrcweir } 922cdf0e10cSrcweir #endif 923cdf0e10cSrcweir if ( _rLine.xHandler.is() ) 924cdf0e10cSrcweir { 925cdf0e10cSrcweir Any aControlValue = _rLine.xHandler->convertToControlValue( 926cdf0e10cSrcweir _rLine.pLine->GetEntryName(), _rPropertyValue, xControl->getValueType() ); 927cdf0e10cSrcweir xControl->setValue( aControlValue ); 928cdf0e10cSrcweir } 929cdf0e10cSrcweir } 930cdf0e10cSrcweir } 931cdf0e10cSrcweir catch( const Exception& ) 932cdf0e10cSrcweir { 933cdf0e10cSrcweir DBG_UNHANDLED_EXCEPTION(); 934cdf0e10cSrcweir } 935cdf0e10cSrcweir } 936cdf0e10cSrcweir 937cdf0e10cSrcweir //------------------------------------------------------------------ impl_getControlAsPropertyValue(const ListBoxLine & _rLine) const938cdf0e10cSrcweir Any OBrowserListBox::impl_getControlAsPropertyValue( const ListBoxLine& _rLine ) const 939cdf0e10cSrcweir { 940cdf0e10cSrcweir Reference< XPropertyControl > xControl( _rLine.pLine->getControl() ); 941cdf0e10cSrcweir Any aPropertyValue; 942cdf0e10cSrcweir try 943cdf0e10cSrcweir { 944cdf0e10cSrcweir #ifdef DBG_UTIL 945cdf0e10cSrcweir if ( !_rLine.xHandler.is() ) 946cdf0e10cSrcweir { 947cdf0e10cSrcweir ::rtl::OString sMessage( "OBrowserListBox::impl_getControlAsPropertyValue: no handler -> no conversion (property: '" ); 948cdf0e10cSrcweir ::rtl::OUString sPropertyName( _rLine.pLine->GetEntryName() ); 949cdf0e10cSrcweir sMessage += ::rtl::OString( sPropertyName.getStr(), sPropertyName.getLength(), RTL_TEXTENCODING_ASCII_US ); 950cdf0e10cSrcweir sMessage += ::rtl::OString( "')!" ); 951cdf0e10cSrcweir DBG_ERROR( sMessage ); 952cdf0e10cSrcweir } 953cdf0e10cSrcweir #endif 954cdf0e10cSrcweir if ( _rLine.xHandler.is() ) 955cdf0e10cSrcweir aPropertyValue = _rLine.xHandler->convertToPropertyValue( _rLine.pLine->GetEntryName(), xControl->getValue() ); 956cdf0e10cSrcweir else 957cdf0e10cSrcweir aPropertyValue = xControl->getValue(); 958cdf0e10cSrcweir } 959cdf0e10cSrcweir catch( const Exception& ) 960cdf0e10cSrcweir { 961cdf0e10cSrcweir DBG_UNHANDLED_EXCEPTION(); 962cdf0e10cSrcweir } 963cdf0e10cSrcweir return aPropertyValue; 964cdf0e10cSrcweir } 965cdf0e10cSrcweir 966cdf0e10cSrcweir //------------------------------------------------------------------ impl_getControlPos(const Reference<XPropertyControl> & _rxControl) const967cdf0e10cSrcweir sal_uInt16 OBrowserListBox::impl_getControlPos( const Reference< XPropertyControl >& _rxControl ) const 968cdf0e10cSrcweir { 969cdf0e10cSrcweir for ( OrderedListBoxLines::const_iterator search = m_aOrderedLines.begin(); 970cdf0e10cSrcweir search != m_aOrderedLines.end(); 971cdf0e10cSrcweir ++search 972cdf0e10cSrcweir ) 973cdf0e10cSrcweir if ( (*search)->second.pLine->getControl().get() == _rxControl.get() ) 974cdf0e10cSrcweir return sal_uInt16( search - m_aOrderedLines.begin() ); 975cdf0e10cSrcweir DBG_ERROR( "OBrowserListBox::impl_getControlPos: invalid control - not part of any of our lines!" ); 976cdf0e10cSrcweir return (sal_uInt16)-1; 977cdf0e10cSrcweir } 978cdf0e10cSrcweir 979cdf0e10cSrcweir //-------------------------------------------------------------------- focusGained(const Reference<XPropertyControl> & _rxControl)980cdf0e10cSrcweir void SAL_CALL OBrowserListBox::focusGained( const Reference< XPropertyControl >& _rxControl ) throw (RuntimeException) 981cdf0e10cSrcweir { 982cdf0e10cSrcweir DBG_TESTSOLARMUTEX(); 983cdf0e10cSrcweir 984cdf0e10cSrcweir DBG_ASSERT( _rxControl.is(), "OBrowserListBox::focusGained: invalid event source!" ); 985cdf0e10cSrcweir if ( !_rxControl.is() ) 986cdf0e10cSrcweir return; 987cdf0e10cSrcweir 988cdf0e10cSrcweir if ( m_pControlObserver ) 989cdf0e10cSrcweir m_pControlObserver->focusGained( _rxControl ); 990cdf0e10cSrcweir 991cdf0e10cSrcweir m_xActiveControl = _rxControl; 992cdf0e10cSrcweir ShowEntry( impl_getControlPos( m_xActiveControl ) ); 993cdf0e10cSrcweir } 994cdf0e10cSrcweir 995cdf0e10cSrcweir //-------------------------------------------------------------------- valueChanged(const Reference<XPropertyControl> & _rxControl)996cdf0e10cSrcweir void SAL_CALL OBrowserListBox::valueChanged( const Reference< XPropertyControl >& _rxControl ) throw (RuntimeException) 997cdf0e10cSrcweir { 998cdf0e10cSrcweir DBG_TESTSOLARMUTEX(); 999cdf0e10cSrcweir 1000cdf0e10cSrcweir DBG_ASSERT( _rxControl.is(), "OBrowserListBox::valueChanged: invalid event source!" ); 1001cdf0e10cSrcweir if ( !_rxControl.is() ) 1002cdf0e10cSrcweir return; 1003cdf0e10cSrcweir 1004cdf0e10cSrcweir if ( m_pControlObserver ) 1005cdf0e10cSrcweir m_pControlObserver->valueChanged( _rxControl ); 1006cdf0e10cSrcweir 1007cdf0e10cSrcweir if ( m_pLineListener ) 1008cdf0e10cSrcweir { 1009cdf0e10cSrcweir const ListBoxLine& rLine = impl_getControlLine( _rxControl ); 1010cdf0e10cSrcweir m_pLineListener->Commit( 1011cdf0e10cSrcweir rLine.pLine->GetEntryName(), 1012cdf0e10cSrcweir impl_getControlAsPropertyValue( rLine ) 1013cdf0e10cSrcweir ); 1014cdf0e10cSrcweir } 1015cdf0e10cSrcweir } 1016cdf0e10cSrcweir 1017cdf0e10cSrcweir //-------------------------------------------------------------------- activateNextControl(const Reference<XPropertyControl> & _rxCurrentControl)1018cdf0e10cSrcweir void SAL_CALL OBrowserListBox::activateNextControl( const Reference< XPropertyControl >& _rxCurrentControl ) throw (RuntimeException) 1019cdf0e10cSrcweir { 1020cdf0e10cSrcweir DBG_TESTSOLARMUTEX(); 1021cdf0e10cSrcweir 1022cdf0e10cSrcweir sal_uInt16 nLine = impl_getControlPos( _rxCurrentControl ); 1023cdf0e10cSrcweir 1024cdf0e10cSrcweir // cycle forwards, 'til we've the next control which can grab the focus 1025cdf0e10cSrcweir ++nLine; 1026cdf0e10cSrcweir while ( (size_t)nLine < m_aOrderedLines.size() ) 1027cdf0e10cSrcweir { 1028cdf0e10cSrcweir if ( m_aOrderedLines[nLine]->second.pLine->GrabFocus() ) 1029cdf0e10cSrcweir break; 1030cdf0e10cSrcweir ++nLine; 1031cdf0e10cSrcweir } 1032cdf0e10cSrcweir 1033cdf0e10cSrcweir if ( ( (size_t)nLine >= m_aOrderedLines.size() ) 1034cdf0e10cSrcweir && ( m_aOrderedLines.size() > 0 ) 1035cdf0e10cSrcweir ) 1036cdf0e10cSrcweir // wrap around 1037cdf0e10cSrcweir m_aOrderedLines[0]->second.pLine->GrabFocus(); 1038cdf0e10cSrcweir } 1039cdf0e10cSrcweir 1040cdf0e10cSrcweir //------------------------------------------------------------------ 1041cdf0e10cSrcweir namespace 1042cdf0e10cSrcweir { 1043cdf0e10cSrcweir //.............................................................. lcl_implDisposeControl_nothrow(const Reference<XPropertyControl> & _rxControl)1044cdf0e10cSrcweir void lcl_implDisposeControl_nothrow( const Reference< XPropertyControl >& _rxControl ) 1045cdf0e10cSrcweir { 1046cdf0e10cSrcweir if ( !_rxControl.is() ) 1047cdf0e10cSrcweir return; 1048cdf0e10cSrcweir try 1049cdf0e10cSrcweir { 1050cdf0e10cSrcweir _rxControl->setControlContext( NULL ); 1051cdf0e10cSrcweir Reference< XComponent > xControlComponent( _rxControl, UNO_QUERY ); 1052cdf0e10cSrcweir if ( xControlComponent.is() ) 1053cdf0e10cSrcweir xControlComponent->dispose(); 1054cdf0e10cSrcweir } 1055cdf0e10cSrcweir catch( const Exception& ) 1056cdf0e10cSrcweir { 1057cdf0e10cSrcweir DBG_UNHANDLED_EXCEPTION(); 1058cdf0e10cSrcweir } 1059cdf0e10cSrcweir } 1060cdf0e10cSrcweir } 1061cdf0e10cSrcweir 1062cdf0e10cSrcweir //------------------------------------------------------------------ Clear()1063cdf0e10cSrcweir void OBrowserListBox::Clear() 1064cdf0e10cSrcweir { 1065cdf0e10cSrcweir for ( ListBoxLines::iterator loop = m_aLines.begin(); 1066cdf0e10cSrcweir loop != m_aLines.end(); 1067cdf0e10cSrcweir ++loop 1068cdf0e10cSrcweir ) 1069cdf0e10cSrcweir { 1070cdf0e10cSrcweir // hide the line 1071cdf0e10cSrcweir loop->second.pLine->Hide(); 1072cdf0e10cSrcweir // reset the listener 1073cdf0e10cSrcweir lcl_implDisposeControl_nothrow( loop->second.pLine->getControl() ); 1074cdf0e10cSrcweir } 1075cdf0e10cSrcweir 1076cdf0e10cSrcweir clearContainer( m_aLines ); 1077cdf0e10cSrcweir clearContainer( m_aOrderedLines ); 1078cdf0e10cSrcweir } 1079cdf0e10cSrcweir 1080cdf0e10cSrcweir //------------------------------------------------------------------ RemoveEntry(const::rtl::OUString & _rName)1081cdf0e10cSrcweir sal_Bool OBrowserListBox::RemoveEntry( const ::rtl::OUString& _rName ) 1082cdf0e10cSrcweir { 1083cdf0e10cSrcweir sal_uInt16 nPos = GetPropertyPos( _rName ); 1084cdf0e10cSrcweir if ( nPos == LISTBOX_ENTRY_NOTFOUND ) 1085cdf0e10cSrcweir return sal_False; 1086cdf0e10cSrcweir 1087cdf0e10cSrcweir OrderedListBoxLines::iterator orderedPos = m_aOrderedLines.begin() + nPos; 1088cdf0e10cSrcweir BrowserLinePointer pLine = (*orderedPos)->second.pLine; 1089cdf0e10cSrcweir pLine->Hide(); 1090cdf0e10cSrcweir lcl_implDisposeControl_nothrow( pLine->getControl() ); 1091cdf0e10cSrcweir 1092cdf0e10cSrcweir m_aLines.erase( *orderedPos ); 1093cdf0e10cSrcweir m_aOrderedLines.erase( orderedPos ); 1094cdf0e10cSrcweir m_aOutOfDateLines.erase( (sal_uInt16)m_aOrderedLines.size() ); 1095cdf0e10cSrcweir // this index *may* have been out of date, which is obsoleted now by m_aOrderedLines shrinking 1096cdf0e10cSrcweir 1097cdf0e10cSrcweir // update the positions of possibly affected lines 1098cdf0e10cSrcweir while ( nPos < m_aOrderedLines.size() ) 1099cdf0e10cSrcweir m_aOutOfDateLines.insert( nPos++ ); 1100cdf0e10cSrcweir UpdatePosNSize( ); 1101cdf0e10cSrcweir 1102cdf0e10cSrcweir return sal_True; 1103cdf0e10cSrcweir } 1104cdf0e10cSrcweir 1105cdf0e10cSrcweir //------------------------------------------------------------------ ChangeEntry(const OLineDescriptor & _rPropertyData,sal_uInt16 nPos)1106cdf0e10cSrcweir void OBrowserListBox::ChangeEntry( const OLineDescriptor& _rPropertyData, sal_uInt16 nPos ) 1107cdf0e10cSrcweir { 1108cdf0e10cSrcweir OSL_PRECOND( _rPropertyData.Control.is(), "OBrowserListBox::ChangeEntry: invalid control!" ); 1109cdf0e10cSrcweir if ( !_rPropertyData.Control.is() ) 1110cdf0e10cSrcweir return; 1111cdf0e10cSrcweir 1112cdf0e10cSrcweir if ( nPos == EDITOR_LIST_REPLACE_EXISTING ) 1113cdf0e10cSrcweir nPos = GetPropertyPos( _rPropertyData.sName ); 1114cdf0e10cSrcweir 1115cdf0e10cSrcweir if ( nPos < m_aOrderedLines.size() ) 1116cdf0e10cSrcweir { 1117cdf0e10cSrcweir Window* pRefWindow = NULL; 1118cdf0e10cSrcweir if ( nPos > 0 ) 1119cdf0e10cSrcweir pRefWindow = m_aOrderedLines[nPos-1]->second.pLine->GetRefWindow(); 1120cdf0e10cSrcweir 1121cdf0e10cSrcweir // the current line and control 1122cdf0e10cSrcweir ListBoxLine& rLine = m_aOrderedLines[nPos]->second; 1123cdf0e10cSrcweir 1124cdf0e10cSrcweir // the old control and some data about it 1125cdf0e10cSrcweir Reference< XPropertyControl > xControl = rLine.pLine->getControl(); 1126cdf0e10cSrcweir Window* pControlWindow = rLine.pLine->getControlWindow(); 1127cdf0e10cSrcweir Point aControlPos; 1128cdf0e10cSrcweir if ( pControlWindow ) 1129cdf0e10cSrcweir aControlPos = pControlWindow->GetPosPixel(); 1130cdf0e10cSrcweir 1131cdf0e10cSrcweir // clean up the old control 1132cdf0e10cSrcweir lcl_implDisposeControl_nothrow( xControl ); 1133cdf0e10cSrcweir 1134cdf0e10cSrcweir // set the new control at the line 1135cdf0e10cSrcweir rLine.pLine->setControl( _rPropertyData.Control ); 1136cdf0e10cSrcweir xControl = rLine.pLine->getControl(); 1137cdf0e10cSrcweir 1138cdf0e10cSrcweir if ( xControl.is() ) 1139cdf0e10cSrcweir xControl->setControlContext( m_pControlContextImpl.get() ); 1140cdf0e10cSrcweir 1141cdf0e10cSrcweir // the initial property value 1142cdf0e10cSrcweir if ( _rPropertyData.bUnknownValue ) 1143cdf0e10cSrcweir xControl->setValue( Any() ); 1144cdf0e10cSrcweir else 1145cdf0e10cSrcweir impl_setControlAsPropertyValue( rLine, _rPropertyData.aValue ); 1146cdf0e10cSrcweir 1147cdf0e10cSrcweir rLine.pLine->SetTitle(_rPropertyData.DisplayName); 1148cdf0e10cSrcweir rLine.xHandler = _rPropertyData.xPropertyHandler; 1149cdf0e10cSrcweir 1150cdf0e10cSrcweir sal_uInt16 nTextWidth = (sal_uInt16)m_aLinesPlayground.GetTextWidth(_rPropertyData.DisplayName); 1151cdf0e10cSrcweir if (m_nTheNameSize< nTextWidth) 1152cdf0e10cSrcweir m_nTheNameSize = nTextWidth; 1153cdf0e10cSrcweir 1154cdf0e10cSrcweir if ( _rPropertyData.HasPrimaryButton ) 1155cdf0e10cSrcweir { 1156cdf0e10cSrcweir if ( _rPropertyData.PrimaryButtonImageURL.getLength() ) 1157cdf0e10cSrcweir rLine.pLine->ShowBrowseButton( _rPropertyData.PrimaryButtonImageURL, true ); 1158cdf0e10cSrcweir else if ( _rPropertyData.PrimaryButtonImage.is() ) 1159cdf0e10cSrcweir rLine.pLine->ShowBrowseButton( Image( _rPropertyData.PrimaryButtonImage ), true ); 1160cdf0e10cSrcweir else 1161cdf0e10cSrcweir rLine.pLine->ShowBrowseButton( true ); 1162cdf0e10cSrcweir 1163cdf0e10cSrcweir if ( _rPropertyData.HasSecondaryButton ) 1164cdf0e10cSrcweir { 1165cdf0e10cSrcweir if ( _rPropertyData.SecondaryButtonImageURL.getLength() ) 1166cdf0e10cSrcweir rLine.pLine->ShowBrowseButton( _rPropertyData.SecondaryButtonImageURL, false ); 1167cdf0e10cSrcweir else if ( _rPropertyData.SecondaryButtonImage.is() ) 1168cdf0e10cSrcweir rLine.pLine->ShowBrowseButton( Image( _rPropertyData.SecondaryButtonImage ), false ); 1169cdf0e10cSrcweir else 1170cdf0e10cSrcweir rLine.pLine->ShowBrowseButton( false ); 1171cdf0e10cSrcweir } 1172cdf0e10cSrcweir else 1173cdf0e10cSrcweir rLine.pLine->HideBrowseButton( false ); 1174cdf0e10cSrcweir 1175cdf0e10cSrcweir rLine.pLine->SetClickListener( this ); 1176cdf0e10cSrcweir } 1177cdf0e10cSrcweir else 1178cdf0e10cSrcweir { 1179cdf0e10cSrcweir rLine.pLine->HideBrowseButton( true ); 1180cdf0e10cSrcweir rLine.pLine->HideBrowseButton( false ); 1181cdf0e10cSrcweir } 1182cdf0e10cSrcweir 1183cdf0e10cSrcweir DBG_ASSERT( ( _rPropertyData.IndentLevel == 0 ) || ( _rPropertyData.IndentLevel == 1 ), 1184cdf0e10cSrcweir "OBrowserListBox::ChangeEntry: unsupported indent level!" ); 1185cdf0e10cSrcweir rLine.pLine->IndentTitle( _rPropertyData.IndentLevel > 0 ); 1186cdf0e10cSrcweir 1187cdf0e10cSrcweir if ( nPos > 0 ) 1188cdf0e10cSrcweir rLine.pLine->SetTabOrder( pRefWindow, WINDOW_ZORDER_BEHIND ); 1189cdf0e10cSrcweir else 1190cdf0e10cSrcweir rLine.pLine->SetTabOrder( pRefWindow, WINDOW_ZORDER_FIRST ); 1191cdf0e10cSrcweir 1192cdf0e10cSrcweir m_aOutOfDateLines.insert( nPos ); 1193cdf0e10cSrcweir rLine.pLine->SetComponentHelpIds( 1194cdf0e10cSrcweir HelpIdUrl::getHelpId( _rPropertyData.HelpURL ), 1195cdf0e10cSrcweir rtl::OUStringToOString( _rPropertyData.PrimaryButtonId, RTL_TEXTENCODING_UTF8 ), 1196cdf0e10cSrcweir rtl::OUStringToOString( _rPropertyData.SecondaryButtonId, RTL_TEXTENCODING_UTF8 ) 1197cdf0e10cSrcweir ); 1198cdf0e10cSrcweir 1199cdf0e10cSrcweir if ( _rPropertyData.bReadOnly ) 1200cdf0e10cSrcweir { 1201cdf0e10cSrcweir rLine.pLine->SetReadOnly( true ); 1202cdf0e10cSrcweir 1203cdf0e10cSrcweir // user controls (i.e. the ones not provided by the usual 1204cdf0e10cSrcweir // XPropertyControlFactory) have no chance to know that they should be read-only, 1205cdf0e10cSrcweir // since XPropertyHandler::describePropertyLine does not transport this 1206cdf0e10cSrcweir // information. 1207cdf0e10cSrcweir // So, we manually switch this to read-only. 1208cdf0e10cSrcweir if ( xControl.is() && ( xControl->getControlType() == PropertyControlType::Unknown ) ) 1209cdf0e10cSrcweir { 1210cdf0e10cSrcweir Edit* pControlWindowAsEdit = dynamic_cast< Edit* >( rLine.pLine->getControlWindow() ); 1211cdf0e10cSrcweir if ( pControlWindowAsEdit ) 1212cdf0e10cSrcweir pControlWindowAsEdit->SetReadOnly( sal_True ); 1213cdf0e10cSrcweir else 1214cdf0e10cSrcweir pControlWindowAsEdit->Enable( sal_False ); 1215cdf0e10cSrcweir } 1216cdf0e10cSrcweir } 1217cdf0e10cSrcweir } 1218cdf0e10cSrcweir } 1219cdf0e10cSrcweir 1220cdf0e10cSrcweir //------------------------------------------------------------------ PreNotify(NotifyEvent & _rNEvt)1221cdf0e10cSrcweir long OBrowserListBox::PreNotify( NotifyEvent& _rNEvt ) 1222cdf0e10cSrcweir { 1223cdf0e10cSrcweir switch ( _rNEvt.GetType() ) 1224cdf0e10cSrcweir { 1225cdf0e10cSrcweir case EVENT_KEYINPUT: 1226cdf0e10cSrcweir { 1227cdf0e10cSrcweir const KeyEvent* pKeyEvent = _rNEvt.GetKeyEvent(); 1228cdf0e10cSrcweir if ( ( pKeyEvent->GetKeyCode().GetModifier() != 0 ) 1229cdf0e10cSrcweir || ( ( pKeyEvent->GetKeyCode().GetCode() != KEY_PAGEUP ) 1230cdf0e10cSrcweir && ( pKeyEvent->GetKeyCode().GetCode() != KEY_PAGEDOWN ) 1231cdf0e10cSrcweir ) 1232cdf0e10cSrcweir ) 1233cdf0e10cSrcweir break; 1234cdf0e10cSrcweir 1235cdf0e10cSrcweir long nScrollOffset = 0; 1236cdf0e10cSrcweir if ( m_aVScroll.IsVisible() ) 1237cdf0e10cSrcweir { 1238cdf0e10cSrcweir if ( pKeyEvent->GetKeyCode().GetCode() == KEY_PAGEUP ) 1239cdf0e10cSrcweir nScrollOffset = -m_aVScroll.GetPageSize(); 1240cdf0e10cSrcweir else if ( pKeyEvent->GetKeyCode().GetCode() == KEY_PAGEDOWN ) 1241cdf0e10cSrcweir nScrollOffset = m_aVScroll.GetPageSize(); 1242cdf0e10cSrcweir } 1243cdf0e10cSrcweir 1244cdf0e10cSrcweir if ( nScrollOffset ) 1245cdf0e10cSrcweir { 1246cdf0e10cSrcweir long nNewThumbPos = m_aVScroll.GetThumbPos() + nScrollOffset; 1247cdf0e10cSrcweir nNewThumbPos = ::std::max( nNewThumbPos, m_aVScroll.GetRangeMin() ); 1248cdf0e10cSrcweir nNewThumbPos = ::std::min( nNewThumbPos, m_aVScroll.GetRangeMax() ); 1249cdf0e10cSrcweir m_aVScroll.DoScroll( nNewThumbPos ); 1250cdf0e10cSrcweir nNewThumbPos = m_aVScroll.GetThumbPos(); 1251cdf0e10cSrcweir 1252cdf0e10cSrcweir sal_uInt16 nFocusControlPos = 0; 1253cdf0e10cSrcweir sal_uInt16 nActiveControlPos = impl_getControlPos( m_xActiveControl ); 1254cdf0e10cSrcweir if ( nActiveControlPos < nNewThumbPos ) 1255cdf0e10cSrcweir nFocusControlPos = (sal_uInt16)nNewThumbPos; 1256cdf0e10cSrcweir else if ( nActiveControlPos >= nNewThumbPos + CalcVisibleLines() ) 1257cdf0e10cSrcweir nFocusControlPos = (sal_uInt16)nNewThumbPos + CalcVisibleLines() - 1; 1258cdf0e10cSrcweir if ( nFocusControlPos ) 1259cdf0e10cSrcweir { 1260cdf0e10cSrcweir if ( nFocusControlPos < m_aOrderedLines.size() ) 1261cdf0e10cSrcweir { 1262cdf0e10cSrcweir m_aOrderedLines[ nFocusControlPos ]->second.pLine->GrabFocus(); 1263cdf0e10cSrcweir } 1264cdf0e10cSrcweir else 1265cdf0e10cSrcweir OSL_ENSURE( false, "OBrowserListBox::PreNotify: internal error, invalid focus control position!" ); 1266cdf0e10cSrcweir } 1267cdf0e10cSrcweir } 1268cdf0e10cSrcweir 1269cdf0e10cSrcweir return 1L; 1270cdf0e10cSrcweir // handled this. In particular, we also consume PageUp/Down events if we do not use them for scrolling, 1271cdf0e10cSrcweir // otherwise they would be used to scroll the document view, which does not sound like it is desired by 1272cdf0e10cSrcweir // the user. 1273cdf0e10cSrcweir } 1274cdf0e10cSrcweir } 1275cdf0e10cSrcweir return Control::PreNotify( _rNEvt ); 1276cdf0e10cSrcweir } 1277cdf0e10cSrcweir 1278cdf0e10cSrcweir //------------------------------------------------------------------ Notify(NotifyEvent & _rNEvt)1279cdf0e10cSrcweir long OBrowserListBox::Notify( NotifyEvent& _rNEvt ) 1280cdf0e10cSrcweir { 1281cdf0e10cSrcweir switch ( _rNEvt.GetType() ) 1282cdf0e10cSrcweir { 1283cdf0e10cSrcweir case EVENT_COMMAND: 1284cdf0e10cSrcweir { 1285cdf0e10cSrcweir const CommandEvent* pCommand = _rNEvt.GetCommandEvent(); 1286cdf0e10cSrcweir if ( ( COMMAND_WHEEL == pCommand->GetCommand() ) 1287cdf0e10cSrcweir || ( COMMAND_STARTAUTOSCROLL == pCommand->GetCommand() ) 1288cdf0e10cSrcweir || ( COMMAND_AUTOSCROLL == pCommand->GetCommand() ) 1289cdf0e10cSrcweir ) 1290cdf0e10cSrcweir { 1291cdf0e10cSrcweir // interested in scroll events if we have a scrollbar 1292cdf0e10cSrcweir if ( m_aVScroll.IsVisible() ) 1293cdf0e10cSrcweir { 1294cdf0e10cSrcweir HandleScrollCommand( *pCommand, NULL, &m_aVScroll ); 1295cdf0e10cSrcweir } 1296cdf0e10cSrcweir } 1297cdf0e10cSrcweir } 1298cdf0e10cSrcweir break; 1299cdf0e10cSrcweir } 1300cdf0e10cSrcweir 1301cdf0e10cSrcweir return Control::Notify( _rNEvt ); 1302cdf0e10cSrcweir } 1303cdf0e10cSrcweir 1304cdf0e10cSrcweir //............................................................................ 1305cdf0e10cSrcweir } // namespace pcr 1306cdf0e10cSrcweir //............................................................................ 1307cdf0e10cSrcweir 1308cdf0e10cSrcweir 1309