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

Generated by: LCOV version 1.10