LCOV - code coverage report
Current view: top level - libreoffice/svtools/source/uno - popupmenucontrollerbase.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 193 0.0 %
Date: 2012-12-27 Functions: 0 28 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include "svtools/popupmenucontrollerbase.hxx"
      21             : 
      22             : #include <com/sun/star/awt/XDevice.hpp>
      23             : #include <com/sun/star/beans/PropertyValue.hpp>
      24             : #include <com/sun/star/awt/MenuItemStyle.hpp>
      25             : #include <com/sun/star/frame/XDispatchProvider.hpp>
      26             : #include <com/sun/star/lang/DisposedException.hpp>
      27             : #include <com/sun/star/awt/XMenuExtended.hpp>
      28             : #include <com/sun/star/util/URLTransformer.hpp>
      29             : 
      30             : #include <vcl/menu.hxx>
      31             : #include <vcl/svapp.hxx>
      32             : #include <rtl/ustrbuf.hxx>
      33             : #include <rtl/logfile.hxx>
      34             : #include <osl/mutex.hxx>
      35             : #include <comphelper/processfactory.hxx>
      36             : 
      37             : //_________________________________________________________________________________________________________________
      38             : //  Defines
      39             : //_________________________________________________________________________________________________________________
      40             : //
      41             : 
      42             : using ::rtl::OUString;
      43             : 
      44             : using namespace com::sun::star;
      45             : using namespace com::sun::star::uno;
      46             : using namespace com::sun::star::lang;
      47             : using namespace com::sun::star::frame;
      48             : using namespace com::sun::star::beans;
      49             : using namespace com::sun::star::util;
      50             : 
      51             : namespace svt
      52             : {
      53             : 
      54           0 : struct PopupMenuControllerBaseDispatchInfo
      55             : {
      56             :     Reference< XDispatch > mxDispatch;
      57             :     const URL maURL;
      58             :     const Sequence< PropertyValue > maArgs;
      59             : 
      60           0 :     PopupMenuControllerBaseDispatchInfo( const Reference< XDispatch >& xDispatch, const URL& rURL, const Sequence< PropertyValue >& rArgs )
      61           0 :         : mxDispatch( xDispatch ), maURL( rURL ), maArgs( rArgs ) {}
      62             : };
      63             : 
      64           0 : PopupMenuControllerBase::PopupMenuControllerBase( const Reference< XMultiServiceFactory >& xServiceManager ) :
      65             :     ::comphelper::OBaseMutex(),
      66             :     PopupMenuControllerBaseType(m_aMutex),
      67             :     m_bInitialized( false ),
      68           0 :     m_xServiceManager( xServiceManager )
      69             : {
      70           0 :     if ( m_xServiceManager.is() )
      71           0 :         m_xURLTransformer.set( util::URLTransformer::create( ::comphelper::getComponentContext(m_xServiceManager) ) );
      72           0 : }
      73             : 
      74           0 : PopupMenuControllerBase::~PopupMenuControllerBase()
      75             : {
      76           0 : }
      77             : 
      78             : // protected function
      79           0 : void PopupMenuControllerBase::throwIfDisposed() throw ( RuntimeException )
      80             : {
      81           0 :     if (rBHelper.bDisposed || rBHelper.bInDispose)
      82           0 :         throw com::sun::star::lang::DisposedException();
      83           0 : }
      84             : 
      85             : // protected function
      86           0 : void PopupMenuControllerBase::resetPopupMenu( com::sun::star::uno::Reference< com::sun::star::awt::XPopupMenu >& rPopupMenu )
      87             : {
      88           0 :     VCLXPopupMenu* pPopupMenu = 0;
      89           0 :     if ( rPopupMenu.is() && rPopupMenu->getItemCount() > 0 )
      90             :     {
      91           0 :          pPopupMenu = (VCLXPopupMenu *)VCLXMenu::GetImplementation( rPopupMenu );
      92           0 :          if ( pPopupMenu )
      93             :          {
      94           0 :             SolarMutexGuard aSolarMutexGuard;
      95             : 
      96           0 :             PopupMenu* pVCLPopupMenu = (PopupMenu *)pPopupMenu->GetMenu();
      97           0 :             pVCLPopupMenu->Clear();
      98             :          }
      99             :     }
     100           0 : }
     101             : 
     102           0 : void SAL_CALL PopupMenuControllerBase::disposing()
     103             : {
     104             :     // Reset our members and set disposed flag
     105           0 :     osl::MutexGuard aLock( m_aMutex );
     106           0 :     m_xFrame.clear();
     107           0 :     m_xDispatch.clear();
     108           0 :     m_xPopupMenu.clear();
     109           0 :     m_xServiceManager.clear();
     110           0 : }
     111             : 
     112             : // XServiceInfo
     113             : 
     114           0 : sal_Bool SAL_CALL PopupMenuControllerBase::supportsService( const ::rtl::OUString& ServiceName ) throw (RuntimeException)
     115             : {
     116           0 :     const Sequence< rtl::OUString > aSNL( getSupportedServiceNames() );
     117           0 :     const rtl::OUString * pArray = aSNL.getConstArray();
     118             : 
     119           0 :     for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
     120           0 :         if( pArray[i] == ServiceName )
     121           0 :             return true;
     122             : 
     123           0 :     return false;
     124             : }
     125             : 
     126             : // XEventListener
     127           0 : void SAL_CALL PopupMenuControllerBase::disposing( const EventObject& ) throw ( RuntimeException )
     128             : {
     129           0 :     osl::MutexGuard aLock( m_aMutex );
     130           0 :     m_xFrame.clear();
     131           0 :     m_xDispatch.clear();
     132           0 :     m_xPopupMenu.clear();
     133           0 : }
     134             : 
     135             : // XMenuListener
     136           0 : void SAL_CALL PopupMenuControllerBase::highlight( const awt::MenuEvent& ) throw (RuntimeException)
     137             : {
     138           0 : }
     139             : 
     140           0 : void PopupMenuControllerBase::impl_select(const Reference< XDispatch >& _xDispatch,const URL& aURL)
     141             : {
     142           0 :     Sequence<PropertyValue>      aArgs;
     143             :     OSL_ENSURE(_xDispatch.is(),"PopupMenuControllerBase::impl_select: No dispatch");
     144           0 :     if ( _xDispatch.is() )
     145           0 :         _xDispatch->dispatch( aURL, aArgs );
     146           0 : }
     147             : 
     148           0 : void SAL_CALL PopupMenuControllerBase::select( const awt::MenuEvent& rEvent ) throw (RuntimeException)
     149             : {
     150           0 :     throwIfDisposed();
     151             : 
     152           0 :     osl::MutexGuard aLock( m_aMutex );
     153             : 
     154           0 :     Reference< awt::XMenuExtended > xExtMenu( m_xPopupMenu, UNO_QUERY );
     155           0 :     if( xExtMenu.is() )
     156             :     {
     157           0 :         Sequence<PropertyValue> aArgs;
     158           0 :         dispatchCommand( xExtMenu->getCommand( rEvent.MenuId ), aArgs );
     159           0 :     }
     160           0 : }
     161             : 
     162           0 : void PopupMenuControllerBase::dispatchCommand( const ::rtl::OUString& sCommandURL, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& rArgs )
     163             : {
     164           0 :     osl::MutexGuard aLock( m_aMutex );
     165             : 
     166           0 :     throwIfDisposed();
     167             : 
     168             :     try
     169             :     {
     170           0 :         Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY_THROW );
     171           0 :         URL aURL;
     172           0 :         aURL.Complete = sCommandURL;
     173           0 :         m_xURLTransformer->parseStrict( aURL );
     174             : 
     175           0 :         Reference< XDispatch > xDispatch( xDispatchProvider->queryDispatch( aURL, OUString(), 0 ), UNO_QUERY_THROW );
     176             : 
     177           0 :         Application::PostUserEvent( STATIC_LINK(0, PopupMenuControllerBase, ExecuteHdl_Impl), new PopupMenuControllerBaseDispatchInfo( xDispatch, aURL, rArgs ) );
     178             : 
     179             :     }
     180           0 :     catch( Exception& )
     181             :     {
     182           0 :     }
     183             : 
     184           0 : }
     185             : 
     186           0 : IMPL_STATIC_LINK_NOINSTANCE( PopupMenuControllerBase, ExecuteHdl_Impl, PopupMenuControllerBaseDispatchInfo*, pDispatchInfo )
     187             : {
     188           0 :     pDispatchInfo->mxDispatch->dispatch( pDispatchInfo->maURL, pDispatchInfo->maArgs );
     189           0 :     delete pDispatchInfo;
     190           0 :     return 0;
     191             : }
     192             : 
     193           0 : void SAL_CALL PopupMenuControllerBase::activate( const awt::MenuEvent& ) throw (RuntimeException)
     194             : {
     195           0 : }
     196             : 
     197           0 : void SAL_CALL PopupMenuControllerBase::deactivate( const awt::MenuEvent& ) throw (RuntimeException)
     198             : {
     199           0 : }
     200             : 
     201           0 : void SAL_CALL PopupMenuControllerBase::updatePopupMenu() throw ( ::com::sun::star::uno::RuntimeException )
     202             : {
     203           0 :     osl::ClearableMutexGuard aLock( m_aMutex );
     204           0 :     throwIfDisposed();
     205           0 :     aLock.clear();
     206             : 
     207           0 :     updateCommand( m_aCommandURL );
     208           0 : }
     209             : 
     210           0 : void SAL_CALL PopupMenuControllerBase::updateCommand( const rtl::OUString& rCommandURL )
     211             : {
     212           0 :     osl::ClearableMutexGuard aLock( m_aMutex );
     213           0 :     Reference< XStatusListener > xStatusListener( static_cast< OWeakObject* >( this ), UNO_QUERY );
     214           0 :     Reference< XDispatch > xDispatch( m_xDispatch );
     215           0 :     URL aTargetURL;
     216           0 :     aTargetURL.Complete = rCommandURL;
     217           0 :     m_xURLTransformer->parseStrict( aTargetURL );
     218           0 :     aLock.clear();
     219             : 
     220             :     // Add/remove status listener to get a status update once
     221           0 :     if ( xDispatch.is() )
     222             :     {
     223           0 :         xDispatch->addStatusListener( xStatusListener, aTargetURL );
     224           0 :         xDispatch->removeStatusListener( xStatusListener, aTargetURL );
     225           0 :     }
     226           0 : }
     227             : 
     228             : 
     229             : // XDispatchProvider
     230             : Reference< XDispatch > SAL_CALL
     231           0 : PopupMenuControllerBase::queryDispatch(
     232             :     const URL& /*aURL*/,
     233             :     const rtl::OUString& /*sTarget*/,
     234             :     sal_Int32 /*nFlags*/ )
     235             : throw( RuntimeException )
     236             : {
     237             :     // must be implemented by subclass
     238           0 :     osl::MutexGuard aLock( m_aMutex );
     239           0 :     throwIfDisposed();
     240             : 
     241           0 :     return Reference< XDispatch >();
     242             : }
     243             : 
     244           0 : Sequence< Reference< XDispatch > > SAL_CALL PopupMenuControllerBase::queryDispatches( const Sequence< DispatchDescriptor >& lDescriptor ) throw( RuntimeException )
     245             : {
     246             :     // Create return list - which must have same size then the given descriptor
     247             :     // It's not allowed to pack it!
     248           0 :     osl::ClearableMutexGuard aLock( m_aMutex );
     249           0 :     throwIfDisposed();
     250           0 :     aLock.clear();
     251             : 
     252           0 :     sal_Int32                                                          nCount = lDescriptor.getLength();
     253           0 :     uno::Sequence< uno::Reference< frame::XDispatch > > lDispatcher( nCount );
     254             : 
     255             :     // Step over all descriptors and try to get any dispatcher for it.
     256           0 :     for( sal_Int32 i=0; i<nCount; ++i )
     257             :     {
     258           0 :         lDispatcher[i] = queryDispatch( lDescriptor[i].FeatureURL  ,
     259           0 :                                         lDescriptor[i].FrameName   ,
     260           0 :                                         lDescriptor[i].SearchFlags );
     261             :     }
     262             : 
     263           0 :     return lDispatcher;
     264             : }
     265             : 
     266             : // XDispatch
     267             : void SAL_CALL
     268           0 : PopupMenuControllerBase::dispatch(
     269             :     const URL& /*aURL*/,
     270             :     const Sequence< PropertyValue >& /*seqProperties*/ )
     271             : throw( ::com::sun::star::uno::RuntimeException )
     272             : {
     273             :     // must be implemented by subclass
     274           0 :     osl::MutexGuard aLock( m_aMutex );
     275           0 :     throwIfDisposed();
     276           0 : }
     277             : 
     278             : void SAL_CALL
     279           0 : PopupMenuControllerBase::addStatusListener(
     280             :     const Reference< XStatusListener >& xControl,
     281             :     const URL& aURL )
     282             : throw( ::com::sun::star::uno::RuntimeException )
     283             : {
     284           0 :     osl::ResettableMutexGuard aLock( m_aMutex );
     285           0 :     throwIfDisposed();
     286           0 :     aLock.clear();
     287             : 
     288           0 :     bool bStatusUpdate( false );
     289           0 :     rBHelper.addListener( ::getCppuType( &xControl ), xControl );
     290             : 
     291           0 :     aLock.reset();
     292           0 :     if ( aURL.Complete.indexOf( m_aBaseURL ) == 0 )
     293           0 :         bStatusUpdate = true;
     294           0 :     aLock.clear();
     295             : 
     296           0 :     if ( bStatusUpdate )
     297             :     {
     298             :         // Dummy update for popup menu controllers
     299           0 :         FeatureStateEvent aEvent;
     300           0 :         aEvent.FeatureURL = aURL;
     301           0 :         aEvent.IsEnabled  = sal_True;
     302           0 :         aEvent.Requery    = sal_False;
     303           0 :         aEvent.State      = Any();
     304           0 :         xControl->statusChanged( aEvent );
     305           0 :     }
     306           0 : }
     307             : 
     308           0 : void SAL_CALL PopupMenuControllerBase::removeStatusListener(
     309             :     const Reference< XStatusListener >& xControl,
     310             :     const URL& /*aURL*/ )
     311             : throw( ::com::sun::star::uno::RuntimeException )
     312             : {
     313           0 :     rBHelper.removeListener( ::getCppuType( &xControl ), xControl );
     314           0 : }
     315             : 
     316           0 : ::rtl::OUString PopupMenuControllerBase::determineBaseURL( const ::rtl::OUString& aURL )
     317             : {
     318             :     // Just use the main part of the URL for popup menu controllers
     319           0 :     sal_Int32     nQueryPart( 0 );
     320           0 :     sal_Int32     nSchemePart( 0 );
     321           0 :     rtl::OUString aMainURL( RTL_CONSTASCII_USTRINGPARAM( "vnd.sun.star.popup:" ));
     322             : 
     323           0 :     nSchemePart = aURL.indexOf( ':' );
     324           0 :     if (( nSchemePart > 0 ) &&
     325           0 :         ( aURL.getLength() > ( nSchemePart+1 )))
     326             :     {
     327           0 :         nQueryPart  = aURL.indexOf( '?', nSchemePart );
     328           0 :         if ( nQueryPart > 0 )
     329           0 :             aMainURL += aURL.copy( nSchemePart, nQueryPart-nSchemePart );
     330           0 :         else if ( nQueryPart == -1 )
     331           0 :             aMainURL += aURL.copy( nSchemePart+1 );
     332             :     }
     333             : 
     334           0 :     return aMainURL;
     335             : }
     336             : 
     337             : // XInitialization
     338           0 : void SAL_CALL PopupMenuControllerBase::initialize( const Sequence< Any >& aArguments ) throw ( Exception, RuntimeException )
     339             : {
     340           0 :     osl::MutexGuard aLock( m_aMutex );
     341             : 
     342           0 :     sal_Bool bInitalized( m_bInitialized );
     343           0 :     if ( !bInitalized )
     344             :     {
     345           0 :         PropertyValue       aPropValue;
     346           0 :         rtl::OUString       aCommandURL;
     347           0 :         Reference< XFrame > xFrame;
     348             : 
     349           0 :         for ( int i = 0; i < aArguments.getLength(); i++ )
     350             :         {
     351           0 :             if ( aArguments[i] >>= aPropValue )
     352             :             {
     353           0 :                 if ( aPropValue.Name == "Frame" )
     354           0 :                     aPropValue.Value >>= xFrame;
     355           0 :                 else if ( aPropValue.Name == "CommandURL" )
     356           0 :                     aPropValue.Value >>= aCommandURL;
     357           0 :                 else if ( aPropValue.Name == "ModuleName" )
     358           0 :                     aPropValue.Value >>= m_aModuleName;
     359             :             }
     360             :         }
     361             : 
     362           0 :         if ( xFrame.is() && !aCommandURL.isEmpty() )
     363             :         {
     364           0 :             m_xFrame        = xFrame;
     365           0 :             m_aCommandURL   = aCommandURL;
     366           0 :             m_aBaseURL      = determineBaseURL( aCommandURL );
     367           0 :             m_bInitialized  = true;
     368           0 :         }
     369           0 :     }
     370           0 : }
     371             : // XPopupMenuController
     372           0 : void SAL_CALL PopupMenuControllerBase::setPopupMenu( const Reference< awt::XPopupMenu >& xPopupMenu ) throw ( RuntimeException )
     373             : {
     374           0 :     osl::MutexGuard aLock( m_aMutex );
     375           0 :     throwIfDisposed();
     376             : 
     377           0 :     if ( m_xFrame.is() && !m_xPopupMenu.is() )
     378             :     {
     379             :         // Create popup menu on demand
     380           0 :         SolarMutexGuard aSolarMutexGuard;
     381             : 
     382           0 :         m_xPopupMenu = xPopupMenu;
     383           0 :         m_xPopupMenu->addMenuListener( Reference< awt::XMenuListener >( (OWeakObject*)this, UNO_QUERY ));
     384             : 
     385           0 :         Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY );
     386             : 
     387           0 :         URL aTargetURL;
     388           0 :         aTargetURL.Complete = m_aCommandURL;
     389           0 :         m_xURLTransformer->parseStrict( aTargetURL );
     390           0 :         m_xDispatch = xDispatchProvider->queryDispatch( aTargetURL, ::rtl::OUString(), 0 );
     391             : 
     392           0 :         impl_setPopupMenu();
     393             : 
     394           0 :         updatePopupMenu();
     395           0 :     }
     396           0 : }
     397           0 : void PopupMenuControllerBase::impl_setPopupMenu()
     398             : {
     399           0 : }
     400             : }
     401             : 
     402             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10