diff options
Diffstat (limited to 'sfx2/source/doc/docfac.cxx')
-rw-r--r-- | sfx2/source/doc/docfac.cxx | 354 |
1 files changed, 354 insertions, 0 deletions
diff --git a/sfx2/source/doc/docfac.cxx b/sfx2/source/doc/docfac.cxx new file mode 100644 index 000000000..a222ef7e4 --- /dev/null +++ b/sfx2/source/doc/docfac.cxx @@ -0,0 +1,354 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <com/sun/star/container/XNameAccess.hpp> +#include <com/sun/star/ucb/SimpleFileAccess.hpp> +#include <com/sun/star/document/XTypeDetection.hpp> +#include <com/sun/star/frame/ModuleManager.hpp> +#include <com/sun/star/frame/XLoadable.hpp> +#include <com/sun/star/frame/XStorable.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <comphelper/processfactory.hxx> +#include <comphelper/propertyvalue.hxx> +#include <unotools/moduleoptions.hxx> +#include <comphelper/sequenceashashmap.hxx> +#include <comphelper/configurationhelper.hxx> + +#include <sfx2/docfilt.hxx> +#include <sfx2/docfac.hxx> +#include <sfx2/viewfac.hxx> +#include <sfx2/fcontnr.hxx> +#include <sfx2/module.hxx> +#include "syspath.hxx" +#include <osl/file.hxx> +#include <osl/security.hxx> + +#include <sal/log.hxx> +#include <tools/debug.hxx> +#include <tools/globname.hxx> + +#include <memory> + +using namespace ::com::sun::star; + + +struct SfxObjectFactory_Impl +{ + std::vector<SfxViewFactory*> aViewFactoryArr;// List of <SfxViewFactory>s + OUString aServiceName; + SfxFilterContainer* pFilterContainer; + SfxModule* pModule; + SvGlobalName aClassName; + + SfxObjectFactory_Impl() : + pFilterContainer ( nullptr ), + pModule ( nullptr ) + {} +}; + +SfxFilterContainer* SfxObjectFactory::GetFilterContainer() const +{ + return pImpl->pFilterContainer; +} + +SfxObjectFactory::SfxObjectFactory +( + const SvGlobalName& rName, + const OUString& sName +) : m_sFactoryName( sName ), + pImpl( new SfxObjectFactory_Impl ) +{ + pImpl->pFilterContainer = new SfxFilterContainer( m_sFactoryName ); + pImpl->aClassName = rName; +} + +SfxObjectFactory::~SfxObjectFactory() +{ + delete pImpl->pFilterContainer; +} + + +void SfxObjectFactory::RegisterViewFactory +( + SfxViewFactory &rFactory +) +{ +#if OSL_DEBUG_LEVEL > 0 + { + const OUString sViewName( rFactory.GetAPIViewName() ); + for (auto const& viewFactory : pImpl->aViewFactoryArr) + { + if ( viewFactory->GetAPIViewName() != sViewName ) + continue; + SAL_WARN( "sfx", "SfxObjectFactory::RegisterViewFactory: duplicate view name: " << sViewName ); + break; + } + } +#endif + auto it = std::find_if(pImpl->aViewFactoryArr.begin(), pImpl->aViewFactoryArr.end(), + [&rFactory](SfxViewFactory* pFactory) { return pFactory->GetOrdinal() > rFactory.GetOrdinal(); }); + pImpl->aViewFactoryArr.insert(it, &rFactory); +} + + +sal_uInt16 SfxObjectFactory::GetViewFactoryCount() const +{ + return pImpl->aViewFactoryArr.size(); +} + + +SfxViewFactory& SfxObjectFactory::GetViewFactory(sal_uInt16 i) const +{ + return *pImpl->aViewFactoryArr[i]; +} + + +SfxModule* SfxObjectFactory::GetModule() const +{ + return pImpl->pModule; +} + +void SfxObjectFactory::SetModule_Impl( SfxModule *pMod ) +{ + pImpl->pModule = pMod; +} + +void SfxObjectFactory::SetSystemTemplate( const OUString& rServiceName, const OUString& rTemplateName ) +{ + static const int nMaxPathSize = 16000; + + const OUString sConfPath = "Office/Factories/" + rServiceName; + static constexpr OUStringLiteral PROP_DEF_TEMPL_CHANGED + = u"ooSetupFactorySystemDefaultTemplateChanged"; + + static const char DEF_TPL_STR[] = "/soffice."; + + OUString sUserTemplateURL; + OUString sPath; + sal_Unicode aPathBuffer[nMaxPathSize]; + if ( SystemPath::GetUserTemplateLocation( aPathBuffer, nMaxPathSize )) + sPath = OUString( aPathBuffer ); + osl::FileBase::getFileURLFromSystemPath( sPath, sUserTemplateURL ); + + if ( sUserTemplateURL.isEmpty()) + return; + + try + { + uno::Reference< lang::XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory(); + uno::Reference< uno::XInterface > xConfig = ::comphelper::ConfigurationHelper::openConfig( + ::comphelper::getProcessComponentContext(), "/org.openoffice.Setup", ::comphelper::EConfigurationModes::Standard ); + + OUString aActualFilter; + ::comphelper::ConfigurationHelper::readRelativeKey( xConfig, sConfPath, "ooSetupFactoryActualFilter" ) >>= aActualFilter; + bool bChanged(false); + ::comphelper::ConfigurationHelper::readRelativeKey( xConfig, sConfPath, PROP_DEF_TEMPL_CHANGED ) >>= bChanged; + + uno::Reference< container::XNameAccess > xFilterFactory( + xFactory->createInstance( "com.sun.star.document.FilterFactory" ), uno::UNO_QUERY_THROW ); + uno::Reference< container::XNameAccess > xTypeDetection( + xFactory->createInstance( "com.sun.star.document.TypeDetection" ), uno::UNO_QUERY_THROW ); + + OUString aActualFilterTypeName; + uno::Sequence< beans::PropertyValue > aActuralFilterData; + xFilterFactory->getByName( aActualFilter ) >>= aActuralFilterData; + for ( const auto& rProp : std::as_const(aActuralFilterData) ) + if ( rProp.Name == "Type" ) + rProp.Value >>= aActualFilterTypeName; + ::comphelper::SequenceAsHashMap aProps1( xTypeDetection->getByName( aActualFilterTypeName ) ); + uno::Sequence< OUString > aAllExt = + aProps1.getUnpackedValueOrDefault("Extensions", uno::Sequence< OUString >() ); + //To-do: check if aAllExt is empty first + const OUString aExt = DEF_TPL_STR + aAllExt[0]; + + sUserTemplateURL += aExt; + + uno::Reference<ucb::XSimpleFileAccess3> xSimpleFileAccess( + ucb::SimpleFileAccess::create( ::comphelper::getComponentContext(xFactory) ) ); + + OUString aBackupURL; + ::osl::Security().getConfigDir(aBackupURL); + aBackupURL += "/temp"; + + if ( !xSimpleFileAccess->exists( aBackupURL ) ) + xSimpleFileAccess->createFolder( aBackupURL ); + + aBackupURL += aExt; + + if ( !rTemplateName.isEmpty() ) + { + if ( xSimpleFileAccess->exists( sUserTemplateURL ) && !bChanged ) + xSimpleFileAccess->copy( sUserTemplateURL, aBackupURL ); + + uno::Reference< document::XTypeDetection > xTypeDetector( xTypeDetection, uno::UNO_QUERY ); + ::comphelper::SequenceAsHashMap aProps2( xTypeDetection->getByName( xTypeDetector->queryTypeByURL( rTemplateName ) ) ); + OUString aFilterName = + aProps2.getUnpackedValueOrDefault("PreferredFilter", OUString() ); + + uno::Sequence< beans::PropertyValue > aArgs{ + comphelper::makePropertyValue("FilterName", aFilterName), + comphelper::makePropertyValue("AsTemplate", true), + comphelper::makePropertyValue("URL", rTemplateName) + }; + + uno::Reference< frame::XLoadable > xLoadable( xFactory->createInstance( rServiceName ), uno::UNO_QUERY ); + xLoadable->load( aArgs ); + + aArgs.realloc( 2 ); + auto pArgs = aArgs.getArray(); + pArgs[1].Name = "Overwrite"; + pArgs[1].Value <<= true; + + uno::Reference< frame::XStorable > xStorable( xLoadable, uno::UNO_QUERY ); + xStorable->storeToURL( sUserTemplateURL, aArgs ); + ::comphelper::ConfigurationHelper::writeRelativeKey( xConfig, sConfPath, PROP_DEF_TEMPL_CHANGED, uno::Any( true )); + ::comphelper::ConfigurationHelper::flush( xConfig ); + } + else + { + DBG_ASSERT( bChanged, "invalid ooSetupFactorySystemDefaultTemplateChanged value!" ); + + xSimpleFileAccess->copy( aBackupURL, sUserTemplateURL ); + xSimpleFileAccess->kill( aBackupURL ); + ::comphelper::ConfigurationHelper::writeRelativeKey( xConfig, sConfPath, PROP_DEF_TEMPL_CHANGED, uno::Any( false )); + ::comphelper::ConfigurationHelper::flush( xConfig ); + } + } + catch(const uno::Exception&) + { + } +} + +void SfxObjectFactory::SetStandardTemplate( const OUString& rServiceName, const OUString& rTemplate ) +{ + SvtModuleOptions::EFactory eFac = SvtModuleOptions::ClassifyFactoryByServiceName(rServiceName); + if (eFac == SvtModuleOptions::EFactory::UNKNOWN_FACTORY) + eFac = SvtModuleOptions::ClassifyFactoryByShortName(rServiceName); + if (eFac != SvtModuleOptions::EFactory::UNKNOWN_FACTORY) + { + SetSystemTemplate( rServiceName, rTemplate ); + SvtModuleOptions().SetFactoryStandardTemplate(eFac, rTemplate); + } +} + +OUString SfxObjectFactory::GetStandardTemplate( std::u16string_view rServiceName ) +{ + SvtModuleOptions::EFactory eFac = SvtModuleOptions::ClassifyFactoryByServiceName(rServiceName); + if (eFac == SvtModuleOptions::EFactory::UNKNOWN_FACTORY) + eFac = SvtModuleOptions::ClassifyFactoryByShortName(rServiceName); + + if (eFac != SvtModuleOptions::EFactory::UNKNOWN_FACTORY) + return SvtModuleOptions().GetFactoryStandardTemplate(eFac); + + return OUString(); +} + +std::shared_ptr<const SfxFilter> SfxObjectFactory::GetTemplateFilter() const +{ + sal_uInt16 nVersion=0; + SfxFilterMatcher aMatcher ( m_sFactoryName ); + SfxFilterMatcherIter aIter( aMatcher ); + std::shared_ptr<const SfxFilter> pFilter; + std::shared_ptr<const SfxFilter> pTemp = aIter.First(); + while ( pTemp ) + { + if( pTemp->IsOwnFormat() && pTemp->IsOwnTemplateFormat() && ( pTemp->GetVersion() > nVersion ) ) + { + pFilter = pTemp; + nVersion = static_cast<sal_uInt16>(pTemp->GetVersion()); + } + + pTemp = aIter.Next(); + } + + return pFilter; +} + +void SfxObjectFactory::SetDocumentServiceName( const OUString& rServiceName ) +{ + pImpl->aServiceName = rServiceName; +} + +const OUString& SfxObjectFactory::GetDocumentServiceName() const +{ + return pImpl->aServiceName; +} + +const SvGlobalName& SfxObjectFactory::GetClassId() const +{ + return pImpl->aClassName; +} + +OUString SfxObjectFactory::GetFactoryURL() const +{ + return "private:factory/" + m_sFactoryName; +} + +OUString SfxObjectFactory::GetModuleName() const +{ + try + { + css::uno::Reference< css::uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext(); + + css::uno::Reference< css::frame::XModuleManager2 > xModuleManager( + css::frame::ModuleManager::create(xContext)); + + ::comphelper::SequenceAsHashMap aPropSet( xModuleManager->getByName(GetDocumentServiceName()) ); + return aPropSet.getUnpackedValueOrDefault("ooSetupFactoryUIName", OUString()); + } + catch(const css::uno::RuntimeException&) + { + throw; + } + catch(const css::uno::Exception&) + { + } + + return OUString(); +} + + +sal_uInt16 SfxObjectFactory::GetViewNo_Impl( const SfxInterfaceId i_nViewId, const sal_uInt16 i_nFallback ) const +{ + for ( sal_uInt16 curViewNo = 0; curViewNo < GetViewFactoryCount(); ++curViewNo ) + { + const SfxInterfaceId curViewId = GetViewFactory( curViewNo ).GetOrdinal(); + if ( i_nViewId == curViewId ) + return curViewNo; + } + return i_nFallback; +} + +SfxViewFactory* SfxObjectFactory::GetViewFactoryByViewName( std::u16string_view i_rViewName ) const +{ + for ( sal_uInt16 nViewNo = 0; + nViewNo < GetViewFactoryCount(); + ++nViewNo + ) + { + SfxViewFactory& rViewFac( GetViewFactory( nViewNo ) ); + if ( ( rViewFac.GetAPIViewName() == i_rViewName ) + || ( rViewFac.GetLegacyViewName() == i_rViewName ) + ) + return &rViewFac; + } + return nullptr; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |