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

Generated by: LCOV version 1.10