/src/libreoffice/sfx2/source/doc/docfac.cxx
Line | Count | Source |
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> |
27 | | #include <comphelper/processfactory.hxx> |
28 | | #include <comphelper/propertyvalue.hxx> |
29 | | #include <unotools/moduleoptions.hxx> |
30 | | #include <comphelper/sequenceashashmap.hxx> |
31 | | #include <comphelper/configurationhelper.hxx> |
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 | | |
49 | | using namespace ::com::sun::star; |
50 | | |
51 | | |
52 | | struct SfxObjectFactory_Impl |
53 | | { |
54 | | std::vector<SfxViewFactory*> aViewFactoryArr;// List of <SfxViewFactory>s |
55 | | OUString aServiceName; |
56 | | SfxFilterContainer* pFilterContainer; |
57 | | SfxModule* pModule; |
58 | | SvGlobalName aClassName; |
59 | | |
60 | | SfxObjectFactory_Impl() : |
61 | 46 | pFilterContainer ( nullptr ), |
62 | 46 | pModule ( nullptr ) |
63 | 46 | {} |
64 | | }; |
65 | | |
66 | | SfxFilterContainer* SfxObjectFactory::GetFilterContainer() const |
67 | 0 | { |
68 | 0 | return pImpl->pFilterContainer; |
69 | 0 | } |
70 | | |
71 | | SfxObjectFactory::SfxObjectFactory |
72 | | ( |
73 | | const SvGlobalName& rName, |
74 | | OUString sName |
75 | 46 | ) : m_sFactoryName(std::move( sName )), |
76 | 46 | pImpl( new SfxObjectFactory_Impl ) |
77 | 46 | { |
78 | 46 | pImpl->pFilterContainer = new SfxFilterContainer( m_sFactoryName ); |
79 | 46 | pImpl->aClassName = rName; |
80 | 46 | } |
81 | | |
82 | | SfxObjectFactory::~SfxObjectFactory() |
83 | 46 | { |
84 | 46 | delete pImpl->pFilterContainer; |
85 | 46 | } |
86 | | |
87 | | |
88 | | void SfxObjectFactory::RegisterViewFactory |
89 | | ( |
90 | | SfxViewFactory &rFactory |
91 | | ) |
92 | 65 | { |
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 | 65 | auto it = std::find_if(pImpl->aViewFactoryArr.begin(), pImpl->aViewFactoryArr.end(), |
106 | 65 | [&rFactory](SfxViewFactory* pFactory) { return pFactory->GetOrdinal() > rFactory.GetOrdinal(); }); |
107 | 65 | pImpl->aViewFactoryArr.insert(it, &rFactory); |
108 | 65 | } |
109 | | |
110 | | |
111 | | sal_uInt16 SfxObjectFactory::GetViewFactoryCount() const |
112 | 12.8k | { |
113 | 12.8k | return pImpl->aViewFactoryArr.size(); |
114 | 12.8k | } |
115 | | |
116 | | |
117 | | SfxViewFactory& SfxObjectFactory::GetViewFactory(sal_uInt16 i) const |
118 | 17.0k | { |
119 | 17.0k | return *pImpl->aViewFactoryArr[i]; |
120 | 17.0k | } |
121 | | |
122 | | |
123 | | SfxModule* SfxObjectFactory::GetModule() const |
124 | 153k | { |
125 | 153k | return pImpl->pModule; |
126 | 153k | } |
127 | | |
128 | | void SfxObjectFactory::SetModule_Impl( SfxModule *pMod ) |
129 | 45 | { |
130 | 45 | pImpl->pModule = pMod; |
131 | 45 | } |
132 | | |
133 | | void SfxObjectFactory::SetSystemTemplate( const OUString& rServiceName, const OUString& rTemplateName ) |
134 | 0 | { |
135 | 0 | static const int nMaxPathSize = 16000; |
136 | |
|
137 | 0 | const OUString sConfPath = "Office/Factories/" + rServiceName; |
138 | 0 | static constexpr OUString PROP_DEF_TEMPL_CHANGED |
139 | 0 | = u"ooSetupFactorySystemDefaultTemplateChanged"_ustr; |
140 | |
|
141 | 0 | static const char DEF_TPL_STR[] = "/soffice."; |
142 | |
|
143 | 0 | OUString sUserTemplateURL; |
144 | 0 | OUString sPath; |
145 | 0 | sal_Unicode aPathBuffer[nMaxPathSize]; |
146 | 0 | if ( SystemPath::GetUserTemplateLocation( aPathBuffer, nMaxPathSize )) |
147 | 0 | sPath = OUString( aPathBuffer ); |
148 | 0 | osl::FileBase::getFileURLFromSystemPath( sPath, sUserTemplateURL ); |
149 | |
|
150 | 0 | if ( sUserTemplateURL.isEmpty()) |
151 | 0 | return; |
152 | | |
153 | 0 | try |
154 | 0 | { |
155 | 0 | uno::Reference< lang::XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory(); |
156 | 0 | uno::Reference< uno::XInterface > xConfig = ::comphelper::ConfigurationHelper::openConfig( |
157 | 0 | ::comphelper::getProcessComponentContext(), u"/org.openoffice.Setup"_ustr, ::comphelper::EConfigurationModes::Standard ); |
158 | |
|
159 | 0 | OUString aActualFilter; |
160 | 0 | ::comphelper::ConfigurationHelper::readRelativeKey( xConfig, sConfPath, u"ooSetupFactoryActualFilter"_ustr ) >>= aActualFilter; |
161 | 0 | bool bChanged(false); |
162 | 0 | ::comphelper::ConfigurationHelper::readRelativeKey( xConfig, sConfPath, PROP_DEF_TEMPL_CHANGED ) >>= bChanged; |
163 | |
|
164 | 0 | uno::Reference< container::XNameAccess > xFilterFactory( |
165 | 0 | xFactory->createInstance( u"com.sun.star.document.FilterFactory"_ustr ), uno::UNO_QUERY_THROW ); |
166 | 0 | uno::Reference< container::XNameAccess > xTypeDetection( |
167 | 0 | xFactory->createInstance( u"com.sun.star.document.TypeDetection"_ustr ), uno::UNO_QUERY_THROW ); |
168 | |
|
169 | 0 | OUString aActualFilterTypeName; |
170 | 0 | uno::Sequence< beans::PropertyValue > aActuralFilterData; |
171 | 0 | xFilterFactory->getByName( aActualFilter ) >>= aActuralFilterData; |
172 | 0 | for (const auto& rProp : aActuralFilterData) |
173 | 0 | if ( rProp.Name == "Type" ) |
174 | 0 | rProp.Value >>= aActualFilterTypeName; |
175 | 0 | ::comphelper::SequenceAsHashMap aProps1( xTypeDetection->getByName( aActualFilterTypeName ) ); |
176 | 0 | uno::Sequence< OUString > aAllExt = |
177 | 0 | aProps1.getUnpackedValueOrDefault(u"Extensions"_ustr, uno::Sequence< OUString >() ); |
178 | | //To-do: check if aAllExt is empty first |
179 | 0 | const OUString aExt = DEF_TPL_STR + aAllExt[0]; |
180 | |
|
181 | 0 | sUserTemplateURL += aExt; |
182 | |
|
183 | 0 | uno::Reference<ucb::XSimpleFileAccess3> xSimpleFileAccess( |
184 | 0 | ucb::SimpleFileAccess::create( ::comphelper::getComponentContext(xFactory) ) ); |
185 | |
|
186 | 0 | OUString aBackupURL; |
187 | 0 | ::osl::Security().getConfigDir(aBackupURL); |
188 | 0 | aBackupURL += "/temp"; |
189 | |
|
190 | 0 | if ( !xSimpleFileAccess->exists( aBackupURL ) ) |
191 | 0 | xSimpleFileAccess->createFolder( aBackupURL ); |
192 | |
|
193 | 0 | aBackupURL += aExt; |
194 | |
|
195 | 0 | if ( !rTemplateName.isEmpty() ) |
196 | 0 | { |
197 | 0 | if ( xSimpleFileAccess->exists( sUserTemplateURL ) && !bChanged ) |
198 | 0 | xSimpleFileAccess->copy( sUserTemplateURL, aBackupURL ); |
199 | |
|
200 | 0 | uno::Reference< document::XTypeDetection > xTypeDetector( xTypeDetection, uno::UNO_QUERY ); |
201 | 0 | ::comphelper::SequenceAsHashMap aProps2( xTypeDetection->getByName( xTypeDetector->queryTypeByURL( rTemplateName ) ) ); |
202 | 0 | OUString aFilterName = |
203 | 0 | aProps2.getUnpackedValueOrDefault(u"PreferredFilter"_ustr, OUString() ); |
204 | |
|
205 | 0 | uno::Sequence< beans::PropertyValue > aArgs{ |
206 | 0 | comphelper::makePropertyValue(u"FilterName"_ustr, aFilterName), |
207 | 0 | comphelper::makePropertyValue(u"AsTemplate"_ustr, true), |
208 | 0 | comphelper::makePropertyValue(u"URL"_ustr, rTemplateName) |
209 | 0 | }; |
210 | |
|
211 | 0 | uno::Reference< frame::XLoadable > xLoadable( xFactory->createInstance( rServiceName ), uno::UNO_QUERY ); |
212 | 0 | xLoadable->load( aArgs ); |
213 | |
|
214 | 0 | aArgs.realloc( 2 ); |
215 | 0 | auto pArgs = aArgs.getArray(); |
216 | 0 | pArgs[1].Name = "Overwrite"; |
217 | 0 | pArgs[1].Value <<= true; |
218 | |
|
219 | 0 | uno::Reference< frame::XStorable > xStorable( xLoadable, uno::UNO_QUERY ); |
220 | 0 | xStorable->storeToURL( sUserTemplateURL, aArgs ); |
221 | 0 | ::comphelper::ConfigurationHelper::writeRelativeKey( xConfig, sConfPath, PROP_DEF_TEMPL_CHANGED, uno::Any( true )); |
222 | 0 | ::comphelper::ConfigurationHelper::flush( xConfig ); |
223 | 0 | } |
224 | 0 | else |
225 | 0 | { |
226 | 0 | DBG_ASSERT( bChanged, "invalid ooSetupFactorySystemDefaultTemplateChanged value!" ); |
227 | |
|
228 | 0 | xSimpleFileAccess->copy( aBackupURL, sUserTemplateURL ); |
229 | 0 | xSimpleFileAccess->kill( aBackupURL ); |
230 | 0 | ::comphelper::ConfigurationHelper::writeRelativeKey( xConfig, sConfPath, PROP_DEF_TEMPL_CHANGED, uno::Any( false )); |
231 | 0 | ::comphelper::ConfigurationHelper::flush( xConfig ); |
232 | 0 | } |
233 | 0 | } |
234 | 0 | catch(const uno::Exception&) |
235 | 0 | { |
236 | 0 | } |
237 | 0 | } |
238 | | |
239 | | void SfxObjectFactory::SetStandardTemplate( const OUString& rServiceName, const OUString& rTemplate ) |
240 | 0 | { |
241 | 0 | SvtModuleOptions::EFactory eFac = SvtModuleOptions::ClassifyFactoryByServiceName(rServiceName); |
242 | 0 | if (eFac == SvtModuleOptions::EFactory::UNKNOWN_FACTORY) |
243 | 0 | eFac = SvtModuleOptions::ClassifyFactoryByShortName(rServiceName); |
244 | 0 | if (eFac != SvtModuleOptions::EFactory::UNKNOWN_FACTORY) |
245 | 0 | { |
246 | 0 | SetSystemTemplate( rServiceName, rTemplate ); |
247 | 0 | SvtModuleOptions().SetFactoryStandardTemplate(eFac, rTemplate); |
248 | 0 | } |
249 | 0 | } |
250 | | |
251 | | OUString SfxObjectFactory::GetStandardTemplate( std::u16string_view rServiceName ) |
252 | 0 | { |
253 | 0 | SvtModuleOptions::EFactory eFac = SvtModuleOptions::ClassifyFactoryByServiceName(rServiceName); |
254 | 0 | if (eFac == SvtModuleOptions::EFactory::UNKNOWN_FACTORY) |
255 | 0 | eFac = SvtModuleOptions::ClassifyFactoryByShortName(rServiceName); |
256 | |
|
257 | 0 | if (eFac != SvtModuleOptions::EFactory::UNKNOWN_FACTORY) |
258 | 0 | return SvtModuleOptions().GetFactoryStandardTemplate(eFac); |
259 | | |
260 | 0 | return OUString(); |
261 | 0 | } |
262 | | |
263 | | std::shared_ptr<const SfxFilter> SfxObjectFactory::GetTemplateFilter() const |
264 | 0 | { |
265 | 0 | sal_uInt16 nVersion=0; |
266 | 0 | SfxFilterMatcher aMatcher ( m_sFactoryName ); |
267 | 0 | SfxFilterMatcherIter aIter( aMatcher ); |
268 | 0 | std::shared_ptr<const SfxFilter> pFilter; |
269 | 0 | std::shared_ptr<const SfxFilter> pTemp = aIter.First(); |
270 | 0 | while ( pTemp ) |
271 | 0 | { |
272 | 0 | if( pTemp->IsOwnFormat() && pTemp->IsOwnTemplateFormat() && ( pTemp->GetVersion() > nVersion ) ) |
273 | 0 | { |
274 | 0 | pFilter = pTemp; |
275 | 0 | nVersion = static_cast<sal_uInt16>(pTemp->GetVersion()); |
276 | 0 | } |
277 | |
|
278 | 0 | pTemp = aIter.Next(); |
279 | 0 | } |
280 | |
|
281 | 0 | return pFilter; |
282 | 0 | } |
283 | | |
284 | | void SfxObjectFactory::SetDocumentServiceName( const OUString& rServiceName ) |
285 | 39 | { |
286 | 39 | pImpl->aServiceName = rServiceName; |
287 | 39 | } |
288 | | |
289 | | const OUString& SfxObjectFactory::GetDocumentServiceName() const |
290 | 45.8M | { |
291 | 45.8M | return pImpl->aServiceName; |
292 | 45.8M | } |
293 | | |
294 | | const SvGlobalName& SfxObjectFactory::GetClassId() const |
295 | 0 | { |
296 | 0 | return pImpl->aClassName; |
297 | 0 | } |
298 | | |
299 | | OUString SfxObjectFactory::GetFactoryURL() const |
300 | 0 | { |
301 | 0 | return "private:factory/" + m_sFactoryName; |
302 | 0 | } |
303 | | |
304 | | OUString SfxObjectFactory::GetModuleName() const |
305 | 0 | { |
306 | 0 | try |
307 | 0 | { |
308 | 0 | const css::uno::Reference< css::uno::XComponentContext >& xContext = ::comphelper::getProcessComponentContext(); |
309 | |
|
310 | 0 | css::uno::Reference< css::frame::XModuleManager2 > xModuleManager( |
311 | 0 | css::frame::ModuleManager::create(xContext)); |
312 | |
|
313 | 0 | ::comphelper::SequenceAsHashMap aPropSet( xModuleManager->getByName(GetDocumentServiceName()) ); |
314 | 0 | return aPropSet.getUnpackedValueOrDefault(u"ooSetupFactoryUIName"_ustr, OUString()); |
315 | 0 | } |
316 | 0 | catch(const css::uno::RuntimeException&) |
317 | 0 | { |
318 | 0 | throw; |
319 | 0 | } |
320 | 0 | catch(const css::uno::Exception&) |
321 | 0 | { |
322 | 0 | } |
323 | | |
324 | 0 | return OUString(); |
325 | 0 | } |
326 | | |
327 | | |
328 | | sal_uInt16 SfxObjectFactory::GetViewNo_Impl( const SfxInterfaceId i_nViewId, const sal_uInt16 i_nFallback ) const |
329 | 4.26k | { |
330 | 4.26k | for ( sal_uInt16 curViewNo = 0; curViewNo < GetViewFactoryCount(); ++curViewNo ) |
331 | 4.26k | { |
332 | 4.26k | const SfxInterfaceId curViewId = GetViewFactory( curViewNo ).GetOrdinal(); |
333 | 4.26k | if ( i_nViewId == curViewId ) |
334 | 4.26k | return curViewNo; |
335 | 4.26k | } |
336 | 0 | return i_nFallback; |
337 | 4.26k | } |
338 | | |
339 | | SfxViewFactory* SfxObjectFactory::GetViewFactoryByViewName( std::u16string_view i_rViewName ) const |
340 | 8.50k | { |
341 | 8.50k | for ( sal_uInt16 nViewNo = 0; |
342 | 8.57k | nViewNo < GetViewFactoryCount(); |
343 | 8.50k | ++nViewNo |
344 | 8.50k | ) |
345 | 8.50k | { |
346 | 8.50k | SfxViewFactory& rViewFac( GetViewFactory( nViewNo ) ); |
347 | 8.50k | if ( ( rViewFac.GetAPIViewName() == i_rViewName ) |
348 | 4.24k | || ( rViewFac.GetLegacyViewName() == i_rViewName ) |
349 | 8.50k | ) |
350 | 8.42k | return &rViewFac; |
351 | 8.50k | } |
352 | 75 | return nullptr; |
353 | 8.50k | } |
354 | | |
355 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |