LCOV - code coverage report
Current view: top level - libreoffice/forms/source/component - clickableimage.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 40 363 11.0 %
Date: 2012-12-27 Functions: 8 46 17.4 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include "clickableimage.hxx"
      21             : #include "controlfeatureinterception.hxx"
      22             : #include "urltransformer.hxx"
      23             : #include "componenttools.hxx"
      24             : #include <com/sun/star/form/XSubmit.hpp>
      25             : #include <com/sun/star/awt/SystemPointer.hpp>
      26             : #include <com/sun/star/form/FormComponentType.hpp>
      27             : #include <com/sun/star/frame/XDispatch.hpp>
      28             : #include <com/sun/star/frame/XDispatchProvider.hpp>
      29             : #include <com/sun/star/frame/FrameSearchFlag.hpp>
      30             : #include <com/sun/star/frame/XController.hpp>
      31             : #include <com/sun/star/frame/XFrame.hpp>
      32             : #include <com/sun/star/awt/ActionEvent.hpp>
      33             : #include <com/sun/star/awt/XActionListener.hpp>
      34             : #include <tools/urlobj.hxx>
      35             : #include <tools/debug.hxx>
      36             : #include <vcl/svapp.hxx>
      37             : #include <sfx2/docfile.hxx>
      38             : #include <sfx2/objsh.hxx>
      39             : #include <osl/mutex.hxx>
      40             : #include "services.hxx"
      41             : #include <comphelper/container.hxx>
      42             : #include <comphelper/listenernotification.hxx>
      43             : #include <svtools/imageresourceaccess.hxx>
      44             : #define LOCAL_URL_PREFIX    '#'
      45             : 
      46             : //.........................................................................
      47             : namespace frm
      48             : {
      49             : //.........................................................................
      50             : 
      51             :     using namespace ::com::sun::star::uno;
      52             :     using namespace ::com::sun::star::sdb;
      53             :     using namespace ::com::sun::star::sdbc;
      54             :     using namespace ::com::sun::star::sdbcx;
      55             :     using namespace ::com::sun::star::beans;
      56             :     using namespace ::com::sun::star::container;
      57             :     using namespace ::com::sun::star::form;
      58             :     using namespace ::com::sun::star::awt;
      59             :     using namespace ::com::sun::star::io;
      60             :     using namespace ::com::sun::star::lang;
      61             :     using namespace ::com::sun::star::util;
      62             :     using namespace ::com::sun::star::frame;
      63             :     using namespace ::com::sun::star::form::submission;
      64             :     using ::com::sun::star::awt::MouseEvent;
      65             :     using ::com::sun::star::task::XInteractionHandler;
      66             : 
      67             :     //==================================================================
      68             :     // OClickableImageBaseControl
      69             :     //==================================================================
      70             :     //------------------------------------------------------------------------------
      71           0 :     Sequence<Type> OClickableImageBaseControl::_getTypes()
      72             :     {
      73           0 :         static Sequence<Type> aTypes;
      74           0 :         if (!aTypes.getLength())
      75           0 :             aTypes = concatSequences(OControl::_getTypes(), OClickableImageBaseControl_BASE::getTypes());
      76           0 :         return aTypes;
      77             :     }
      78             : 
      79             :     //------------------------------------------------------------------------------
      80           0 :     OClickableImageBaseControl::OClickableImageBaseControl(const Reference<XMultiServiceFactory>& _rxFactory, const ::rtl::OUString& _aService)
      81             :         :OControl(_rxFactory, _aService)
      82             :         ,m_pThread(NULL)
      83             :         ,m_aSubmissionVetoListeners( m_aMutex )
      84             :         ,m_aApproveActionListeners( m_aMutex )
      85           0 :         ,m_aActionListeners( m_aMutex )
      86             :     {
      87           0 :         m_pFeatureInterception.reset( new ControlFeatureInterception( _rxFactory ) );
      88           0 :     }
      89             : 
      90             :     //------------------------------------------------------------------------------
      91           0 :     OClickableImageBaseControl::~OClickableImageBaseControl()
      92             :     {
      93           0 :         if (!OComponentHelper::rBHelper.bDisposed)
      94             :         {
      95           0 :             acquire();
      96           0 :             dispose();
      97             :         }
      98           0 :     }
      99             : 
     100             :     // UNO Anbindung
     101             :     //------------------------------------------------------------------------------
     102           0 :     Any SAL_CALL OClickableImageBaseControl::queryAggregation(const Type& _rType) throw (RuntimeException)
     103             :     {
     104           0 :         Any aReturn = OControl::queryAggregation(_rType);
     105           0 :         if (!aReturn.hasValue())
     106           0 :             aReturn = OClickableImageBaseControl_BASE::queryInterface(_rType);
     107           0 :         return aReturn;
     108             :     }
     109             : 
     110             :     // XApproveActionBroadcaster
     111             :     //------------------------------------------------------------------------------
     112           0 :     void OClickableImageBaseControl::addApproveActionListener(
     113             :             const Reference<XApproveActionListener>& l) throw( RuntimeException )
     114             :     {
     115           0 :         m_aApproveActionListeners.addInterface(l);
     116           0 :     }
     117             : 
     118             :     //------------------------------------------------------------------------------
     119           0 :     void OClickableImageBaseControl::removeApproveActionListener(
     120             :             const Reference<XApproveActionListener>& l) throw( RuntimeException )
     121             :     {
     122           0 :         m_aApproveActionListeners.removeInterface(l);
     123           0 :     }
     124             : 
     125             :     //--------------------------------------------------------------------
     126           0 :     void SAL_CALL OClickableImageBaseControl::registerDispatchProviderInterceptor( const Reference< XDispatchProviderInterceptor >& _rxInterceptor ) throw (RuntimeException)
     127             :     {
     128           0 :         m_pFeatureInterception->registerDispatchProviderInterceptor( _rxInterceptor  );
     129           0 :     }
     130             : 
     131             :     //--------------------------------------------------------------------
     132           0 :     void SAL_CALL OClickableImageBaseControl::releaseDispatchProviderInterceptor( const Reference< XDispatchProviderInterceptor >& _rxInterceptor ) throw (RuntimeException)
     133             :     {
     134           0 :         m_pFeatureInterception->releaseDispatchProviderInterceptor( _rxInterceptor  );
     135           0 :     }
     136             : 
     137             :     // OComponentHelper
     138             :     //------------------------------------------------------------------------------
     139           0 :     void OClickableImageBaseControl::disposing()
     140             :     {
     141           0 :         EventObject aEvent( static_cast< XWeak* >( this ) );
     142           0 :         m_aApproveActionListeners.disposeAndClear( aEvent );
     143           0 :         m_aActionListeners.disposeAndClear( aEvent );
     144           0 :         m_aSubmissionVetoListeners.disposeAndClear( aEvent );
     145           0 :         m_pFeatureInterception->dispose();
     146             : 
     147             :         {
     148           0 :             ::osl::MutexGuard aGuard( m_aMutex );
     149           0 :             if( m_pThread )
     150             :             {
     151           0 :                 m_pThread->release();
     152           0 :                 m_pThread = NULL;
     153           0 :             }
     154             :         }
     155             : 
     156           0 :         OControl::disposing();
     157           0 :     }
     158             : 
     159             :     //------------------------------------------------------------------------------
     160           0 :     OImageProducerThread_Impl* OClickableImageBaseControl::getImageProducerThread()
     161             :     {
     162           0 :         if ( !m_pThread )
     163             :         {
     164           0 :             m_pThread = new OImageProducerThread_Impl( this );
     165           0 :             m_pThread->acquire();
     166           0 :             m_pThread->create();
     167             :         }
     168           0 :         return m_pThread;
     169             :     }
     170             : 
     171             :     //------------------------------------------------------------------------------
     172           0 :     bool OClickableImageBaseControl::approveAction( )
     173             :     {
     174           0 :         sal_Bool bCancelled = sal_False;
     175           0 :         EventObject aEvent( static_cast< XWeak* >( this ) );
     176             : 
     177           0 :         ::cppu::OInterfaceIteratorHelper aIter( m_aApproveActionListeners );
     178           0 :         while( !bCancelled && aIter.hasMoreElements() )
     179             :         {
     180             :             // Jede approveAction-Methode muss thread-safe sein!!!
     181           0 :             if( !static_cast< XApproveActionListener* >( aIter.next() )->approveAction( aEvent ) )
     182           0 :                 bCancelled = sal_True;
     183             :         }
     184             : 
     185           0 :         return !bCancelled;
     186             :     }
     187             : 
     188             :     //------------------------------------------------------------------------------
     189             :     // Diese Methode wird auch aus einem Thread gerufen und muss deshalb
     190             :     // thread-safe sein.
     191           0 :     void OClickableImageBaseControl::actionPerformed_Impl(sal_Bool bNotifyListener, const MouseEvent& rEvt)
     192             :     {
     193           0 :         if( bNotifyListener )
     194             :         {
     195           0 :             if ( !approveAction() )
     196             :                 return;
     197             :         }
     198             : 
     199             :         // Ob der Rest des Codes Thread-Safe ist weiss man nicht genau. Deshalb
     200             :         // wird das meiste bei gelocktem Solar-Mutex erledigen.
     201           0 :         Reference<XPropertySet>  xSet;
     202           0 :         Reference< XInterface > xModelsParent;
     203           0 :         FormButtonType eButtonType = FormButtonType_PUSH;
     204             :         {
     205           0 :             SolarMutexGuard aGuard;
     206             : 
     207             :             // Parent holen
     208           0 :             Reference<XFormComponent>  xComp(getModel(), UNO_QUERY);
     209           0 :             if (!xComp.is())
     210             :                 return;
     211             : 
     212           0 :             xModelsParent = xComp->getParent();
     213           0 :             if (!xModelsParent.is())
     214             :                 return;
     215             : 
     216             :             // which button type?
     217           0 :             xSet = xSet.query( xComp );
     218           0 :             if ( !xSet.is() )
     219             :                 return;
     220           0 :             xSet->getPropertyValue(PROPERTY_BUTTONTYPE) >>= eButtonType;
     221             :         }
     222             : 
     223           0 :         switch (eButtonType)
     224             :         {
     225             :             case FormButtonType_RESET:
     226             :             {
     227             :                 // reset-Methoden muessen thread-safe sein!
     228           0 :                 Reference<XReset>  xReset(xModelsParent, UNO_QUERY);
     229           0 :                 if (!xReset.is())
     230             :                     return;
     231             : 
     232           0 :                 xReset->reset();
     233             :             }
     234           0 :             break;
     235             : 
     236             :             case FormButtonType_SUBMIT:
     237             :             {
     238             :                 // if some outer component can provide an interaction handler, use it
     239           0 :                 Reference< XInteractionHandler > xHandler( m_pFeatureInterception->queryDispatch( "private:/InteractionHandler" ), UNO_QUERY );
     240             :                 try
     241             :                 {
     242           0 :                     implSubmit( rEvt, xHandler );
     243             :                 }
     244           0 :                 catch( const Exception& )
     245             :                 {
     246             :                     // ignore
     247           0 :                 }
     248             :             }
     249           0 :             break;
     250             : 
     251             :             case FormButtonType_URL:
     252             :             {
     253           0 :                 SolarMutexGuard aGuard;
     254             : 
     255           0 :                 Reference< XModel >  xModel = getXModel(xModelsParent);
     256           0 :                 if (!xModel.is())
     257             :                     return;
     258             : 
     259             :                 ///////////////////////////////////////////////////////////////////////
     260             :                 // Jetzt URL ausfuehren
     261           0 :                 Reference< XController >  xController = xModel->getCurrentController();
     262           0 :                 if (!xController.is())
     263             :                     return;
     264             : 
     265           0 :                 Reference< XFrame >  xFrame = xController->getFrame();
     266           0 :                 if( !xFrame.is() )
     267             :                     return;
     268             : 
     269           0 :                 URL aURL;
     270             :                 aURL.Complete =
     271           0 :                     getString(xSet->getPropertyValue(PROPERTY_TARGET_URL));
     272             : 
     273           0 :                 if (!aURL.Complete.isEmpty() && (LOCAL_URL_PREFIX == aURL.Complete.getStr()[0]))
     274             :                 {   // the URL contains a local URL only. Since the URLTransformer does not handle this case correctly
     275             :                     // (it can't: it does not know the document URL), we have to take care for this ourself.
     276             :                     // The real solution would be to not allow such relative URLs (there is a rule that at runtime, all
     277             :                     // URLs have to be absolute), but for compatibility reasons this is no option.
     278             :                     // The more as the user does not want to see a local URL as "file://<path>/<document>#mark" if it
     279             :                     // could be "#mark" as well.
     280             :                     // If we someday say that this hack (yes, it's kind of a hack) is not sustainable anymore, the complete
     281             :                     // solutiuon would be:
     282             :                     // * recognize URLs consisting of a mark only while _reading_ the document
     283             :                     // * for this, allow the INetURLObject (which at the moment is invoked when reading URLs) to
     284             :                     //   transform such mark-only URLs into correct absolute URLs
     285             :                     // * at the UI, show only the mark
     286             :                     // * !!!! recognize every SAVEAS on the document, so the absolute URL can be adjusted. This seems
     287             :                     // rather impossible !!!
     288           0 :                     aURL.Mark = aURL.Complete;
     289           0 :                     aURL.Complete = xModel->getURL();
     290           0 :                     aURL.Complete += aURL.Mark;
     291             :                 }
     292             : 
     293           0 :                 sal_Bool bDispatchUrlInternal = sal_False;
     294           0 :                 xSet->getPropertyValue(PROPERTY_DISPATCHURLINTERNAL) >>= bDispatchUrlInternal;
     295           0 :                 if ( bDispatchUrlInternal )
     296             :                 {
     297           0 :                     m_pFeatureInterception->getTransformer().parseSmartWithAsciiProtocol( aURL, INET_FILE_SCHEME );
     298             : 
     299           0 :                     ::rtl::OUString aTargetFrame;
     300           0 :                     xSet->getPropertyValue(PROPERTY_TARGET_FRAME) >>= aTargetFrame;
     301             : 
     302           0 :                     Reference< XDispatch >  xDisp = Reference< XDispatchProvider > (xFrame,UNO_QUERY)->queryDispatch( aURL, aTargetFrame,
     303             :                             FrameSearchFlag::SELF | FrameSearchFlag::PARENT |
     304           0 :                             FrameSearchFlag::SIBLINGS | FrameSearchFlag::CREATE );
     305             : 
     306           0 :                     Sequence<PropertyValue> aArgs(1);
     307           0 :                     PropertyValue& rProp = aArgs.getArray()[0];
     308           0 :                     rProp.Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Referer") );
     309           0 :                     rProp.Value <<= xModel->getURL();
     310             : 
     311           0 :                     if (xDisp.is())
     312           0 :                         xDisp->dispatch( aURL, aArgs );
     313             :                 }
     314             :                 else
     315             :                 {
     316           0 :                     URL aHyperLink = m_pFeatureInterception->getTransformer().getStrictURLFromAscii( ".uno:OpenHyperlink" );
     317             : 
     318           0 :                     Reference< XDispatch >  xDisp = Reference< XDispatchProvider > (xFrame,UNO_QUERY)->queryDispatch(aHyperLink, ::rtl::OUString() , 0);
     319             : 
     320           0 :                     if ( xDisp.is() )
     321             :                     {
     322           0 :                         Sequence<PropertyValue> aProps(3);
     323           0 :                         aProps[0].Name  = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("URL"));
     324           0 :                         aProps[0].Value <<= aURL.Complete;
     325             : 
     326           0 :                         aProps[1].Name  = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("FrameName"));
     327           0 :                         aProps[1].Value = xSet->getPropertyValue(PROPERTY_TARGET_FRAME);
     328             : 
     329           0 :                         aProps[2].Name  = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Referer"));
     330           0 :                         aProps[2].Value <<= xModel->getURL();
     331             : 
     332           0 :                         xDisp->dispatch( aHyperLink, aProps );
     333           0 :                     }
     334           0 :                 }
     335           0 :             }   break;
     336             :             default:
     337             :             {
     338             :                     // notify the action listeners for a push button
     339           0 :                 ActionEvent aEvt(static_cast<XWeak*>(this), m_aActionCommand);
     340           0 :                 m_aActionListeners.notifyEach( &XActionListener::actionPerformed, aEvt );
     341             :             }
     342           0 :         }
     343             :     }
     344             : 
     345             : 
     346             :     //--------------------------------------------------------------------
     347           0 :     void SAL_CALL OClickableImageBaseControl::addSubmissionVetoListener( const Reference< submission::XSubmissionVetoListener >& listener ) throw (NoSupportException, RuntimeException)
     348             :     {
     349           0 :         m_aSubmissionVetoListeners.addInterface( listener );
     350           0 :     }
     351             : 
     352             :     //--------------------------------------------------------------------
     353           0 :     void SAL_CALL OClickableImageBaseControl::removeSubmissionVetoListener( const Reference< submission::XSubmissionVetoListener >& listener ) throw (NoSupportException, RuntimeException)
     354             :     {
     355           0 :         m_aSubmissionVetoListeners.removeInterface( listener );
     356           0 :     }
     357             : 
     358             :     //--------------------------------------------------------------------
     359           0 :     void SAL_CALL OClickableImageBaseControl::submitWithInteraction( const Reference< XInteractionHandler >& _rxHandler ) throw (VetoException, WrappedTargetException, RuntimeException)
     360             :     {
     361           0 :         implSubmit( MouseEvent(), _rxHandler );
     362           0 :     }
     363             : 
     364             :     //--------------------------------------------------------------------
     365           0 :     void SAL_CALL OClickableImageBaseControl::submit(  ) throw (VetoException, WrappedTargetException, RuntimeException)
     366             :     {
     367           0 :         implSubmit( MouseEvent(), NULL );
     368           0 :     }
     369             : 
     370             :     //--------------------------------------------------------------------
     371           0 :     Sequence< ::rtl::OUString > SAL_CALL OClickableImageBaseControl::getSupportedServiceNames(  ) throw (RuntimeException)
     372             :     {
     373           0 :         Sequence< ::rtl::OUString > aSupported = OControl::getSupportedServiceNames();
     374           0 :         aSupported.realloc( aSupported.getLength() + 1 );
     375             : 
     376           0 :         ::rtl::OUString* pArray = aSupported.getArray();
     377           0 :         pArray[ aSupported.getLength() - 1 ] = FRM_SUN_CONTROL_SUBMITBUTTON;
     378             : 
     379           0 :         return aSupported;
     380             :     }
     381             : 
     382             :     //--------------------------------------------------------------------
     383           0 :     void OClickableImageBaseControl::implSubmit( const MouseEvent& _rEvent, const Reference< XInteractionHandler >& _rxHandler ) SAL_THROW((VetoException, WrappedTargetException, RuntimeException))
     384             :     {
     385             :         try
     386             :         {
     387             :             // allow the veto listeners to join the game
     388           0 :             m_aSubmissionVetoListeners.notifyEach( &XSubmissionVetoListener::submitting, EventObject( *this ) );
     389             : 
     390             :             // see whether there's an "submit interceptor" set at our model
     391           0 :             Reference< submission::XSubmissionSupplier > xSubmissionSupp( getModel(), UNO_QUERY );
     392           0 :             Reference< XSubmission > xSubmission;
     393           0 :             if ( xSubmissionSupp.is() )
     394           0 :                 xSubmission = xSubmissionSupp->getSubmission();
     395             : 
     396           0 :             if ( xSubmission.is() )
     397             :             {
     398           0 :                 if ( !_rxHandler.is() )
     399           0 :                     xSubmission->submit();
     400             :                 else
     401           0 :                     xSubmission->submitWithInteraction( _rxHandler );
     402             :             }
     403             :             else
     404             :             {
     405             :                 // no "interceptor" -> ordinary (old-way) submission
     406           0 :                 Reference< XChild > xChild( getModel(), UNO_QUERY );
     407           0 :                 Reference< XSubmit > xParentSubmission;
     408           0 :                 if ( xChild.is() )
     409           0 :                     xParentSubmission = xParentSubmission.query( xChild->getParent() );
     410           0 :                 if ( xParentSubmission.is() )
     411           0 :                     xParentSubmission->submit( this, _rEvent );
     412           0 :             }
     413             :         }
     414           0 :         catch( const VetoException& )
     415             :         {
     416             :             // allowed to leave
     417           0 :             throw;
     418             :         }
     419           0 :         catch( const RuntimeException& )
     420             :         {
     421             :             // allowed to leave
     422           0 :             throw;
     423             :         }
     424           0 :         catch( const WrappedTargetException& )
     425             :         {
     426             :             // allowed to leave
     427           0 :             throw;
     428             :         }
     429           0 :         catch( const Exception& e )
     430             :         {
     431             :             OSL_FAIL( "OClickableImageBaseControl::implSubmit: caught an unknown exception!" );
     432           0 :             throw WrappedTargetException( ::rtl::OUString(), *this, makeAny( e ) );
     433             :         }
     434           0 :     }
     435             : 
     436             :     //==================================================================
     437             :     // OClickableImageBaseModel
     438             :     //==================================================================
     439             :     //------------------------------------------------------------------------------
     440           0 :     Sequence<Type> OClickableImageBaseModel::_getTypes()
     441             :     {
     442             :         return concatSequences(
     443             :             OControlModel::_getTypes(),
     444             :             OClickableImageBaseModel_Base::getTypes()
     445           0 :         );
     446             :     }
     447             : 
     448             :     //------------------------------------------------------------------
     449             :     DBG_NAME( OClickableImageBaseModel )
     450             :     //------------------------------------------------------------------
     451           3 :     OClickableImageBaseModel::OClickableImageBaseModel( const Reference< XMultiServiceFactory >& _rxFactory, const ::rtl::OUString& _rUnoControlModelTypeName,
     452             :             const ::rtl::OUString& rDefault )
     453             :         :OControlModel( _rxFactory, _rUnoControlModelTypeName, rDefault )
     454             :         ,OPropertyChangeListener(m_aMutex)
     455             :         ,m_pMedium(NULL)
     456             :         ,m_pProducer( NULL )
     457             :         ,m_bDispatchUrlInternal(sal_False)
     458             :         ,m_bDownloading(sal_False)
     459           3 :         ,m_bProdStarted(sal_False)
     460             :     {
     461             :         DBG_CTOR( OClickableImageBaseModel, NULL );
     462           3 :         implConstruct();
     463           3 :         m_eButtonType = FormButtonType_PUSH;
     464           3 :     }
     465             : 
     466             :     //------------------------------------------------------------------
     467           0 :     OClickableImageBaseModel::OClickableImageBaseModel( const OClickableImageBaseModel* _pOriginal, const Reference<XMultiServiceFactory>& _rxFactory )
     468             :         :OControlModel( _pOriginal, _rxFactory )
     469             :         ,OPropertyChangeListener( m_aMutex )
     470             :         ,m_pMedium( NULL )
     471             :         ,m_pProducer( NULL )
     472             :         ,m_bDispatchUrlInternal(sal_False)
     473             :         ,m_bDownloading( sal_False )
     474           0 :         ,m_bProdStarted( sal_False )
     475             :     {
     476             :         DBG_CTOR( OClickableImageBaseModel, NULL );
     477           0 :         implConstruct();
     478             : 
     479             :         // copy properties
     480           0 :         m_eButtonType           = _pOriginal->m_eButtonType;
     481           0 :         m_sTargetURL            = _pOriginal->m_sTargetURL;
     482           0 :         m_sTargetFrame          = _pOriginal->m_sTargetFrame;
     483           0 :         m_bDispatchUrlInternal  = _pOriginal->m_bDispatchUrlInternal;
     484           0 :     }
     485             : 
     486             :     //------------------------------------------------------------------------------
     487           0 :     void OClickableImageBaseModel::implInitializeImageURL( )
     488             :     {
     489           0 :         osl_atomic_increment( &m_refCount );
     490             :         {
     491             :             // simulate a propertyChanged event for the ImageURL
     492           0 :             Any aImageURL;
     493           0 :             getFastPropertyValue( aImageURL, PROPERTY_ID_IMAGE_URL );
     494           0 :             _propertyChanged( PropertyChangeEvent( *this, PROPERTY_IMAGE_URL, sal_False, PROPERTY_ID_IMAGE_URL, Any( ), aImageURL ) );
     495             :         }
     496           0 :         osl_atomic_decrement( &m_refCount );
     497           0 :     }
     498             : 
     499             :     //------------------------------------------------------------------------------
     500           3 :     void OClickableImageBaseModel::implConstruct()
     501             :     {
     502           3 :         m_pProducer = new ImageProducer;
     503           3 :         increment( m_refCount );
     504             :         {
     505           3 :             m_xProducer = m_pProducer;
     506             : 
     507           3 :             if ( m_xAggregateSet.is() )
     508             :             {
     509           3 :                 OPropertyChangeMultiplexer* pMultiplexer = new OPropertyChangeMultiplexer( this, m_xAggregateSet );
     510           3 :                 pMultiplexer->addProperty( PROPERTY_IMAGE_URL );
     511             :             }
     512             :         }
     513           3 :         decrement(m_refCount);
     514           3 :     }
     515             : 
     516             :     //------------------------------------------------------------------------------
     517           6 :     OClickableImageBaseModel::~OClickableImageBaseModel()
     518             :     {
     519           3 :         if (!OComponentHelper::rBHelper.bDisposed)
     520             :         {
     521           0 :             acquire();
     522           0 :             dispose();
     523             :         }
     524             :         DBG_ASSERT(m_pMedium == NULL, "OClickableImageBaseModel::~OClickableImageBaseModel : leaving a memory leak ...");
     525             :             // spaetestens im dispose sollte das aufgeraeumt worden sein
     526             : 
     527             :         DBG_DTOR( OClickableImageBaseModel, NULL );
     528           3 :     }
     529             : 
     530             :     // XImageProducer
     531             :     //--------------------------------------------------------------------
     532           0 :     void SAL_CALL OClickableImageBaseModel::addConsumer( const Reference< XImageConsumer >& _rxConsumer ) throw (RuntimeException)
     533             :     {
     534           0 :         ImageModelMethodGuard aGuard( *this );
     535           0 :         GetImageProducer()->addConsumer( _rxConsumer );
     536           0 :     }
     537             : 
     538             :     //--------------------------------------------------------------------
     539           0 :     void SAL_CALL OClickableImageBaseModel::removeConsumer( const Reference< XImageConsumer >& _rxConsumer ) throw (RuntimeException)
     540             :     {
     541           0 :         ImageModelMethodGuard aGuard( *this );
     542           0 :         GetImageProducer()->removeConsumer( _rxConsumer );
     543           0 :     }
     544             : 
     545             :     //--------------------------------------------------------------------
     546           0 :     void SAL_CALL OClickableImageBaseModel::startProduction(  ) throw (RuntimeException)
     547             :     {
     548           0 :         ImageModelMethodGuard aGuard( *this );
     549           0 :         GetImageProducer()->startProduction();
     550           0 :     }
     551             : 
     552             :     //--------------------------------------------------------------------
     553           0 :     Reference< submission::XSubmission > SAL_CALL OClickableImageBaseModel::getSubmission() throw (RuntimeException)
     554             :     {
     555           0 :         return m_xSubmissionDelegate;
     556             :     }
     557             : 
     558             :     //--------------------------------------------------------------------
     559           0 :     void SAL_CALL OClickableImageBaseModel::setSubmission( const Reference< submission::XSubmission >& _submission ) throw (RuntimeException)
     560             :     {
     561           0 :         m_xSubmissionDelegate = _submission;
     562           0 :     }
     563             : 
     564             :     //--------------------------------------------------------------------
     565           0 :     Sequence< ::rtl::OUString > SAL_CALL OClickableImageBaseModel::getSupportedServiceNames(  ) throw (RuntimeException)
     566             :     {
     567           0 :         Sequence< ::rtl::OUString > aSupported = OControlModel::getSupportedServiceNames();
     568           0 :         aSupported.realloc( aSupported.getLength() + 1 );
     569             : 
     570           0 :         ::rtl::OUString* pArray = aSupported.getArray();
     571           0 :         pArray[ aSupported.getLength() - 1 ] = FRM_SUN_COMPONENT_SUBMITBUTTON;
     572             : 
     573           0 :         return aSupported;
     574             :     }
     575             : 
     576             :     // OComponentHelper
     577             :     //------------------------------------------------------------------------------
     578           3 :     void OClickableImageBaseModel::disposing()
     579             :     {
     580           3 :         OControlModel::disposing();
     581           3 :         if (m_pMedium)
     582             :         {
     583           0 :             delete m_pMedium;
     584           0 :             m_pMedium = NULL;
     585             :         }
     586             : 
     587           3 :         m_xProducer = NULL;
     588           3 :         m_pProducer = NULL;
     589           3 :     }
     590             : 
     591             :     //------------------------------------------------------------------------------
     592         171 :     Any SAL_CALL OClickableImageBaseModel::queryAggregation(const Type& _rType) throw (RuntimeException)
     593             :     {
     594             :         // order matters:
     595             :         // we definately want to "overload" the XImageProducer interface of our aggregate,
     596             :         // thus check OClickableImageBaseModel_Base (which provides this) first
     597         171 :         Any aReturn = OClickableImageBaseModel_Base::queryInterface( _rType );
     598             : 
     599             :         // BUT: _don't_ let it feel responsible for the XTypeProvider interface
     600             :         // (as this is implemented by our base class in the proper way)
     601         342 :         if  (   _rType.equals( ::getCppuType( static_cast< Reference< XTypeProvider >* >( NULL ) ) )
     602         171 :             ||  !aReturn.hasValue()
     603             :             )
     604         135 :             aReturn = OControlModel::queryAggregation( _rType );
     605             : 
     606         171 :         return aReturn;
     607             :     }
     608             : 
     609             :     //------------------------------------------------------------------------------
     610          22 :     void OClickableImageBaseModel::getFastPropertyValue(Any& rValue, sal_Int32 nHandle) const
     611             :     {
     612          22 :         switch (nHandle)
     613             :         {
     614           0 :             case PROPERTY_ID_BUTTONTYPE             : rValue <<= m_eButtonType; break;
     615           0 :             case PROPERTY_ID_TARGET_URL             : rValue <<= m_sTargetURL; break;
     616           0 :             case PROPERTY_ID_TARGET_FRAME           : rValue <<= m_sTargetFrame; break;
     617           0 :             case PROPERTY_ID_DISPATCHURLINTERNAL    : rValue <<= m_bDispatchUrlInternal; break;
     618             :             default:
     619          22 :                 OControlModel::getFastPropertyValue(rValue, nHandle);
     620             :         }
     621          22 :     }
     622             : 
     623             :     //------------------------------------------------------------------------------
     624           9 :     void OClickableImageBaseModel::setFastPropertyValue_NoBroadcast(sal_Int32 nHandle, const Any& rValue) throw ( Exception)
     625             :     {
     626           9 :         switch (nHandle)
     627             :         {
     628             :             case PROPERTY_ID_BUTTONTYPE :
     629             :                 DBG_ASSERT(isA(rValue, static_cast<FormButtonType*>(NULL)), "OClickableImageBaseModel::setFastPropertyValue_NoBroadcast : invalid type !" );
     630           0 :                 rValue >>= m_eButtonType;
     631           0 :                 break;
     632             : 
     633             :             case PROPERTY_ID_TARGET_URL :
     634             :                 DBG_ASSERT(rValue.getValueType().getTypeClass() == TypeClass_STRING, "OClickableImageBaseModel::setFastPropertyValue_NoBroadcast : invalid type !" );
     635           0 :                 rValue >>= m_sTargetURL;
     636           0 :                 break;
     637             : 
     638             :             case PROPERTY_ID_TARGET_FRAME :
     639             :                 DBG_ASSERT(rValue.getValueType().getTypeClass() == TypeClass_STRING, "OClickableImageBaseModel::setFastPropertyValue_NoBroadcast : invalid type !" );
     640           0 :                 rValue >>= m_sTargetFrame;
     641           0 :                 break;
     642             : 
     643             :             case PROPERTY_ID_DISPATCHURLINTERNAL:
     644             :                 DBG_ASSERT(rValue.getValueType().getTypeClass() == TypeClass_BOOLEAN, "OClickableImageBaseModel::setFastPropertyValue_NoBroadcast : invalid type !" );
     645           0 :                 rValue >>= m_bDispatchUrlInternal;
     646           0 :                 break;
     647             : 
     648             :             default:
     649           9 :                 OControlModel::setFastPropertyValue_NoBroadcast(nHandle, rValue);
     650             :         }
     651           9 :     }
     652             : 
     653             :     //------------------------------------------------------------------------------
     654          12 :     sal_Bool OClickableImageBaseModel::convertFastPropertyValue(Any& rConvertedValue, Any& rOldValue, sal_Int32 nHandle, const Any& rValue)
     655             :                                 throw( IllegalArgumentException )
     656             :     {
     657          12 :         switch (nHandle)
     658             :         {
     659             :             case PROPERTY_ID_BUTTONTYPE :
     660           0 :                 return tryPropertyValueEnum( rConvertedValue, rOldValue, rValue, m_eButtonType );
     661             : 
     662             :             case PROPERTY_ID_TARGET_URL :
     663           0 :                 return tryPropertyValue(rConvertedValue, rOldValue, rValue, m_sTargetURL);
     664             : 
     665             :             case PROPERTY_ID_TARGET_FRAME :
     666           0 :                 return tryPropertyValue(rConvertedValue, rOldValue, rValue, m_sTargetFrame);
     667             : 
     668             :             case PROPERTY_ID_DISPATCHURLINTERNAL :
     669           0 :                 return tryPropertyValue(rConvertedValue, rOldValue, rValue, m_bDispatchUrlInternal);
     670             : 
     671             :             default:
     672          12 :                 return OControlModel::convertFastPropertyValue(rConvertedValue, rOldValue, nHandle, rValue);
     673             :         }
     674             :     }
     675             : 
     676             :     //------------------------------------------------------------------------------
     677           0 :     void OClickableImageBaseModel::StartProduction()
     678             :     {
     679           0 :         ImageProducer *pImgProd = GetImageProducer();
     680             :         // grab the ImageURL
     681           0 :         rtl::OUString sURL;
     682           0 :         getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ImageURL") ) ) >>= sURL;
     683           0 :         if (!m_pMedium)
     684             :         {
     685           0 :             if ( ::svt::GraphicAccess::isSupportedURL( sURL )  )
     686           0 :                 pImgProd->SetImage( sURL );
     687             :             else
     688             :                 // caution: the medium may be NULL if somebody gave us a invalid URL to work with
     689           0 :                 pImgProd->SetImage(String());
     690           0 :             m_bDownloading = sal_False;
     691           0 :             return;
     692             :         }
     693           0 :         if (m_pMedium->GetErrorCode()==0)
     694             :         {
     695           0 :             SvStream* pStream = m_pMedium->GetInStream();
     696             : 
     697           0 :             pImgProd->SetImage(*pStream);
     698           0 :             pImgProd->startProduction();
     699           0 :             m_bProdStarted = sal_True;
     700             :         }
     701             :         else
     702             :         {
     703           0 :             pImgProd->SetImage(String());
     704           0 :             delete m_pMedium;
     705           0 :             m_pMedium = 0;
     706           0 :             m_bDownloading = sal_False;
     707           0 :         }
     708             :     }
     709             : 
     710             :     //------------------------------------------------------------------------------
     711           0 :     void OClickableImageBaseModel::SetURL( const ::rtl::OUString& rURL )
     712             :     {
     713           0 :         if (m_pMedium || rURL.isEmpty())
     714             :         {
     715             :             // Den Stream am Producer freigeben, bevor das Medium geloscht wird.
     716           0 :             GetImageProducer()->SetImage(String());
     717           0 :             delete m_pMedium;
     718           0 :             m_pMedium = NULL;
     719             :         }
     720             : 
     721             :         // the SfxMedium is not allowed to be created with an invalid URL, so we have to check this first
     722           0 :         INetURLObject aUrl(rURL);
     723           0 :         if (INET_PROT_NOT_VALID == aUrl.GetProtocol())
     724             :             // we treat an invalid URL like we would treat no URL
     725           0 :             return;
     726             : 
     727           0 :         if (!rURL.isEmpty() && !::svt::GraphicAccess::isSupportedURL( rURL ) )
     728             :        {
     729           0 :             if (m_pMedium)
     730           0 :                 delete m_pMedium;
     731             : 
     732           0 :             m_pMedium = new SfxMedium(rURL, STREAM_STD_READ);
     733             : 
     734             :             // Das XModel suchen, um an die Object-Shell oder zumindest den
     735             :             // Referer zu gelangen.
     736             :             // Das Model findet man allerdings nur beim Laden von HTML-Dokumenten
     737             :             // und dann, wenn die URL in einem bereits geladenen Dokument
     738             :             // geaendert wird. Waehrend des Ladens kommt man nicht an das
     739             :             // Model ran.
     740           0 :             Reference< XModel >  xModel;
     741           0 :             InterfaceRef  xIfc( *this );
     742           0 :             while( !xModel.is() && xIfc.is() )
     743             :             {
     744           0 :                 Reference<XChild>  xChild( xIfc, UNO_QUERY );
     745           0 :                 xIfc = xChild->getParent();
     746           0 :                 query_interface(xIfc, xModel);
     747           0 :             }
     748             : 
     749             :             // Die Object-Shell suchen, indem wir
     750             :             // ueber alle Object-Shells iterieren und deren XModel mit dem
     751             :             // eigenen vergleichen. Als Optimierung probieren wir aber erstmal
     752             :             // die aktuelle Object-Shell.
     753             :             // wir unser XModel mit dem aller Object
     754           0 :             SfxObjectShell *pObjSh = 0;
     755             : 
     756           0 :             if( xModel.is() )
     757             :             {
     758           0 :                 SfxObjectShell *pTestObjSh = SfxObjectShell::Current();
     759           0 :                 if( pTestObjSh )
     760             :                 {
     761           0 :                     Reference< XModel >  xTestModel = pTestObjSh->GetModel();
     762           0 :                     if( xTestModel == xModel )
     763           0 :                         pObjSh = pTestObjSh;
     764             :                 }
     765           0 :                 if( !pObjSh )
     766             :                 {
     767           0 :                     pTestObjSh = SfxObjectShell::GetFirst();
     768           0 :                     while( !pObjSh && pTestObjSh )
     769             :                     {
     770           0 :                         Reference< XModel > xTestModel = pTestObjSh->GetModel();
     771           0 :                         if( xTestModel == xModel )
     772           0 :                             pObjSh = pTestObjSh;
     773             :                         else
     774           0 :                             pTestObjSh = SfxObjectShell::GetNext( *pTestObjSh );
     775           0 :                     }
     776             :                 }
     777             :             }
     778             : 
     779             :     #ifdef USE_REGISTER_TRANSFER
     780             :             if( pObjSh )
     781             :             {
     782             :                 // Target-Frame uebertragen, damit auch javascript:-URLs
     783             :                 // "geladen" werden koennen.
     784             :                 const SfxMedium *pShMedium = pObjSh->GetMedium();
     785             :                 if( pShMedium )
     786             :                     m_pMedium->SetLoadTargetFrame(pShMedium->GetLoadTargetFrame());
     787             :             }
     788             :     #else
     789           0 :             if( pObjSh )
     790             :             {
     791             :                 // Target-Frame uebertragen, damit auch javascript:-URLs
     792             :                 // "geladen" werden koennen.
     793           0 :                 const SfxMedium *pShMedium = pObjSh->GetMedium();
     794           0 :                 if( pShMedium )
     795           0 :                     m_pMedium->SetLoadTargetFrame(pShMedium->GetLoadTargetFrame());
     796             :             }
     797             :     #endif
     798             : 
     799             :             // Downloading-Flag auf sal_True setzen. Es werden dann auch
     800             :             // Data-Available-Links, wenn wir in den Pending-Staus gelangen.
     801           0 :             m_bDownloading = sal_True;
     802           0 :             m_bProdStarted = sal_False;
     803             : 
     804             :             // Download anstossen (Achtung: Kann auch synchron sein).
     805           0 :             m_pMedium->DownLoad(STATIC_LINK(this, OClickableImageBaseModel, DownloadDoneLink));
     806             :         }
     807             :         else
     808             :         {
     809           0 :             if ( ::svt::GraphicAccess::isSupportedURL( rURL )  )
     810           0 :                 GetImageProducer()->SetImage( rURL );
     811           0 :             GetImageProducer()->startProduction();
     812           0 :         }
     813             :     }
     814             : 
     815             :     //------------------------------------------------------------------------------
     816           0 :     void OClickableImageBaseModel::DataAvailable()
     817             :     {
     818           0 :         if (!m_bProdStarted)
     819           0 :             StartProduction();
     820             : 
     821           0 :         GetImageProducer()->NewDataAvailable();
     822           0 :     }
     823             : 
     824             :     //------------------------------------------------------------------------------
     825           0 :     void OClickableImageBaseModel::DownloadDone()
     826             :     {
     827           0 :         DataAvailable();
     828           0 :         m_bDownloading = sal_False;
     829           0 :     }
     830             : 
     831             :     //------------------------------------------------------------------------------
     832           0 :     IMPL_STATIC_LINK( OClickableImageBaseModel, DownloadDoneLink, void*, EMPTYARG )
     833             :     {
     834           0 :         ::osl::MutexGuard aGuard( pThis->m_aMutex );
     835           0 :         pThis->DownloadDone();
     836           0 :         return 0;
     837             :     }
     838             : 
     839             :     //------------------------------------------------------------------------------
     840           0 :     void OClickableImageBaseModel::_propertyChanged( const PropertyChangeEvent& rEvt )
     841             :         throw( RuntimeException )
     842             :     {
     843             :         // Wenn eine URL gesetzt worden ist, muss die noch an den ImageProducer
     844             :         // weitergereicht werden.
     845           0 :         ::osl::MutexGuard aGuard(m_aMutex);
     846           0 :         SetURL( getString(rEvt.NewValue) );
     847           0 :     }
     848             : 
     849             :     // -----------------------------------------------------------------------------
     850           0 :     Any OClickableImageBaseModel::getPropertyDefaultByHandle( sal_Int32 nHandle ) const
     851             :     {
     852           0 :         switch (nHandle)
     853             :         {
     854           0 :             case PROPERTY_ID_BUTTONTYPE             : return makeAny( FormButtonType_PUSH );
     855             :             case PROPERTY_ID_TARGET_URL             :
     856           0 :             case PROPERTY_ID_TARGET_FRAME           : return makeAny( ::rtl::OUString() );
     857           0 :             case PROPERTY_ID_DISPATCHURLINTERNAL    : return makeAny( sal_False );
     858             :             default:
     859           0 :                 return OControlModel::getPropertyDefaultByHandle(nHandle);
     860             :         }
     861             :     }
     862             : 
     863             :     //==================================================================
     864             :     // OImageProducerThread_Impl
     865             :     //==================================================================
     866             :     //------------------------------------------------------------------
     867           0 :     EventObject* OImageProducerThread_Impl::cloneEvent( const EventObject* _pEvt ) const
     868             :     {
     869           0 :         return new EventObject( *_pEvt );
     870             :     }
     871             : 
     872             :     //------------------------------------------------------------------
     873           0 :     void OImageProducerThread_Impl::processEvent( ::cppu::OComponentHelper *pCompImpl,
     874             :                                                 const EventObject* pEvt,
     875             :                                                 const Reference<XControl>&,
     876             :                                                 sal_Bool )
     877             :     {
     878           0 :         ((OClickableImageBaseControl *)pCompImpl)->actionPerformed_Impl( sal_True, *(MouseEvent *)pEvt );
     879           0 :     }
     880             : 
     881             : //.........................................................................
     882             : }   // namespace frm
     883             : //.........................................................................
     884             : 
     885             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10