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

Generated by: LCOV version 1.10