Line data Source code
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/registry/MergeConflictException.hpp>
21 : #include <com/sun/star/registry/XSimpleRegistry.hpp>
22 : #include <com/sun/star/container/XNameAccess.hpp>
23 : #include <com/sun/star/ucb/SimpleFileAccess.hpp>
24 : #include <com/sun/star/document/XTypeDetection.hpp>
25 : #include <com/sun/star/frame/ModuleManager.hpp>
26 : #include <com/sun/star/frame/XLoadable.hpp>
27 : #include <com/sun/star/frame/XStorable.hpp>
28 : #include <comphelper/processfactory.hxx>
29 : #include <unotools/pathoptions.hxx>
30 : #include <unotools/moduleoptions.hxx>
31 : #include <unotools/ucbstreamhelper.hxx>
32 : #include <unotools/localfilehelper.hxx>
33 : #include <comphelper/sequenceashashmap.hxx>
34 : #include <comphelper/configurationhelper.hxx>
35 :
36 : #include <sfx2/sfx.hrc>
37 : #include <sfx2/docfilt.hxx>
38 : #include <sfx2/docfac.hxx>
39 : #include <sfx2/viewfac.hxx>
40 : #include <sfx2/fcontnr.hxx>
41 : #include "arrdecl.hxx"
42 : #include <sfx2/app.hxx>
43 : #include <sfx2/module.hxx>
44 : #include <sfx2/mnumgr.hxx>
45 : #include <sfx2/sfxresid.hxx>
46 : #include <sfx2/sfxuno.hxx>
47 : #include "syspath.hxx"
48 : #include <osl/file.hxx>
49 : #include <osl/security.hxx>
50 : #include "doc.hrc"
51 :
52 : #include <rtl/strbuf.hxx>
53 :
54 : #include <assert.h>
55 :
56 : using namespace ::com::sun::star;
57 :
58 :
59 :
60 : typedef std::vector<SfxViewFactory*> SfxViewFactoryArr_Impl;
61 :
62 0 : struct SfxObjectFactory_Impl
63 : {
64 : SfxViewFactoryArr_Impl aViewFactoryArr;// List of <SfxViewFactory>s
65 : ResId* pNameResId;
66 : OUString aServiceName;
67 : SfxFilterContainer* pFilterContainer;
68 : SfxModule* pModule;
69 : sal_uInt16 nImageId;
70 : OUString aStandardTemplate;
71 : bool bTemplateInitialized;
72 : SvGlobalName aClassName;
73 :
74 0 : SfxObjectFactory_Impl() :
75 : pNameResId ( NULL ),
76 : pFilterContainer ( NULL ),
77 : pModule ( NULL ),
78 : nImageId ( 0 ),
79 0 : bTemplateInitialized( false )
80 0 : {}
81 : };
82 :
83 :
84 :
85 0 : SfxFilterContainer* SfxObjectFactory::GetFilterContainer( bool /*bForceLoad*/ ) const
86 : {
87 0 : return pImpl->pFilterContainer;
88 : }
89 :
90 :
91 :
92 0 : SfxObjectFactory::SfxObjectFactory
93 : (
94 : const SvGlobalName& rName,
95 : SfxObjectShellFlags nFlagsP,
96 : const char* pName
97 : ) : pShortName( pName ),
98 0 : pImpl( new SfxObjectFactory_Impl ),
99 0 : nFlags( nFlagsP )
100 : {
101 0 : pImpl->pFilterContainer = new SfxFilterContainer( OUString::createFromAscii( pName ) );
102 :
103 0 : OUString aShortName( OUString::createFromAscii( pShortName ) );
104 0 : aShortName = aShortName.toAsciiLowerCase();
105 0 : pImpl->aClassName = rName;
106 0 : if ( aShortName == "swriter" )
107 0 : pImpl->pNameResId = new SfxResId( STR_DOCTYPENAME_SW );
108 0 : else if ( aShortName == "swriter/web" )
109 0 : pImpl->pNameResId = new SfxResId( STR_DOCTYPENAME_SWWEB );
110 0 : else if ( aShortName == "swriter/globaldocument" )
111 0 : pImpl->pNameResId = new SfxResId( STR_DOCTYPENAME_SWGLOB );
112 0 : else if ( aShortName == "scalc" )
113 0 : pImpl->pNameResId = new SfxResId( STR_DOCTYPENAME_SC );
114 0 : else if ( aShortName == "simpress" )
115 0 : pImpl->pNameResId = new SfxResId( STR_DOCTYPENAME_SI );
116 0 : else if ( aShortName == "sdraw" )
117 0 : pImpl->pNameResId = new SfxResId( STR_DOCTYPENAME_SD );
118 0 : else if ( aShortName == "message" )
119 0 : pImpl->pNameResId = new SfxResId( STR_DOCTYPENAME_MESSAGE );
120 0 : }
121 :
122 :
123 :
124 0 : SfxObjectFactory::~SfxObjectFactory()
125 : {
126 :
127 0 : delete pImpl->pNameResId;
128 0 : delete pImpl->pFilterContainer;
129 0 : delete pImpl;
130 0 : }
131 :
132 :
133 :
134 0 : void SfxObjectFactory::RegisterViewFactory
135 : (
136 : SfxViewFactory &rFactory
137 : )
138 : {
139 : #if OSL_DEBUG_LEVEL > 0
140 : {
141 : const OUString sViewName( rFactory.GetAPIViewName() );
142 : for ( SfxViewFactoryArr_Impl::const_iterator it = pImpl->aViewFactoryArr.begin(); it != pImpl->aViewFactoryArr.end(); ++it )
143 : {
144 : if ( (*it)->GetAPIViewName() != sViewName )
145 : continue;
146 : OStringBuffer aStr("SfxObjectFactory::RegisterViewFactory: duplicate view name '");
147 : aStr.append(OUStringToOString(sViewName, RTL_TEXTENCODING_ASCII_US));
148 : aStr.append("'!");
149 : OSL_FAIL(aStr.getStr());
150 : break;
151 : }
152 : }
153 : #endif
154 0 : SfxViewFactoryArr_Impl::iterator it = pImpl->aViewFactoryArr.begin();
155 0 : for ( ; it != pImpl->aViewFactoryArr.end() &&
156 0 : (*it)->GetOrdinal() <= rFactory.GetOrdinal();
157 : ++it )
158 : /* empty loop */;
159 0 : pImpl->aViewFactoryArr.insert(it, &rFactory);
160 0 : }
161 :
162 :
163 :
164 0 : sal_uInt16 SfxObjectFactory::GetViewFactoryCount() const
165 : {
166 0 : return pImpl->aViewFactoryArr.size();
167 : }
168 :
169 :
170 :
171 0 : SfxViewFactory& SfxObjectFactory::GetViewFactory(sal_uInt16 i) const
172 : {
173 0 : return *pImpl->aViewFactoryArr[i];
174 : }
175 :
176 :
177 :
178 0 : SfxModule* SfxObjectFactory::GetModule() const
179 : {
180 0 : return pImpl->pModule;
181 : }
182 :
183 0 : void SfxObjectFactory::SetModule_Impl( SfxModule *pMod )
184 : {
185 0 : pImpl->pModule = pMod;
186 0 : }
187 :
188 0 : void SfxObjectFactory::SetSystemTemplate( const OUString& rServiceName, const OUString& rTemplateName )
189 : {
190 : static const int nMaxPathSize = 16000;
191 0 : static OUString SERVICE_FILTER_FACTORY("com.sun.star.document.FilterFactory");
192 0 : static OUString SERVICE_TYPE_DECTECTION("com.sun.star.document.TypeDetection");
193 :
194 0 : static OUString CONF_ROOT("/org.openoffice.Setup");
195 0 : static OUString CONF_PATH = "Office/Factories/" + rServiceName;
196 0 : static OUString PROP_DEF_TEMPL_CHANGED("ooSetupFactorySystemDefaultTemplateChanged");
197 0 : static OUString PROP_ACTUAL_FILTER("ooSetupFactoryActualFilter");
198 :
199 0 : static OUString DEF_TPL_STR("/soffice.");
200 :
201 0 : OUString sURL;
202 0 : OUString sPath;
203 : sal_Unicode aPathBuffer[nMaxPathSize];
204 0 : if ( SystemPath::GetUserTemplateLocation( aPathBuffer, nMaxPathSize ))
205 0 : sPath = OUString( aPathBuffer );
206 0 : ::utl::LocalFileHelper::ConvertPhysicalNameToURL( sPath, sURL );
207 :
208 0 : OUString aUserTemplateURL( sURL );
209 0 : if ( !aUserTemplateURL.isEmpty())
210 : {
211 : try
212 : {
213 0 : uno::Reference< lang::XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory();
214 : uno::Reference< uno::XInterface > xConfig = ::comphelper::ConfigurationHelper::openConfig(
215 0 : ::comphelper::getProcessComponentContext(), CONF_ROOT, ::comphelper::ConfigurationHelper::E_STANDARD );
216 :
217 0 : OUString aActualFilter;
218 0 : ::comphelper::ConfigurationHelper::readRelativeKey( xConfig, CONF_PATH, PROP_ACTUAL_FILTER ) >>= aActualFilter;
219 0 : bool bChanged(false);
220 0 : ::comphelper::ConfigurationHelper::readRelativeKey( xConfig, CONF_PATH, PROP_DEF_TEMPL_CHANGED ) >>= bChanged;
221 :
222 : uno::Reference< container::XNameAccess > xFilterFactory(
223 0 : xFactory->createInstance( SERVICE_FILTER_FACTORY ), uno::UNO_QUERY_THROW );
224 : uno::Reference< container::XNameAccess > xTypeDetection(
225 0 : xFactory->createInstance( SERVICE_TYPE_DECTECTION ), uno::UNO_QUERY_THROW );
226 :
227 0 : OUString aActualFilterTypeName;
228 0 : uno::Sequence< beans::PropertyValue > aActuralFilterData;
229 0 : xFilterFactory->getByName( aActualFilter ) >>= aActuralFilterData;
230 0 : for ( sal_Int32 nInd = 0; nInd < aActuralFilterData.getLength(); nInd++ )
231 0 : if ( aActuralFilterData[nInd].Name == "Type" )
232 0 : aActuralFilterData[nInd].Value >>= aActualFilterTypeName;
233 0 : ::comphelper::SequenceAsHashMap aProps1( xTypeDetection->getByName( aActualFilterTypeName ) );
234 : uno::Sequence< OUString > aAllExt =
235 0 : aProps1.getUnpackedValueOrDefault("Extensions", uno::Sequence< OUString >() );
236 : //To-do: check if aAllExt is empty first
237 0 : OUString aExt = aAllExt[0];
238 :
239 0 : aUserTemplateURL += DEF_TPL_STR;
240 0 : aUserTemplateURL += aExt;
241 :
242 : uno::Reference<ucb::XSimpleFileAccess3> xSimpleFileAccess(
243 0 : ucb::SimpleFileAccess::create( ::comphelper::getComponentContext(xFactory) ) );
244 :
245 0 : OUString aBackupURL;
246 0 : ::osl::Security().getConfigDir(aBackupURL);
247 0 : aBackupURL += "/temp";
248 :
249 0 : if ( !xSimpleFileAccess->exists( aBackupURL ) )
250 0 : xSimpleFileAccess->createFolder( aBackupURL );
251 :
252 0 : aBackupURL += DEF_TPL_STR;
253 0 : aBackupURL += aExt;
254 :
255 0 : if ( !rTemplateName.isEmpty() )
256 : {
257 0 : if ( xSimpleFileAccess->exists( aUserTemplateURL ) && !bChanged )
258 0 : xSimpleFileAccess->copy( aUserTemplateURL, aBackupURL );
259 :
260 0 : uno::Reference< document::XTypeDetection > xTypeDetector( xTypeDetection, uno::UNO_QUERY );
261 0 : ::comphelper::SequenceAsHashMap aProps2( xTypeDetection->getByName( xTypeDetector->queryTypeByURL( rTemplateName ) ) );
262 : OUString aFilterName =
263 0 : aProps2.getUnpackedValueOrDefault("PreferredFilter", OUString() );
264 :
265 0 : uno::Sequence< beans::PropertyValue > aArgs( 3 );
266 0 : aArgs[0].Name = "FilterName";
267 0 : aArgs[0].Value <<= aFilterName;
268 0 : aArgs[1].Name = "AsTemplate";
269 0 : aArgs[1].Value <<= sal_True;
270 0 : aArgs[2].Name = "URL";
271 0 : aArgs[2].Value <<= OUString( rTemplateName );
272 :
273 0 : uno::Reference< frame::XLoadable > xLoadable( xFactory->createInstance( OUString( rServiceName ) ), uno::UNO_QUERY );
274 0 : xLoadable->load( aArgs );
275 :
276 0 : aArgs.realloc( 2 );
277 0 : aArgs[1].Name = "Overwrite";
278 0 : aArgs[1].Value <<= sal_True;
279 :
280 0 : uno::Reference< frame::XStorable > xStorable( xLoadable, uno::UNO_QUERY );
281 0 : xStorable->storeToURL( aUserTemplateURL, aArgs );
282 0 : ::comphelper::ConfigurationHelper::writeRelativeKey( xConfig, CONF_PATH, PROP_DEF_TEMPL_CHANGED, uno::makeAny( sal_True ));
283 0 : ::comphelper::ConfigurationHelper::flush( xConfig );
284 : }
285 : else
286 : {
287 : DBG_ASSERT( bChanged, "invalid ooSetupFactorySystemDefaultTemplateChanged value!" );
288 :
289 0 : xSimpleFileAccess->copy( aBackupURL, aUserTemplateURL );
290 0 : xSimpleFileAccess->kill( aBackupURL );
291 0 : ::comphelper::ConfigurationHelper::writeRelativeKey( xConfig, CONF_PATH, PROP_DEF_TEMPL_CHANGED, uno::makeAny( sal_False ));
292 0 : ::comphelper::ConfigurationHelper::flush( xConfig );
293 0 : }
294 : }
295 0 : catch(const uno::Exception&)
296 : {
297 : }
298 0 : }
299 0 : }
300 :
301 0 : void SfxObjectFactory::SetStandardTemplate( const OUString& rServiceName, const OUString& rTemplate )
302 : {
303 0 : SvtModuleOptions::EFactory eFac = SvtModuleOptions::ClassifyFactoryByServiceName(rServiceName);
304 0 : if (eFac == SvtModuleOptions::E_UNKNOWN_FACTORY)
305 0 : eFac = SvtModuleOptions::ClassifyFactoryByShortName(rServiceName);
306 0 : if (eFac != SvtModuleOptions::E_UNKNOWN_FACTORY)
307 : {
308 0 : SetSystemTemplate( rServiceName, rTemplate );
309 0 : SvtModuleOptions().SetFactoryStandardTemplate(eFac, rTemplate);
310 : }
311 0 : }
312 :
313 0 : OUString SfxObjectFactory::GetStandardTemplate( const OUString& rServiceName )
314 : {
315 0 : SvtModuleOptions::EFactory eFac = SvtModuleOptions::ClassifyFactoryByServiceName(rServiceName);
316 0 : if (eFac == SvtModuleOptions::E_UNKNOWN_FACTORY)
317 0 : eFac = SvtModuleOptions::ClassifyFactoryByShortName(rServiceName);
318 :
319 0 : OUString sTemplate;
320 0 : if (eFac != SvtModuleOptions::E_UNKNOWN_FACTORY)
321 0 : sTemplate = SvtModuleOptions().GetFactoryStandardTemplate(eFac);
322 :
323 0 : return sTemplate;
324 : }
325 :
326 0 : const SfxFilter* SfxObjectFactory::GetTemplateFilter() const
327 : {
328 0 : sal_uInt16 nVersion=0;
329 0 : SfxFilterMatcher aMatcher ( OUString::createFromAscii( pShortName ) );
330 0 : SfxFilterMatcherIter aIter( aMatcher );
331 0 : const SfxFilter *pFilter = 0;
332 0 : const SfxFilter *pTemp = aIter.First();
333 0 : while ( pTemp )
334 : {
335 0 : if( pTemp->IsOwnFormat() && pTemp->IsOwnTemplateFormat() && ( pTemp->GetVersion() > nVersion ) )
336 : {
337 0 : pFilter = pTemp;
338 0 : nVersion = (sal_uInt16) pTemp->GetVersion();
339 : }
340 :
341 0 : pTemp = aIter.Next();
342 : }
343 :
344 0 : return pFilter;
345 : }
346 :
347 0 : void SfxObjectFactory::SetDocumentServiceName( const OUString& rServiceName )
348 : {
349 0 : pImpl->aServiceName = rServiceName;
350 0 : }
351 :
352 0 : const OUString& SfxObjectFactory::GetDocumentServiceName() const
353 : {
354 0 : return pImpl->aServiceName;
355 : }
356 :
357 0 : const SvGlobalName& SfxObjectFactory::GetClassId() const
358 : {
359 0 : return pImpl->aClassName;
360 : }
361 :
362 0 : OUString SfxObjectFactory::GetFactoryURL() const
363 : {
364 0 : OUStringBuffer aURLComposer;
365 0 : aURLComposer.append("private:factory/");
366 0 : aURLComposer.appendAscii(GetShortName());
367 0 : return aURLComposer.makeStringAndClear();
368 : }
369 :
370 0 : OUString SfxObjectFactory::GetModuleName() const
371 : {
372 : try
373 : {
374 0 : css::uno::Reference< css::uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
375 :
376 : css::uno::Reference< css::frame::XModuleManager2 > xModuleManager(
377 0 : css::frame::ModuleManager::create(xContext));
378 :
379 0 : OUString sDocService(GetDocumentServiceName());
380 0 : ::comphelper::SequenceAsHashMap aPropSet( xModuleManager->getByName(sDocService) );
381 0 : OUString sModuleName = aPropSet.getUnpackedValueOrDefault("ooSetupFactoryUIName", OUString());
382 0 : return sModuleName;
383 : }
384 0 : catch(const css::uno::RuntimeException&)
385 : {
386 0 : throw;
387 : }
388 0 : catch(const css::uno::Exception&)
389 : {
390 : }
391 :
392 0 : return OUString();
393 : }
394 :
395 :
396 0 : sal_uInt16 SfxObjectFactory::GetViewNo_Impl( const sal_uInt16 i_nViewId, const sal_uInt16 i_nFallback ) const
397 : {
398 0 : for ( sal_uInt16 curViewNo = 0; curViewNo < GetViewFactoryCount(); ++curViewNo )
399 : {
400 0 : const sal_uInt16 curViewId = GetViewFactory( curViewNo ).GetOrdinal();
401 0 : if ( i_nViewId == curViewId )
402 0 : return curViewNo;
403 : }
404 0 : return i_nFallback;
405 : }
406 :
407 0 : SfxViewFactory* SfxObjectFactory::GetViewFactoryByViewName( const OUString& i_rViewName ) const
408 : {
409 0 : for ( sal_uInt16 nViewNo = 0;
410 0 : nViewNo < GetViewFactoryCount();
411 : ++nViewNo
412 : )
413 : {
414 0 : SfxViewFactory& rViewFac( GetViewFactory( nViewNo ) );
415 0 : if ( ( rViewFac.GetAPIViewName() == i_rViewName )
416 0 : || ( rViewFac.GetLegacyViewName() == i_rViewName )
417 : )
418 0 : return &rViewFac;
419 : }
420 0 : return NULL;
421 : }
422 :
423 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|