LCOV - code coverage report
Current view: top level - forms/source/component - Button.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 213 314 67.8 %
Date: 2015-06-13 12:38:46 Functions: 44 55 80.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             : 
      21             : #include "Button.hxx"
      22             : 
      23             : #include <com/sun/star/awt/XVclWindowPeer.hpp>
      24             : 
      25             : #include <comphelper/streamsection.hxx>
      26             : #include <comphelper/basicio.hxx>
      27             : #include <comphelper/processfactory.hxx>
      28             : #include <tools/diagnose_ex.h>
      29             : #include <tools/debug.hxx>
      30             : #include <tools/urlobj.hxx>
      31             : #include <vcl/svapp.hxx>
      32             : #include <osl/mutex.hxx>
      33             : 
      34             : namespace frm
      35             : {
      36             : 
      37             : 
      38             : using namespace ::com::sun::star::uno;
      39             : using namespace ::com::sun::star::sdb;
      40             : using namespace ::com::sun::star::sdbc;
      41             : using namespace ::com::sun::star::sdbcx;
      42             : using namespace ::com::sun::star::beans;
      43             : using namespace ::com::sun::star::container;
      44             : using namespace ::com::sun::star::form;
      45             : using namespace ::com::sun::star::awt;
      46             : using namespace ::com::sun::star::io;
      47             : using namespace ::com::sun::star::lang;
      48             : using namespace ::com::sun::star::util;
      49             : using ::com::sun::star::frame::XDispatchProviderInterceptor;
      50             : 
      51             : 
      52             : //= OButtonModel
      53             : 
      54             : 
      55          54 : OButtonModel::OButtonModel(const Reference<XComponentContext>& _rxFactory)
      56             :     :OClickableImageBaseModel( _rxFactory, VCL_CONTROLMODEL_COMMANDBUTTON, FRM_SUN_CONTROL_COMMANDBUTTON )
      57             :                                     // use the old control name for compatibility reasons
      58             :     ,m_aResetHelper( *this, m_aMutex )
      59          54 :     ,m_eDefaultState( TRISTATE_FALSE )
      60             : {
      61          54 :     m_nClassId = FormComponentType::COMMANDBUTTON;
      62          54 : }
      63             : 
      64             : 
      65        9726 : Any SAL_CALL OButtonModel::queryAggregation( const Type& _type ) throw(RuntimeException, std::exception)
      66             : {
      67        9726 :     Any aReturn = OClickableImageBaseModel::queryAggregation( _type );
      68        9726 :     if ( !aReturn.hasValue() )
      69         764 :         aReturn = OButtonModel_Base::queryInterface( _type );
      70        9726 :     return aReturn;
      71             : }
      72             : 
      73             : 
      74          22 : Sequence< Type > OButtonModel::_getTypes()
      75             : {
      76             :     return ::comphelper::concatSequences(
      77             :         OClickableImageBaseModel::_getTypes(),
      78             :         OButtonModel_Base::getTypes()
      79          22 :     );
      80             : }
      81             : 
      82             : 
      83           0 : OButtonModel::OButtonModel( const OButtonModel* _pOriginal, const Reference<XComponentContext>& _rxFactory )
      84             :     :OClickableImageBaseModel( _pOriginal, _rxFactory )
      85             :     ,m_aResetHelper( *this, m_aMutex )
      86           0 :     ,m_eDefaultState( _pOriginal->m_eDefaultState )
      87             : {
      88           0 :     m_nClassId = FormComponentType::COMMANDBUTTON;
      89             : 
      90           0 :     implInitializeImageURL();
      91           0 : }
      92             : 
      93             : 
      94         102 : OButtonModel::~OButtonModel()
      95             : {
      96         102 : }
      97             : 
      98             : 
      99          51 : void OButtonModel::describeFixedProperties( Sequence< Property >& _rProps ) const
     100             : {
     101          51 :     BEGIN_DESCRIBE_PROPERTIES( 6, OClickableImageBaseModel )
     102          51 :         DECL_PROP1( BUTTONTYPE,             FormButtonType,             BOUND );
     103          51 :         DECL_PROP1( DEFAULT_STATE,          sal_Int16,                  BOUND );
     104          51 :         DECL_PROP1( DISPATCHURLINTERNAL,    sal_Bool,                   BOUND );
     105          51 :         DECL_PROP1( TARGET_URL,             OUString,            BOUND );
     106          51 :         DECL_PROP1( TARGET_FRAME,           OUString,            BOUND );
     107          51 :         DECL_PROP1( TABINDEX,               sal_Int16,                  BOUND );
     108             :     END_DESCRIBE_PROPERTIES();
     109          51 : }
     110             : 
     111             : 
     112           0 : IMPLEMENT_DEFAULT_CLONING( OButtonModel )
     113             : 
     114             : // XServiceInfo
     115             : 
     116           1 : StringSequence  OButtonModel::getSupportedServiceNames() throw(std::exception)
     117             : {
     118           1 :     StringSequence aSupported = OClickableImageBaseModel::getSupportedServiceNames();
     119           1 :     aSupported.realloc( aSupported.getLength() + 2 );
     120             : 
     121           1 :     OUString* pArray = aSupported.getArray();
     122           1 :     pArray[ aSupported.getLength() - 2 ] = FRM_SUN_COMPONENT_COMMANDBUTTON;
     123           1 :     pArray[ aSupported.getLength() - 1 ] = FRM_COMPONENT_COMMANDBUTTON;
     124             : 
     125           1 :     return aSupported;
     126             : }
     127             : 
     128             : 
     129           2 : OUString OButtonModel::getServiceName() throw ( ::com::sun::star::uno::RuntimeException, std::exception)
     130             : {
     131           2 :     return OUString(FRM_COMPONENT_COMMANDBUTTON); // old (non-sun) name for compatibility !
     132             : }
     133             : 
     134             : 
     135           0 : void OButtonModel::write(const Reference<XObjectOutputStream>& _rxOutStream) throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException, std::exception)
     136             : {
     137           0 :     OClickableImageBaseModel::write(_rxOutStream);
     138             : 
     139           0 :     _rxOutStream->writeShort(0x0003);   // Version
     140             : 
     141             :     {
     142           0 :         OStreamSection aSection( _rxOutStream.get() );
     143             :             // this will allow readers to skip unknown bytes in their dtor
     144             : 
     145           0 :         _rxOutStream->writeShort( (sal_uInt16)m_eButtonType );
     146             : 
     147           0 :         OUString sTmp = INetURLObject::decode( m_sTargetURL, INetURLObject::DECODE_UNAMBIGUOUS);
     148           0 :         _rxOutStream << sTmp;
     149           0 :         _rxOutStream << m_sTargetFrame;
     150           0 :         writeHelpTextCompatibly(_rxOutStream);
     151           0 :         _rxOutStream << isDispatchUrlInternal();
     152             :     }
     153           0 : }
     154             : 
     155             : 
     156           0 : void OButtonModel::read(const Reference<XObjectInputStream>& _rxInStream) throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException, std::exception)
     157             : {
     158           0 :     OClickableImageBaseModel::read(_rxInStream);
     159             : 
     160           0 :     sal_uInt16 nVersion = _rxInStream->readShort();     // Version
     161           0 :     switch (nVersion)
     162             :     {
     163             :         case 0x0001:
     164             :         {
     165           0 :             m_eButtonType = (FormButtonType)_rxInStream->readShort();
     166             : 
     167           0 :             _rxInStream >> m_sTargetURL;
     168           0 :             _rxInStream >> m_sTargetFrame;
     169             :         }
     170           0 :         break;
     171             : 
     172             :         case 0x0002:
     173             :         {
     174           0 :             m_eButtonType = (FormButtonType)_rxInStream->readShort();
     175             : 
     176           0 :             _rxInStream >> m_sTargetURL;
     177           0 :             _rxInStream >> m_sTargetFrame;
     178           0 :             readHelpTextCompatibly(_rxInStream);
     179             :         }
     180           0 :         break;
     181             : 
     182             :         case 0x0003:
     183             :         {
     184           0 :             OStreamSection aSection( _rxInStream.get() );
     185             :             // this will skip any unknown bytes in it's dtor
     186             : 
     187             :             // button type
     188           0 :             m_eButtonType = (FormButtonType)_rxInStream->readShort();
     189             : 
     190             :             // URL
     191           0 :             _rxInStream >> m_sTargetURL;
     192             : 
     193             :             // target frame
     194           0 :             _rxInStream >> m_sTargetFrame;
     195             : 
     196             :             // help text
     197           0 :             readHelpTextCompatibly(_rxInStream);
     198             : 
     199             :             // DispatchInternal
     200             :             bool bDispath;
     201           0 :             _rxInStream >> bDispath;
     202           0 :             setDispatchUrlInternal(bDispath);
     203             :         }
     204           0 :         break;
     205             : 
     206             :         default:
     207             :             OSL_FAIL("OButtonModel::read : unknown version !");
     208           0 :             m_eButtonType = FormButtonType_PUSH;
     209           0 :             m_sTargetURL.clear();
     210           0 :             m_sTargetFrame.clear();
     211           0 :             break;
     212             :     }
     213           0 : }
     214             : 
     215             : 
     216          51 : void SAL_CALL OButtonModel::disposing()
     217             : {
     218          51 :     m_aResetHelper.disposing();
     219          51 :     OClickableImageBaseModel::disposing();
     220          51 : }
     221             : 
     222             : 
     223           0 : void SAL_CALL OButtonModel::reset() throw (RuntimeException, std::exception)
     224             : {
     225           0 :     if ( !m_aResetHelper.approveReset() )
     226           0 :         return;
     227             : 
     228           0 :     impl_resetNoBroadcast_nothrow();
     229             : 
     230           0 :     m_aResetHelper.notifyResetted();
     231             : }
     232             : 
     233             : 
     234          31 : void SAL_CALL OButtonModel::addResetListener( const Reference< XResetListener >& _listener ) throw (RuntimeException, std::exception)
     235             : {
     236          31 :     m_aResetHelper.addResetListener( _listener );
     237          31 : }
     238             : 
     239             : 
     240          31 : void SAL_CALL OButtonModel::removeResetListener( const Reference< XResetListener >& _listener ) throw (RuntimeException, std::exception)
     241             : {
     242          31 :     m_aResetHelper.removeResetListener( _listener );
     243          31 : }
     244             : 
     245             : 
     246        3788 : void SAL_CALL OButtonModel::getFastPropertyValue( Any& _rValue, sal_Int32 _nHandle ) const
     247             : {
     248        3788 :     switch ( _nHandle )
     249             :     {
     250             :     case PROPERTY_ID_DEFAULT_STATE:
     251          52 :         _rValue <<= (sal_Int16)m_eDefaultState;
     252          52 :         break;
     253             : 
     254             :     default:
     255        3736 :         OClickableImageBaseModel::getFastPropertyValue( _rValue, _nHandle );
     256        3736 :         break;
     257             :     }
     258        3788 : }
     259             : 
     260             : 
     261         142 : void SAL_CALL OButtonModel::setFastPropertyValue_NoBroadcast( sal_Int32 _nHandle, const Any& _rValue ) throw (Exception, std::exception)
     262             : {
     263         142 :     switch ( _nHandle )
     264             :     {
     265             :     case PROPERTY_ID_DEFAULT_STATE:
     266             :     {
     267           0 :         sal_Int16 nDefaultState( (sal_Int16)TRISTATE_FALSE );
     268           0 :         OSL_VERIFY( _rValue >>= nDefaultState );
     269           0 :         m_eDefaultState = (ToggleState)nDefaultState;
     270           0 :         impl_resetNoBroadcast_nothrow();
     271             :     }
     272           0 :     break;
     273             : 
     274             :     default:
     275         142 :         OClickableImageBaseModel::setFastPropertyValue_NoBroadcast( _nHandle, _rValue );
     276         142 :         break;
     277             :     }
     278         142 : }
     279             : 
     280             : 
     281         197 : sal_Bool SAL_CALL OButtonModel::convertFastPropertyValue( Any& _rConvertedValue, Any& _rOldValue, sal_Int32 _nHandle, const Any& _rValue ) throw (IllegalArgumentException)
     282             : {
     283         197 :     bool bModified = false;
     284         197 :     switch ( _nHandle )
     285             :     {
     286             :     case PROPERTY_ID_DEFAULT_STATE:
     287           1 :         bModified = tryPropertyValue( _rConvertedValue, _rOldValue, _rValue, (sal_Int16)m_eDefaultState );
     288           1 :         break;
     289             : 
     290             :     default:
     291         196 :         bModified = OClickableImageBaseModel::convertFastPropertyValue( _rConvertedValue, _rOldValue, _nHandle, _rValue );
     292         196 :         break;
     293             :     }
     294         197 :     return bModified;
     295             : }
     296             : 
     297             : 
     298           8 : Any OButtonModel::getPropertyDefaultByHandle( sal_Int32 _nHandle ) const
     299             : {
     300           8 :     Any aDefault;
     301           8 :     switch ( _nHandle )
     302             :     {
     303             :     case PROPERTY_ID_DEFAULT_STATE:
     304           2 :         aDefault <<= (sal_Int16)TRISTATE_FALSE;
     305           2 :         break;
     306             : 
     307             :     default:
     308           6 :         aDefault = OClickableImageBaseModel::getPropertyDefaultByHandle( _nHandle );
     309           6 :         break;
     310             :     }
     311           8 :     return aDefault;
     312             : }
     313             : 
     314             : 
     315           0 : void OButtonModel::impl_resetNoBroadcast_nothrow()
     316             : {
     317             :     try
     318             :     {
     319           0 :         setPropertyValue( PROPERTY_STATE, getPropertyValue( PROPERTY_DEFAULT_STATE ) );
     320             :     }
     321           0 :     catch( const Exception& )
     322             :     {
     323             :         DBG_UNHANDLED_EXCEPTION();
     324             :     }
     325           0 : }
     326             : 
     327             : 
     328             : // OButtonControl
     329             : 
     330             : 
     331          62 : Sequence<Type> OButtonControl::_getTypes()
     332             : {
     333             :     return ::comphelper::concatSequences(
     334             :         OButtonControl_BASE::getTypes(),
     335             :         OClickableImageBaseControl::_getTypes(),
     336             :         OFormNavigationHelper::getTypes()
     337          62 :     );
     338             : }
     339             : 
     340             : 
     341           1 : StringSequence  OButtonControl::getSupportedServiceNames() throw(std::exception)
     342             : {
     343           1 :     StringSequence aSupported = OClickableImageBaseControl::getSupportedServiceNames();
     344           1 :     aSupported.realloc(aSupported.getLength() + 2);
     345             : 
     346           1 :     OUString*pArray = aSupported.getArray();
     347           1 :     pArray[aSupported.getLength()-2] = FRM_SUN_CONTROL_COMMANDBUTTON;
     348           1 :     pArray[aSupported.getLength()-1] = STARDIV_ONE_FORM_CONTROL_COMMANDBUTTON;
     349           1 :     return aSupported;
     350             : }
     351             : 
     352             : 
     353         123 : OButtonControl::OButtonControl(const Reference<XComponentContext>& _rxFactory)
     354             :                  :OClickableImageBaseControl(_rxFactory, VCL_CONTROL_COMMANDBUTTON)
     355             :                  ,OFormNavigationHelper( _rxFactory )
     356             :                  ,m_nClickEvent( 0 )
     357             :                  ,m_nTargetUrlFeatureId( -1 )
     358         123 :                  ,m_bEnabledByPropertyValue( false )
     359             : {
     360         123 :     osl_atomic_increment(&m_refCount);
     361             :     {
     362             :         // Register as ActionListener
     363         123 :         Reference<XButton>  xButton;
     364         123 :         query_aggregation( m_xAggregate, xButton);
     365         123 :         if (xButton.is())
     366         123 :             xButton->addActionListener(this);
     367             :     }
     368             :     // For Listener: refcount at one
     369         123 :     osl_atomic_decrement(&m_refCount);
     370         123 : }
     371             : 
     372             : 
     373         345 : OButtonControl::~OButtonControl()
     374             : {
     375         115 :     if (m_nClickEvent)
     376           0 :         Application::RemoveUserEvent(m_nClickEvent);
     377         230 : }
     378             : 
     379             : // UNO binding
     380             : 
     381        3307 : Any SAL_CALL OButtonControl::queryAggregation(const Type& _rType) throw (RuntimeException, std::exception)
     382             : {
     383             :     // if asked for the XTypeProvider, don't let OButtonControl_BASE do this
     384        3307 :     Any aReturn;
     385        3307 :     if ( !_rType.equals( cppu::UnoType<XTypeProvider>::get() ) )
     386        3276 :         aReturn = OButtonControl_BASE::queryInterface( _rType );
     387             : 
     388        3307 :     if ( !aReturn.hasValue() )
     389        1661 :         aReturn = OClickableImageBaseControl::queryAggregation( _rType );
     390             : 
     391        3307 :     if ( !aReturn.hasValue() )
     392         164 :         aReturn = OFormNavigationHelper::queryInterface( _rType );
     393             : 
     394        3307 :     return aReturn;
     395             : }
     396             : 
     397             : 
     398         115 : void SAL_CALL OButtonControl::disposing()
     399             : {
     400         115 :     startOrStopModelPropertyListening( false );
     401             : 
     402         115 :     OClickableImageBaseControl::disposing();
     403         115 :     OFormNavigationHelper::dispose();
     404         115 : }
     405             : 
     406             : 
     407         432 : void SAL_CALL OButtonControl::disposing( const EventObject& _rSource ) throw( RuntimeException, std::exception )
     408             : {
     409         432 :     OControl::disposing( _rSource );
     410         432 :     OFormNavigationHelper::disposing( _rSource );
     411         432 : }
     412             : 
     413             : // ActionListener
     414             : 
     415           1 : void OButtonControl::actionPerformed(const ActionEvent& /*rEvent*/) throw ( ::com::sun::star::uno::RuntimeException, std::exception)
     416             : {
     417             :     // Asynchronous for css::util::URL-Button
     418           1 :     ImplSVEvent * n = Application::PostUserEvent( LINK(this, OButtonControl,OnClick) );
     419             :     {
     420           1 :         ::osl::MutexGuard aGuard( m_aMutex );
     421           1 :         m_nClickEvent = n;
     422             :     }
     423           1 : }
     424             : 
     425             : 
     426           2 : IMPL_LINK_NOARG(OButtonControl, OnClick)
     427             : {
     428           1 :     ::osl::ClearableMutexGuard aGuard( m_aMutex );
     429           1 :     m_nClickEvent = 0;
     430             : 
     431           1 :     if (m_aApproveActionListeners.getLength())
     432             :     {
     433             :         // if there are listeners, start the action in an own thread, to not allow
     434             :         // them to block us here (we're in the application's main thread)
     435           0 :         getImageProducerThread()->addEvent();
     436             :     }
     437             :     else
     438             :     {
     439             :         // Else, don't. We then must not notify the Listeners in any case,
     440             :         // not even if added later on.
     441           1 :         aGuard.clear();
     442             : 
     443             :         // recognize the button type
     444           1 :         Reference<XPropertySet>  xSet(getModel(), UNO_QUERY);
     445           1 :         if (!xSet.is())
     446           0 :             return 0L;
     447             : 
     448           1 :         if (FormButtonType_PUSH == *static_cast<FormButtonType const *>(xSet->getPropertyValue(PROPERTY_BUTTONTYPE).getValue()))
     449             :         {
     450             :             // notify the action listeners for a push button
     451           1 :             ::cppu::OInterfaceIteratorHelper aIter(m_aActionListeners);
     452           2 :             ActionEvent aEvt(static_cast<XWeak*>(this), m_aActionCommand);
     453           3 :             while(aIter.hasMoreElements() )
     454             :             {
     455             :                 // catch exceptions
     456             :                 // and catch them on a per-listener basis - if one listener fails, the others still need
     457             :                 // to get notified
     458             :                 try
     459             :                 {
     460           1 :                     static_cast< XActionListener* >( aIter.next() )->actionPerformed(aEvt);
     461             :                 }
     462             : #ifdef DBG_UTIL
     463             :                 catch( const RuntimeException& )
     464             :                 {
     465             :                     // silence this
     466             :                 }
     467             : #endif
     468           0 :                 catch( const Exception& )
     469             :                 {
     470             :                     OSL_FAIL( "OButtonControl::OnClick: caught a exception other than RuntimeException!" );
     471             :                 }
     472           1 :             }
     473             :         }
     474             :         else
     475           0 :             actionPerformed_Impl( false, ::com::sun::star::awt::MouseEvent() );
     476             :     }
     477           1 :     return 0L;
     478             : }
     479             : 
     480             : 
     481           0 : void OButtonControl::actionPerformed_Impl( bool _bNotifyListener, const ::com::sun::star::awt::MouseEvent& _rEvt )
     482             : {
     483             :     {
     484           0 :         sal_Int16 nFeatureId = -1;
     485             :         {
     486           0 :             ::osl::MutexGuard aGuard( m_aMutex );
     487           0 :             nFeatureId = m_nTargetUrlFeatureId;
     488             :         }
     489             : 
     490           0 :         if ( nFeatureId != -1 )
     491             :         {
     492           0 :             if ( !approveAction() )
     493           0 :                 return;
     494             : 
     495           0 :             SolarMutexGuard aGuard;
     496           0 :             dispatch( nFeatureId );
     497           0 :             return;
     498             :         }
     499             :     }
     500             : 
     501           0 :     OClickableImageBaseControl::actionPerformed_Impl( _bNotifyListener, _rEvt );
     502             : }
     503             : 
     504             : // XButton
     505             : 
     506           1 : void OButtonControl::setLabel(const OUString& Label) throw( RuntimeException, std::exception )
     507             : {
     508           1 :     Reference<XButton>  xButton;
     509           1 :     query_aggregation( m_xAggregate, xButton );
     510           1 :     if (xButton.is())
     511           1 :         xButton->setLabel(Label);
     512           1 : }
     513             : 
     514             : 
     515           1 : void SAL_CALL OButtonControl::setActionCommand(const OUString& _rCommand) throw( RuntimeException, std::exception )
     516             : {
     517             :     {
     518           1 :         ::osl::MutexGuard aGuard( m_aMutex );
     519           1 :         m_aActionCommand = _rCommand;
     520             :     }
     521             : 
     522           1 :     Reference<XButton>  xButton;
     523           1 :     query_aggregation( m_xAggregate, xButton);
     524           1 :     if (xButton.is())
     525           1 :         xButton->setActionCommand(_rCommand);
     526           1 : }
     527             : 
     528             : 
     529           8 : void SAL_CALL OButtonControl::addActionListener(const Reference<XActionListener>& _rxListener) throw( RuntimeException, std::exception )
     530             : {
     531           8 :     m_aActionListeners.addInterface(_rxListener);
     532           8 : }
     533             : 
     534             : 
     535           8 : void SAL_CALL OButtonControl::removeActionListener(const Reference<XActionListener>& _rxListener) throw( RuntimeException, std::exception )
     536             : {
     537           8 :     m_aActionListeners.removeInterface(_rxListener);
     538           8 : }
     539             : 
     540             : 
     541         345 : class DoPropertyListening
     542             : {
     543             : private:
     544             :     Reference< XPropertySet >               m_xProps;
     545             :     Reference< XPropertyChangeListener >    m_xListener;
     546             :     bool                                    m_bStartListening;
     547             : 
     548             : public:
     549             :     DoPropertyListening(
     550             :         const Reference< XInterface >& _rxComponent,
     551             :         const Reference< XPropertyChangeListener >& _rxListener,
     552             :         bool _bStart
     553             :     );
     554             : 
     555             :     void    handleListening( const OUString& _rPropertyName );
     556             : };
     557             : 
     558             : 
     559         345 : DoPropertyListening::DoPropertyListening(
     560             :         const Reference< XInterface >& _rxComponent, const Reference< XPropertyChangeListener >& _rxListener,
     561             :         bool _bStart )
     562             :     :m_xProps( _rxComponent, UNO_QUERY )
     563             :     ,m_xListener( _rxListener )
     564         345 :     ,m_bStartListening( _bStart )
     565             : {
     566             :     DBG_ASSERT( m_xProps.is() || !_rxComponent.is(), "DoPropertyListening::DoPropertyListening: valid component, but no property set!" );
     567             :     DBG_ASSERT( m_xListener.is(), "DoPropertyListening::DoPropertyListening: invalid listener!" );
     568         345 : }
     569             : 
     570             : 
     571        1035 : void DoPropertyListening::handleListening( const OUString& _rPropertyName )
     572             : {
     573        1035 :     if ( m_xProps.is() )
     574             :     {
     575         489 :         if ( m_bStartListening )
     576         345 :             m_xProps->addPropertyChangeListener( _rPropertyName, m_xListener );
     577             :         else
     578         144 :             m_xProps->removePropertyChangeListener( _rPropertyName, m_xListener );
     579             :     }
     580        1035 : }
     581             : 
     582             : 
     583         345 : void OButtonControl::startOrStopModelPropertyListening( bool _bStart )
     584             : {
     585         345 :     DoPropertyListening aListeningHandler( getModel(), this, _bStart );
     586         345 :     aListeningHandler.handleListening( PROPERTY_TARGET_URL );
     587         345 :     aListeningHandler.handleListening( PROPERTY_BUTTONTYPE );
     588         345 :     aListeningHandler.handleListening( PROPERTY_ENABLED );
     589         345 : }
     590             : 
     591             : 
     592         115 : sal_Bool SAL_CALL OButtonControl::setModel( const Reference< XControlModel >& _rxModel ) throw ( RuntimeException, std::exception )
     593             : {
     594         115 :     startOrStopModelPropertyListening( false );
     595         115 :     bool bResult = OClickableImageBaseControl::setModel( _rxModel );
     596         115 :     startOrStopModelPropertyListening( true );
     597             : 
     598         115 :     m_bEnabledByPropertyValue = true;
     599         115 :     Reference< XPropertySet > xModelProps( _rxModel, UNO_QUERY );
     600         115 :     if ( xModelProps.is() )
     601         115 :         xModelProps->getPropertyValue( PROPERTY_ENABLED ) >>= m_bEnabledByPropertyValue;
     602             : 
     603         115 :     modelFeatureUrlPotentiallyChanged( );
     604             : 
     605         115 :     return bResult;
     606             : }
     607             : 
     608             : 
     609         115 : void OButtonControl::modelFeatureUrlPotentiallyChanged( )
     610             : {
     611         115 :     sal_Int16 nOldUrlFeatureId = m_nTargetUrlFeatureId;
     612             : 
     613             :     // Do we have another TargetURL now? If so, we need to update our dispatches
     614         115 :     m_nTargetUrlFeatureId = getModelUrlFeatureId( );
     615         115 :     if ( nOldUrlFeatureId != m_nTargetUrlFeatureId )
     616             :     {
     617           0 :         invalidateSupportedFeaturesSet();
     618           0 :         if ( !isDesignMode() )
     619           0 :             updateDispatches( );
     620             :     }
     621         115 : }
     622             : 
     623             : 
     624           0 : void SAL_CALL OButtonControl::propertyChange( const PropertyChangeEvent& _rEvent ) throw ( RuntimeException, std::exception )
     625             : {
     626           0 :     if  (   _rEvent.PropertyName == PROPERTY_TARGET_URL
     627           0 :         ||  _rEvent.PropertyName == PROPERTY_BUTTONTYPE
     628             :         )
     629             :     {
     630           0 :         modelFeatureUrlPotentiallyChanged( );
     631             :     }
     632           0 :     else if ( _rEvent.PropertyName == PROPERTY_ENABLED )
     633             :     {
     634           0 :         _rEvent.NewValue >>= m_bEnabledByPropertyValue;
     635             :     }
     636           0 : }
     637             : 
     638             : 
     639             : namespace
     640             : {
     641           0 :     bool isFormControllerURL( const OUString& _rURL )
     642             :     {
     643           0 :         return  ( _rURL.getLength() > RTL_CONSTASCII_LENGTH( ".uno:FormController/" ) )
     644           0 :             &&  ( _rURL.startsWith( ".uno:FormController/" ) );
     645             :     }
     646             : }
     647             : 
     648             : 
     649         115 : sal_Int16 OButtonControl::getModelUrlFeatureId( ) const
     650             : {
     651         115 :     sal_Int16 nFeatureId = -1;
     652             : 
     653             :     // some URL related properties of the model
     654         115 :     OUString sUrl;
     655         115 :     FormButtonType eButtonType = FormButtonType_PUSH;
     656             : 
     657         230 :     Reference< XPropertySet > xModelProps( const_cast< OButtonControl* >( this )->getModel(), UNO_QUERY );
     658         115 :     if ( xModelProps.is() )
     659             :     {
     660         115 :         xModelProps->getPropertyValue( PROPERTY_TARGET_URL ) >>= sUrl;
     661         115 :         xModelProps->getPropertyValue( PROPERTY_BUTTONTYPE ) >>= eButtonType;
     662             :     }
     663             : 
     664             :     // are we a URL button?
     665         115 :     if ( eButtonType == FormButtonType_URL )
     666             :     {
     667             :         // is it a feature URL?
     668           0 :         if ( isFormControllerURL( sUrl ) )
     669             :         {
     670           0 :             nFeatureId = OFormNavigationMapper::getFeatureId( sUrl );
     671             :         }
     672             :     }
     673             : 
     674         230 :     return nFeatureId;
     675             : }
     676             : 
     677             : 
     678          49 : void SAL_CALL OButtonControl::setDesignMode( sal_Bool _bOn ) throw( RuntimeException, std::exception )
     679             : {
     680          49 :     OClickableImageBaseControl::setDesignMode( _bOn  );
     681             : 
     682          49 :     if ( _bOn )
     683          17 :         disconnectDispatchers();
     684             :     else
     685          32 :         connectDispatchers();
     686             :         // this will connect if not already connected and just update else
     687          49 : }
     688             : 
     689             : 
     690          94 : void OButtonControl::getSupportedFeatures( ::std::vector< sal_Int16 >& /* [out] */ _rFeatureIds )
     691             : {
     692          94 :     if ( -1 != m_nTargetUrlFeatureId )
     693           0 :         _rFeatureIds.push_back( m_nTargetUrlFeatureId );
     694          94 : }
     695             : 
     696             : 
     697           0 : void OButtonControl::featureStateChanged( sal_Int16 _nFeatureId, bool _bEnabled )
     698             : {
     699           0 :     if ( _nFeatureId == m_nTargetUrlFeatureId )
     700             :     {
     701             :         // enable or disable our peer, according to the new state
     702           0 :         Reference< XVclWindowPeer > xPeer( getPeer(), UNO_QUERY );
     703           0 :         if ( xPeer.is() )
     704           0 :             xPeer->setProperty( PROPERTY_ENABLED, makeAny( m_bEnabledByPropertyValue && _bEnabled ) );
     705             :             // if we're disabled according to our model's property, then
     706             :             // we don't care for the feature state, but *are* disabled.
     707             :             // If the model's property states that we're enabled, then we *do*
     708             :             // care for the feature state
     709             :     }
     710             : 
     711             :     // base class
     712           0 :     OFormNavigationHelper::featureStateChanged( _nFeatureId, _bEnabled );
     713           0 : }
     714             : 
     715             : 
     716         226 : void OButtonControl::allFeatureStatesChanged( )
     717             : {
     718         226 :     if ( -1 != m_nTargetUrlFeatureId )
     719             :         // we have only one supported feature, so simulate it has changed ...
     720           0 :         featureStateChanged( m_nTargetUrlFeatureId, isEnabled( m_nTargetUrlFeatureId ) );
     721             : 
     722             :     // base class
     723         226 :     OFormNavigationHelper::allFeatureStatesChanged( );
     724         226 : }
     725             : 
     726             : 
     727           0 : bool OButtonControl::isEnabled( sal_Int16 _nFeatureId ) const
     728             : {
     729           0 :     if ( const_cast< OButtonControl* >( this )->isDesignMode() )
     730             :         // TODO: the model property?
     731           0 :        return true;
     732             : 
     733           0 :     return OFormNavigationHelper::isEnabled( _nFeatureId );
     734             : }
     735             : 
     736             : 
     737          31 : void SAL_CALL OButtonControl::registerDispatchProviderInterceptor( const Reference< XDispatchProviderInterceptor >& _rxInterceptor ) throw (RuntimeException, std::exception)
     738             : {
     739          31 :     OClickableImageBaseControl::registerDispatchProviderInterceptor( _rxInterceptor );
     740          31 :     OFormNavigationHelper::registerDispatchProviderInterceptor( _rxInterceptor );
     741          31 : }
     742             : 
     743             : 
     744          31 : void SAL_CALL OButtonControl::releaseDispatchProviderInterceptor( const Reference< XDispatchProviderInterceptor >& _rxInterceptor ) throw (RuntimeException, std::exception)
     745             : {
     746          31 :     OClickableImageBaseControl::releaseDispatchProviderInterceptor( _rxInterceptor );
     747          31 :     OFormNavigationHelper::releaseDispatchProviderInterceptor( _rxInterceptor );
     748          31 : }
     749             : 
     750             : }   // namespace frm
     751             : 
     752             : extern "C" SAL_DLLPUBLIC_EXPORT ::com::sun::star::uno::XInterface* SAL_CALL
     753          54 : com_sun_star_form_OButtonModel_get_implementation(::com::sun::star::uno::XComponentContext* component,
     754             :         ::com::sun::star::uno::Sequence<css::uno::Any> const &)
     755             : {
     756          54 :     return cppu::acquire(new frm::OButtonModel(component));
     757             : }
     758             : 
     759             : extern "C" SAL_DLLPUBLIC_EXPORT ::com::sun::star::uno::XInterface* SAL_CALL
     760         123 : com_sun_star_form_OButtonControl_get_implementation(::com::sun::star::uno::XComponentContext* component,
     761             :         ::com::sun::star::uno::Sequence<css::uno::Any> const &)
     762             : {
     763         123 :     return cppu::acquire(new frm::OButtonControl(component));
     764             : }
     765             : 
     766             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11