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