1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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>
52 #include <rtl/strbuf.hxx>
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
66 OUString aServiceName
;
67 SfxFilterContainer
* pFilterContainer
;
70 OUString aStandardTemplate
;
71 bool bTemplateInitialized
;
72 SvGlobalName aClassName
;
74 SfxObjectFactory_Impl() :
76 pFilterContainer ( NULL
),
79 bTemplateInitialized( false )
85 SfxFilterContainer
* SfxObjectFactory::GetFilterContainer( bool /*bForceLoad*/ ) const
87 return pImpl
->pFilterContainer
;
92 SfxObjectFactory::SfxObjectFactory
94 const SvGlobalName
& rName
,
95 SfxObjectShellFlags nFlagsP
,
97 ) : pShortName( pName
),
98 pImpl( new SfxObjectFactory_Impl
),
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
;
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
)
146 OStringBuffer
aStr("SfxObjectFactory::RegisterViewFactory: duplicate view name '");
147 aStr
.append(OUStringToOString(sViewName
, RTL_TEXTENCODING_ASCII_US
));
149 OSL_FAIL(aStr
.getStr());
154 SfxViewFactoryArr_Impl::iterator it
= pImpl
->aViewFactoryArr
.begin();
155 for ( ; it
!= pImpl
->aViewFactoryArr
.end() &&
156 (*it
)->GetOrdinal() <= rFactory
.GetOrdinal();
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.";
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
) ) );
246 ::osl::Security().getConfigDir(aBackupURL
);
247 aBackupURL
+= "/temp";
249 if ( !xSimpleFileAccess
->exists( aBackupURL
) )
250 xSimpleFileAccess
->createFolder( aBackupURL
);
252 aBackupURL
+= DEF_TPL_STR
;
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
);
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
);
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
);
320 if (eFac
!= SvtModuleOptions::EFactory::UNKNOWN_FACTORY
)
321 sTemplate
= SvtModuleOptions().GetFactoryStandardTemplate(eFac
);
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();
335 if( pTemp
->IsOwnFormat() && pTemp
->IsOwnTemplateFormat() && ( pTemp
->GetVersion() > nVersion
) )
338 nVersion
= (sal_uInt16
) pTemp
->GetVersion();
341 pTemp
= aIter
.Next();
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());
384 catch(const css::uno::RuntimeException
&)
388 catch(const css::uno::Exception
&)
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
)
407 SfxViewFactory
* SfxObjectFactory::GetViewFactoryByViewName( const OUString
& i_rViewName
) const
409 for ( sal_uInt16 nViewNo
= 0;
410 nViewNo
< GetViewFactoryCount();
414 SfxViewFactory
& rViewFac( GetViewFactory( nViewNo
) );
415 if ( ( rViewFac
.GetAPIViewName() == i_rViewName
)
416 || ( rViewFac
.GetLegacyViewName() == i_rViewName
)
423 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */