Version 3.6.0.4, tag libreoffice-3.6.0.4
[LibreOffice.git] / sfx2 / source / doc / docfac.cxx
blobde87ca6db8fcb4baab5a43e1b366f93eba73de31
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
29 #include <com/sun/star/registry/MergeConflictException.hpp>
30 #include <com/sun/star/registry/XSimpleRegistry.hpp>
31 #include <com/sun/star/container/XNameAccess.hpp>
32 #include <com/sun/star/ucb/XSimpleFileAccess.hpp>
33 #include <com/sun/star/document/XTypeDetection.hpp>
34 #include <com/sun/star/frame/XLoadable.hpp>
35 #include <com/sun/star/frame/XStorable.hpp>
36 #include <comphelper/processfactory.hxx>
37 #include <unotools/pathoptions.hxx>
38 #include <unotools/moduleoptions.hxx>
39 #include <unotools/ucbstreamhelper.hxx>
40 #include <unotools/localfilehelper.hxx>
41 #include <comphelper/sequenceashashmap.hxx>
42 #include <comphelper/configurationhelper.hxx>
44 #include <sfx2/sfx.hrc>
45 #include <sfx2/docfilt.hxx>
46 #include <sfx2/docfac.hxx>
47 #include "sfx2/viewfac.hxx"
48 #include "fltfnc.hxx"
49 #include "arrdecl.hxx"
50 #include <sfx2/app.hxx>
51 #include <sfx2/module.hxx>
52 #include <sfx2/mnumgr.hxx>
53 #include "sfx2/sfxresid.hxx"
54 #include <sfx2/sfxuno.hxx>
55 #include "syspath.hxx"
56 #include <osl/file.hxx>
57 #include <osl/security.hxx>
58 #include "doc.hrc"
60 #include <rtl/strbuf.hxx>
62 #include <assert.h>
64 namespace css = ::com::sun::star;
65 using namespace ::com::sun::star;
67 //========================================================================
69 DECL_PTRARRAY( SfxViewFactoryArr_Impl, SfxViewFactory*, 2, 2 )
71 //========================================================================
73 DBG_NAME(SfxObjectFactory)
75 //========================================================================
77 struct SfxObjectFactory_Impl
79 SfxViewFactoryArr_Impl aViewFactoryArr;// List of <SfxViewFactory>s
80 SfxFilterArr_Impl aFilterArr; // List of <SFxFilter>n
81 ResId* pNameResId;
82 ::rtl::OUString aServiceName;
83 SfxFilterContainer* pFilterContainer;
84 SfxModule* pModule;
85 sal_uInt16 nImageId;
86 String aStandardTemplate;
87 sal_Bool bTemplateInitialized;
88 SvGlobalName aClassName;
90 SfxObjectFactory_Impl() :
91 pNameResId ( NULL ),
92 pFilterContainer ( NULL ),
93 pModule ( NULL ),
94 nImageId ( 0 ),
95 bTemplateInitialized( sal_False )
99 //========================================================================
101 SfxFilterContainer* SfxObjectFactory::GetFilterContainer( sal_Bool /*bForceLoad*/ ) const
103 return pImpl->pFilterContainer;
106 //--------------------------------------------------------------------
108 SfxObjectFactory::SfxObjectFactory
110 const SvGlobalName& rName,
111 SfxObjectShellFlags nFlagsP,
112 const char* pName
113 ) : pShortName( pName ),
114 pImpl( new SfxObjectFactory_Impl ),
115 nFlags( nFlagsP )
117 DBG_CTOR(SfxObjectFactory, 0);
118 pImpl->pFilterContainer = new SfxFilterContainer( String::CreateFromAscii( pName ) );
120 String aShortName( String::CreateFromAscii( pShortName ) );
121 aShortName.ToLowerAscii();
122 pImpl->aClassName = rName;
123 if ( aShortName.EqualsAscii( "swriter" ) )
124 pImpl->pNameResId = new SfxResId( STR_DOCTYPENAME_SW );
125 else if ( aShortName.EqualsAscii( "swriter/web" ) )
126 pImpl->pNameResId = new SfxResId( STR_DOCTYPENAME_SWWEB );
127 else if ( aShortName.EqualsAscii( "swriter/globaldocument" ) )
128 pImpl->pNameResId = new SfxResId( STR_DOCTYPENAME_SWGLOB );
129 else if ( aShortName.EqualsAscii( "scalc" ) )
130 pImpl->pNameResId = new SfxResId( STR_DOCTYPENAME_SC );
131 else if ( aShortName.EqualsAscii( "simpress" ) )
132 pImpl->pNameResId = new SfxResId( STR_DOCTYPENAME_SI );
133 else if ( aShortName.EqualsAscii( "sdraw" ) )
134 pImpl->pNameResId = new SfxResId( STR_DOCTYPENAME_SD );
135 else if ( aShortName.EqualsAscii( "message" ) )
136 pImpl->pNameResId = new SfxResId( STR_DOCTYPENAME_MESSAGE );
139 //--------------------------------------------------------------------
141 SfxObjectFactory::~SfxObjectFactory()
143 DBG_DTOR(SfxObjectFactory, 0);
145 const sal_uInt16 nCount = pImpl->aFilterArr.Count();
146 for ( sal_uInt16 i = 0; i < nCount; ++i )
147 delete pImpl->aFilterArr[i];
148 delete pImpl->pNameResId;
149 delete pImpl->pFilterContainer;
150 delete pImpl;
153 //--------------------------------------------------------------------
155 void SfxObjectFactory::RegisterViewFactory
157 SfxViewFactory &rFactory
160 #if OSL_DEBUG_LEVEL > 0
162 const String sViewName( rFactory.GetAPIViewName() );
163 for ( sal_uInt16 i = 0; i < pImpl->aViewFactoryArr.Count(); ++i )
165 if ( !pImpl->aViewFactoryArr[i]->GetAPIViewName().Equals( sViewName ) )
166 continue;
167 rtl::OStringBuffer aStr(RTL_CONSTASCII_STRINGPARAM(
168 "SfxObjectFactory::RegisterViewFactory: duplicate view name '"));
169 aStr.append(rtl::OUStringToOString(sViewName, RTL_TEXTENCODING_ASCII_US));
170 aStr.append(RTL_CONSTASCII_STRINGPARAM("'!"));
171 OSL_FAIL(aStr.getStr());
172 break;
175 #endif
176 sal_uInt16 nPos;
177 for ( nPos = 0;
178 nPos < pImpl->aViewFactoryArr.Count() &&
179 pImpl->aViewFactoryArr[nPos]->GetOrdinal() <= rFactory.GetOrdinal();
180 ++nPos )
181 /* empty loop */;
182 pImpl->aViewFactoryArr.Insert(nPos, &rFactory);
185 //--------------------------------------------------------------------
187 sal_uInt16 SfxObjectFactory::GetViewFactoryCount() const
189 return pImpl->aViewFactoryArr.Count();
192 //--------------------------------------------------------------------
194 SfxViewFactory& SfxObjectFactory::GetViewFactory(sal_uInt16 i) const
196 return *pImpl->aViewFactoryArr[i];
199 //--------------------------------------------------------------------
201 SfxModule* SfxObjectFactory::GetModule() const
203 return pImpl->pModule;
206 void SfxObjectFactory::SetModule_Impl( SfxModule *pMod )
208 pImpl->pModule = pMod;
211 void SfxObjectFactory::SetSystemTemplate( const String& rServiceName, const String& rTemplateName )
213 static const int nMaxPathSize = 16000;
214 static ::rtl::OUString SERVICE_FILTER_FACTORY("com.sun.star.document.FilterFactory");
215 static ::rtl::OUString SERVICE_TYPE_DECTECTION("com.sun.star.document.TypeDetection");
216 static ::rtl::OUString SERVICE_SIMPLE_ACCESS("com.sun.star.ucb.SimpleFileAccess");
218 static ::rtl::OUString CONF_ROOT("/org.openoffice.Setup");
219 static ::rtl::OUString CONF_PATH = ::rtl::OUString("Office/Factories/" ) + ::rtl::OUString( rServiceName );
220 static ::rtl::OUString PROP_DEF_TEMPL_CHANGED("ooSetupFactorySystemDefaultTemplateChanged");
221 static ::rtl::OUString PROP_ACTUAL_FILTER("ooSetupFactoryActualFilter");
223 static ::rtl::OUString DEF_TPL_STR("/soffice.");
225 rtl::OUString sURL;
226 String sPath;
227 sal_Unicode aPathBuffer[nMaxPathSize];
228 if ( SystemPath::GetUserTemplateLocation( aPathBuffer, nMaxPathSize ))
229 sPath = String( aPathBuffer );
230 ::utl::LocalFileHelper::ConvertPhysicalNameToURL( sPath, sURL );
232 ::rtl::OUString aUserTemplateURL( sURL );
233 if ( !aUserTemplateURL.isEmpty())
237 uno::Reference< lang::XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory();
238 uno::Reference< uno::XInterface > xConfig = ::comphelper::ConfigurationHelper::openConfig(
239 xFactory, CONF_ROOT, ::comphelper::ConfigurationHelper::E_STANDARD );
241 ::rtl::OUString aActualFilter;
242 ::comphelper::ConfigurationHelper::readRelativeKey( xConfig, CONF_PATH, PROP_ACTUAL_FILTER ) >>= aActualFilter;
243 sal_Bool bChanged(sal_False);
244 ::comphelper::ConfigurationHelper::readRelativeKey( xConfig, CONF_PATH, PROP_DEF_TEMPL_CHANGED ) >>= bChanged;
246 uno::Reference< container::XNameAccess > xFilterFactory(
247 xFactory->createInstance( SERVICE_FILTER_FACTORY ), uno::UNO_QUERY_THROW );
248 uno::Reference< container::XNameAccess > xTypeDetection(
249 xFactory->createInstance( SERVICE_TYPE_DECTECTION ), uno::UNO_QUERY_THROW );
251 ::rtl::OUString aActualFilterTypeName;
252 uno::Sequence< beans::PropertyValue > aActuralFilterData;
253 xFilterFactory->getByName( aActualFilter ) >>= aActuralFilterData;
254 for ( sal_Int32 nInd = 0; nInd < aActuralFilterData.getLength(); nInd++ )
255 if ( aActuralFilterData[nInd].Name == "Type" )
256 aActuralFilterData[nInd].Value >>= aActualFilterTypeName;
257 ::comphelper::SequenceAsHashMap aProps1( xTypeDetection->getByName( aActualFilterTypeName ) );
258 uno::Sequence< ::rtl::OUString > aAllExt =
259 aProps1.getUnpackedValueOrDefault( ::rtl::OUString("Extensions"), uno::Sequence< ::rtl::OUString >() );
260 //To-do: check if aAllExt is empty first
261 ::rtl::OUString aExt = aAllExt[0];
263 aUserTemplateURL += DEF_TPL_STR;
264 aUserTemplateURL += aExt;
266 uno::Reference< ucb::XSimpleFileAccess > xSimpleFileAccess(
267 xFactory->createInstance( SERVICE_SIMPLE_ACCESS ), uno::UNO_QUERY_THROW );
269 ::rtl::OUString aBackupURL;
270 ::osl::Security().getConfigDir(aBackupURL);
271 aBackupURL += ::rtl::OUString("/temp");
273 if ( !xSimpleFileAccess->exists( aBackupURL ) )
274 xSimpleFileAccess->createFolder( aBackupURL );
276 aBackupURL += DEF_TPL_STR;
277 aBackupURL += aExt;
279 if ( rTemplateName.Len() != 0 )
281 if ( xSimpleFileAccess->exists( aUserTemplateURL ) && !bChanged )
282 xSimpleFileAccess->copy( aUserTemplateURL, aBackupURL );
284 uno::Reference< document::XTypeDetection > xTypeDetector( xTypeDetection, uno::UNO_QUERY );
285 ::comphelper::SequenceAsHashMap aProps2( xTypeDetection->getByName( xTypeDetector->queryTypeByURL( rTemplateName ) ) );
286 ::rtl::OUString aFilterName =
287 aProps2.getUnpackedValueOrDefault( ::rtl::OUString("PreferredFilter"), ::rtl::OUString() );
289 uno::Sequence< beans::PropertyValue > aArgs( 3 );
290 aArgs[0].Name = ::rtl::OUString("FilterName");
291 aArgs[0].Value <<= aFilterName;
292 aArgs[1].Name = ::rtl::OUString("AsTemplate");
293 aArgs[1].Value <<= sal_True;
294 aArgs[2].Name = ::rtl::OUString("URL");
295 aArgs[2].Value <<= ::rtl::OUString( rTemplateName );
297 uno::Reference< frame::XLoadable > xLoadable( xFactory->createInstance( ::rtl::OUString( rServiceName ) ), uno::UNO_QUERY );
298 xLoadable->load( aArgs );
300 aArgs.realloc( 2 );
301 aArgs[1].Name = ::rtl::OUString("Overwrite");
302 aArgs[1].Value <<= sal_True;
304 uno::Reference< frame::XStorable > xStorable( xLoadable, uno::UNO_QUERY );
305 xStorable->storeToURL( aUserTemplateURL, aArgs );
306 ::comphelper::ConfigurationHelper::writeRelativeKey( xConfig, CONF_PATH, PROP_DEF_TEMPL_CHANGED, uno::makeAny( sal_True ));
307 ::comphelper::ConfigurationHelper::flush( xConfig );
309 else
311 DBG_ASSERT( bChanged, "invalid ooSetupFactorySystemDefaultTemplateChanged value!" );
313 xSimpleFileAccess->copy( aBackupURL, aUserTemplateURL );
314 xSimpleFileAccess->kill( aBackupURL );
315 ::comphelper::ConfigurationHelper::writeRelativeKey( xConfig, CONF_PATH, PROP_DEF_TEMPL_CHANGED, uno::makeAny( sal_False ));
316 ::comphelper::ConfigurationHelper::flush( xConfig );
319 catch(const uno::Exception&)
325 void SfxObjectFactory::SetStandardTemplate( const String& rServiceName, const String& rTemplate )
327 SvtModuleOptions::EFactory eFac = SvtModuleOptions::ClassifyFactoryByServiceName(rServiceName);
328 if (eFac == SvtModuleOptions::E_UNKNOWN_FACTORY)
329 eFac = SvtModuleOptions::ClassifyFactoryByShortName(rServiceName);
330 if (eFac != SvtModuleOptions::E_UNKNOWN_FACTORY)
332 SetSystemTemplate( rServiceName, rTemplate );
333 SvtModuleOptions().SetFactoryStandardTemplate(eFac, rTemplate);
337 String SfxObjectFactory::GetStandardTemplate( const String& rServiceName )
339 SvtModuleOptions::EFactory eFac = SvtModuleOptions::ClassifyFactoryByServiceName(rServiceName);
340 if (eFac == SvtModuleOptions::E_UNKNOWN_FACTORY)
341 eFac = SvtModuleOptions::ClassifyFactoryByShortName(rServiceName);
343 String sTemplate;
344 if (eFac != SvtModuleOptions::E_UNKNOWN_FACTORY)
345 sTemplate = SvtModuleOptions().GetFactoryStandardTemplate(eFac);
347 return sTemplate;
350 const SfxFilter* SfxObjectFactory::GetTemplateFilter() const
352 sal_uInt16 nVersion=0;
353 SfxFilterMatcher aMatcher ( String::CreateFromAscii( pShortName ) );
354 SfxFilterMatcherIter aIter( aMatcher );
355 const SfxFilter *pFilter = 0;
356 const SfxFilter *pTemp = aIter.First();
357 while ( pTemp )
359 if( pTemp->IsOwnFormat() && pTemp->IsOwnTemplateFormat() && ( pTemp->GetVersion() > nVersion ) )
361 pFilter = pTemp;
362 nVersion = (sal_uInt16) pTemp->GetVersion();
365 pTemp = aIter.Next();
368 return pFilter;
371 void SfxObjectFactory::SetDocumentServiceName( const ::rtl::OUString& rServiceName )
373 pImpl->aServiceName = rServiceName;
376 const ::rtl::OUString& SfxObjectFactory::GetDocumentServiceName() const
378 return pImpl->aServiceName;
381 const SvGlobalName& SfxObjectFactory::GetClassId() const
383 return pImpl->aClassName;
386 String SfxObjectFactory::GetFactoryURL() const
388 ::rtl::OUStringBuffer aURLComposer;
389 aURLComposer.appendAscii(RTL_CONSTASCII_STRINGPARAM("private:factory/"));
390 aURLComposer.appendAscii(GetShortName());
391 return aURLComposer.makeStringAndClear();
394 String SfxObjectFactory::GetModuleName() const
396 static ::rtl::OUString SERVICENAME_MODULEMANAGER("com.sun.star.frame.ModuleManager");
397 static ::rtl::OUString PROP_MODULEUINAME ("ooSetupFactoryUIName");
401 css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = ::comphelper::getProcessServiceFactory();
403 css::uno::Reference< css::container::XNameAccess > xModuleManager(
404 xSMGR->createInstance(SERVICENAME_MODULEMANAGER),
405 css::uno::UNO_QUERY_THROW);
407 ::rtl::OUString sDocService(GetDocumentServiceName());
408 ::comphelper::SequenceAsHashMap aPropSet( xModuleManager->getByName(sDocService) );
409 ::rtl::OUString sModuleName = aPropSet.getUnpackedValueOrDefault(PROP_MODULEUINAME, ::rtl::OUString());
410 return String(sModuleName);
412 catch(const css::uno::RuntimeException&)
414 throw;
416 catch(const css::uno::Exception&)
420 return String();
424 sal_uInt16 SfxObjectFactory::GetViewNo_Impl( const sal_uInt16 i_nViewId, const sal_uInt16 i_nFallback ) const
426 for ( sal_uInt16 curViewNo = 0; curViewNo < GetViewFactoryCount(); ++curViewNo )
428 const sal_uInt16 curViewId = GetViewFactory( curViewNo ).GetOrdinal();
429 if ( i_nViewId == curViewId )
430 return curViewNo;
432 return i_nFallback;
435 SfxViewFactory* SfxObjectFactory::GetViewFactoryByViewName( const String& i_rViewName ) const
437 for ( sal_uInt16 nViewNo = 0;
438 nViewNo < GetViewFactoryCount();
439 ++nViewNo
442 SfxViewFactory& rViewFac( GetViewFactory( nViewNo ) );
443 if ( ( rViewFac.GetAPIViewName() == i_rViewName )
444 || ( rViewFac.GetLegacyViewName() == i_rViewName )
446 return &rViewFac;
448 return NULL;
451 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */