31#include <sfx2/sfxsids.hrc>
34#include <com/sun/star/container/XContainerQuery.hpp>
35#include <com/sun/star/document/XTypeDetection.hpp>
36#include <com/sun/star/frame/XFrame.hpp>
37#include <com/sun/star/frame/XLoadable.hpp>
38#include <com/sun/star/task/XInteractionHandler.hpp>
39#include <com/sun/star/task/XInteractionHandler2.hpp>
40#include <com/sun/star/document/XViewDataSupplier.hpp>
41#include <com/sun/star/container/XIndexAccess.hpp>
42#include <com/sun/star/frame/XSynchronousFrameLoader.hpp>
43#include <com/sun/star/frame/XController2.hpp>
44#include <com/sun/star/frame/XModel2.hpp>
45#include <com/sun/star/lang/XServiceInfo.hpp>
46#include <com/sun/star/lang/XInitialization.hpp>
47#include <com/sun/star/uno/XComponentContext.hpp>
48#include <com/sun/star/util/XCloseable.hpp>
69using ::com::sun::star::beans::PropertyValue;
70using ::com::sun::star::container::XContainerQuery;
71using ::com::sun::star::container::XEnumeration;
72using ::com::sun::star::document::XTypeDetection;
73using ::com::sun::star::frame::XFrame;
74using ::com::sun::star::frame::XLoadable;
75using ::com::sun::star::task::XInteractionHandler;
76using ::com::sun::star::task::XInteractionHandler2;
77using ::com::sun::star::uno::Any;
78using ::com::sun::star::uno::Exception;
79using ::com::sun::star::uno::Reference;
80using ::com::sun::star::uno::RuntimeException;
81using ::com::sun::star::uno::Sequence;
82using ::com::sun::star::uno::UNO_QUERY;
83using ::com::sun::star::uno::UNO_QUERY_THROW;
84using ::com::sun::star::uno::UNO_SET_THROW;
85using ::com::sun::star::util::XCloseable;
86using ::com::sun::star::document::XViewDataSupplier;
87using ::com::sun::star::container::XIndexAccess;
88using ::com::sun::star::frame::XController2;
89using ::com::sun::star::frame::XModel2;
93class SfxFrameLoader_Impl :
public ::cppu::WeakImplHelper< css::frame::XSynchronousFrameLoader, css::lang::XServiceInfo >
95 css::uno::Reference < css::uno::XComponentContext >
m_aContext;
98 explicit SfxFrameLoader_Impl(
const css::uno::Reference < css::uno::XComponentContext >& _rxContext );
109 virtual sal_Bool SAL_CALL load(
const css::uno::Sequence< css::beans::PropertyValue >& _rArgs,
const css::uno::Reference< css::frame::XFrame >& _rxFrame )
override;
110 virtual void SAL_CALL cancel()
override;
113 virtual ~SfxFrameLoader_Impl()
override;
116 std::shared_ptr<const SfxFilter> impl_getFilterFromServiceName_nothrow(
117 const OUString& i_rServiceName
120 static OUString impl_askForFilter_nothrow(
121 const css::uno::Reference< css::task::XInteractionHandler >& i_rxHandler,
122 const OUString& i_rDocumentURL
125 std::shared_ptr<const SfxFilter> impl_detectFilterForURL(
126 const OUString& _rURL,
127 const ::comphelper::NamedValueCollection& i_rDescriptor,
131 static bool impl_createNewDocWithSlotParam(
132 const sal_uInt16 _nSlotID,
133 const css::uno::Reference< css::frame::XFrame >& i_rxFrame,
137 void impl_determineFilter(
141 bool impl_determineTemplateDocument(
145 static sal_uInt16 impl_findSlotParam(
146 std::u16string_view i_rFactoryURL
150 const css::uno::Reference< css::frame::XModel2 >& i_rxDocument
153 static void impl_handleCaughtError_nothrow(
154 const css::uno::Any& i_rCaughtError,
155 const ::comphelper::NamedValueCollection& i_rDescriptor
158 static void impl_removeLoaderArguments(
164 const ::comphelper::NamedValueCollection& i_rDescriptor
167 static ::comphelper::NamedValueCollection
168 impl_extractViewCreationArgs(
172 static css::uno::Reference< css::frame::XController2 >
173 impl_createDocumentView(
174 const css::uno::Reference< css::frame::XModel2 >& i_rModel,
175 const css::uno::Reference< css::frame::XFrame >& i_rFrame,
176 const ::comphelper::NamedValueCollection& i_rViewFactoryArgs,
177 const OUString& i_rViewName
181SfxFrameLoader_Impl::SfxFrameLoader_Impl(
const Reference< css::uno::XComponentContext >& _rxContext )
186SfxFrameLoader_Impl::~SfxFrameLoader_Impl()
191std::shared_ptr<const SfxFilter> SfxFrameLoader_Impl::impl_detectFilterForURL(
const OUString& sURL,
192 const ::comphelper::NamedValueCollection& i_rDescriptor,
const SfxFilterMatcher& rMatcher )
const
197 if ( sURL.isEmpty() )
200 Reference< XTypeDetection > xDetect(
201 m_aContext->getServiceManager()->createInstanceWithContext(
"com.sun.star.document.TypeDetection", m_aContext),
205 aNewArgs.
put(
"URL", sURL );
207 if ( i_rDescriptor.has(
"InteractionHandler" ) )
208 aNewArgs.
put(
"InteractionHandler", i_rDescriptor.get(
"InteractionHandler" ) );
209 if ( i_rDescriptor.has(
"StatusIndicator" ) )
210 aNewArgs.
put(
"StatusIndicator", i_rDescriptor.get(
"StatusIndicator" ) );
213 OUString
sType = xDetect->queryTypeByDescriptor( aQueryArgs,
true );
214 if ( !
sType.isEmpty() )
216 std::shared_ptr<const SfxFilter> pFilter = rMatcher.
GetFilter4EA( sType );
218 sFilter = pFilter->GetName();
225 catch(
const Exception& )
231 std::shared_ptr<const SfxFilter> pFilter;
232 if (!sFilter.isEmpty())
238std::shared_ptr<const SfxFilter> SfxFrameLoader_Impl::impl_getFilterFromServiceName_nothrow(
const OUString& i_rServiceName )
const
243 aQuery.
put(
"DocumentService", i_rServiceName );
245 const Reference< XContainerQuery > xQuery(
246 m_aContext->getServiceManager()->createInstanceWithContext(
"com.sun.star.document.FilterFactory", m_aContext),
253 Reference < XEnumeration > xEnum( xQuery->createSubSetEnumerationByProperties(
255 while ( xEnum->hasMoreElements() )
258 OUString sFilterName = aType.getOrDefault(
"Name", OUString() );
259 if ( sFilterName.isEmpty() )
267 if ( ( ( nFlags & nMust ) == nMust )
268 && ( ( nFlags & nDont ) == SfxFilterFlags::NONE )
275 catch(
const Exception& )
283OUString SfxFrameLoader_Impl::impl_askForFilter_nothrow(
const Reference< XInteractionHandler >& i_rxHandler,
284 const OUString& i_rDocumentURL )
288 OUString sFilterName;
291 ::framework::RequestFilterSelect aRequest( i_rDocumentURL );
292 i_rxHandler->handle( aRequest.GetRequest() );
293 if( !aRequest.isAbort() )
294 sFilterName = aRequest.getFilter();
296 catch(
const Exception& )
304bool lcl_getDispatchResult(
const SfxPoolItem* _pResult )
311 bool bSuccess =
true;
322bool SfxFrameLoader_Impl::impl_createNewDocWithSlotParam(
const sal_uInt16 _nSlotID,
const Reference< XFrame >& i_rxFrame,
323 const bool i_bHidden )
328 aRequest.AppendItem(
SfxBoolItem( SID_HIDDEN,
true ) );
329 return lcl_getDispatchResult(
SfxGetpApp()->ExecuteSlot( aRequest ) );
335 const OUString sURL = io_rDescriptor.
getOrDefault(
"URL", OUString() );
336 const OUString sTypeName = io_rDescriptor.
getOrDefault(
"TypeName", OUString() );
337 const OUString sFilterName = io_rDescriptor.
getOrDefault(
"FilterName", OUString() );
339 const Reference< XInteractionHandler >
340 xInteraction = io_rDescriptor.
getOrDefault(
"InteractionHandler", Reference< XInteractionHandler >() );
343 std::shared_ptr<const SfxFilter> pFilter;
346 if ( !sFilterName.isEmpty() )
350 if ( !pFilter && !sTypeName.isEmpty() )
355 pFilter = impl_getFilterFromServiceName_nothrow( sServiceName );
358 if ( !pFilter && xInteraction.is() && !sURL.isEmpty() )
360 OUString sSelectedFilter = impl_askForFilter_nothrow( xInteraction, sURL );
361 if ( !sSelectedFilter.isEmpty() )
368 io_rDescriptor.
put(
"FilterName", pFilter->GetFilterName() );
373 if ( pFilter->IsOwnTemplateFormat() && !io_rDescriptor.
has(
"AsTemplate" ) )
374 io_rDescriptor.
put(
"AsTemplate",
true );
378 io_rDescriptor.
put(
"DocumentService", pFilter->GetServiceName() );
382SfxObjectShellRef SfxFrameLoader_Impl::impl_findObjectShell(
const Reference< XModel2 >& i_rxDocument )
387 if ( i_rxDocument == pDoc->GetModel() )
393 SAL_WARN(
"sfx.view",
"SfxFrameLoader_Impl::impl_findObjectShell: model is not based on SfxObjectShell - wrong frame loader usage!" );
402 const OUString sTemplateRegioName = io_rDescriptor.
getOrDefault(
"TemplateRegionName", OUString() );
405 const OUString sURL = io_rDescriptor.
getOrDefault(
"URL", OUString() );
408 OUString sTemplateURL;
409 if ( !sTemplateRegioName.isEmpty() && !
sTemplateName.isEmpty() )
422 if ( !sTemplateURL.isEmpty() )
426 std::shared_ptr<const SfxFilter> pTemplateFilter = impl_detectFilterForURL( sTemplateURL, io_rDescriptor,
SfxGetpApp()->GetFilterMatcher() );
427 if ( pTemplateFilter )
430 io_rDescriptor.
put(
"FilterName", pTemplateFilter->GetName() );
431 io_rDescriptor.
put(
"FileName", sTemplateURL );
432 io_rDescriptor.
put(
"AsTemplate",
true );
437 io_rDescriptor.
put(
"DocumentService", pTemplateFilter->GetServiceName() );
449sal_uInt16 SfxFrameLoader_Impl::impl_findSlotParam( std::u16string_view i_rFactoryURL )
451 std::u16string_view sSlotParam;
452 const size_t nParamPos = i_rFactoryURL.find(
'?' );
453 if ( nParamPos != std::u16string_view::npos )
456 const size_t nSlotPos = i_rFactoryURL.find( u
"slot=", nParamPos );
457 if ( nSlotPos > 0 && nSlotPos != std::u16string_view::npos )
458 sSlotParam = i_rFactoryURL.substr( nSlotPos + 5 );
461 if ( !sSlotParam.empty() )
468void SfxFrameLoader_Impl::impl_handleCaughtError_nothrow(
const Any& i_rCaughtError, const ::comphelper::NamedValueCollection& i_rDescriptor )
472 const Reference< XInteractionHandler > xInteraction =
473 i_rDescriptor.getOrDefault(
"InteractionHandler", Reference< XInteractionHandler >() );
474 if ( !xInteraction.is() )
478 pRequest->addContinuation( pApprove );
480 const Reference< XInteractionHandler2 > xHandler( xInteraction, UNO_QUERY );
481 #if OSL_DEBUG_LEVEL > 0
482 const bool bHandled =
484 xHandler.is() && xHandler->handleInteractionRequest( pRequest );
486 #if OSL_DEBUG_LEVEL > 0
490 ::cppu::throwException( i_rCaughtError );
493 catch(
const Exception& )
503 io_rDescriptor.
remove(
"StatusIndicator" );
504 io_rDescriptor.
remove(
"Model" );
510 static const std::u16string_view sKnownViewArgs[] = {
u"JumpMark",
u"PickListEntry" };
513 for (
const auto& rKnownViewArg : sKnownViewArgs)
515 const OUString sKnownViewArg(rKnownViewArg);
516 if ( io_rDescriptor.
has( sKnownViewArg ) )
518 aViewArgs.
put( sKnownViewArg, io_rDescriptor.
get( sKnownViewArg ) );
519 io_rDescriptor.
remove( sKnownViewArg );
526SfxInterfaceId SfxFrameLoader_Impl::impl_determineEffectiveViewId_nothrow(
const SfxObjectShell& i_rDocument, const ::comphelper::NamedValueCollection& i_rDescriptor )
528 SfxInterfaceId nViewId(i_rDescriptor.getOrDefault(
"ViewId", sal_Int16( 0 ) ));
534 Reference< XViewDataSupplier > xViewDataSupplier( i_rDocument.
GetModel(), UNO_QUERY );
535 Reference< XIndexAccess > xViewData;
536 if ( xViewDataSupplier.is() )
537 xViewData.set( xViewDataSupplier->getViewData() );
539 if ( !xViewData.is() || ( xViewData->getCount() == 0 ) )
544 Sequence< PropertyValue > aViewData;
545 if ( !( xViewData->getByIndex( 0 ) >>= aViewData ) )
561 catch(
const Exception& )
572Reference< XController2 > SfxFrameLoader_Impl::impl_createDocumentView(
const Reference< XModel2 >& i_rModel,
573 const Reference< XFrame >& i_rFrame, const ::comphelper::NamedValueCollection& i_rViewFactoryArgs,
574 const OUString& i_rViewName )
577 const Reference< XController2 >
xController( i_rModel->createViewController(
579 i_rViewFactoryArgs.getPropertyValues(),
589std::shared_ptr<const SfxFilter> getEmptyURLFilter(std::u16string_view sURL)
599 aExt, SfxFilterFlags::IMPORT | SfxFilterFlags::EXPORT | SfxFilterFlags::PREFERED);
609sal_Bool SAL_CALL SfxFrameLoader_Impl::load(
const Sequence< PropertyValue >& rArgs,
610 const Reference< XFrame >& _rTargetFrame )
614 SAL_INFO(
"sfx.view",
"SfxFrameLoader::load" );
619 if ( !aDescriptor.has(
"Referer" ) )
620 aDescriptor.put(
"Referer", OUString() );
623 Reference< XModel2 >
xModel = aDescriptor.getOrDefault(
"Model", Reference< XModel2 >() );
624 const bool bExternalModel =
xModel.is();
627 const OUString sURL = aDescriptor.getOrDefault(
"URL", OUString() );
628 const bool bIsFactoryURL = sURL.startsWith(
"private:factory/" );
629 std::shared_ptr<const SfxFilter> pEmptyURLFilter;
630 bool bInitNewModel = bIsFactoryURL;
631 const bool bIsDefault = bIsFactoryURL && !bExternalModel;
632 if (!aDescriptor.has(
"Replaceable"))
633 aDescriptor.put(
"Replaceable", bIsDefault);
636 const OUString sFactory = sURL.copy(
sizeof(
"private:factory/" ) -1 );
638 const sal_uInt16 nSlotParam = impl_findSlotParam( sFactory );
639 if ( nSlotParam != 0 )
641 return impl_createNewDocWithSlotParam( nSlotParam, _rTargetFrame, aDescriptor.getOrDefault(
"Hidden",
false ) );
644 const bool bDescribesValidTemplate = impl_determineTemplateDocument( aDescriptor );
645 if ( bDescribesValidTemplate )
650 bInitNewModel =
false;
655 aDescriptor.put(
"DocumentService", sServiceName );
661 aDescriptor.put(
"FileName", aDescriptor.get(
"URL" ) );
665 pEmptyURLFilter = getEmptyURLFilter(sURL);
668 aDescriptor.put(
"DocumentService", pEmptyURLFilter->GetServiceName());
669 if (impl_determineTemplateDocument(aDescriptor))
674 bInitNewModel =
false;
676 aDescriptor.remove(
"UCBContent");
680 bInitNewModel =
true;
686 bool bLoadSuccess =
false;
693 if ( !bExternalModel )
695 bool bInternalFilter = aDescriptor.getOrDefault<OUString>(
"FilterProvider", OUString()).isEmpty();
697 if (bInternalFilter && !bInitNewModel)
702 impl_determineFilter(aDescriptor);
706 const OUString
sServiceName = aDescriptor.getOrDefault(
"DocumentService", OUString() );
707 xModel.set(
m_aContext->getServiceManager()->createInstanceWithContext(sServiceName, m_aContext), UNO_QUERY_THROW );
710 const Reference< XLoadable > xLoadable( xModel, UNO_QUERY_THROW );
713 xLoadable->initNew();
715 impl_removeLoaderArguments( aDescriptor );
716 xModel->attachResource( OUString(), aDescriptor.getPropertyValues() );
720 xLoadable->load( aDescriptor.getPropertyValues() );
726 impl_removeLoaderArguments( aDescriptor );
727 xModel->attachResource(
xModel->getURL(), aDescriptor.getPropertyValues() );
741 auto pMedium = xDoc->GetMedium();
742 auto& rItemSet = pMedium->GetItemSet();
743 rItemSet.ClearItem(SID_TEMPLATE);
744 rItemSet.Put(
SfxStringItem(SID_FILTER_NAME, pEmptyURLFilter->GetFilterName()));
745 pMedium->SetName(sURL,
true);
746 pMedium->SetFilter(pEmptyURLFilter);
747 pMedium->GetInitFileDate(
true);
749 xDoc->FinishedLoading();
753 const SfxInterfaceId nViewId = impl_determineEffectiveViewId_nothrow( *xDoc, aDescriptor );
754 const sal_Int16 nViewNo = xDoc->GetFactory().GetViewNo_Impl( nViewId, 0 );
755 const OUString sViewName( xDoc->GetFactory().GetViewFactory( nViewNo ).GetAPIViewName() );
759 impl_createDocumentView( xModel, _rTargetFrame, aViewCreationArgs, sViewName );
761 Reference<lang::XInitialization> xInit(xController, UNO_QUERY);
764 uno::Sequence<uno::Any> aArgs;
765 xInit->initialize(aArgs);
772 const Any aError( ::cppu::getCaughtException() );
773 if ( !aDescriptor.getOrDefault(
"Silent",
false ) )
774 impl_handleCaughtError_nothrow( aError, aDescriptor );
778 if ( !bLoadSuccess && !bExternalModel )
782 const Reference< XCloseable > xCloseable( xModel, UNO_QUERY_THROW );
783 xCloseable->close(
true );
794void SfxFrameLoader_Impl::cancel()
799OUString SAL_CALL SfxFrameLoader_Impl::getImplementationName()
801 return "com.sun.star.comp.office.FrameLoader";
805sal_Bool SAL_CALL SfxFrameLoader_Impl::supportsService(
const OUString& sServiceName )
811Sequence< OUString > SAL_CALL SfxFrameLoader_Impl::getSupportedServiceNames()
813 return {
"com.sun.star.frame.SynchronousFrameLoader",
"com.sun.star.frame.OfficeFrameLoader" };
818extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
820 css::uno::XComponentContext *context,
821 css::uno::Sequence<css::uno::Any>
const &)
823 return cppu::acquire(
new SfxFrameLoader_Impl(context));
constexpr OUStringLiteral sServiceName
SfxApplication * SfxGetpApp()
constexpr OUStringLiteral sViewId
constexpr OUStringLiteral sTemplateName
SfxFilterMatcher & GetFilterMatcher()
bool GetFull(std::u16string_view rRegion, std::u16string_view rName, OUString &rPath)
std::shared_ptr< const SfxFilter > GetFilter4FilterName(const OUString &rName, SfxFilterFlags nMust=SfxFilterFlags::NONE, SfxFilterFlags nDont=SFX_FILTER_NOTINSTALLED) const
std::shared_ptr< const SfxFilter > GetFilter4EA(const OUString &rEA, SfxFilterFlags nMust=SfxFilterFlags::IMPORT, SfxFilterFlags nDont=SFX_FILTER_NOTINSTALLED) const
std::shared_ptr< const SfxFilter > GetFilter4Extension(const OUString &rExt, SfxFilterFlags nMust=SfxFilterFlags::IMPORT, SfxFilterFlags nDont=SFX_FILTER_NOTINSTALLED) const
static OUString GetStandardTemplate(std::u16string_view rServiceName)
SfxViewFactory * GetViewFactoryByViewName(std::u16string_view i_rViewName) const
returns the view factory whose GetAPIViewName or GetLegacyViewName delivers the requested logical nam...
SfxViewFactory & GetViewFactory(sal_uInt16 i=0) const
static OUString GetServiceNameFromFactory(const OUString &rFact)
static SAL_WARN_UNUSED_RESULT SfxObjectShell * GetNext(const SfxObjectShell &rPrev, const std::function< bool(const SfxObjectShell *)> &isObjectShell=nullptr, bool bOnlyVisible=true)
virtual SfxObjectFactory & GetFactory() const =0
css::uno::Reference< css::frame::XModel3 > GetModel() const
static SAL_WARN_UNUSED_RESULT SfxObjectShell * GetFirst(const std::function< bool(const SfxObjectShell *)> &isObjectShell=nullptr, bool bOnlyVisible=true)
SfxInterfaceId GetOrdinal() const
bool has(const OUString &_rValueName) const
const css::uno::Any & get(const OUString &_rValueName) const
bool remove(const OUString &_rValueName)
bool put(const OUString &_rValueName, const VALUE_TYPE &_rValue)
css::uno::Sequence< css::beans::NamedValue > getNamedValues() const
css::uno::Sequence< css::beans::PropertyValue > getPropertyValues() const
VALUE_TYPE getOrDefault(const OUString &_rValueName, const VALUE_TYPE &_rDefault) const
Reference< XComponentContext > m_aContext
#define ENSURE_OR_THROW(c, m)
#define DBG_UNHANDLED_EXCEPTION(...)
#define SFX_FILTER_NOTINSTALLED
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * com_sun_star_comp_office_FrameLoader_get_implementation(css::uno::XComponentContext *context, css::uno::Sequence< css::uno::Any > const &)
#define SAL_WARN(area, stream)
#define SAL_INFO(area, stream)
css::uno::Sequence< OUString > getSupportedServiceNames()
OUString getImplementationName()
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
sal_Int32 toInt32(std::u16string_view str, sal_Int16 radix=10)
void ConnectFrameControllerModel(const css::uno::Reference< css::frame::XFrame > &xFrame, const css::uno::Reference< css::frame::XController2 > &xController, const css::uno::Reference< css::frame::XModel > &xModel)
constexpr auto SFX_INTERFACE_NONE
Reference< XController > xController
Reference< XModel > xModel