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"
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>
60 #include <rtl/strbuf.hxx>
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
82 ::rtl::OUString aServiceName
;
83 SfxFilterContainer
* pFilterContainer
;
86 String aStandardTemplate
;
87 sal_Bool bTemplateInitialized
;
88 SvGlobalName aClassName
;
90 SfxObjectFactory_Impl() :
92 pFilterContainer ( NULL
),
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
,
113 ) : pShortName( pName
),
114 pImpl( new SfxObjectFactory_Impl
),
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
;
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
) )
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());
178 nPos
< pImpl
->aViewFactoryArr
.Count() &&
179 pImpl
->aViewFactoryArr
[nPos
]->GetOrdinal() <= rFactory
.GetOrdinal();
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.");
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
;
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
);
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
);
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
);
344 if (eFac
!= SvtModuleOptions::E_UNKNOWN_FACTORY
)
345 sTemplate
= SvtModuleOptions().GetFactoryStandardTemplate(eFac
);
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();
359 if( pTemp
->IsOwnFormat() && pTemp
->IsOwnTemplateFormat() && ( pTemp
->GetVersion() > nVersion
) )
362 nVersion
= (sal_uInt16
) pTemp
->GetVersion();
365 pTemp
= aIter
.Next();
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
&)
416 catch(const css::uno::Exception
&)
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
)
435 SfxViewFactory
* SfxObjectFactory::GetViewFactoryByViewName( const String
& i_rViewName
) const
437 for ( sal_uInt16 nViewNo
= 0;
438 nViewNo
< GetViewFactoryCount();
442 SfxViewFactory
& rViewFac( GetViewFactory( nViewNo
) );
443 if ( ( rViewFac
.GetAPIViewName() == i_rViewName
)
444 || ( rViewFac
.GetLegacyViewName() == i_rViewName
)
451 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */