LibreOffice Module sfx2 (master) 1
docfac.cxx
Go to the documentation of this file.
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#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>
32
33#include <sfx2/docfilt.hxx>
34#include <sfx2/docfac.hxx>
35#include <sfx2/viewfac.hxx>
36#include <sfx2/fcontnr.hxx>
37#include <sfx2/module.hxx>
38#include "syspath.hxx"
39#include <osl/file.hxx>
40#include <osl/security.hxx>
41
42#include <sal/log.hxx>
43#include <tools/debug.hxx>
44#include <tools/globname.hxx>
45
46#include <memory>
47#include <utility>
48
49using namespace ::com::sun::star;
50
51
53{
54 std::vector<SfxViewFactory*> aViewFactoryArr;// List of <SfxViewFactory>s
55 OUString aServiceName;
59
61 pFilterContainer ( nullptr ),
62 pModule ( nullptr )
63 {}
64};
65
67{
68 return pImpl->pFilterContainer;
69}
70
72(
73 const SvGlobalName& rName,
74 OUString sName
75) : m_sFactoryName(std::move( sName )),
76 pImpl( new SfxObjectFactory_Impl )
77{
78 pImpl->pFilterContainer = new SfxFilterContainer( m_sFactoryName );
79 pImpl->aClassName = rName;
80}
81
83{
84 delete pImpl->pFilterContainer;
85}
86
87
89(
90 SfxViewFactory &rFactory
91)
92{
93#if OSL_DEBUG_LEVEL > 0
94 {
95 const OUString sViewName( rFactory.GetAPIViewName() );
96 for (auto const& viewFactory : pImpl->aViewFactoryArr)
97 {
98 if ( viewFactory->GetAPIViewName() != sViewName )
99 continue;
100 SAL_WARN( "sfx", "SfxObjectFactory::RegisterViewFactory: duplicate view name: " << sViewName );
101 break;
102 }
103 }
104#endif
105 auto it = std::find_if(pImpl->aViewFactoryArr.begin(), pImpl->aViewFactoryArr.end(),
106 [&rFactory](SfxViewFactory* pFactory) { return pFactory->GetOrdinal() > rFactory.GetOrdinal(); });
107 pImpl->aViewFactoryArr.insert(it, &rFactory);
108}
109
110
112{
113 return pImpl->aViewFactoryArr.size();
114}
115
116
118{
119 return *pImpl->aViewFactoryArr[i];
120}
121
122
124{
125 return pImpl->pModule;
126}
127
129{
130 pImpl->pModule = pMod;
131}
132
133void SfxObjectFactory::SetSystemTemplate( const OUString& rServiceName, const OUString& rTemplateName )
134{
135 static const int nMaxPathSize = 16000;
136
137 const OUString sConfPath = "Office/Factories/" + rServiceName;
138 static constexpr OUStringLiteral PROP_DEF_TEMPL_CHANGED
139 = u"ooSetupFactorySystemDefaultTemplateChanged";
140
141 static const char DEF_TPL_STR[] = "/soffice.";
142
143 OUString sUserTemplateURL;
144 OUString sPath;
145 sal_Unicode aPathBuffer[nMaxPathSize];
146 if ( SystemPath::GetUserTemplateLocation( aPathBuffer, nMaxPathSize ))
147 sPath = OUString( aPathBuffer );
148 osl::FileBase::getFileURLFromSystemPath( sPath, sUserTemplateURL );
149
150 if ( sUserTemplateURL.isEmpty())
151 return;
152
153 try
154 {
155 uno::Reference< lang::XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory();
156 uno::Reference< uno::XInterface > xConfig = ::comphelper::ConfigurationHelper::openConfig(
157 ::comphelper::getProcessComponentContext(), "/org.openoffice.Setup", ::comphelper::EConfigurationModes::Standard );
158
159 OUString aActualFilter;
160 ::comphelper::ConfigurationHelper::readRelativeKey( xConfig, sConfPath, "ooSetupFactoryActualFilter" ) >>= aActualFilter;
161 bool bChanged(false);
162 ::comphelper::ConfigurationHelper::readRelativeKey( xConfig, sConfPath, PROP_DEF_TEMPL_CHANGED ) >>= bChanged;
163
164 uno::Reference< container::XNameAccess > xFilterFactory(
165 xFactory->createInstance( "com.sun.star.document.FilterFactory" ), uno::UNO_QUERY_THROW );
166 uno::Reference< container::XNameAccess > xTypeDetection(
167 xFactory->createInstance( "com.sun.star.document.TypeDetection" ), uno::UNO_QUERY_THROW );
168
169 OUString aActualFilterTypeName;
170 uno::Sequence< beans::PropertyValue > aActuralFilterData;
171 xFilterFactory->getByName( aActualFilter ) >>= aActuralFilterData;
172 for ( const auto& rProp : std::as_const(aActuralFilterData) )
173 if ( rProp.Name == "Type" )
174 rProp.Value >>= aActualFilterTypeName;
175 ::comphelper::SequenceAsHashMap aProps1( xTypeDetection->getByName( aActualFilterTypeName ) );
176 uno::Sequence< OUString > aAllExt =
177 aProps1.getUnpackedValueOrDefault("Extensions", uno::Sequence< OUString >() );
178 //To-do: check if aAllExt is empty first
179 const OUString aExt = DEF_TPL_STR + aAllExt[0];
180
181 sUserTemplateURL += aExt;
182
183 uno::Reference<ucb::XSimpleFileAccess3> xSimpleFileAccess(
184 ucb::SimpleFileAccess::create( ::comphelper::getComponentContext(xFactory) ) );
185
186 OUString aBackupURL;
187 ::osl::Security().getConfigDir(aBackupURL);
188 aBackupURL += "/temp";
189
190 if ( !xSimpleFileAccess->exists( aBackupURL ) )
191 xSimpleFileAccess->createFolder( aBackupURL );
192
193 aBackupURL += aExt;
194
195 if ( !rTemplateName.isEmpty() )
196 {
197 if ( xSimpleFileAccess->exists( sUserTemplateURL ) && !bChanged )
198 xSimpleFileAccess->copy( sUserTemplateURL, aBackupURL );
199
200 uno::Reference< document::XTypeDetection > xTypeDetector( xTypeDetection, uno::UNO_QUERY );
201 ::comphelper::SequenceAsHashMap aProps2( xTypeDetection->getByName( xTypeDetector->queryTypeByURL( rTemplateName ) ) );
202 OUString aFilterName =
203 aProps2.getUnpackedValueOrDefault("PreferredFilter", OUString() );
204
205 uno::Sequence< beans::PropertyValue > aArgs{
206 comphelper::makePropertyValue("FilterName", aFilterName),
207 comphelper::makePropertyValue("AsTemplate", true),
208 comphelper::makePropertyValue("URL", rTemplateName)
209 };
210
211 uno::Reference< frame::XLoadable > xLoadable( xFactory->createInstance( rServiceName ), uno::UNO_QUERY );
212 xLoadable->load( aArgs );
213
214 aArgs.realloc( 2 );
215 auto pArgs = aArgs.getArray();
216 pArgs[1].Name = "Overwrite";
217 pArgs[1].Value <<= true;
218
219 uno::Reference< frame::XStorable > xStorable( xLoadable, uno::UNO_QUERY );
220 xStorable->storeToURL( sUserTemplateURL, aArgs );
221 ::comphelper::ConfigurationHelper::writeRelativeKey( xConfig, sConfPath, PROP_DEF_TEMPL_CHANGED, uno::Any( true ));
223 }
224 else
225 {
226 DBG_ASSERT( bChanged, "invalid ooSetupFactorySystemDefaultTemplateChanged value!" );
227
228 xSimpleFileAccess->copy( aBackupURL, sUserTemplateURL );
229 xSimpleFileAccess->kill( aBackupURL );
230 ::comphelper::ConfigurationHelper::writeRelativeKey( xConfig, sConfPath, PROP_DEF_TEMPL_CHANGED, uno::Any( false ));
232 }
233 }
234 catch(const uno::Exception&)
235 {
236 }
237}
238
239void SfxObjectFactory::SetStandardTemplate( const OUString& rServiceName, const OUString& rTemplate )
240{
245 {
246 SetSystemTemplate( rServiceName, rTemplate );
248 }
249}
250
251OUString SfxObjectFactory::GetStandardTemplate( std::u16string_view rServiceName )
252{
256
259
260 return OUString();
261}
262
263std::shared_ptr<const SfxFilter> SfxObjectFactory::GetTemplateFilter() const
264{
265 sal_uInt16 nVersion=0;
266 SfxFilterMatcher aMatcher ( m_sFactoryName );
267 SfxFilterMatcherIter aIter( aMatcher );
268 std::shared_ptr<const SfxFilter> pFilter;
269 std::shared_ptr<const SfxFilter> pTemp = aIter.First();
270 while ( pTemp )
271 {
272 if( pTemp->IsOwnFormat() && pTemp->IsOwnTemplateFormat() && ( pTemp->GetVersion() > nVersion ) )
273 {
274 pFilter = pTemp;
275 nVersion = static_cast<sal_uInt16>(pTemp->GetVersion());
276 }
277
278 pTemp = aIter.Next();
279 }
280
281 return pFilter;
282}
283
284void SfxObjectFactory::SetDocumentServiceName( const OUString& rServiceName )
285{
286 pImpl->aServiceName = rServiceName;
287}
288
290{
291 return pImpl->aServiceName;
292}
293
295{
296 return pImpl->aClassName;
297}
298
300{
301 return "private:factory/" + m_sFactoryName;
302}
303
305{
306 try
307 {
308 css::uno::Reference< css::uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
309
310 css::uno::Reference< css::frame::XModuleManager2 > xModuleManager(
311 css::frame::ModuleManager::create(xContext));
312
313 ::comphelper::SequenceAsHashMap aPropSet( xModuleManager->getByName(GetDocumentServiceName()) );
314 return aPropSet.getUnpackedValueOrDefault("ooSetupFactoryUIName", OUString());
315 }
316 catch(const css::uno::RuntimeException&)
317 {
318 throw;
319 }
320 catch(const css::uno::Exception&)
321 {
322 }
323
324 return OUString();
325}
326
327
328sal_uInt16 SfxObjectFactory::GetViewNo_Impl( const SfxInterfaceId i_nViewId, const sal_uInt16 i_nFallback ) const
329{
330 for ( sal_uInt16 curViewNo = 0; curViewNo < GetViewFactoryCount(); ++curViewNo )
331 {
332 const SfxInterfaceId curViewId = GetViewFactory( curViewNo ).GetOrdinal();
333 if ( i_nViewId == curViewId )
334 return curViewNo;
335 }
336 return i_nFallback;
337}
338
339SfxViewFactory* SfxObjectFactory::GetViewFactoryByViewName( std::u16string_view i_rViewName ) const
340{
341 for ( sal_uInt16 nViewNo = 0;
342 nViewNo < GetViewFactoryCount();
343 ++nViewNo
344 )
345 {
346 SfxViewFactory& rViewFac( GetViewFactory( nViewNo ) );
347 if ( ( rViewFac.GetAPIViewName() == i_rViewName )
348 || ( rViewFac.GetLegacyViewName() == i_rViewName )
349 )
350 return &rViewFac;
351 }
352 return nullptr;
353}
354
355/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
const sal_uInt16 nVersion
Definition: childwin.cxx:43
std::shared_ptr< const SfxFilter > First()
Definition: fltfnc.cxx:820
std::shared_ptr< const SfxFilter > Next()
Definition: fltfnc.cxx:827
OUString GetFactoryURL() const
Definition: docfac.cxx:299
static void SetStandardTemplate(const OUString &rServiceName, const OUString &rTemplateName)
Definition: docfac.cxx:239
void RegisterViewFactory(SfxViewFactory &rFactory)
Definition: docfac.cxx:89
SfxModule * GetModule() const
Definition: docfac.cxx:123
SfxFilterContainer * GetFilterContainer() const
Definition: docfac.cxx:66
static OUString GetStandardTemplate(std::u16string_view rServiceName)
Definition: docfac.cxx:251
OUString GetModuleName() const
Definition: docfac.cxx:304
SfxViewFactory * GetViewFactoryByViewName(std::u16string_view i_rViewName) const
returns the view factory whose GetAPIViewName or GetLegacyViewName delivers the requested logical nam...
Definition: docfac.cxx:339
SfxViewFactory & GetViewFactory(sal_uInt16 i=0) const
Definition: docfac.cxx:117
std::shared_ptr< const SfxFilter > GetTemplateFilter() const
Definition: docfac.cxx:263
SAL_DLLPRIVATE sal_uInt16 GetViewNo_Impl(const SfxInterfaceId i_nViewId, const sal_uInt16 i_nFallback) const
Definition: docfac.cxx:328
static void SetSystemTemplate(const OUString &rServiceName, const OUString &rTemplateName)
Definition: docfac.cxx:133
const OUString & GetDocumentServiceName() const
Definition: docfac.cxx:289
const SvGlobalName & GetClassId() const
Definition: docfac.cxx:294
SfxObjectFactory(const SvGlobalName &rName, OUString sFactoryName)
Definition: docfac.cxx:72
const OUString m_sFactoryName
Definition: docfac.hxx:43
std::unique_ptr< SfxObjectFactory_Impl > pImpl
Definition: docfac.hxx:44
SAL_DLLPRIVATE void SetModule_Impl(SfxModule *)
Definition: docfac.cxx:128
sal_uInt16 GetViewFactoryCount() const
Definition: docfac.cxx:111
void SetDocumentServiceName(const OUString &rServiceName)
Definition: docfac.cxx:284
OUString GetLegacyViewName() const
returns a legacy view name. This is "view" with an appended ordinal/ID.
Definition: viewfac.cxx:29
OUString GetAPIViewName() const
returns an API-compatible view name.
Definition: viewfac.cxx:34
SfxInterfaceId GetOrdinal() const
Definition: viewfac.hxx:40
OUString GetFactoryStandardTemplate(EFactory eFactory) const
void SetFactoryStandardTemplate(EFactory eFactory, const OUString &sTemplate)
static EFactory ClassifyFactoryByShortName(std::u16string_view sName)
static EFactory ClassifyFactoryByServiceName(std::u16string_view sName)
static css::uno::Any readRelativeKey(const css::uno::Reference< css::uno::XInterface > &xCFG, const OUString &sRelPath, const OUString &sKey)
static css::uno::Reference< css::uno::XInterface > openConfig(const css::uno::Reference< css::uno::XComponentContext > &rxContext, const OUString &sPackage, EConfigurationModes eMode)
static void flush(const css::uno::Reference< css::uno::XInterface > &xCFG)
static void writeRelativeKey(const css::uno::Reference< css::uno::XInterface > &xCFG, const OUString &sRelPath, const OUString &sKey, const css::uno::Any &aValue)
TValueType getUnpackedValueOrDefault(const OUString &sKey, const TValueType &aDefault) const
#define DBG_ASSERT(sCon, aError)
float u
Reference< XSingleServiceFactory > xFactory
OUString sName
#define SAL_WARN(area, stream)
bool GetUserTemplateLocation(sal_Unicode *pFolder, int nSize)
Definition: syspath.cxx:25
css::beans::PropertyValue makePropertyValue(const OUString &rName, T &&rValue)
int i
OUString aServiceName
Definition: docfac.cxx:55
SfxFilterContainer * pFilterContainer
Definition: docfac.cxx:56
SvGlobalName aClassName
Definition: docfac.cxx:58
std::vector< SfxViewFactory * > aViewFactoryArr
Definition: docfac.cxx:54
SfxModule * pModule
Definition: docfac.cxx:57
sal_uInt16 sal_Unicode