LCOV - code coverage report
Current view: top level - extensions/source/propctrlr - browserlistbox.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 524 0.0 %
Date: 2014-04-14 Functions: 0 70 0.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10