Branch libreoffice-5-0-4
[LibreOffice.git] / sfx2 / source / doc / docfac.cxx
blobba2ff680d591c34450bad2cb467390fe133e8366
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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/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>
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"
52 #include <rtl/strbuf.hxx>
54 #include <assert.h>
56 using namespace ::com::sun::star;
60 typedef std::vector<SfxViewFactory*> SfxViewFactoryArr_Impl;
62 struct SfxObjectFactory_Impl
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;
74 SfxObjectFactory_Impl() :
75 pNameResId ( NULL ),
76 pFilterContainer ( NULL ),
77 pModule ( NULL ),
78 nImageId ( 0 ),
79 bTemplateInitialized( false )
85 SfxFilterContainer* SfxObjectFactory::GetFilterContainer( bool /*bForceLoad*/ ) const
87 return pImpl->pFilterContainer;
92 SfxObjectFactory::SfxObjectFactory
94 const SvGlobalName& rName,
95 SfxObjectShellFlags nFlagsP,
96 const char* pName
97 ) : pShortName( pName ),
98 pImpl( new SfxObjectFactory_Impl ),
99 nFlags( nFlagsP )
101 pImpl->pFilterContainer = new SfxFilterContainer( OUString::createFromAscii( pName ) );
103 OUString aShortName( OUString::createFromAscii( pShortName ) );
104 aShortName = aShortName.toAsciiLowerCase();
105 pImpl->aClassName = rName;
106 if ( aShortName == "swriter" )
107 pImpl->pNameResId = new SfxResId( STR_DOCTYPENAME_SW );
108 else if ( aShortName == "swriter/web" )
109 pImpl->pNameResId = new SfxResId( STR_DOCTYPENAME_SWWEB );
110 else if ( aShortName == "swriter/globaldocument" )
111 pImpl->pNameResId = new SfxResId( STR_DOCTYPENAME_SWGLOB );
112 else if ( aShortName == "scalc" )
113 pImpl->pNameResId = new SfxResId( STR_DOCTYPENAME_SC );
114 else if ( aShortName == "simpress" )
115 pImpl->pNameResId = new SfxResId( STR_DOCTYPENAME_SI );
116 else if ( aShortName == "sdraw" )
117 pImpl->pNameResId = new SfxResId( STR_DOCTYPENAME_SD );
118 else if ( aShortName == "message" )
119 pImpl->pNameResId = new SfxResId( STR_DOCTYPENAME_MESSAGE );
124 SfxObjectFactory::~SfxObjectFactory()
127 delete pImpl->pNameResId;
128 delete pImpl->pFilterContainer;
129 delete pImpl;
134 void SfxObjectFactory::RegisterViewFactory
136 SfxViewFactory &rFactory
139 #if OSL_DEBUG_LEVEL > 0
141 const OUString sViewName( rFactory.GetAPIViewName() );
142 for ( SfxViewFactoryArr_Impl::const_iterator it = pImpl->aViewFactoryArr.begin(); it != pImpl->aViewFactoryArr.end(); ++it )
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;
153 #endif
154 SfxViewFactoryArr_Impl::iterator it = pImpl->aViewFactoryArr.begin();
155 for ( ; it != pImpl->aViewFactoryArr.end() &&
156 (*it)->GetOrdinal() <= rFactory.GetOrdinal();
157 ++it )
158 /* empty loop */;
159 pImpl->aViewFactoryArr.insert(it, &rFactory);
164 sal_uInt16 SfxObjectFactory::GetViewFactoryCount() const
166 return pImpl->aViewFactoryArr.size();
171 SfxViewFactory& SfxObjectFactory::GetViewFactory(sal_uInt16 i) const
173 return *pImpl->aViewFactoryArr[i];
178 SfxModule* SfxObjectFactory::GetModule() const
180 return pImpl->pModule;
183 void SfxObjectFactory::SetModule_Impl( SfxModule *pMod )
185 pImpl->pModule = pMod;
188 void SfxObjectFactory::SetSystemTemplate( const OUString& rServiceName, const OUString& rTemplateName )
190 static const int nMaxPathSize = 16000;
191 static const char SERVICE_FILTER_FACTORY[] = "com.sun.star.document.FilterFactory";
192 static const char SERVICE_TYPE_DECTECTION[] = "com.sun.star.document.TypeDetection";
194 static const char CONF_ROOT[] = "/org.openoffice.Setup";
195 OUString CONF_PATH = "Office/Factories/" + rServiceName;
196 static const char PROP_DEF_TEMPL_CHANGED[] = "ooSetupFactorySystemDefaultTemplateChanged";
197 static const char PROP_ACTUAL_FILTER[] = "ooSetupFactoryActualFilter";
199 static const char DEF_TPL_STR[] = "/soffice.";
201 OUString sURL;
202 OUString sPath;
203 sal_Unicode aPathBuffer[nMaxPathSize];
204 if ( SystemPath::GetUserTemplateLocation( aPathBuffer, nMaxPathSize ))
205 sPath = OUString( aPathBuffer );
206 ::utl::LocalFileHelper::ConvertPhysicalNameToURL( sPath, sURL );
208 OUString aUserTemplateURL( sURL );
209 if ( !aUserTemplateURL.isEmpty())
213 uno::Reference< lang::XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory();
214 uno::Reference< uno::XInterface > xConfig = ::comphelper::ConfigurationHelper::openConfig(
215 ::comphelper::getProcessComponentContext(), CONF_ROOT, ::comphelper::ConfigurationHelper::E_STANDARD );
217 OUString aActualFilter;
218 ::comphelper::ConfigurationHelper::readRelativeKey( xConfig, CONF_PATH, PROP_ACTUAL_FILTER ) >>= aActualFilter;
219 bool bChanged(false);
220 ::comphelper::ConfigurationHelper::readRelativeKey( xConfig, CONF_PATH, PROP_DEF_TEMPL_CHANGED ) >>= bChanged;
222 uno::Reference< container::XNameAccess > xFilterFactory(
223 xFactory->createInstance( SERVICE_FILTER_FACTORY ), uno::UNO_QUERY_THROW );
224 uno::Reference< container::XNameAccess > xTypeDetection(
225 xFactory->createInstance( SERVICE_TYPE_DECTECTION ), uno::UNO_QUERY_THROW );
227 OUString aActualFilterTypeName;
228 uno::Sequence< beans::PropertyValue > aActuralFilterData;
229 xFilterFactory->getByName( aActualFilter ) >>= aActuralFilterData;
230 for ( sal_Int32 nInd = 0; nInd < aActuralFilterData.getLength(); nInd++ )
231 if ( aActuralFilterData[nInd].Name == "Type" )
232 aActuralFilterData[nInd].Value >>= aActualFilterTypeName;
233 ::comphelper::SequenceAsHashMap aProps1( xTypeDetection->getByName( aActualFilterTypeName ) );
234 uno::Sequence< OUString > aAllExt =
235 aProps1.getUnpackedValueOrDefault("Extensions", uno::Sequence< OUString >() );
236 //To-do: check if aAllExt is empty first
237 OUString aExt = aAllExt[0];
239 aUserTemplateURL += DEF_TPL_STR;
240 aUserTemplateURL += aExt;
242 uno::Reference<ucb::XSimpleFileAccess3> xSimpleFileAccess(
243 ucb::SimpleFileAccess::create( ::comphelper::getComponentContext(xFactory) ) );
245 OUString aBackupURL;
246 ::osl::Security().getConfigDir(aBackupURL);
247 aBackupURL += "/temp";
249 if ( !xSimpleFileAccess->exists( aBackupURL ) )
250 xSimpleFileAccess->createFolder( aBackupURL );
252 aBackupURL += DEF_TPL_STR;
253 aBackupURL += aExt;
255 if ( !rTemplateName.isEmpty() )
257 if ( xSimpleFileAccess->exists( aUserTemplateURL ) && !bChanged )
258 xSimpleFileAccess->copy( aUserTemplateURL, aBackupURL );
260 uno::Reference< document::XTypeDetection > xTypeDetector( xTypeDetection, uno::UNO_QUERY );
261 ::comphelper::SequenceAsHashMap aProps2( xTypeDetection->getByName( xTypeDetector->queryTypeByURL( rTemplateName ) ) );
262 OUString aFilterName =
263 aProps2.getUnpackedValueOrDefault("PreferredFilter", OUString() );
265 uno::Sequence< beans::PropertyValue > aArgs( 3 );
266 aArgs[0].Name = "FilterName";
267 aArgs[0].Value <<= aFilterName;
268 aArgs[1].Name = "AsTemplate";
269 aArgs[1].Value <<= sal_True;
270 aArgs[2].Name = "URL";
271 aArgs[2].Value <<= OUString( rTemplateName );
273 uno::Reference< frame::XLoadable > xLoadable( xFactory->createInstance( OUString( rServiceName ) ), uno::UNO_QUERY );
274 xLoadable->load( aArgs );
276 aArgs.realloc( 2 );
277 aArgs[1].Name = "Overwrite";
278 aArgs[1].Value <<= sal_True;
280 uno::Reference< frame::XStorable > xStorable( xLoadable, uno::UNO_QUERY );
281 xStorable->storeToURL( aUserTemplateURL, aArgs );
282 ::comphelper::ConfigurationHelper::writeRelativeKey( xConfig, CONF_PATH, PROP_DEF_TEMPL_CHANGED, uno::makeAny( sal_True ));
283 ::comphelper::ConfigurationHelper::flush( xConfig );
285 else
287 DBG_ASSERT( bChanged, "invalid ooSetupFactorySystemDefaultTemplateChanged value!" );
289 xSimpleFileAccess->copy( aBackupURL, aUserTemplateURL );
290 xSimpleFileAccess->kill( aBackupURL );
291 ::comphelper::ConfigurationHelper::writeRelativeKey( xConfig, CONF_PATH, PROP_DEF_TEMPL_CHANGED, uno::makeAny( sal_False ));
292 ::comphelper::ConfigurationHelper::flush( xConfig );
295 catch(const uno::Exception&)
301 void SfxObjectFactory::SetStandardTemplate( const OUString& rServiceName, const OUString& rTemplate )
303 SvtModuleOptions::EFactory eFac = SvtModuleOptions::ClassifyFactoryByServiceName(rServiceName);
304 if (eFac == SvtModuleOptions::EFactory::UNKNOWN_FACTORY)
305 eFac = SvtModuleOptions::ClassifyFactoryByShortName(rServiceName);
306 if (eFac != SvtModuleOptions::EFactory::UNKNOWN_FACTORY)
308 SetSystemTemplate( rServiceName, rTemplate );
309 SvtModuleOptions().SetFactoryStandardTemplate(eFac, rTemplate);
313 OUString SfxObjectFactory::GetStandardTemplate( const OUString& rServiceName )
315 SvtModuleOptions::EFactory eFac = SvtModuleOptions::ClassifyFactoryByServiceName(rServiceName);
316 if (eFac == SvtModuleOptions::EFactory::UNKNOWN_FACTORY)
317 eFac = SvtModuleOptions::ClassifyFactoryByShortName(rServiceName);
319 OUString sTemplate;
320 if (eFac != SvtModuleOptions::EFactory::UNKNOWN_FACTORY)
321 sTemplate = SvtModuleOptions().GetFactoryStandardTemplate(eFac);
323 return sTemplate;
326 const SfxFilter* SfxObjectFactory::GetTemplateFilter() const
328 sal_uInt16 nVersion=0;
329 SfxFilterMatcher aMatcher ( OUString::createFromAscii( pShortName ) );
330 SfxFilterMatcherIter aIter( aMatcher );
331 const SfxFilter *pFilter = 0;
332 const SfxFilter *pTemp = aIter.First();
333 while ( pTemp )
335 if( pTemp->IsOwnFormat() && pTemp->IsOwnTemplateFormat() && ( pTemp->GetVersion() > nVersion ) )
337 pFilter = pTemp;
338 nVersion = (sal_uInt16) pTemp->GetVersion();
341 pTemp = aIter.Next();
344 return pFilter;
347 void SfxObjectFactory::SetDocumentServiceName( const OUString& rServiceName )
349 pImpl->aServiceName = rServiceName;
352 const OUString& SfxObjectFactory::GetDocumentServiceName() const
354 return pImpl->aServiceName;
357 const SvGlobalName& SfxObjectFactory::GetClassId() const
359 return pImpl->aClassName;
362 OUString SfxObjectFactory::GetFactoryURL() const
364 OUStringBuffer aURLComposer;
365 aURLComposer.append("private:factory/");
366 aURLComposer.appendAscii(GetShortName());
367 return aURLComposer.makeStringAndClear();
370 OUString SfxObjectFactory::GetModuleName() const
374 css::uno::Reference< css::uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
376 css::uno::Reference< css::frame::XModuleManager2 > xModuleManager(
377 css::frame::ModuleManager::create(xContext));
379 OUString sDocService(GetDocumentServiceName());
380 ::comphelper::SequenceAsHashMap aPropSet( xModuleManager->getByName(sDocService) );
381 OUString sModuleName = aPropSet.getUnpackedValueOrDefault("ooSetupFactoryUIName", OUString());
382 return sModuleName;
384 catch(const css::uno::RuntimeException&)
386 throw;
388 catch(const css::uno::Exception&)
392 return OUString();
396 sal_uInt16 SfxObjectFactory::GetViewNo_Impl( const sal_uInt16 i_nViewId, const sal_uInt16 i_nFallback ) const
398 for ( sal_uInt16 curViewNo = 0; curViewNo < GetViewFactoryCount(); ++curViewNo )
400 const sal_uInt16 curViewId = GetViewFactory( curViewNo ).GetOrdinal();
401 if ( i_nViewId == curViewId )
402 return curViewNo;
404 return i_nFallback;
407 SfxViewFactory* SfxObjectFactory::GetViewFactoryByViewName( const OUString& i_rViewName ) const
409 for ( sal_uInt16 nViewNo = 0;
410 nViewNo < GetViewFactoryCount();
411 ++nViewNo
414 SfxViewFactory& rViewFac( GetViewFactory( nViewNo ) );
415 if ( ( rViewFac.GetAPIViewName() == i_rViewName )
416 || ( rViewFac.GetLegacyViewName() == i_rViewName )
418 return &rViewFac;
420 return NULL;
423 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */