LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/extensions/source/propctrlr - browserlistbox.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 2 523 0.4 %
Date: 2013-07-09 Functions: 2 70 2.9 %
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           1 :     ::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();
     172             :         virtual void SAL_CALL release() throw();
     173             : 
     174             :     protected:
     175             :         ~PropertyControlContext_Impl();
     176             : 
     177             :         // XPropertyControlObserver
     178             :         virtual void SAL_CALL focusGained( const Reference< XPropertyControl >& Control ) throw (RuntimeException);
     179             :         virtual void SAL_CALL valueChanged( const Reference< XPropertyControl >& Control ) throw (RuntimeException);
     180             :         // XPropertyControlContext
     181             :         virtual void SAL_CALL activateNextControl( const Reference< XPropertyControl >& CurrentControl ) throw (RuntimeException);
     182             : 
     183             :         // IEventProcessor
     184             :         virtual void processEvent( const ::comphelper::AnyEvent& _rEvent );
     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)
     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)
     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)
     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             :     DBG_NAME(OBrowserListBox)
     350             :     //------------------------------------------------------------------
     351           0 :     OBrowserListBox::OBrowserListBox( Window* pParent, WinBits nWinStyle)
     352             :             :Control(pParent, nWinStyle| WB_CLIPCHILDREN)
     353             :             ,m_aLinesPlayground(this,WB_DIALOGCONTROL | WB_CLIPCHILDREN)
     354             :             ,m_aVScroll(this,WB_VSCROLL|WB_REPEAT|WB_DRAG)
     355           0 :             ,m_pHelpWindow( new InspectorHelpWindow( this ) )
     356             :             ,m_pLineListener(NULL)
     357             :             ,m_pControlObserver( NULL )
     358             :             ,m_nYOffset(0)
     359             :             ,m_nCurrentPreferredHelpHeight(0)
     360             :             ,m_nTheNameSize(0)
     361             :             ,m_bIsActive(sal_False)
     362             :             ,m_bUpdate(sal_True)
     363           0 :             ,m_pControlContextImpl( new PropertyControlContext_Impl( *this ) )
     364             :     {
     365             :         DBG_CTOR(OBrowserListBox,NULL);
     366             : 
     367           0 :         ListBox aListBox(this,WB_DROPDOWN);
     368           0 :         aListBox.SetPosSizePixel(Point(0,0),Size(100,100));
     369           0 :         m_nRowHeight = (sal_uInt16)aListBox.GetSizePixel().Height()+2;
     370           0 :         SetBackground( pParent->GetBackground() );
     371           0 :         m_aLinesPlayground.SetBackground( GetBackground() );
     372             : 
     373           0 :         m_aLinesPlayground.SetPosPixel(Point(0,0));
     374           0 :         m_aLinesPlayground.SetPaintTransparent(sal_True);
     375           0 :         m_aLinesPlayground.Show();
     376           0 :         m_aVScroll.Hide();
     377           0 :         m_aVScroll.SetScrollHdl(LINK(this, OBrowserListBox, ScrollHdl));
     378           0 :     }
     379             : 
     380             :     //------------------------------------------------------------------
     381           0 :     OBrowserListBox::~OBrowserListBox()
     382             :     {
     383             :         OSL_ENSURE( !IsModified(), "OBrowserListBox::~OBrowserListBox: still modified - should have been committed before!" );
     384             :             // doing the commit here, while we, as well as our owner, as well as some other components,
     385             :             // are already "half dead" (means within their dtor) is potentially dangerous.
     386             :             // By definition, CommitModified has to be called (if necessary) before destruction
     387             : 
     388           0 :         m_pControlContextImpl->dispose();
     389           0 :         m_pControlContextImpl.clear();
     390             : 
     391           0 :         Hide();
     392           0 :         Clear();
     393             : 
     394             :         DBG_DTOR(OBrowserListBox,NULL);
     395           0 :     }
     396             : 
     397             :     //------------------------------------------------------------------
     398           0 :     sal_Bool OBrowserListBox::IsModified( ) const
     399             :     {
     400           0 :         sal_Bool bModified = sal_False;
     401             : 
     402           0 :         if ( m_bIsActive && m_xActiveControl.is() )
     403           0 :             bModified = m_xActiveControl->isModified();
     404             : 
     405           0 :         return bModified;
     406             :     }
     407             : 
     408             :     //------------------------------------------------------------------
     409           0 :     void OBrowserListBox::CommitModified( )
     410             :     {
     411           0 :         if ( IsModified() && m_xActiveControl.is() )
     412             :         {
     413             :             // for the time of this commit, notify all events synchronously
     414             :             // #i63814#
     415           0 :             m_pControlContextImpl->setNotificationMode( PropertyControlContext_Impl::eSynchronously );
     416             :             try
     417             :             {
     418           0 :                 m_xActiveControl->notifyModifiedValue();
     419             :             }
     420           0 :             catch( const Exception& )
     421             :             {
     422             :                 DBG_UNHANDLED_EXCEPTION();
     423             :             }
     424           0 :             m_pControlContextImpl->setNotificationMode( PropertyControlContext_Impl::eAsynchronously );
     425             :         }
     426           0 :     }
     427             : 
     428             :     //------------------------------------------------------------------
     429           0 :     void OBrowserListBox::ActivateListBox(sal_Bool _bActive)
     430             :     {
     431           0 :         m_bIsActive = _bActive;
     432           0 :         if (m_bIsActive)
     433             :         {
     434             :             // TODO: what's the sense of this?
     435           0 :             m_aVScroll.SetThumbPos(100);
     436           0 :             MoveThumbTo(0);
     437           0 :             Resize();
     438             :         }
     439           0 :     }
     440             : 
     441             :     //------------------------------------------------------------------
     442           0 :     long OBrowserListBox::impl_getPrefererredHelpHeight()
     443             :     {
     444           0 :         return HasHelpSection() ? m_pHelpWindow->GetOptimalHeightPixel() : 0;
     445             :     }
     446             : 
     447             :     //------------------------------------------------------------------
     448           0 :     void OBrowserListBox::Resize()
     449             :     {
     450           0 :         Rectangle aPlayground( Point( 0, 0 ), GetOutputSizePixel() );
     451           0 :         Size aHelpWindowDistance( LogicToPixel( Size( 0, LAYOUT_HELP_WINDOW_DISTANCE_APPFONT ), MAP_APPFONT ) );
     452             : 
     453           0 :         long nHelpWindowHeight = m_nCurrentPreferredHelpHeight = impl_getPrefererredHelpHeight();
     454           0 :         bool bPositionHelpWindow = ( nHelpWindowHeight != 0 );
     455             : 
     456           0 :         Rectangle aLinesArea( aPlayground );
     457           0 :         if ( bPositionHelpWindow )
     458             :         {
     459           0 :             aLinesArea.Bottom() -= nHelpWindowHeight;
     460           0 :             aLinesArea.Bottom() -= aHelpWindowDistance.Height();
     461             :         }
     462           0 :         m_aLinesPlayground.SetPosSizePixel( aLinesArea.TopLeft(), aLinesArea.GetSize() );
     463             : 
     464           0 :         UpdateVScroll();
     465             : 
     466           0 :         sal_Bool bNeedScrollbar = m_aLines.size() > (sal_uInt32)CalcVisibleLines();
     467           0 :         if ( !bNeedScrollbar )
     468             :         {
     469           0 :             if ( m_aVScroll.IsVisible() )
     470           0 :                 m_aVScroll.Hide();
     471             :             // scroll to top
     472           0 :             m_nYOffset = 0;
     473           0 :             m_aVScroll.SetThumbPos( 0 );
     474             :         }
     475             :         else
     476             :         {
     477           0 :             Size aVScrollSize( m_aVScroll.GetSizePixel() );
     478             : 
     479             :             // adjust the playground's width
     480           0 :             aLinesArea.Right() -= aVScrollSize.Width();
     481           0 :             m_aLinesPlayground.SetPosSizePixel( aLinesArea.TopLeft(), aLinesArea.GetSize() );
     482             : 
     483             :             // position the scrollbar
     484           0 :             aVScrollSize.Height() = aLinesArea.GetHeight();
     485           0 :             Point aVScrollPos( aLinesArea.GetWidth(), 0 );
     486           0 :             m_aVScroll.SetPosSizePixel( aVScrollPos, aVScrollSize );
     487             :         }
     488             : 
     489           0 :         for ( sal_uInt16 i = 0; i < m_aLines.size(); ++i )
     490           0 :             m_aOutOfDateLines.insert( i );
     491             : 
     492             :         // repaint
     493           0 :         EnablePaint(sal_False);
     494           0 :         UpdatePlayGround();
     495           0 :         EnablePaint(sal_True);
     496             : 
     497             :         // show the scrollbar
     498           0 :         if ( bNeedScrollbar )
     499           0 :             m_aVScroll.Show();
     500             : 
     501             :         // position the help window
     502           0 :         if ( bPositionHelpWindow )
     503             :         {
     504           0 :             Rectangle aHelpArea( aPlayground );
     505           0 :             aHelpArea.Top() = aLinesArea.Bottom() + aHelpWindowDistance.Height();
     506           0 :             m_pHelpWindow->SetPosSizePixel( aHelpArea.TopLeft(), aHelpArea.GetSize() );
     507             :         }
     508           0 :     }
     509             : 
     510             :     //------------------------------------------------------------------
     511           0 :     void OBrowserListBox::SetListener( IPropertyLineListener* _pListener )
     512             :     {
     513           0 :         m_pLineListener = _pListener;
     514           0 :     }
     515             : 
     516             :     //------------------------------------------------------------------
     517           0 :     void OBrowserListBox::SetObserver( IPropertyControlObserver* _pObserver )
     518             :     {
     519           0 :         m_pControlObserver = _pObserver;
     520           0 :     }
     521             : 
     522             :     //------------------------------------------------------------------
     523           0 :     void OBrowserListBox::EnableHelpSection( bool _bEnable )
     524             :     {
     525           0 :         m_pHelpWindow->Show( _bEnable );
     526           0 :         Resize();
     527           0 :     }
     528             : 
     529             :     //------------------------------------------------------------------
     530           0 :     bool OBrowserListBox::HasHelpSection() const
     531             :     {
     532           0 :         return m_pHelpWindow->IsVisible();
     533             :     }
     534             : 
     535             :     //------------------------------------------------------------------
     536           0 :     void OBrowserListBox::SetHelpText( const OUString& _rHelpText )
     537             :     {
     538             :         OSL_ENSURE( HasHelpSection(), "OBrowserListBox::SetHelpText: help section not visible!" );
     539           0 :         m_pHelpWindow->SetText( _rHelpText );
     540           0 :         if ( m_nCurrentPreferredHelpHeight != impl_getPrefererredHelpHeight() )
     541           0 :             Resize();
     542           0 :     }
     543             : 
     544             :     //------------------------------------------------------------------
     545           0 :     void OBrowserListBox::SetHelpLineLimites( sal_Int32 _nMinLines, sal_Int32 _nMaxLines )
     546             :     {
     547           0 :         m_pHelpWindow->SetLimits( _nMinLines, _nMaxLines );
     548           0 :     }
     549             : 
     550             :     //------------------------------------------------------------------
     551           0 :     sal_uInt16 OBrowserListBox::CalcVisibleLines()
     552             :     {
     553           0 :         Size aSize(m_aLinesPlayground.GetOutputSizePixel());
     554           0 :         sal_uInt16 nResult = 0;
     555           0 :         if (0 != m_nRowHeight)
     556           0 :             nResult = (sal_uInt16) aSize.Height()/m_nRowHeight;
     557             : 
     558           0 :         return nResult;
     559             :     }
     560             : 
     561             :     //------------------------------------------------------------------
     562           0 :     void OBrowserListBox::UpdateVScroll()
     563             :     {
     564           0 :         sal_uInt16 nLines = CalcVisibleLines();
     565           0 :         m_aVScroll.SetPageSize(nLines-1);
     566           0 :         m_aVScroll.SetVisibleSize(nLines-1);
     567             : 
     568           0 :         size_t nCount = m_aLines.size();
     569           0 :         if (nCount>0)
     570             :         {
     571           0 :             m_aVScroll.SetRange(Range(0,nCount-1));
     572           0 :             m_nYOffset = -m_aVScroll.GetThumbPos()*m_nRowHeight;
     573             :         }
     574             :         else
     575             :         {
     576           0 :             m_aVScroll.SetRange(Range(0,0));
     577           0 :             m_nYOffset = 0;
     578             :         }
     579           0 :     }
     580             : 
     581             :     //------------------------------------------------------------------
     582           0 :     void OBrowserListBox::PositionLine( sal_uInt16 _nIndex )
     583             :     {
     584           0 :         Size aSize(m_aLinesPlayground.GetOutputSizePixel());
     585           0 :         Point aPos(0, m_nYOffset);
     586             : 
     587           0 :         aSize.Height() = m_nRowHeight;
     588             : 
     589           0 :         aPos.Y() += _nIndex * m_nRowHeight;
     590             : 
     591           0 :         if ( _nIndex < m_aLines.size() )
     592             :         {
     593           0 :             BrowserLinePointer pLine = m_aLines[ _nIndex ].pLine;
     594             : 
     595           0 :             pLine->SetPosSizePixel( aPos, aSize );
     596           0 :             pLine->SetTitleWidth( m_nTheNameSize + 2 * FRAME_OFFSET );
     597             : 
     598             :             // show the line if necessary
     599           0 :             if ( !pLine->IsVisible() )
     600           0 :                 pLine->Show();
     601             :         }
     602           0 :     }
     603             : 
     604             :     //------------------------------------------------------------------
     605           0 :     void OBrowserListBox::UpdatePosNSize()
     606             :     {
     607           0 :         for  (  ::std::set< sal_uInt16 >::const_iterator aLoop = m_aOutOfDateLines.begin();
     608           0 :                 aLoop != m_aOutOfDateLines.end();
     609             :                 ++aLoop
     610             :              )
     611             :         {
     612             :             DBG_ASSERT( *aLoop < m_aLines.size(), "OBrowserListBox::UpdatePosNSize: invalid line index!" );
     613           0 :             if ( *aLoop < m_aLines.size() )
     614           0 :                 PositionLine( *aLoop );
     615             :         }
     616           0 :         m_aOutOfDateLines.clear();
     617           0 :     }
     618             : 
     619             :     //------------------------------------------------------------------
     620           0 :     void OBrowserListBox::UpdatePlayGround()
     621             :     {
     622           0 :         sal_Int32 nThumbPos = m_aVScroll.GetThumbPos();
     623           0 :         sal_Int32 nLines = CalcVisibleLines();
     624             : 
     625           0 :         sal_uInt16 nEnd = (sal_uInt16)(nThumbPos + nLines);
     626           0 :         if (nEnd >= m_aLines.size())
     627           0 :             nEnd = (sal_uInt16)m_aLines.size()-1;
     628             : 
     629           0 :         if ( !m_aLines.empty() )
     630             :         {
     631           0 :             for ( sal_uInt16 i = (sal_uInt16)nThumbPos; i <= nEnd; ++i )
     632           0 :                 m_aOutOfDateLines.insert( i );
     633           0 :             UpdatePosNSize();
     634             :         }
     635           0 :     }
     636             : 
     637             :     //------------------------------------------------------------------
     638           0 :     void OBrowserListBox::UpdateAll()
     639             :     {
     640           0 :         Resize();
     641           0 :     }
     642             : 
     643             :     //------------------------------------------------------------------
     644           0 :     void OBrowserListBox::DisableUpdate()
     645             :     {
     646           0 :         m_bUpdate = sal_False;
     647           0 :     }
     648             : 
     649             :     //------------------------------------------------------------------
     650           0 :     void OBrowserListBox::EnableUpdate()
     651             :     {
     652           0 :         m_bUpdate = sal_True;
     653           0 :         UpdateAll();
     654           0 :     }
     655             : 
     656             :     //------------------------------------------------------------------
     657           0 :     void OBrowserListBox::SetPropertyValue(const OUString& _rEntryName, const Any& _rValue, bool _bUnknownValue )
     658             :     {
     659           0 :         ListBoxLines::iterator line = m_aLines.begin();
     660           0 :         for ( ; line != m_aLines.end() && ( line->aName != _rEntryName ); ++line )
     661             :             ;
     662             : 
     663           0 :         if ( line != m_aLines.end() )
     664             :         {
     665           0 :             if ( _bUnknownValue )
     666             :             {
     667           0 :                 Reference< XPropertyControl > xControl( line->pLine->getControl() );
     668             :                 OSL_ENSURE( xControl.is(), "OBrowserListBox::SetPropertyValue: illegal control!" );
     669           0 :                 if ( xControl.is() )
     670           0 :                     xControl->setValue( Any() );
     671             :             }
     672             :             else
     673           0 :                 impl_setControlAsPropertyValue( *line, _rValue );
     674             :         }
     675           0 :     }
     676             : 
     677             :     //------------------------------------------------------------------------
     678           0 :     sal_uInt16 OBrowserListBox::GetPropertyPos( const OUString& _rEntryName ) const
     679             :     {
     680           0 :         sal_uInt16 nRet = LISTBOX_ENTRY_NOTFOUND;
     681           0 :         for ( ListBoxLines::const_iterator linePos = m_aLines.begin();
     682           0 :               linePos != m_aLines.end();
     683             :               ++linePos
     684             :             )
     685             :         {
     686           0 :             if ( linePos->aName == _rEntryName )
     687             :             {
     688           0 :                 nRet = (sal_uInt16)( linePos - m_aLines.begin() );
     689           0 :                 break;
     690             :             }
     691             :         }
     692             : 
     693           0 :         return nRet;
     694             :     }
     695             : 
     696             :     //------------------------------------------------------------------------
     697           0 :     bool OBrowserListBox::impl_getBrowserLineForName( const OUString& _rEntryName, BrowserLinePointer& _out_rpLine ) const
     698             :     {
     699           0 :         ListBoxLines::const_iterator line = m_aLines.begin();
     700           0 :         for ( ; line != m_aLines.end() && ( line->aName != _rEntryName ); ++line )
     701             :             ;
     702             : 
     703           0 :         if ( line != m_aLines.end() )
     704           0 :             _out_rpLine = line->pLine;
     705             :         else
     706           0 :             _out_rpLine.reset();
     707           0 :         return ( NULL != _out_rpLine.get() );
     708             :     }
     709             : 
     710             :     //------------------------------------------------------------------------
     711           0 :     void OBrowserListBox::EnablePropertyControls( const OUString& _rEntryName, sal_Int16 _nControls, bool _bEnable )
     712             :     {
     713           0 :         BrowserLinePointer pLine;
     714           0 :         if ( impl_getBrowserLineForName( _rEntryName, pLine ) )
     715           0 :             pLine->EnablePropertyControls( _nControls, _bEnable );
     716           0 :     }
     717             : 
     718             :     //------------------------------------------------------------------------
     719           0 :     void OBrowserListBox::EnablePropertyLine( const OUString& _rEntryName, bool _bEnable )
     720             :     {
     721           0 :         BrowserLinePointer pLine;
     722           0 :         if ( impl_getBrowserLineForName( _rEntryName, pLine ) )
     723           0 :             pLine->EnablePropertyLine( _bEnable );
     724           0 :     }
     725             : 
     726             :     //------------------------------------------------------------------------
     727           0 :     Reference< XPropertyControl > OBrowserListBox::GetPropertyControl( const OUString& _rEntryName )
     728             :     {
     729           0 :         BrowserLinePointer pLine;
     730           0 :         if ( impl_getBrowserLineForName( _rEntryName, pLine ) )
     731           0 :             return pLine->getControl();
     732           0 :         return NULL;
     733             :     }
     734             : 
     735             :     //------------------------------------------------------------------
     736           0 :     sal_uInt16 OBrowserListBox::InsertEntry(const OLineDescriptor& _rPropertyData, sal_uInt16 _nPos)
     737             :     {
     738             :         // create a new line
     739           0 :         BrowserLinePointer pBrowserLine( new OBrowserLine( _rPropertyData.sName, &m_aLinesPlayground ) );
     740             : 
     741             :         // check that the name is unique
     742           0 :         ListBoxLines::iterator it = m_aLines.begin();
     743           0 :         for ( ; it != m_aLines.end() && ( it->aName != _rPropertyData.sName ); ++it )
     744             :             ;
     745             :         OSL_ENSURE( it == m_aLines.end(), "OBrowserListBox::InsertEntry: already have another line for this name!" );
     746             : 
     747           0 :         ListBoxLine aNewLine( _rPropertyData.sName, pBrowserLine, _rPropertyData.xPropertyHandler );
     748           0 :         sal_uInt16 nInsertPos = _nPos;
     749           0 :         if ( _nPos >= m_aLines.size() )
     750             :         {
     751           0 :             nInsertPos = static_cast< sal_uInt16 >( m_aLines.size() );
     752           0 :             m_aLines.push_back( aNewLine );
     753             :         }
     754             :         else
     755           0 :             m_aLines.insert( m_aLines.begin() + _nPos, aNewLine );
     756             : 
     757           0 :         pBrowserLine->SetTitleWidth(m_nTheNameSize);
     758           0 :         if (m_bUpdate)
     759             :         {
     760           0 :             UpdateVScroll();
     761           0 :             Invalidate();
     762             :         }
     763             : 
     764             :         // initialize the entry
     765           0 :         ChangeEntry(_rPropertyData, nInsertPos);
     766             : 
     767             :         // update the positions of possibly affected lines
     768           0 :         sal_uInt16 nUpdatePos = nInsertPos;
     769           0 :         while ( nUpdatePos < m_aLines.size() )
     770           0 :             m_aOutOfDateLines.insert( nUpdatePos++ );
     771           0 :         UpdatePosNSize( );
     772             : 
     773           0 :         return nInsertPos;
     774             :     }
     775             : 
     776             :     //------------------------------------------------------------------
     777           0 :     sal_Int32 OBrowserListBox::GetMinimumWidth()
     778             :     {
     779           0 :         return m_nTheNameSize + 2 * FRAME_OFFSET + (m_nRowHeight - 4) * 8;
     780             :     }
     781             : 
     782             :     //------------------------------------------------------------------
     783           0 :     sal_Int32 OBrowserListBox::GetMinimumHeight()
     784             :     {
     785             :         // assume that we want to display 5 rows, at least
     786           0 :         sal_Int32 nMinHeight = m_nRowHeight * 5;
     787             : 
     788           0 :         if ( HasHelpSection() )
     789             :         {
     790           0 :             Size aHelpWindowDistance( LogicToPixel( Size( 0, LAYOUT_HELP_WINDOW_DISTANCE_APPFONT ), MAP_APPFONT ) );
     791           0 :             nMinHeight += aHelpWindowDistance.Height();
     792             : 
     793           0 :             nMinHeight += m_pHelpWindow->GetMinimalHeightPixel();
     794             :         }
     795             : 
     796           0 :         return nMinHeight;
     797             :     }
     798             : 
     799             :     //------------------------------------------------------------------
     800           0 :     void OBrowserListBox::ShowEntry(sal_uInt16 _nPos)
     801             :     {
     802           0 :         if ( _nPos < m_aLines.size() )
     803             :         {
     804           0 :             sal_Int32 nThumbPos = m_aVScroll.GetThumbPos();
     805             : 
     806           0 :             if (_nPos < nThumbPos)
     807           0 :                 MoveThumbTo(_nPos);
     808             :             else
     809             :             {
     810           0 :                 sal_Int32 nLines = CalcVisibleLines();
     811           0 :                 if (_nPos >= nThumbPos + nLines)
     812           0 :                     MoveThumbTo(_nPos - nLines + 1);
     813             :             }
     814             :         }
     815             : 
     816           0 :     }
     817             : 
     818             :     //------------------------------------------------------------------
     819           0 :     void OBrowserListBox::MoveThumbTo(sal_Int32 _nNewThumbPos)
     820             :     {
     821             :         // disable painting to prevent flicker
     822           0 :         m_aLinesPlayground.EnablePaint(sal_False);
     823             : 
     824           0 :         sal_Int32 nDelta = _nNewThumbPos - m_aVScroll.GetThumbPos();
     825             :         // adjust the scrollbar
     826           0 :         m_aVScroll.SetThumbPos(_nNewThumbPos);
     827           0 :         sal_Int32 nThumbPos = _nNewThumbPos;
     828             : 
     829           0 :         m_nYOffset = -m_aVScroll.GetThumbPos() * m_nRowHeight;
     830             : 
     831           0 :         sal_Int32 nLines = CalcVisibleLines();
     832           0 :         sal_uInt16 nEnd = (sal_uInt16)(nThumbPos + nLines);
     833             : 
     834           0 :         m_aLinesPlayground.Scroll(0, -nDelta * m_nRowHeight, SCROLL_CHILDREN);
     835             : 
     836           0 :         if (1 == nDelta)
     837             :         {
     838             :             // TODO: what's the sense of this two PositionLines? Why not just one call?
     839           0 :             PositionLine(nEnd-1);
     840           0 :             PositionLine(nEnd);
     841             :         }
     842           0 :         else if (-1 == nDelta)
     843             :         {
     844           0 :             PositionLine((sal_uInt16)nThumbPos);
     845             :         }
     846           0 :         else if (0 != nDelta)
     847             :         {
     848           0 :             UpdatePlayGround();
     849             :         }
     850             : 
     851           0 :         m_aLinesPlayground.EnablePaint(sal_True);
     852           0 :         m_aLinesPlayground.Invalidate(INVALIDATE_CHILDREN);
     853           0 :     }
     854             : 
     855             :     //------------------------------------------------------------------
     856           0 :     IMPL_LINK(OBrowserListBox, ScrollHdl, ScrollBar*, _pScrollBar )
     857             :     {
     858             :         DBG_ASSERT(_pScrollBar == &m_aVScroll, "OBrowserListBox::ScrollHdl: where does this come from?");
     859             :         (void)_pScrollBar;
     860             : 
     861             :         // disable painting to prevent flicker
     862           0 :         m_aLinesPlayground.EnablePaint(sal_False);
     863             : 
     864           0 :         sal_Int32 nThumbPos = m_aVScroll.GetThumbPos();
     865             : 
     866           0 :         sal_Int32 nDelta = m_aVScroll.GetDelta();
     867           0 :         m_nYOffset = -nThumbPos * m_nRowHeight;
     868             : 
     869           0 :         sal_uInt16 nEnd = (sal_uInt16)(nThumbPos + CalcVisibleLines());
     870             : 
     871           0 :         m_aLinesPlayground.Scroll(0, -nDelta * m_nRowHeight, SCROLL_CHILDREN);
     872             : 
     873           0 :         if (1 == nDelta)
     874             :         {
     875           0 :             PositionLine(nEnd-1);
     876           0 :             PositionLine(nEnd);
     877             :         }
     878           0 :         else if (nDelta==-1)
     879             :         {
     880           0 :             PositionLine((sal_uInt16)nThumbPos);
     881             :         }
     882           0 :         else if (nDelta!=0 || m_aVScroll.GetType() == SCROLL_DONTKNOW)
     883             :         {
     884           0 :             UpdatePlayGround();
     885             :         }
     886             : 
     887           0 :         m_aLinesPlayground.EnablePaint(sal_True);
     888           0 :         return 0;
     889             :     }
     890             : 
     891             :     //------------------------------------------------------------------
     892           0 :     void OBrowserListBox::buttonClicked( OBrowserLine* _pLine, sal_Bool _bPrimary )
     893             :     {
     894             :         DBG_ASSERT( _pLine, "OBrowserListBox::buttonClicked: invalid browser line!" );
     895           0 :         if ( _pLine && m_pLineListener )
     896             :         {
     897           0 :             m_pLineListener->Clicked( _pLine->GetEntryName(), _bPrimary );
     898             :         }
     899           0 :     }
     900             : 
     901             :     //------------------------------------------------------------------
     902           0 :     void OBrowserListBox::impl_setControlAsPropertyValue( const ListBoxLine& _rLine, const Any& _rPropertyValue )
     903             :     {
     904           0 :         Reference< XPropertyControl > xControl( _rLine.pLine->getControl() );
     905             :         try
     906             :         {
     907           0 :             if ( _rPropertyValue.getValueType().equals( _rLine.pLine->getControl()->getValueType() ) )
     908             :             {
     909           0 :                 xControl->setValue( _rPropertyValue );
     910             :             }
     911             :             else
     912             :             {
     913             :     #ifdef DBG_UTIL
     914             :                 if ( !_rLine.xHandler.is() )
     915             :                 {
     916             :                     OString sMessage( "OBrowserListBox::impl_setControlAsPropertyValue: no handler -> no conversion (property: '" );
     917             :                     OUString sPropertyName( _rLine.pLine->GetEntryName() );
     918             :                     sMessage += OString( sPropertyName.getStr(), sPropertyName.getLength(), RTL_TEXTENCODING_ASCII_US );
     919             :                     sMessage += OString( "')!" );
     920             :                     OSL_FAIL( sMessage.getStr() );
     921             :                 }
     922             :     #endif
     923           0 :                 if ( _rLine.xHandler.is() )
     924             :                 {
     925           0 :                     Any aControlValue = _rLine.xHandler->convertToControlValue(
     926           0 :                         _rLine.pLine->GetEntryName(), _rPropertyValue, xControl->getValueType() );
     927           0 :                     xControl->setValue( aControlValue );
     928             :                 }
     929             :             }
     930             :         }
     931           0 :         catch( const Exception& )
     932             :         {
     933             :             DBG_UNHANDLED_EXCEPTION();
     934           0 :         }
     935           0 :     }
     936             : 
     937             :     //------------------------------------------------------------------
     938           0 :     Any OBrowserListBox::impl_getControlAsPropertyValue( const ListBoxLine& _rLine ) const
     939             :     {
     940           0 :         Reference< XPropertyControl > xControl( _rLine.pLine->getControl() );
     941           0 :         Any aPropertyValue;
     942             :         try
     943             :         {
     944             :         #ifdef DBG_UTIL
     945             :             if ( !_rLine.xHandler.is() )
     946             :             {
     947             :                 OString sMessage( "OBrowserListBox::impl_getControlAsPropertyValue: no handler -> no conversion (property: '" );
     948             :                 OUString sPropertyName( _rLine.pLine->GetEntryName() );
     949             :                 sMessage += OString( sPropertyName.getStr(), sPropertyName.getLength(), RTL_TEXTENCODING_ASCII_US );
     950             :                 sMessage += OString( "')!" );
     951             :                 OSL_FAIL( sMessage.getStr() );
     952             :             }
     953             :         #endif
     954           0 :             if ( _rLine.xHandler.is() )
     955           0 :                 aPropertyValue = _rLine.xHandler->convertToPropertyValue( _rLine.pLine->GetEntryName(), xControl->getValue() );
     956             :             else
     957           0 :                 aPropertyValue = xControl->getValue();
     958             :         }
     959           0 :         catch( const Exception& )
     960             :         {
     961             :             DBG_UNHANDLED_EXCEPTION();
     962             :         }
     963           0 :         return aPropertyValue;
     964             :     }
     965             : 
     966             :     //------------------------------------------------------------------
     967           0 :     sal_uInt16 OBrowserListBox::impl_getControlPos( const Reference< XPropertyControl >& _rxControl ) const
     968             :     {
     969           0 :         for ( ListBoxLines::const_iterator search = m_aLines.begin(); search != m_aLines.end(); ++search )
     970           0 :             if ( search->pLine->getControl().get() == _rxControl.get() )
     971           0 :                 return sal_uInt16( search - m_aLines.begin() );
     972             : 
     973             :         OSL_FAIL( "OBrowserListBox::impl_getControlPos: invalid control - not part of any of our lines!" );
     974           0 :         return (sal_uInt16)-1;
     975             :     }
     976             : 
     977             :     //--------------------------------------------------------------------
     978           0 :     void SAL_CALL OBrowserListBox::focusGained( const Reference< XPropertyControl >& _rxControl ) throw (RuntimeException)
     979             :     {
     980             :         DBG_TESTSOLARMUTEX();
     981             : 
     982             :         DBG_ASSERT( _rxControl.is(), "OBrowserListBox::focusGained: invalid event source!" );
     983           0 :         if ( !_rxControl.is() )
     984           0 :             return;
     985             : 
     986           0 :         if ( m_pControlObserver )
     987           0 :             m_pControlObserver->focusGained( _rxControl );
     988             : 
     989           0 :         m_xActiveControl = _rxControl;
     990           0 :         ShowEntry( impl_getControlPos( m_xActiveControl ) );
     991             :     }
     992             : 
     993             :     //--------------------------------------------------------------------
     994           0 :     void SAL_CALL OBrowserListBox::valueChanged( const Reference< XPropertyControl >& _rxControl ) throw (RuntimeException)
     995             :     {
     996             :         DBG_TESTSOLARMUTEX();
     997             : 
     998             :         DBG_ASSERT( _rxControl.is(), "OBrowserListBox::valueChanged: invalid event source!" );
     999           0 :         if ( !_rxControl.is() )
    1000           0 :             return;
    1001             : 
    1002           0 :         if ( m_pControlObserver )
    1003           0 :             m_pControlObserver->valueChanged( _rxControl );
    1004             : 
    1005           0 :         if ( m_pLineListener )
    1006             :         {
    1007           0 :             const ListBoxLine& rLine = m_aLines[ impl_getControlPos( _rxControl ) ];
    1008             :             m_pLineListener->Commit(
    1009           0 :                 rLine.pLine->GetEntryName(),
    1010             :                 impl_getControlAsPropertyValue( rLine )
    1011           0 :             );
    1012             :         }
    1013             :     }
    1014             : 
    1015             :     //--------------------------------------------------------------------
    1016           0 :     void SAL_CALL OBrowserListBox::activateNextControl( const Reference< XPropertyControl >& _rxCurrentControl ) throw (RuntimeException)
    1017             :     {
    1018             :         DBG_TESTSOLARMUTEX();
    1019             : 
    1020           0 :         sal_uInt16 nLine = impl_getControlPos( _rxCurrentControl );
    1021             : 
    1022             :         // cycle forwards, 'til we've the next control which can grab the focus
    1023           0 :         ++nLine;
    1024           0 :         while ( static_cast< size_t >( nLine ) < m_aLines.size() )
    1025             :         {
    1026           0 :             if ( m_aLines[nLine].pLine->GrabFocus() )
    1027           0 :                 break;
    1028           0 :             ++nLine;
    1029             :         }
    1030             : 
    1031             :         // wrap around?
    1032           0 :         if ( ( static_cast< size_t >( nLine ) >= m_aLines.size() ) && ( m_aLines.size() > 0 ) )
    1033           0 :             m_aLines[0].pLine->GrabFocus();
    1034           0 :     }
    1035             : 
    1036             :     //------------------------------------------------------------------
    1037             :     namespace
    1038             :     {
    1039             :         //..............................................................
    1040           0 :         void lcl_implDisposeControl_nothrow( const Reference< XPropertyControl >& _rxControl )
    1041             :         {
    1042           0 :             if ( !_rxControl.is() )
    1043           0 :                 return;
    1044             :             try
    1045             :             {
    1046           0 :                 _rxControl->setControlContext( NULL );
    1047           0 :                 Reference< XComponent > xControlComponent( _rxControl, UNO_QUERY );
    1048           0 :                 if ( xControlComponent.is() )
    1049           0 :                     xControlComponent->dispose();
    1050             :             }
    1051           0 :             catch( const Exception& )
    1052             :             {
    1053             :                 DBG_UNHANDLED_EXCEPTION();
    1054             :             }
    1055             :         }
    1056             :     }
    1057             : 
    1058             :     //------------------------------------------------------------------
    1059           0 :     void OBrowserListBox::Clear()
    1060             :     {
    1061           0 :         for ( ListBoxLines::iterator loop = m_aLines.begin(); loop != m_aLines.end(); ++loop )
    1062             :         {
    1063             :             // hide the line
    1064           0 :             loop->pLine->Hide();
    1065             :             // reset the listener
    1066           0 :             lcl_implDisposeControl_nothrow( loop->pLine->getControl() );
    1067             :         }
    1068             : 
    1069           0 :         clearContainer( m_aLines );
    1070           0 :     }
    1071             : 
    1072             :     //------------------------------------------------------------------
    1073           0 :     sal_Bool OBrowserListBox::RemoveEntry( const OUString& _rName )
    1074             :     {
    1075           0 :         sal_uInt16 nPos = 0;
    1076           0 :         ListBoxLines::iterator it = m_aLines.begin();
    1077           0 :         for ( ; it != m_aLines.end() && ( it->aName != _rName ); ++it, ++nPos )
    1078             :             ;
    1079             : 
    1080           0 :         if ( it == m_aLines.end() )
    1081           0 :             return sal_False;
    1082             : 
    1083           0 :         m_aLines.erase( it );
    1084           0 :         m_aOutOfDateLines.erase( (sal_uInt16)m_aLines.size() );
    1085             : 
    1086             :         // update the positions of possibly affected lines
    1087           0 :         while ( nPos < m_aLines.size() )
    1088           0 :             m_aOutOfDateLines.insert( nPos++ );
    1089           0 :         UpdatePosNSize( );
    1090             : 
    1091           0 :         return sal_True;
    1092             :     }
    1093             : 
    1094             :     //------------------------------------------------------------------
    1095           0 :     void OBrowserListBox::ChangeEntry( const OLineDescriptor& _rPropertyData, sal_uInt16 nPos )
    1096             :     {
    1097             :         OSL_PRECOND( _rPropertyData.Control.is(), "OBrowserListBox::ChangeEntry: invalid control!" );
    1098           0 :         if ( !_rPropertyData.Control.is() )
    1099           0 :             return;
    1100             : 
    1101           0 :         if ( nPos == EDITOR_LIST_REPLACE_EXISTING )
    1102           0 :             nPos = GetPropertyPos( _rPropertyData.sName );
    1103             : 
    1104           0 :         if ( nPos < m_aLines.size() )
    1105             :         {
    1106           0 :             Window* pRefWindow = NULL;
    1107           0 :             if ( nPos > 0 )
    1108           0 :                 pRefWindow = m_aLines[nPos-1].pLine->GetRefWindow();
    1109             : 
    1110             :             // the current line and control
    1111           0 :             ListBoxLine& rLine = m_aLines[nPos];
    1112             : 
    1113             :             // the old control and some data about it
    1114           0 :             Reference< XPropertyControl > xControl = rLine.pLine->getControl();
    1115           0 :             Window* pControlWindow = rLine.pLine->getControlWindow();
    1116           0 :             Point aControlPos;
    1117           0 :             if ( pControlWindow )
    1118           0 :                 aControlPos = pControlWindow->GetPosPixel();
    1119             : 
    1120             :             // clean up the old control
    1121           0 :             lcl_implDisposeControl_nothrow( xControl );
    1122             : 
    1123             :             // set the new control at the line
    1124           0 :             rLine.pLine->setControl( _rPropertyData.Control );
    1125           0 :             xControl = rLine.pLine->getControl();
    1126             : 
    1127           0 :             if ( xControl.is() )
    1128           0 :                 xControl->setControlContext( m_pControlContextImpl.get() );
    1129             : 
    1130             :             // the initial property value
    1131           0 :             if ( _rPropertyData.bUnknownValue )
    1132           0 :                 xControl->setValue( Any() );
    1133             :             else
    1134           0 :                 impl_setControlAsPropertyValue( rLine, _rPropertyData.aValue );
    1135             : 
    1136           0 :             rLine.pLine->SetTitle(_rPropertyData.DisplayName);
    1137           0 :             rLine.xHandler = _rPropertyData.xPropertyHandler;
    1138             : 
    1139           0 :             sal_uInt16 nTextWidth = (sal_uInt16)m_aLinesPlayground.GetTextWidth(_rPropertyData.DisplayName);
    1140           0 :             if (m_nTheNameSize< nTextWidth)
    1141           0 :                 m_nTheNameSize = nTextWidth;
    1142             : 
    1143           0 :             if ( _rPropertyData.HasPrimaryButton )
    1144             :             {
    1145           0 :                 if ( !_rPropertyData.PrimaryButtonImageURL.isEmpty() )
    1146           0 :                     rLine.pLine->ShowBrowseButton( _rPropertyData.PrimaryButtonImageURL, true );
    1147           0 :                 else if ( _rPropertyData.PrimaryButtonImage.is() )
    1148           0 :                     rLine.pLine->ShowBrowseButton( Image( _rPropertyData.PrimaryButtonImage ), true );
    1149             :                 else
    1150           0 :                     rLine.pLine->ShowBrowseButton( true );
    1151             : 
    1152           0 :                 if ( _rPropertyData.HasSecondaryButton )
    1153             :                 {
    1154           0 :                     if ( !_rPropertyData.SecondaryButtonImageURL.isEmpty() )
    1155           0 :                         rLine.pLine->ShowBrowseButton( _rPropertyData.SecondaryButtonImageURL, false );
    1156           0 :                     else if ( _rPropertyData.SecondaryButtonImage.is() )
    1157           0 :                         rLine.pLine->ShowBrowseButton( Image( _rPropertyData.SecondaryButtonImage ), false );
    1158             :                     else
    1159           0 :                         rLine.pLine->ShowBrowseButton( false );
    1160             :                 }
    1161             :                 else
    1162           0 :                     rLine.pLine->HideBrowseButton( false );
    1163             : 
    1164           0 :                 rLine.pLine->SetClickListener( this );
    1165             :             }
    1166             :             else
    1167             :             {
    1168           0 :                 rLine.pLine->HideBrowseButton( true );
    1169           0 :                 rLine.pLine->HideBrowseButton( false );
    1170             :             }
    1171             : 
    1172             :             DBG_ASSERT( ( _rPropertyData.IndentLevel == 0 ) || ( _rPropertyData.IndentLevel == 1 ),
    1173             :                 "OBrowserListBox::ChangeEntry: unsupported indent level!" );
    1174           0 :             rLine.pLine->IndentTitle( _rPropertyData.IndentLevel > 0 );
    1175             : 
    1176           0 :             if ( nPos > 0 )
    1177           0 :                 rLine.pLine->SetTabOrder( pRefWindow, WINDOW_ZORDER_BEHIND );
    1178             :             else
    1179           0 :                 rLine.pLine->SetTabOrder( pRefWindow, WINDOW_ZORDER_FIRST );
    1180             : 
    1181           0 :             m_aOutOfDateLines.insert( nPos );
    1182             :             rLine.pLine->SetComponentHelpIds(
    1183             :                 HelpIdUrl::getHelpId( _rPropertyData.HelpURL ),
    1184             :                 OUStringToOString( _rPropertyData.PrimaryButtonId, RTL_TEXTENCODING_UTF8 ),
    1185             :                 OUStringToOString( _rPropertyData.SecondaryButtonId, RTL_TEXTENCODING_UTF8 )
    1186           0 :             );
    1187             : 
    1188           0 :             if ( _rPropertyData.bReadOnly )
    1189             :             {
    1190           0 :                 rLine.pLine->SetReadOnly( true );
    1191             : 
    1192             :                 // user controls (i.e. the ones not provided by the usual
    1193             :                 // XPropertyControlFactory) have no chance to know that they should be read-only,
    1194             :                 // since XPropertyHandler::describePropertyLine does not transport this
    1195             :                 // information.
    1196             :                 // So, we manually switch this to read-only.
    1197           0 :                 if ( xControl.is() && ( xControl->getControlType() == PropertyControlType::Unknown ) )
    1198             :                 {
    1199           0 :                     Edit* pControlWindowAsEdit = dynamic_cast< Edit* >( rLine.pLine->getControlWindow() );
    1200           0 :                     if ( pControlWindowAsEdit )
    1201           0 :                         pControlWindowAsEdit->SetReadOnly( sal_True );
    1202             :                     else
    1203           0 :                         pControlWindowAsEdit->Enable( sal_False );
    1204             :                 }
    1205           0 :             }
    1206             :         }
    1207             :     }
    1208             : 
    1209             :     //------------------------------------------------------------------
    1210           0 :     long OBrowserListBox::PreNotify( NotifyEvent& _rNEvt )
    1211             :     {
    1212           0 :         switch ( _rNEvt.GetType() )
    1213             :         {
    1214             :         case EVENT_KEYINPUT:
    1215             :         {
    1216           0 :             const KeyEvent* pKeyEvent = _rNEvt.GetKeyEvent();
    1217           0 :             if  (   ( pKeyEvent->GetKeyCode().GetModifier() != 0 )
    1218           0 :                 ||  (   ( pKeyEvent->GetKeyCode().GetCode() != KEY_PAGEUP )
    1219           0 :                     &&  ( pKeyEvent->GetKeyCode().GetCode() != KEY_PAGEDOWN )
    1220             :                     )
    1221             :                 )
    1222           0 :                 break;
    1223             : 
    1224           0 :             long nScrollOffset = 0;
    1225           0 :             if ( m_aVScroll.IsVisible() )
    1226             :             {
    1227           0 :                 if ( pKeyEvent->GetKeyCode().GetCode() == KEY_PAGEUP )
    1228           0 :                     nScrollOffset = -m_aVScroll.GetPageSize();
    1229           0 :                 else if ( pKeyEvent->GetKeyCode().GetCode() == KEY_PAGEDOWN )
    1230           0 :                     nScrollOffset = m_aVScroll.GetPageSize();
    1231             :             }
    1232             : 
    1233           0 :             if ( nScrollOffset )
    1234             :             {
    1235           0 :                 long nNewThumbPos = m_aVScroll.GetThumbPos() + nScrollOffset;
    1236           0 :                 nNewThumbPos = ::std::max( nNewThumbPos, m_aVScroll.GetRangeMin() );
    1237           0 :                 nNewThumbPos = ::std::min( nNewThumbPos, m_aVScroll.GetRangeMax() );
    1238           0 :                 m_aVScroll.DoScroll( nNewThumbPos );
    1239           0 :                 nNewThumbPos = m_aVScroll.GetThumbPos();
    1240             : 
    1241           0 :                 sal_uInt16 nFocusControlPos = 0;
    1242           0 :                 sal_uInt16 nActiveControlPos = impl_getControlPos( m_xActiveControl );
    1243           0 :                 if ( nActiveControlPos < nNewThumbPos )
    1244           0 :                     nFocusControlPos = (sal_uInt16)nNewThumbPos;
    1245           0 :                 else if ( nActiveControlPos >= nNewThumbPos + CalcVisibleLines() )
    1246           0 :                     nFocusControlPos = (sal_uInt16)nNewThumbPos + CalcVisibleLines() - 1;
    1247           0 :                 if ( nFocusControlPos )
    1248             :                 {
    1249           0 :                     if ( nFocusControlPos < m_aLines.size() )
    1250             :                     {
    1251           0 :                         m_aLines[ nFocusControlPos ].pLine->GrabFocus();
    1252             :                     }
    1253             :                     else
    1254             :                         OSL_FAIL( "OBrowserListBox::PreNotify: internal error, invalid focus control position!" );
    1255             :                 }
    1256             :             }
    1257             : 
    1258           0 :             return 1L;
    1259             :             // handled this. In particular, we also consume PageUp/Down events if we do not use them for scrolling,
    1260             :             // otherwise they would be used to scroll the document view, which does not sound like it is desired by
    1261             :             // the user.
    1262             :         }
    1263             :         }
    1264           0 :         return Control::PreNotify( _rNEvt );
    1265             :     }
    1266             : 
    1267             :     //------------------------------------------------------------------
    1268           0 :     long OBrowserListBox::Notify( NotifyEvent& _rNEvt )
    1269             :     {
    1270           0 :         switch ( _rNEvt.GetType() )
    1271             :         {
    1272             :         case EVENT_COMMAND:
    1273             :         {
    1274           0 :             const CommandEvent* pCommand = _rNEvt.GetCommandEvent();
    1275           0 :             if  (   ( COMMAND_WHEEL == pCommand->GetCommand() )
    1276           0 :                 ||  ( COMMAND_STARTAUTOSCROLL == pCommand->GetCommand() )
    1277           0 :                 ||  ( COMMAND_AUTOSCROLL == pCommand->GetCommand() )
    1278             :                 )
    1279             :             {
    1280             :                 // interested in scroll events if we have a scrollbar
    1281           0 :                 if ( m_aVScroll.IsVisible() )
    1282             :                 {
    1283           0 :                     HandleScrollCommand( *pCommand, NULL, &m_aVScroll );
    1284             :                 }
    1285             :             }
    1286             :         }
    1287           0 :         break;
    1288             :         }
    1289             : 
    1290           0 :         return Control::Notify( _rNEvt );
    1291             :     }
    1292             : 
    1293             : //............................................................................
    1294           3 : } // namespace pcr
    1295             : //............................................................................
    1296             : 
    1297             : 
    1298             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10