LCOV - code coverage report
Current view: top level - sfx2/source/view - frmload.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 266 0.0 %
Date: 2014-04-14 Functions: 0 23 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             : 
      21             : #include <sal/macros.h>
      22             : #include "objshimp.hxx"
      23             : #include <sfx2/app.hxx>
      24             : #include <sfx2/dispatch.hxx>
      25             : #include <sfx2/docfac.hxx>
      26             : #include <sfx2/docfile.hxx>
      27             : #include <sfx2/docfilt.hxx>
      28             : #include <sfx2/doctempl.hxx>
      29             : #include <sfx2/fcontnr.hxx>
      30             : #include <sfx2/frame.hxx>
      31             : #include <sfx2/objsh.hxx>
      32             : #include <sfx2/request.hxx>
      33             : #include <sfx2/sfx.hrc>
      34             : #include <sfx2/sfxsids.hrc>
      35             : #include <sfx2/sfxuno.hxx>
      36             : #include <sfx2/viewfrm.hxx>
      37             : #include <sfx2/viewsh.hxx>
      38             : #include <sfx2/viewfac.hxx>
      39             : 
      40             : #include <com/sun/star/container/XContainerQuery.hpp>
      41             : #include <com/sun/star/document/XTypeDetection.hpp>
      42             : #include <com/sun/star/frame/XFrame.hpp>
      43             : #include <com/sun/star/frame/XLoadable.hpp>
      44             : #include <com/sun/star/frame/XModel.hpp>
      45             : #include <com/sun/star/task/XInteractionHandler.hpp>
      46             : #include <com/sun/star/task/XInteractionHandler2.hpp>
      47             : #include <com/sun/star/document/XViewDataSupplier.hpp>
      48             : #include <com/sun/star/container/XIndexAccess.hpp>
      49             : #include <com/sun/star/frame/XSynchronousFrameLoader.hpp>
      50             : #include <com/sun/star/frame/XController2.hpp>
      51             : #include <com/sun/star/frame/XModel2.hpp>
      52             : #include <com/sun/star/lang/XServiceInfo.hpp>
      53             : 
      54             : #include <comphelper/interaction.hxx>
      55             : #include <comphelper/namedvaluecollection.hxx>
      56             : #include <cppuhelper/exc_hlp.hxx>
      57             : #include <cppuhelper/implbase2.hxx>
      58             : #include <cppuhelper/supportsservice.hxx>
      59             : #include <framework/interaction.hxx>
      60             : #include <rtl/ref.hxx>
      61             : #include <rtl/ustring.h>
      62             : #include <sot/storinfo.hxx>
      63             : #include <svtools/ehdl.hxx>
      64             : #include <svl/eitem.hxx>
      65             : #include <svl/itemset.hxx>
      66             : #include <unotools/moduleoptions.hxx>
      67             : #include <svtools/sfxecode.hxx>
      68             : #include <svl/stritem.hxx>
      69             : #include <toolkit/helper/vclunohelper.hxx>
      70             : #include <tools/diagnose_ex.h>
      71             : #include <ucbhelper/simpleinteractionrequest.hxx>
      72             : #include <osl/mutex.hxx>
      73             : 
      74             : using ::com::sun::star::beans::PropertyValue;
      75             : using ::com::sun::star::container::XContainerQuery;
      76             : using ::com::sun::star::container::XEnumeration;
      77             : using ::com::sun::star::document::XTypeDetection;
      78             : using ::com::sun::star::frame::XFrame;
      79             : using ::com::sun::star::frame::XLoadable;
      80             : using ::com::sun::star::frame::XModel;
      81             : using ::com::sun::star::lang::XMultiServiceFactory;
      82             : using ::com::sun::star::task::XInteractionHandler;
      83             : using ::com::sun::star::task::XInteractionHandler2;
      84             : using ::com::sun::star::task::XInteractionRequest;
      85             : using ::com::sun::star::task::XStatusIndicator;
      86             : using ::com::sun::star::uno::Any;
      87             : using ::com::sun::star::uno::Exception;
      88             : using ::com::sun::star::uno::Reference;
      89             : using ::com::sun::star::uno::RuntimeException;
      90             : using ::com::sun::star::uno::Sequence;
      91             : using ::com::sun::star::uno::UNO_QUERY;
      92             : using ::com::sun::star::uno::UNO_QUERY_THROW;
      93             : using ::com::sun::star::uno::UNO_SET_THROW;
      94             : using ::com::sun::star::uno::makeAny;
      95             : using ::com::sun::star::util::XCloseable;
      96             : using ::com::sun::star::document::XViewDataSupplier;
      97             : using ::com::sun::star::container::XIndexAccess;
      98             : using ::com::sun::star::frame::XController2;
      99             : using ::com::sun::star::frame::XController;
     100             : using ::com::sun::star::frame::XModel2;
     101             : 
     102             : namespace {
     103             : 
     104             : class SfxFrameLoader_Impl : public ::cppu::WeakImplHelper2< css::frame::XSynchronousFrameLoader, css::lang::XServiceInfo >
     105             : {
     106             :     css::uno::Reference < css::uno::XComponentContext >  m_aContext;
     107             : 
     108             : public:
     109             :     SfxFrameLoader_Impl( const css::uno::Reference < css::uno::XComponentContext >& _rxContext );
     110             : 
     111             :     virtual OUString SAL_CALL getImplementationName()
     112             :         throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     113             : 
     114             :     virtual sal_Bool SAL_CALL supportsService(OUString const & ServiceName)
     115             :         throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     116             : 
     117             :     virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames()
     118             :         throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     119             : 
     120             : 
     121             :     // XSynchronousFrameLoader
     122             : 
     123             :     virtual sal_Bool SAL_CALL load( const css::uno::Sequence< css::beans::PropertyValue >& _rArgs, const css::uno::Reference< css::frame::XFrame >& _rxFrame ) throw( css::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
     124             :     virtual void SAL_CALL cancel() throw( css::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
     125             : 
     126             : protected:
     127             :     virtual                 ~SfxFrameLoader_Impl();
     128             : 
     129             : private:
     130             :     const SfxFilter*    impl_getFilterFromServiceName_nothrow(
     131             :                             const OUString& i_rServiceName
     132             :                         ) const;
     133             : 
     134             :     OUString     impl_askForFilter_nothrow(
     135             :                             const css::uno::Reference< css::task::XInteractionHandler >& i_rxHandler,
     136             :                             const OUString& i_rDocumentURL
     137             :                         ) const;
     138             : 
     139             :     const SfxFilter*    impl_detectFilterForURL(
     140             :                             const OUString& _rURL,
     141             :                             const ::comphelper::NamedValueCollection& i_rDescriptor,
     142             :                             const SfxFilterMatcher& rMatcher
     143             :                         ) const;
     144             : 
     145             :     bool            impl_createNewDocWithSlotParam(
     146             :                             const sal_uInt16 _nSlotID,
     147             :                             const css::uno::Reference< css::frame::XFrame >& i_rxFrame,
     148             :                             const bool i_bHidden
     149             :                         );
     150             : 
     151             :     void                impl_determineFilter(
     152             :                                   ::comphelper::NamedValueCollection& io_rDescriptor
     153             :                         ) const;
     154             : 
     155             :     bool                impl_determineTemplateDocument(
     156             :                             ::comphelper::NamedValueCollection& io_rDescriptor
     157             :                         ) const;
     158             : 
     159             :     sal_uInt16              impl_findSlotParam(
     160             :                             const OUString& i_rFactoryURL
     161             :                         ) const;
     162             : 
     163             :     SfxObjectShellRef   impl_findObjectShell(
     164             :                             const css::uno::Reference< css::frame::XModel2 >& i_rxDocument
     165             :                         ) const;
     166             : 
     167             :     void                impl_handleCaughtError_nothrow(
     168             :                             const css::uno::Any& i_rCaughtError,
     169             :                             const ::comphelper::NamedValueCollection& i_rDescriptor
     170             :                         ) const;
     171             : 
     172             :     void                impl_removeLoaderArguments(
     173             :                             ::comphelper::NamedValueCollection& io_rDescriptor
     174             :                         );
     175             : 
     176             :     sal_Int16           impl_determineEffectiveViewId_nothrow(
     177             :                             const SfxObjectShell& i_rDocument,
     178             :                             const ::comphelper::NamedValueCollection& i_rDescriptor
     179             :                         );
     180             : 
     181             :     ::comphelper::NamedValueCollection
     182             :                         impl_extractViewCreationArgs(
     183             :                                   ::comphelper::NamedValueCollection& io_rDescriptor
     184             :                         );
     185             : 
     186             :     css::uno::Reference< css::frame::XController2 >
     187             :                         impl_createDocumentView(
     188             :                             const css::uno::Reference< css::frame::XModel2 >& i_rModel,
     189             :                             const css::uno::Reference< css::frame::XFrame >& i_rFrame,
     190             :                             const ::comphelper::NamedValueCollection& i_rViewFactoryArgs,
     191             :                             const OUString& i_rViewName
     192             :                         );
     193             : };
     194             : 
     195           0 : SfxFrameLoader_Impl::SfxFrameLoader_Impl( const Reference< css::uno::XComponentContext >& _rxContext )
     196           0 :     :m_aContext( _rxContext )
     197             : {
     198           0 : }
     199             : 
     200           0 : SfxFrameLoader_Impl::~SfxFrameLoader_Impl()
     201             : {
     202           0 : }
     203             : 
     204             : 
     205           0 : const SfxFilter* SfxFrameLoader_Impl::impl_detectFilterForURL( const OUString& sURL,
     206             :         const ::comphelper::NamedValueCollection& i_rDescriptor, const SfxFilterMatcher& rMatcher ) const
     207             : {
     208           0 :     OUString sFilter;
     209             :     try
     210             :     {
     211           0 :         if ( sURL.isEmpty() )
     212           0 :             return 0;
     213             : 
     214             :         Reference< XTypeDetection > xDetect(
     215           0 :             m_aContext->getServiceManager()->createInstanceWithContext("com.sun.star.document.TypeDetection", m_aContext),
     216           0 :             UNO_QUERY_THROW);
     217             : 
     218           0 :         ::comphelper::NamedValueCollection aNewArgs;
     219           0 :         aNewArgs.put( "URL", sURL );
     220             : 
     221           0 :         if ( i_rDescriptor.has( "InteractionHandler" ) )
     222           0 :             aNewArgs.put( "InteractionHandler", i_rDescriptor.get( "InteractionHandler" ) );
     223           0 :         if ( i_rDescriptor.has( "StatusIndicator" ) )
     224           0 :             aNewArgs.put( "StatusIndicator", i_rDescriptor.get( "StatusIndicator" ) );
     225             : 
     226           0 :         Sequence< PropertyValue > aQueryArgs( aNewArgs.getPropertyValues() );
     227           0 :         OUString sType = xDetect->queryTypeByDescriptor( aQueryArgs, sal_True );
     228           0 :         if ( !sType.isEmpty() )
     229             :         {
     230           0 :             const SfxFilter* pFilter = rMatcher.GetFilter4EA( sType );
     231           0 :             if ( pFilter )
     232           0 :                 sFilter = pFilter->GetName();
     233           0 :         }
     234             :     }
     235           0 :     catch ( const RuntimeException& )
     236             :     {
     237           0 :         throw;
     238             :     }
     239           0 :     catch( const Exception& )
     240             :     {
     241             :         DBG_UNHANDLED_EXCEPTION();
     242           0 :         sFilter = OUString();
     243             :     }
     244             : 
     245           0 :     const SfxFilter* pFilter = 0;
     246           0 :     if (!sFilter.isEmpty())
     247           0 :         pFilter = rMatcher.GetFilter4FilterName(sFilter);
     248           0 :     return pFilter;
     249             : }
     250             : 
     251             : 
     252           0 : const SfxFilter* SfxFrameLoader_Impl::impl_getFilterFromServiceName_nothrow( const OUString& i_rServiceName ) const
     253             : {
     254             :     try
     255             :     {
     256           0 :         ::comphelper::NamedValueCollection aQuery;
     257           0 :         aQuery.put( "DocumentService", i_rServiceName );
     258             : 
     259             :         const Reference< XContainerQuery > xQuery(
     260           0 :             m_aContext->getServiceManager()->createInstanceWithContext("com.sun.star.document.FilterFactory", m_aContext),
     261           0 :             UNO_QUERY_THROW );
     262             : 
     263           0 :         const SfxFilterMatcher& rMatcher = SFX_APP()->GetFilterMatcher();
     264           0 :         const SfxFilterFlags nMust = SFX_FILTER_IMPORT;
     265           0 :         const SfxFilterFlags nDont = SFX_FILTER_NOTINSTALLED;
     266             : 
     267           0 :         Reference < XEnumeration > xEnum( xQuery->createSubSetEnumerationByProperties(
     268           0 :             aQuery.getNamedValues() ), UNO_SET_THROW );
     269           0 :         while ( xEnum->hasMoreElements() )
     270             :         {
     271           0 :             ::comphelper::NamedValueCollection aType( xEnum->nextElement() );
     272           0 :             OUString sFilterName = aType.getOrDefault( "Name", OUString() );
     273           0 :             if ( sFilterName.isEmpty() )
     274           0 :                 continue;
     275             : 
     276           0 :             const SfxFilter* pFilter = rMatcher.GetFilter4FilterName( sFilterName );
     277           0 :             if ( !pFilter )
     278           0 :                 continue;
     279             : 
     280           0 :             SfxFilterFlags nFlags = pFilter->GetFilterFlags();
     281           0 :             if  (   ( ( nFlags & nMust ) == nMust )
     282           0 :                 &&  ( ( nFlags & nDont ) == 0 )
     283             :                 )
     284             :             {
     285           0 :                 return pFilter;
     286             :             }
     287           0 :         }
     288             :     }
     289           0 :     catch( const Exception& )
     290             :     {
     291             :         DBG_UNHANDLED_EXCEPTION();
     292             :     }
     293           0 :     return NULL;
     294             : }
     295             : 
     296             : 
     297           0 : OUString SfxFrameLoader_Impl::impl_askForFilter_nothrow( const Reference< XInteractionHandler >& i_rxHandler,
     298             :                                                                  const OUString& i_rDocumentURL ) const
     299             : {
     300           0 :     ENSURE_OR_THROW( i_rxHandler.is(), "invalid interaction handler" );
     301             : 
     302           0 :     OUString sFilterName;
     303             :     try
     304             :     {
     305           0 :         ::framework::RequestFilterSelect aRequest( i_rDocumentURL );
     306           0 :         i_rxHandler->handle( aRequest.GetRequest() );
     307           0 :         if( !aRequest.isAbort() )
     308           0 :             sFilterName = aRequest.getFilter();
     309             :     }
     310           0 :     catch( const Exception& )
     311             :     {
     312             :         DBG_UNHANDLED_EXCEPTION();
     313             :     }
     314             : 
     315           0 :     return sFilterName;
     316             : }
     317             : 
     318             : 
     319             : namespace
     320             : {
     321           0 :     bool lcl_getDispatchResult( const SfxPoolItem* _pResult )
     322             :     {
     323           0 :         if ( !_pResult )
     324           0 :             return false;
     325             : 
     326             :         // default must be set to true, because some return values
     327             :         // cant be checked, but nonetheless indicate "success"!
     328           0 :         bool bSuccess = true;
     329             : 
     330             :         // On the other side some special slots return a boolean state,
     331             :         // which can be set to FALSE.
     332           0 :         SfxBoolItem *pItem = PTR_CAST( SfxBoolItem, _pResult );
     333           0 :         if ( pItem )
     334           0 :             bSuccess = pItem->GetValue();
     335             : 
     336           0 :         return bSuccess;
     337             :     }
     338             : }
     339             : 
     340             : 
     341           0 : bool SfxFrameLoader_Impl::impl_createNewDocWithSlotParam( const sal_uInt16 _nSlotID, const Reference< XFrame >& i_rxFrame,
     342             :                                                               const bool i_bHidden )
     343             : {
     344           0 :     SfxRequest aRequest( _nSlotID, SFX_CALLMODE_SYNCHRON, SFX_APP()->GetPool() );
     345           0 :     aRequest.AppendItem( SfxUnoFrameItem( SID_FILLFRAME, i_rxFrame ) );
     346           0 :     if ( i_bHidden )
     347           0 :         aRequest.AppendItem( SfxBoolItem( SID_HIDDEN, true ) );
     348           0 :     return lcl_getDispatchResult( SFX_APP()->ExecuteSlot( aRequest ) );
     349             : }
     350             : 
     351             : 
     352           0 : void SfxFrameLoader_Impl::impl_determineFilter( ::comphelper::NamedValueCollection& io_rDescriptor ) const
     353             : {
     354           0 :     const OUString     sURL         = io_rDescriptor.getOrDefault( "URL",                OUString() );
     355           0 :     const OUString     sTypeName    = io_rDescriptor.getOrDefault( "TypeName",           OUString() );
     356           0 :     const OUString     sFilterName  = io_rDescriptor.getOrDefault( "FilterName",         OUString() );
     357           0 :     const OUString     sServiceName = io_rDescriptor.getOrDefault( "DocumentService",    OUString() );
     358             :     const Reference< XInteractionHandler >
     359           0 :                               xInteraction = io_rDescriptor.getOrDefault( "InteractionHandler", Reference< XInteractionHandler >() );
     360             : 
     361           0 :     const SfxFilterMatcher& rMatcher = SFX_APP()->GetFilterMatcher();
     362           0 :     const SfxFilter* pFilter = NULL;
     363             : 
     364             :     // get filter by its name directly ...
     365           0 :     if ( !sFilterName.isEmpty() )
     366           0 :         pFilter = rMatcher.GetFilter4FilterName( sFilterName );
     367             : 
     368             :     // or search the preferred filter for the detected type ...
     369           0 :     if ( !pFilter && !sTypeName.isEmpty() )
     370           0 :         pFilter = rMatcher.GetFilter4EA( sTypeName );
     371             : 
     372             :     // or use given document service for detection, too
     373           0 :     if ( !pFilter && !sServiceName.isEmpty() )
     374           0 :         pFilter = impl_getFilterFromServiceName_nothrow( sServiceName );
     375             : 
     376             :     // or use interaction to ask user for right filter.
     377           0 :     if ( !pFilter && xInteraction.is() && !sURL.isEmpty() )
     378             :     {
     379           0 :         OUString sSelectedFilter = impl_askForFilter_nothrow( xInteraction, sURL );
     380           0 :         if ( !sSelectedFilter.isEmpty() )
     381           0 :             pFilter = rMatcher.GetFilter4FilterName( sSelectedFilter );
     382             :     }
     383             : 
     384           0 :     if ( pFilter )
     385             :     {
     386           0 :         io_rDescriptor.put( "FilterName", OUString( pFilter->GetFilterName() ) );
     387             : 
     388             :         // If detected filter indicates using of an own template format
     389             :         // add property "AsTemplate" to descriptor. But suppress this step
     390             :         // if such property already exists.
     391           0 :         if ( pFilter->IsOwnTemplateFormat() && !io_rDescriptor.has( "AsTemplate" ) )
     392           0 :             io_rDescriptor.put( "AsTemplate", true );
     393             : 
     394             :         // The DocumentService property will finally be used to determine the document type to create, so
     395             :         // override it with the service name as indicated by the found filter.
     396           0 :         io_rDescriptor.put( "DocumentService", OUString( pFilter->GetServiceName() ) );
     397           0 :     }
     398           0 : }
     399             : 
     400             : 
     401           0 : SfxObjectShellRef SfxFrameLoader_Impl::impl_findObjectShell( const Reference< XModel2 >& i_rxDocument ) const
     402             : {
     403           0 :     for ( SfxObjectShell* pDoc = SfxObjectShell::GetFirst( NULL, false ); pDoc; pDoc = SfxObjectShell::GetNext( *pDoc, NULL, false ) )
     404             :     {
     405           0 :         if ( i_rxDocument == pDoc->GetModel() )
     406             :         {
     407           0 :             return pDoc;
     408             :         }
     409             :     }
     410             : 
     411             :     SAL_WARN( "sfx.view", "SfxFrameLoader_Impl::impl_findObjectShell: model is not based on SfxObjectShell - wrong frame loader usage!" );
     412           0 :     return NULL;
     413             : }
     414             : 
     415             : 
     416           0 : bool SfxFrameLoader_Impl::impl_determineTemplateDocument( ::comphelper::NamedValueCollection& io_rDescriptor ) const
     417             : {
     418             :     try
     419             :     {
     420           0 :         const OUString sTemplateRegioName = io_rDescriptor.getOrDefault( "TemplateRegionName", OUString() );
     421           0 :         const OUString sTemplateName      = io_rDescriptor.getOrDefault( "TemplateName",       OUString() );
     422           0 :         const OUString sServiceName       = io_rDescriptor.getOrDefault( "DocumentService",    OUString() );
     423           0 :         const OUString sURL               = io_rDescriptor.getOrDefault( "URL",                OUString() );
     424             : 
     425             :         // determine the full URL of the template to use, if any
     426           0 :         OUString sTemplateURL;
     427           0 :         if ( !sTemplateRegioName.isEmpty() && !sTemplateName.isEmpty() )
     428             :         {
     429           0 :             SfxDocumentTemplates aTmpFac;
     430           0 :             aTmpFac.GetFull( sTemplateRegioName, sTemplateName, sTemplateURL );
     431             :         }
     432             :         else
     433             :         {
     434           0 :             if ( !sServiceName.isEmpty() )
     435           0 :                 sTemplateURL = SfxObjectFactory::GetStandardTemplate( sServiceName );
     436             :             else
     437           0 :                 sTemplateURL = SfxObjectFactory::GetStandardTemplate( SfxObjectShell::GetServiceNameFromFactory( sURL ) );
     438             :         }
     439             : 
     440           0 :         if ( !sTemplateURL.isEmpty() )
     441             :         {
     442             :             // detect the filter for the template. Might still be NULL (if the template is broken, or does not
     443             :             // exist, or some such), but this is handled by our caller the same way as if no template/URL was present.
     444           0 :             const SfxFilter* pTemplateFilter = impl_detectFilterForURL( sTemplateURL, io_rDescriptor, SFX_APP()->GetFilterMatcher() );
     445           0 :             if ( pTemplateFilter )
     446             :             {
     447             :                 // load the template document, but, well, "as template"
     448           0 :                 io_rDescriptor.put( "FilterName", OUString( pTemplateFilter->GetName() ) );
     449           0 :                 io_rDescriptor.put( "FileName", OUString( sTemplateURL ) );
     450           0 :                 io_rDescriptor.put( "AsTemplate", sal_True );
     451             : 
     452             :                 // #i21583#
     453             :                 // the DocumentService property will finally be used to create the document. Thus, override any possibly
     454             :                 // present value with the document service of the template.
     455           0 :                 io_rDescriptor.put( "DocumentService", OUString( pTemplateFilter->GetServiceName() ) );
     456           0 :                 return true;
     457             :             }
     458           0 :         }
     459             :     }
     460           0 :     catch (...)
     461             :     {
     462             :     }
     463           0 :     return false;
     464             : }
     465             : 
     466             : 
     467           0 : sal_uInt16 SfxFrameLoader_Impl::impl_findSlotParam( const OUString& i_rFactoryURL ) const
     468             : {
     469           0 :     OUString sSlotParam;
     470           0 :     const sal_Int32 nParamPos = i_rFactoryURL.indexOf( '?' );
     471           0 :     if ( nParamPos >= 0 )
     472             :     {
     473             :         // currently only the "slot" parameter is supported
     474           0 :         const sal_Int32 nSlotPos = i_rFactoryURL.indexOf( "slot=", nParamPos );
     475           0 :         if ( nSlotPos > 0 )
     476           0 :             sSlotParam = i_rFactoryURL.copy( nSlotPos + 5 );
     477             :     }
     478             : 
     479           0 :     if ( !sSlotParam.isEmpty() )
     480           0 :         return sal_uInt16( sSlotParam.toInt32() );
     481             : 
     482           0 :     return 0;
     483             : }
     484             : 
     485             : 
     486           0 : void SfxFrameLoader_Impl::impl_handleCaughtError_nothrow( const Any& i_rCaughtError, const ::comphelper::NamedValueCollection& i_rDescriptor ) const
     487             : {
     488             :     try
     489             :     {
     490             :         const Reference< XInteractionHandler > xInteraction =
     491           0 :             i_rDescriptor.getOrDefault( "InteractionHandler", Reference< XInteractionHandler >() );
     492           0 :         if ( !xInteraction.is() )
     493           0 :             return;
     494           0 :         ::rtl::Reference< ::comphelper::OInteractionRequest > pRequest( new ::comphelper::OInteractionRequest( i_rCaughtError ) );
     495           0 :         ::rtl::Reference< ::comphelper::OInteractionApprove > pApprove( new ::comphelper::OInteractionApprove );
     496           0 :         pRequest->addContinuation( pApprove.get() );
     497             : 
     498           0 :         const Reference< XInteractionHandler2 > xHandler( xInteraction, UNO_QUERY );
     499             :     #if OSL_DEBUG_LEVEL > 0
     500             :         const bool bHandled =
     501             :     #endif
     502           0 :         xHandler.is() && xHandler->handleInteractionRequest( pRequest.get() );
     503             : 
     504             :     #if OSL_DEBUG_LEVEL > 0
     505             :         if ( !bHandled )
     506             :             // the interaction handler couldn't deal with this error
     507             :             // => report it as assertion, at least (done in the DBG_UNHANDLED_EXCEPTION below)
     508             :             ::cppu::throwException( i_rCaughtError );
     509             :     #endif
     510             :     }
     511           0 :     catch( const Exception& )
     512             :     {
     513             :         DBG_UNHANDLED_EXCEPTION();
     514             :     }
     515             : }
     516             : 
     517             : 
     518           0 : void SfxFrameLoader_Impl::impl_removeLoaderArguments( ::comphelper::NamedValueCollection& io_rDescriptor )
     519             : {
     520             :     // remove the arguments which are for the loader only, and not for a call to attachResource
     521           0 :     io_rDescriptor.remove( "StatusIndicator" );
     522           0 :     io_rDescriptor.remove( "Model" );
     523           0 : }
     524             : 
     525             : 
     526           0 : ::comphelper::NamedValueCollection SfxFrameLoader_Impl::impl_extractViewCreationArgs( ::comphelper::NamedValueCollection& io_rDescriptor )
     527             : {
     528             :     const sal_Char* pKnownViewArgs[] = {
     529             :         "JumpMark"
     530           0 :     };
     531             : 
     532           0 :     ::comphelper::NamedValueCollection aViewArgs;
     533           0 :     for ( size_t i=0; i < sizeof( pKnownViewArgs ) / sizeof( pKnownViewArgs[0] ); ++i )
     534             :     {
     535           0 :         if ( io_rDescriptor.has( pKnownViewArgs[i] ) )
     536             :         {
     537           0 :             aViewArgs.put( pKnownViewArgs[i], io_rDescriptor.get( pKnownViewArgs[i] ) );
     538           0 :             io_rDescriptor.remove( pKnownViewArgs[i] );
     539             :         }
     540             :     }
     541           0 :     return aViewArgs;
     542             : }
     543             : 
     544             : 
     545           0 : sal_Int16 SfxFrameLoader_Impl::impl_determineEffectiveViewId_nothrow( const SfxObjectShell& i_rDocument, const ::comphelper::NamedValueCollection& i_rDescriptor )
     546             : {
     547           0 :     sal_Int16 nViewId = i_rDescriptor.getOrDefault( "ViewId", sal_Int16( 0 ) );
     548             :     try
     549             :     {
     550           0 :         if ( nViewId == 0 ) do
     551             :         {
     552           0 :             Reference< XViewDataSupplier > xViewDataSupplier( i_rDocument.GetModel(), UNO_QUERY );
     553           0 :             Reference< XIndexAccess > xViewData;
     554           0 :             if ( xViewDataSupplier.is() )
     555           0 :                 xViewData.set( xViewDataSupplier->getViewData() );
     556             : 
     557           0 :             if ( !xViewData.is() || ( xViewData->getCount() == 0 ) )
     558             :                 // no view data stored together with the model
     559           0 :                 break;
     560             : 
     561             :             // obtain the ViewID from the view data
     562           0 :             Sequence< PropertyValue > aViewData;
     563           0 :             if ( !( xViewData->getByIndex( 0 ) >>= aViewData ) )
     564           0 :                 break;
     565             : 
     566           0 :             ::comphelper::NamedValueCollection aNamedViewData( aViewData );
     567           0 :             OUString sViewId = aNamedViewData.getOrDefault( "ViewId", OUString() );
     568           0 :             if ( sViewId.isEmpty() )
     569           0 :                 break;
     570             : 
     571             :             // somewhat weird convention here ... in the view data, the ViewId is a string, effectively describing
     572             :             // a view name. In the document load descriptor, the ViewId is in fact the numeric ID.
     573             : 
     574           0 :             SfxViewFactory* pViewFactory = i_rDocument.GetFactory().GetViewFactoryByViewName( sViewId );
     575           0 :             if ( pViewFactory )
     576           0 :                 nViewId = sal_Int16( pViewFactory->GetOrdinal() );
     577             :         }
     578             :         while ( false );
     579             :     }
     580           0 :     catch( const Exception& )
     581             :     {
     582             :         DBG_UNHANDLED_EXCEPTION();
     583             :     }
     584             : 
     585           0 :     if ( nViewId == 0 )
     586           0 :         nViewId = i_rDocument.GetFactory().GetViewFactory( 0 ).GetOrdinal();
     587           0 :     return nViewId;
     588             : }
     589             : 
     590             : 
     591           0 : Reference< XController2 > SfxFrameLoader_Impl::impl_createDocumentView( const Reference< XModel2 >& i_rModel,
     592             :         const Reference< XFrame >& i_rFrame, const ::comphelper::NamedValueCollection& i_rViewFactoryArgs,
     593             :         const OUString& i_rViewName )
     594             : {
     595             :     // let the model create a new controller
     596           0 :     const Reference< XController2 > xController( i_rModel->createViewController(
     597             :         i_rViewName,
     598             :         i_rViewFactoryArgs.getPropertyValues(),
     599             :         i_rFrame
     600           0 :     ), UNO_SET_THROW );
     601             : 
     602             :     // introduce model/view/controller to each other
     603           0 :     xController->attachModel( i_rModel.get() );
     604           0 :     i_rModel->connectController( xController.get() );
     605           0 :     i_rFrame->setComponent( xController->getComponentWindow(), xController.get() );
     606           0 :     xController->attachFrame( i_rFrame );
     607           0 :     i_rModel->setCurrentController( xController.get() );
     608             : 
     609           0 :     return xController;
     610             : }
     611             : 
     612             : 
     613           0 : sal_Bool SAL_CALL SfxFrameLoader_Impl::load( const Sequence< PropertyValue >& rArgs,
     614             :                                              const Reference< XFrame >& _rTargetFrame )
     615             :     throw( RuntimeException, std::exception )
     616             : {
     617           0 :     ENSURE_OR_THROW( _rTargetFrame.is(), "illegal NULL frame" );
     618             : 
     619           0 :     SolarMutexGuard aGuard;
     620             : 
     621             :     SAL_INFO( "sfx.view", "SfxFrameLoader::load" );
     622             : 
     623           0 :     ::comphelper::NamedValueCollection aDescriptor( rArgs );
     624             : 
     625             :     // ensure the descriptor contains a referrer
     626           0 :     if ( !aDescriptor.has( "Referer" ) )
     627           0 :         aDescriptor.put( "Referer", OUString() );
     628             : 
     629             :     // did the caller already pass a model?
     630           0 :     Reference< XModel2 > xModel = aDescriptor.getOrDefault( "Model", Reference< XModel2 >() );
     631           0 :     const bool bExternalModel = xModel.is();
     632             : 
     633             :     // check for factory URLs to create a new doc, instead of loading one
     634           0 :     const OUString sURL = aDescriptor.getOrDefault( "URL", OUString() );
     635           0 :     const bool bIsFactoryURL = sURL.startsWith( "private:factory/" );
     636           0 :     bool bInitNewModel = bIsFactoryURL;
     637           0 :     if ( bIsFactoryURL && !bExternalModel )
     638             :     {
     639           0 :         const OUString sFactory = sURL.copy( sizeof( "private:factory/" ) -1 );
     640             :         // special handling for some weird factory URLs a la private:factory/swriter?slot=21053
     641           0 :         const sal_uInt16 nSlotParam = impl_findSlotParam( sFactory );
     642           0 :         if ( nSlotParam != 0 )
     643             :         {
     644           0 :             return impl_createNewDocWithSlotParam( nSlotParam, _rTargetFrame, aDescriptor.getOrDefault( "Hidden", false ) );
     645             :         }
     646             : 
     647           0 :         const bool bDescribesValidTemplate = impl_determineTemplateDocument( aDescriptor );
     648           0 :         if ( bDescribesValidTemplate )
     649             :         {
     650             :             // if the media descriptor allowed us to determine a template document to create the new document
     651             :             // from, then do not init a new document model from scratch (below), but instead load the
     652             :             // template document
     653           0 :             bInitNewModel = false;
     654             :         }
     655             :         else
     656             :         {
     657           0 :             const OUString sServiceName = SfxObjectShell::GetServiceNameFromFactory( sFactory );
     658           0 :             aDescriptor.put( "DocumentService", sServiceName );
     659           0 :         }
     660             :     }
     661             :     else
     662             :     {
     663             :         // compatibility
     664           0 :         aDescriptor.put( "FileName", aDescriptor.get( "URL" ) );
     665             :     }
     666             : 
     667           0 :     bool bLoadSuccess = false;
     668             :     try
     669             :     {
     670             :         // extract view releant arguments from the loader args
     671           0 :         ::comphelper::NamedValueCollection aViewCreationArgs( impl_extractViewCreationArgs( aDescriptor ) );
     672             : 
     673             :         // no model passed from outside? => create one from scratch
     674           0 :         if ( !xModel.is() )
     675             :         {
     676           0 :             bool bInternalFilter = aDescriptor.getOrDefault<OUString>("FilterProvider", OUString()).isEmpty();
     677             : 
     678           0 :             if (bInternalFilter && !bInitNewModel)
     679             :             {
     680             :                 // Ensure that the current SfxFilter instance is loaded before
     681             :                 // going further.  We don't need to do this for external
     682             :                 // filter providers.
     683           0 :                 impl_determineFilter(aDescriptor);
     684             :             }
     685             : 
     686             :             // create the new doc
     687           0 :             const OUString sServiceName = aDescriptor.getOrDefault( "DocumentService", OUString() );
     688           0 :             xModel.set( m_aContext->getServiceManager()->createInstanceWithContext(sServiceName, m_aContext), UNO_QUERY_THROW );
     689             : 
     690             :             // load resp. init it
     691           0 :             const Reference< XLoadable > xLoadable( xModel, UNO_QUERY_THROW );
     692           0 :             if ( bInitNewModel )
     693             :             {
     694           0 :                 xLoadable->initNew();
     695             : 
     696           0 :                 impl_removeLoaderArguments( aDescriptor );
     697           0 :                 xModel->attachResource( OUString(), aDescriptor.getPropertyValues() );
     698             :             }
     699             :             else
     700             :             {
     701           0 :                 xLoadable->load( aDescriptor.getPropertyValues() );
     702           0 :             }
     703             :         }
     704             :         else
     705             :         {
     706             :             // tell the doc its (current) load args.
     707           0 :             impl_removeLoaderArguments( aDescriptor );
     708           0 :             xModel->attachResource( xModel->getURL(), aDescriptor.getPropertyValues() );
     709             :         }
     710             : 
     711             :         // get the SfxObjectShell (still needed at the moment)
     712             :         // SfxObjectShellRef is used here ( instead of ...Lock ) since the model is closed below if necessary
     713             :         // SfxObjectShellLock would be even dangerous here, since the lifetime control should be done outside in case of success
     714           0 :         const SfxObjectShellRef xDoc = impl_findObjectShell( xModel );
     715           0 :         ENSURE_OR_THROW( xDoc.Is(), "no SfxObjectShell for the given model" );
     716             : 
     717             :         // ensure the ID of the to-be-created view is in the descriptor, if possible
     718           0 :         const sal_Int16 nViewId = impl_determineEffectiveViewId_nothrow( *xDoc, aDescriptor );
     719           0 :         const sal_Int16 nViewNo = xDoc->GetFactory().GetViewNo_Impl( nViewId, 0 );
     720           0 :         const OUString sViewName( xDoc->GetFactory().GetViewFactory( nViewNo ).GetAPIViewName() );
     721             : 
     722             :         // plug the document into the frame
     723           0 :         impl_createDocumentView( xModel, _rTargetFrame, aViewCreationArgs, sViewName );
     724           0 :         bLoadSuccess = true;
     725             :     }
     726           0 :     catch ( Exception& )
     727             :     {
     728           0 :         const Any aError( ::cppu::getCaughtException() );
     729           0 :         if ( !aDescriptor.getOrDefault( "Silent", sal_False ) )
     730           0 :             impl_handleCaughtError_nothrow( aError, aDescriptor );
     731             :     }
     732             : 
     733             :     // if loading was not successful, close the document
     734           0 :     if ( !bLoadSuccess && !bExternalModel )
     735             :     {
     736             :         try
     737             :         {
     738           0 :             const Reference< XCloseable > xCloseable( xModel, UNO_QUERY_THROW );
     739           0 :             xCloseable->close( sal_True );
     740             :         }
     741           0 :         catch ( Exception& )
     742             :         {
     743             :             DBG_UNHANDLED_EXCEPTION();
     744             :         }
     745             :     }
     746             : 
     747           0 :     return bLoadSuccess;
     748             : }
     749             : 
     750           0 : void SfxFrameLoader_Impl::cancel() throw( RuntimeException, std::exception )
     751             : {
     752           0 : }
     753             : 
     754             : /* XServiceInfo */
     755           0 : OUString SAL_CALL SfxFrameLoader_Impl::getImplementationName() throw( RuntimeException, std::exception )
     756             : {
     757           0 :     return OUString("com.sun.star.comp.office.FrameLoader");
     758             : }
     759             :                                                                                                                                 \
     760             : /* XServiceInfo */
     761           0 : sal_Bool SAL_CALL SfxFrameLoader_Impl::supportsService( const OUString& sServiceName ) throw( RuntimeException, std::exception )
     762             : {
     763           0 :     return cppu::supportsService(this, sServiceName);
     764             : }
     765             : 
     766             : /* XServiceInfo */
     767           0 : Sequence< OUString > SAL_CALL SfxFrameLoader_Impl::getSupportedServiceNames() throw( RuntimeException, std::exception )
     768             : {
     769           0 :     Sequence< OUString > seqServiceNames( 2 );
     770           0 :     seqServiceNames.getArray() [0] = "com.sun.star.frame.SynchronousFrameLoader";
     771           0 :     seqServiceNames.getArray() [1] = "com.sun.star.frame.OfficeFrameLoader";
     772           0 :     return seqServiceNames ;
     773             : }
     774             : 
     775             : }
     776             : 
     777             : extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * SAL_CALL
     778           0 : com_sun_star_comp_office_FrameLoader_get_implementation(
     779             :     css::uno::XComponentContext *context,
     780             :     css::uno::Sequence<css::uno::Any> const &)
     781             : {
     782           0 :     return cppu::acquire(new SfxFrameLoader_Impl(context));
     783             : }
     784             : 
     785             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10