1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <com/sun/star/container/XNameAccess.hpp>
21 #include <com/sun/star/ucb/SimpleFileAccess.hpp>
22 #include <com/sun/star/document/XTypeDetection.hpp>
23 #include <com/sun/star/frame/ModuleManager.hpp>
24 #include <com/sun/star/frame/XLoadable.hpp>
25 #include <com/sun/star/frame/XStorable.hpp>
26 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
27 #include <comphelper/processfactory.hxx>
28 #include <unotools/moduleoptions.hxx>
29 #include <comphelper/sequenceashashmap.hxx>
30 #include <comphelper/configurationhelper.hxx>
32 #include <sfx2/docfilt.hxx>
33 #include <sfx2/docfac.hxx>
34 #include <sfx2/viewfac.hxx>
35 #include <sfx2/fcontnr.hxx>
36 #include <sfx2/module.hxx>
37 #include "syspath.hxx"
38 #include <osl/file.hxx>
39 #include <osl/security.hxx>
41 #include <sal/log.hxx>
42 #include <tools/debug.hxx>
43 #include <tools/globname.hxx>
47 using namespace ::com::sun::star
;
50 struct SfxObjectFactory_Impl
52 std::vector
<SfxViewFactory
*> aViewFactoryArr
;// List of <SfxViewFactory>s
53 OUString aServiceName
;
54 SfxFilterContainer
* pFilterContainer
;
56 SvGlobalName aClassName
;
58 SfxObjectFactory_Impl() :
59 pFilterContainer ( nullptr ),
64 SfxFilterContainer
* SfxObjectFactory::GetFilterContainer() const
66 return pImpl
->pFilterContainer
;
69 SfxObjectFactory::SfxObjectFactory
71 const SvGlobalName
& rName
,
73 ) : m_sFactoryName( sName
),
74 pImpl( new SfxObjectFactory_Impl
)
76 pImpl
->pFilterContainer
= new SfxFilterContainer( m_sFactoryName
);
77 pImpl
->aClassName
= rName
;
80 SfxObjectFactory::~SfxObjectFactory()
82 delete pImpl
->pFilterContainer
;
86 void SfxObjectFactory::RegisterViewFactory
88 SfxViewFactory
&rFactory
91 #if OSL_DEBUG_LEVEL > 0
93 const OUString
sViewName( rFactory
.GetAPIViewName() );
94 for (auto const& viewFactory
: pImpl
->aViewFactoryArr
)
96 if ( viewFactory
->GetAPIViewName() != sViewName
)
98 SAL_WARN( "sfx", "SfxObjectFactory::RegisterViewFactory: duplicate view name: " << sViewName
);
103 auto it
= std::find_if(pImpl
->aViewFactoryArr
.begin(), pImpl
->aViewFactoryArr
.end(),
104 [&rFactory
](SfxViewFactory
* pFactory
) { return pFactory
->GetOrdinal() > rFactory
.GetOrdinal(); });
105 pImpl
->aViewFactoryArr
.insert(it
, &rFactory
);
109 sal_uInt16
SfxObjectFactory::GetViewFactoryCount() const
111 return pImpl
->aViewFactoryArr
.size();
115 SfxViewFactory
& SfxObjectFactory::GetViewFactory(sal_uInt16 i
) const
117 return *pImpl
->aViewFactoryArr
[i
];
121 SfxModule
* SfxObjectFactory::GetModule() const
123 return pImpl
->pModule
;
126 void SfxObjectFactory::SetModule_Impl( SfxModule
*pMod
)
128 pImpl
->pModule
= pMod
;
131 void SfxObjectFactory::SetSystemTemplate( const OUString
& rServiceName
, const OUString
& rTemplateName
)
133 static const int nMaxPathSize
= 16000;
135 const OUString sConfPath
= "Office/Factories/" + rServiceName
;
136 static const char PROP_DEF_TEMPL_CHANGED
[] = "ooSetupFactorySystemDefaultTemplateChanged";
138 static const char DEF_TPL_STR
[] = "/soffice.";
140 OUString sUserTemplateURL
;
142 sal_Unicode aPathBuffer
[nMaxPathSize
];
143 if ( SystemPath::GetUserTemplateLocation( aPathBuffer
, nMaxPathSize
))
144 sPath
= OUString( aPathBuffer
);
145 osl::FileBase::getFileURLFromSystemPath( sPath
, sUserTemplateURL
);
147 if ( sUserTemplateURL
.isEmpty())
152 uno::Reference
< lang::XMultiServiceFactory
> xFactory
= ::comphelper::getProcessServiceFactory();
153 uno::Reference
< uno::XInterface
> xConfig
= ::comphelper::ConfigurationHelper::openConfig(
154 ::comphelper::getProcessComponentContext(), "/org.openoffice.Setup", ::comphelper::EConfigurationModes::Standard
);
156 OUString aActualFilter
;
157 ::comphelper::ConfigurationHelper::readRelativeKey( xConfig
, sConfPath
, "ooSetupFactoryActualFilter" ) >>= aActualFilter
;
158 bool bChanged(false);
159 ::comphelper::ConfigurationHelper::readRelativeKey( xConfig
, sConfPath
, PROP_DEF_TEMPL_CHANGED
) >>= bChanged
;
161 uno::Reference
< container::XNameAccess
> xFilterFactory(
162 xFactory
->createInstance( "com.sun.star.document.FilterFactory" ), uno::UNO_QUERY_THROW
);
163 uno::Reference
< container::XNameAccess
> xTypeDetection(
164 xFactory
->createInstance( "com.sun.star.document.TypeDetection" ), uno::UNO_QUERY_THROW
);
166 OUString aActualFilterTypeName
;
167 uno::Sequence
< beans::PropertyValue
> aActuralFilterData
;
168 xFilterFactory
->getByName( aActualFilter
) >>= aActuralFilterData
;
169 for ( const auto& rProp
: std::as_const(aActuralFilterData
) )
170 if ( rProp
.Name
== "Type" )
171 rProp
.Value
>>= aActualFilterTypeName
;
172 ::comphelper::SequenceAsHashMap
aProps1( xTypeDetection
->getByName( aActualFilterTypeName
) );
173 uno::Sequence
< OUString
> aAllExt
=
174 aProps1
.getUnpackedValueOrDefault("Extensions", uno::Sequence
< OUString
>() );
175 //To-do: check if aAllExt is empty first
176 const OUString aExt
= DEF_TPL_STR
+ aAllExt
[0];
178 sUserTemplateURL
+= aExt
;
180 uno::Reference
<ucb::XSimpleFileAccess3
> xSimpleFileAccess(
181 ucb::SimpleFileAccess::create( ::comphelper::getComponentContext(xFactory
) ) );
184 ::osl::Security().getConfigDir(aBackupURL
);
185 aBackupURL
+= "/temp";
187 if ( !xSimpleFileAccess
->exists( aBackupURL
) )
188 xSimpleFileAccess
->createFolder( aBackupURL
);
192 if ( !rTemplateName
.isEmpty() )
194 if ( xSimpleFileAccess
->exists( sUserTemplateURL
) && !bChanged
)
195 xSimpleFileAccess
->copy( sUserTemplateURL
, aBackupURL
);
197 uno::Reference
< document::XTypeDetection
> xTypeDetector( xTypeDetection
, uno::UNO_QUERY
);
198 ::comphelper::SequenceAsHashMap
aProps2( xTypeDetection
->getByName( xTypeDetector
->queryTypeByURL( rTemplateName
) ) );
199 OUString aFilterName
=
200 aProps2
.getUnpackedValueOrDefault("PreferredFilter", OUString() );
202 uno::Sequence
< beans::PropertyValue
> aArgs( 3 );
203 aArgs
[0].Name
= "FilterName";
204 aArgs
[0].Value
<<= aFilterName
;
205 aArgs
[1].Name
= "AsTemplate";
206 aArgs
[1].Value
<<= true;
207 aArgs
[2].Name
= "URL";
208 aArgs
[2].Value
<<= rTemplateName
;
210 uno::Reference
< frame::XLoadable
> xLoadable( xFactory
->createInstance( rServiceName
), uno::UNO_QUERY
);
211 xLoadable
->load( aArgs
);
214 aArgs
[1].Name
= "Overwrite";
215 aArgs
[1].Value
<<= true;
217 uno::Reference
< frame::XStorable
> xStorable( xLoadable
, uno::UNO_QUERY
);
218 xStorable
->storeToURL( sUserTemplateURL
, aArgs
);
219 ::comphelper::ConfigurationHelper::writeRelativeKey( xConfig
, sConfPath
, PROP_DEF_TEMPL_CHANGED
, uno::makeAny( true ));
220 ::comphelper::ConfigurationHelper::flush( xConfig
);
224 DBG_ASSERT( bChanged
, "invalid ooSetupFactorySystemDefaultTemplateChanged value!" );
226 xSimpleFileAccess
->copy( aBackupURL
, sUserTemplateURL
);
227 xSimpleFileAccess
->kill( aBackupURL
);
228 ::comphelper::ConfigurationHelper::writeRelativeKey( xConfig
, sConfPath
, PROP_DEF_TEMPL_CHANGED
, uno::makeAny( false ));
229 ::comphelper::ConfigurationHelper::flush( xConfig
);
232 catch(const uno::Exception
&)
237 void SfxObjectFactory::SetStandardTemplate( const OUString
& rServiceName
, const OUString
& rTemplate
)
239 SvtModuleOptions::EFactory eFac
= SvtModuleOptions::ClassifyFactoryByServiceName(rServiceName
);
240 if (eFac
== SvtModuleOptions::EFactory::UNKNOWN_FACTORY
)
241 eFac
= SvtModuleOptions::ClassifyFactoryByShortName(rServiceName
);
242 if (eFac
!= SvtModuleOptions::EFactory::UNKNOWN_FACTORY
)
244 SetSystemTemplate( rServiceName
, rTemplate
);
245 SvtModuleOptions().SetFactoryStandardTemplate(eFac
, rTemplate
);
249 OUString
SfxObjectFactory::GetStandardTemplate( const OUString
& rServiceName
)
251 SvtModuleOptions::EFactory eFac
= SvtModuleOptions::ClassifyFactoryByServiceName(rServiceName
);
252 if (eFac
== SvtModuleOptions::EFactory::UNKNOWN_FACTORY
)
253 eFac
= SvtModuleOptions::ClassifyFactoryByShortName(rServiceName
);
255 if (eFac
!= SvtModuleOptions::EFactory::UNKNOWN_FACTORY
)
256 return SvtModuleOptions().GetFactoryStandardTemplate(eFac
);
261 std::shared_ptr
<const SfxFilter
> SfxObjectFactory::GetTemplateFilter() const
263 sal_uInt16 nVersion
=0;
264 SfxFilterMatcher
aMatcher ( m_sFactoryName
);
265 SfxFilterMatcherIter
aIter( aMatcher
);
266 std::shared_ptr
<const SfxFilter
> pFilter
;
267 std::shared_ptr
<const SfxFilter
> pTemp
= aIter
.First();
270 if( pTemp
->IsOwnFormat() && pTemp
->IsOwnTemplateFormat() && ( pTemp
->GetVersion() > nVersion
) )
273 nVersion
= static_cast<sal_uInt16
>(pTemp
->GetVersion());
276 pTemp
= aIter
.Next();
282 void SfxObjectFactory::SetDocumentServiceName( const OUString
& rServiceName
)
284 pImpl
->aServiceName
= rServiceName
;
287 const OUString
& SfxObjectFactory::GetDocumentServiceName() const
289 return pImpl
->aServiceName
;
292 const SvGlobalName
& SfxObjectFactory::GetClassId() const
294 return pImpl
->aClassName
;
297 OUString
SfxObjectFactory::GetFactoryURL() const
299 return "private:factory/" + m_sFactoryName
;
302 OUString
SfxObjectFactory::GetModuleName() const
306 css::uno::Reference
< css::uno::XComponentContext
> xContext
= ::comphelper::getProcessComponentContext();
308 css::uno::Reference
< css::frame::XModuleManager2
> xModuleManager(
309 css::frame::ModuleManager::create(xContext
));
311 ::comphelper::SequenceAsHashMap
aPropSet( xModuleManager
->getByName(GetDocumentServiceName()) );
312 return aPropSet
.getUnpackedValueOrDefault("ooSetupFactoryUIName", OUString());
314 catch(const css::uno::RuntimeException
&)
318 catch(const css::uno::Exception
&)
326 sal_uInt16
SfxObjectFactory::GetViewNo_Impl( const SfxInterfaceId i_nViewId
, const sal_uInt16 i_nFallback
) const
328 for ( sal_uInt16 curViewNo
= 0; curViewNo
< GetViewFactoryCount(); ++curViewNo
)
330 const SfxInterfaceId curViewId
= GetViewFactory( curViewNo
).GetOrdinal();
331 if ( i_nViewId
== curViewId
)
337 SfxViewFactory
* SfxObjectFactory::GetViewFactoryByViewName( const OUString
& i_rViewName
) const
339 for ( sal_uInt16 nViewNo
= 0;
340 nViewNo
< GetViewFactoryCount();
344 SfxViewFactory
& rViewFac( GetViewFactory( nViewNo
) );
345 if ( ( rViewFac
.GetAPIViewName() == i_rViewName
)
346 || ( rViewFac
.GetLegacyViewName() == i_rViewName
)
353 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */