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

Generated by: LCOV version 1.10