1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: doctemplates.cxx,v $
10 * $Revision: 1.42.84.2 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sfx2.hxx"
34 #include "doctemplates.hxx"
35 #include <vos/mutex.hxx>
36 #include <tools/debug.hxx>
37 #include <tools/urlobj.hxx>
38 #include <rtl/ustring.hxx>
39 #include <rtl/ustrbuf.hxx>
40 #include <osl/file.hxx>
41 #ifndef _SV_RESARY_HXX
42 #include <tools/resary.hxx>
44 #include <vcl/svapp.hxx>
45 #include <vcl/wrkwin.hxx>
46 #include <comphelper/sequenceashashmap.hxx>
47 #include <svtools/pathoptions.hxx>
48 #include <comphelper/processfactory.hxx>
49 #include <com/sun/star/beans/PropertyAttribute.hpp>
50 #include <com/sun/star/beans/XPropertySet.hpp>
51 #include <com/sun/star/beans/XPropertySetInfo.hpp>
52 #include <com/sun/star/beans/XPropertyContainer.hpp>
53 #include <com/sun/star/beans/StringPair.hpp>
54 #include <com/sun/star/util/XMacroExpander.hpp>
55 #include <com/sun/star/container/XContainerQuery.hpp>
56 #include <com/sun/star/document/XTypeDetection.hpp>
57 #include <com/sun/star/document/XStandaloneDocumentInfo.hpp>
58 #include <com/sun/star/sdbc/XResultSet.hpp>
59 #include <com/sun/star/sdbc/XRow.hpp>
60 #include <com/sun/star/ucb/NameClash.hpp>
61 #include <com/sun/star/ucb/NameClashException.hpp>
62 #include <com/sun/star/ucb/TransferInfo.hpp>
63 #include <com/sun/star/ucb/XCommandEnvironment.hpp>
64 #include <com/sun/star/ucb/XContentAccess.hpp>
65 #include <com/sun/star/frame/XModuleManager.hpp>
66 #include <com/sun/star/uno/Exception.hpp>
67 #include <com/sun/star/util/XOfficeInstallationDirectories.hpp>
69 #include <svtools/templatefoldercache.hxx>
70 #include <unotools/configmgr.hxx>
71 #include <unotools/ucbhelper.hxx>
73 #include "sfxresid.hxx"
74 #include "sfxurlrelocator.hxx"
75 #include "doctemplateslocal.hxx"
76 #include <sfx2/docfac.hxx>
79 //-----------------------------------------------------------------------------
81 //=============================================================================
83 #define TEMPLATE_SERVICE_NAME "com.sun.star.frame.DocumentTemplates"
84 #define TEMPLATE_IMPLEMENTATION_NAME "com.sun.star.comp.sfx2.DocumentTemplates"
86 #define SERVICENAME_TYPEDETECTION "com.sun.star.document.TypeDetection"
87 #define SERVICENAME_DOCINFO "com.sun.star.document.StandaloneDocumentInfo"
89 #define TEMPLATE_ROOT_URL "vnd.sun.star.hier:/templates"
91 #define IS_FOLDER "IsFolder"
92 #define IS_DOCUMENT "IsDocument"
93 #define TARGET_URL "TargetURL"
94 #define TEMPLATE_VERSION "TemplateComponentVersion"
95 #define TEMPLATE_VERSION_VALUE "2"
96 #define TYPE_FOLDER "application/vnd.sun.star.hier-folder"
97 #define TYPE_LINK "application/vnd.sun.star.hier-link"
98 #define TYPE_FSYS_FOLDER "application/vnd.sun.staroffice.fsys-folder"
99 #define TYPE_FSYS_FILE "application/vnd.sun.staroffice.fsys-file"
101 #define PROPERTY_DIRLIST "DirectoryList"
102 #define PROPERTY_NEEDSUPDATE "NeedsUpdate"
103 #define PROPERTY_TYPE "TypeDescription"
105 #define TARGET_DIR_URL "TargetDirURL"
106 #define COMMAND_DELETE "delete"
107 #define COMMAND_TRANSFER "transfer"
109 #define STANDARD_FOLDER "standard"
113 //=============================================================================
115 using namespace ::com::sun::star
;
116 using namespace ::com::sun::star::beans
;
117 using namespace ::com::sun::star::document
;
118 using namespace ::com::sun::star::io
;
119 using namespace ::com::sun::star::lang
;
120 using namespace ::com::sun::star::sdbc
;
121 using namespace ::com::sun::star::ucb
;
122 using namespace ::com::sun::star::uno
;
123 using namespace ::com::sun::star::container
;
124 using namespace ::com::sun::star::util
;
126 using namespace ::rtl
;
127 using namespace ::ucbhelper
;
128 using namespace ::comphelper
;
130 //=============================================================================
132 class WaitWindow_Impl
: public WorkWindow
141 virtual void Paint( const Rectangle
& rRect
);
147 //=============================================================================
151 OUString maShortName
;
155 DECLARE_LIST( NameList_Impl
, NamePair_Impl
* )
158 class GroupList_Impl
;
159 class DocTemplates_EntryData_Impl
;
160 class GroupData_Impl
;
162 //=============================================================================
163 #include <com/sun/star/task/XInteractionHandler.hpp>
164 #include <com/sun/star/ucb/XProgressHandler.hpp>
165 #include <com/sun/star/ucb/XCommandEnvironment.hpp>
167 class TplTaskEnvironment
: public ::cppu::WeakImplHelper1
< ucb::XCommandEnvironment
>
169 uno::Reference
< task::XInteractionHandler
> m_xInteractionHandler
;
170 uno::Reference
< ucb::XProgressHandler
> m_xProgressHandler
;
173 TplTaskEnvironment( const uno::Reference
< task::XInteractionHandler
>& rxInteractionHandler
)
174 : m_xInteractionHandler( rxInteractionHandler
)
177 virtual uno::Reference
<task::XInteractionHandler
> SAL_CALL
getInteractionHandler() throw (uno::RuntimeException
)
178 { return m_xInteractionHandler
; }
180 virtual uno::Reference
<ucb::XProgressHandler
> SAL_CALL
getProgressHandler() throw (uno::RuntimeException
)
181 { return m_xProgressHandler
; }
184 class SfxDocTplService_Impl
186 uno::Reference
< XMultiServiceFactory
> mxFactory
;
187 uno::Reference
< XCommandEnvironment
> maCmdEnv
;
188 uno::Reference
< XStandaloneDocumentInfo
> mxInfo
;
189 uno::Reference
< XTypeDetection
> mxType
;
191 ::osl::Mutex maMutex
;
192 Sequence
< OUString
> maTemplateDirs
;
194 NameList_Impl maNames
;
196 Content maRootContent
;
197 Updater_Impl
* mpUpdater
;
198 sal_Bool mbIsInitialized
: 1;
199 sal_Bool mbLocaleSet
: 1;
201 SfxURLRelocator_Impl maRelocator
;
204 void getDefaultLocale();
206 void readFolderList();
207 sal_Bool
needsUpdate();
208 OUString
getLongName( const OUString
& rShortName
);
209 sal_Bool
setTitleForURL( const OUString
& rURL
, const OUString
& aTitle
);
210 sal_Bool
getTitleFromURL( const OUString
& rURL
, OUString
& aTitle
, OUString
& aType
, sal_Bool
& bDocHasTitle
);
212 sal_Bool
addEntry( Content
& rParentFolder
,
213 const OUString
& rTitle
,
214 const OUString
& rTargetURL
,
215 const OUString
& rType
);
217 sal_Bool
createFolder( const OUString
& rNewFolderURL
,
218 sal_Bool bCreateParent
,
219 sal_Bool bFsysFolder
,
220 Content
&rNewFolder
);
222 sal_Bool
CreateNewUniqueFolderWithPrefix( const ::rtl::OUString
& aPath
,
223 const ::rtl::OUString
& aPrefix
,
224 ::rtl::OUString
& aNewFolderName
,
225 ::rtl::OUString
& aNewFolderURL
,
226 Content
& aNewFolder
);
227 ::rtl::OUString
CreateNewUniqueFileWithPrefix( const ::rtl::OUString
& aPath
,
228 const ::rtl::OUString
& aPrefix
,
229 const ::rtl::OUString
& aExt
);
231 uno::Sequence
< beans::StringPair
> ReadUINamesForTemplateDir_Impl( const ::rtl::OUString
& aUserPath
);
232 sal_Bool
UpdateUINamesForTemplateDir_Impl( const ::rtl::OUString
& aUserPath
,
233 const ::rtl::OUString
& aGroupName
,
234 const ::rtl::OUString
& aNewFolderName
);
235 sal_Bool
ReplaceUINamesForTemplateDir_Impl( const ::rtl::OUString
& aUserPath
,
236 const ::rtl::OUString
& aFsysGroupName
,
237 const ::rtl::OUString
& aOldGroupName
,
238 const ::rtl::OUString
& aNewGroupName
);
239 sal_Bool
RemoveUINamesForTemplateDir_Impl( const ::rtl::OUString
& aUserPath
,
240 const ::rtl::OUString
& aGroupName
);
241 sal_Bool
WriteUINamesForTemplateDir_Impl( const ::rtl::OUString
& aUserPath
,
242 const uno::Sequence
< beans::StringPair
>& aUINames
);
244 ::rtl::OUString
CreateNewGroupFsys( const ::rtl::OUString
& rGroupName
, Content
& aGroup
);
246 sal_Bool
removeContent( Content
& rContent
);
247 sal_Bool
removeContent( const OUString
& rContentURL
);
249 sal_Bool
setProperty( Content
& rContent
,
250 const OUString
& rPropName
,
251 const Any
& rPropValue
);
252 sal_Bool
getProperty( Content
& rContent
,
253 const OUString
& rPropName
,
256 void createFromContent( GroupList_Impl
& rList
,
259 sal_Bool bWriteableContent
= sal_False
);
260 void addHierGroup( GroupList_Impl
& rList
,
261 const OUString
& rTitle
,
262 const OUString
& rOwnURL
);
263 void addFsysGroup( GroupList_Impl
& rList
,
264 const OUString
& rTitle
,
265 const OUString
& rUITitle
,
266 const OUString
& rOwnURL
,
267 sal_Bool bWriteableGroup
= sal_False
);
268 void removeFromHierarchy( DocTemplates_EntryData_Impl
*pData
);
269 void addToHierarchy( GroupData_Impl
*pGroup
,
270 DocTemplates_EntryData_Impl
*pData
);
272 void removeFromHierarchy( GroupData_Impl
*pGroup
);
273 void addGroupToHierarchy( GroupData_Impl
*pGroup
);
275 void updateData( DocTemplates_EntryData_Impl
*pData
);
278 SfxDocTplService_Impl( uno::Reference
< XMultiServiceFactory
> xFactory
);
279 ~SfxDocTplService_Impl();
281 sal_Bool
init() { if ( !mbIsInitialized
) init_Impl(); return mbIsInitialized
; }
282 Content
getContent() { return maRootContent
; }
284 void setLocale( const Locale
& rLocale
);
287 sal_Bool
storeTemplate( const OUString
& rGroupName
,
288 const OUString
& rTemplateName
,
289 const uno::Reference
< XSTORABLE
>& rStorable
);
291 sal_Bool
addTemplate( const OUString
& rGroupName
,
292 const OUString
& rTemplateName
,
293 const OUString
& rSourceURL
);
294 sal_Bool
removeTemplate( const OUString
& rGroupName
,
295 const OUString
& rTemplateName
);
296 sal_Bool
renameTemplate( const OUString
& rGroupName
,
297 const OUString
& rOldName
,
298 const OUString
& rNewName
);
300 sal_Bool
addGroup( const OUString
& rGroupName
);
301 sal_Bool
removeGroup( const OUString
& rGroupName
);
302 sal_Bool
renameGroup( const OUString
& rOldName
,
303 const OUString
& rNewName
);
305 void update( sal_Bool bUpdateNow
);
307 void finished() { mpUpdater
= NULL
; }
310 //=============================================================================
312 class Updater_Impl
: public ::vos::OThread
315 SfxDocTplService_Impl
*mpDocTemplates
;
318 Updater_Impl( SfxDocTplService_Impl
* pTemplates
);
321 virtual void SAL_CALL
run();
322 virtual void SAL_CALL
onTerminated();
325 //=============================================================================
327 class DocTemplates_EntryData_Impl
331 OUString maTargetURL
;
332 OUString maHierarchyURL
;
334 sal_Bool mbInHierarchy
: 1;
335 sal_Bool mbInUse
: 1;
336 sal_Bool mbUpdateType
: 1;
337 sal_Bool mbUpdateLink
: 1;
340 DocTemplates_EntryData_Impl( const OUString
& rTitle
);
342 void setInUse() { mbInUse
= sal_True
; }
343 void setHierarchy( sal_Bool bInHierarchy
) { mbInHierarchy
= bInHierarchy
; }
344 void setUpdateLink( sal_Bool bUpdateLink
) { mbUpdateLink
= bUpdateLink
; }
345 void setUpdateType( sal_Bool bUpdateType
) { mbUpdateType
= bUpdateType
; }
347 sal_Bool
getInUse() const { return mbInUse
; }
348 sal_Bool
getInHierarchy() const { return mbInHierarchy
; }
349 sal_Bool
getUpdateLink() const { return mbUpdateLink
; }
350 sal_Bool
getUpdateType() const { return mbUpdateType
; }
352 const OUString
& getHierarchyURL() const { return maHierarchyURL
; }
353 const OUString
& getTargetURL() const { return maTargetURL
; }
354 const OUString
& getTitle() const { return maTitle
; }
355 const OUString
& getType() const { return maType
; }
357 void setHierarchyURL( const OUString
& rURL
) { maHierarchyURL
= rURL
; }
358 void setTargetURL( const OUString
& rURL
) { maTargetURL
= rURL
; }
359 void setType( const OUString
& rType
) { maType
= rType
; }
362 //=============================================================================
366 DECLARE_LIST( EntryList_Impl
, DocTemplates_EntryData_Impl
* )
367 EntryList_Impl maEntries
;
369 OUString maHierarchyURL
;
370 OUString maTargetURL
;
371 sal_Bool mbInUse
: 1;
372 sal_Bool mbInHierarchy
: 1;
375 GroupData_Impl( const OUString
& rTitle
);
378 void setInUse() { mbInUse
= sal_True
; }
379 void setHierarchy( sal_Bool bInHierarchy
) { mbInHierarchy
= bInHierarchy
; }
380 void setHierarchyURL( const OUString
& rURL
) { maHierarchyURL
= rURL
; }
381 void setTargetURL( const OUString
& rURL
) { maTargetURL
= rURL
; }
383 sal_Bool
getInUse() { return mbInUse
; }
384 sal_Bool
getInHierarchy() { return mbInHierarchy
; }
385 const OUString
& getHierarchyURL() const { return maHierarchyURL
; }
386 const OUString
& getTargetURL() const { return maTargetURL
; }
387 const OUString
& getTitle() const { return maTitle
; }
389 DocTemplates_EntryData_Impl
* addEntry( const OUString
& rTitle
,
390 const OUString
& rTargetURL
,
391 const OUString
& rType
,
392 const OUString
& rHierURL
);
393 ULONG
count() { return maEntries
.Count(); }
394 DocTemplates_EntryData_Impl
* getEntry( ULONG nPos
) { return maEntries
.GetObject( nPos
); }
397 DECLARE_LIST( GroupList_Impl
, GroupData_Impl
* )
399 //=============================================================================
400 //=============================================================================
401 //=============================================================================
403 //-----------------------------------------------------------------------------
404 // private SfxDocTplService_Impl
405 //-----------------------------------------------------------------------------
406 void SfxDocTplService_Impl::init_Impl()
408 uno::Reference
< lang::XMultiServiceFactory
> xFactory
= ::comphelper::getProcessServiceFactory();
411 uno::Reference
< task::XInteractionHandler
> xInteractionHandler( xFactory
->createInstance( DEFINE_CONST_UNICODE("com.sun.star.task.InteractionHandler") ), uno::UNO_QUERY
);
412 maCmdEnv
= new TplTaskEnvironment( xInteractionHandler
);
415 ::osl::ClearableMutexGuard
aGuard( maMutex
);
416 sal_Bool bIsInitialized
= sal_False
;
417 sal_Bool bNeedsUpdate
= sal_False
;
422 // convert locale to string
423 OUString aLang
= maLocale
.Language
;
424 aLang
+= String( '-' );
425 aLang
+= maLocale
.Country
;
427 // set maRootContent to the root of the templates hierarchy. Create the
428 // entry if necessary
430 maRootURL
= OUString( RTL_CONSTASCII_USTRINGPARAM( TEMPLATE_ROOT_URL
) );
431 maRootURL
+= String( '/' );
434 ::rtl::OUString
aTemplVersPropName( RTL_CONSTASCII_USTRINGPARAM( TEMPLATE_VERSION
) );
435 ::rtl::OUString
aTemplVers( RTL_CONSTASCII_USTRINGPARAM( TEMPLATE_VERSION_VALUE
) );
436 if ( Content::create( maRootURL
, maCmdEnv
, maRootContent
) )
439 ::rtl::OUString aPropValue
;
440 if ( getProperty( maRootContent
, aTemplVersPropName
, aValue
)
441 && ( aValue
>>= aPropValue
)
442 && aPropValue
.equals( aTemplVers
) )
444 bIsInitialized
= sal_True
;
447 removeContent( maRootContent
);
450 if ( !bIsInitialized
)
452 if ( createFolder( maRootURL
, sal_True
, sal_False
, maRootContent
)
453 && setProperty( maRootContent
, aTemplVersPropName
, uno::makeAny( aTemplVers
) ) )
454 bIsInitialized
= sal_True
;
456 bNeedsUpdate
= sal_True
;
459 if ( bIsInitialized
)
461 OUString
aService( RTL_CONSTASCII_USTRINGPARAM( SERVICENAME_DOCINFO
) );
463 mxInfo
= uno::Reference
< XStandaloneDocumentInfo
> (
464 mxFactory
->createInstance( aService
), UNO_QUERY
);
465 } catch (uno::RuntimeException
&) {
466 OSL_ENSURE(false, "SfxDocTplService_Impl::init_Impl: "
467 "cannot create DocumentProperties service");
470 aService
= OUString( RTL_CONSTASCII_USTRINGPARAM( SERVICENAME_TYPEDETECTION
) );
471 mxType
= uno::Reference
< XTypeDetection
> ( mxFactory
->createInstance( aService
), UNO_QUERY
);
479 ::vos::OClearableGuard
aSolarGuard( Application::GetSolarMutex() );
481 WaitWindow_Impl
* pWin
= new WaitWindow_Impl();
484 ::osl::ClearableMutexGuard
anotherGuard( maMutex
);
488 anotherGuard
.clear();
489 ::vos::OGuard
aSecondSolarGuard( Application::GetSolarMutex() );
493 else if ( needsUpdate() )
494 // the UI should be shown only on the first update
499 DBG_ERRORFILE( "init_Impl(): Could not create root" );
502 mbIsInitialized
= bIsInitialized
;
505 //-----------------------------------------------------------------------------
506 void SfxDocTplService_Impl::getDefaultLocale()
510 ::osl::MutexGuard
aGuard( maMutex
);
513 rtl::OUString aLocale
;
514 utl::ConfigManager::GetDirectConfigProperty( utl::ConfigManager::LOCALE
)
517 if ( aLocale
.getLength() > 0 )
519 sal_Int32 nPos
= aLocale
.indexOf( sal_Unicode( '-' ) );
522 maLocale
.Language
= aLocale
.copy( 0, nPos
);
523 nPos
= aLocale
.indexOf( sal_Unicode( '_' ), nPos
+ 1 );
527 = aLocale
.copy( maLocale
.Language
.getLength() + 1,
528 nPos
- maLocale
.Language
.getLength() - 1 );
530 = aLocale
.copy( nPos
+ 1 );
535 = aLocale
.copy( maLocale
.Language
.getLength() + 1 );
541 mbLocaleSet
= sal_True
;
546 // -----------------------------------------------------------------------
547 void SfxDocTplService_Impl::readFolderList()
549 ::vos::OGuard
aGuard( Application::GetSolarMutex() );
551 ResStringArray
aShortNames( SfxResId( TEMPLATE_SHORT_NAMES_ARY
) );
552 ResStringArray
aLongNames( SfxResId( TEMPLATE_LONG_NAMES_ARY
) );
554 NamePair_Impl
* pPair
;
556 USHORT nCount
= (USHORT
)( Min( aShortNames
.Count(), aLongNames
.Count() ) );
558 for ( USHORT i
=0; i
<nCount
; i
++ )
560 pPair
= new NamePair_Impl
;
561 pPair
->maShortName
= aShortNames
.GetString( i
);
562 pPair
->maLongName
= aLongNames
.GetString( i
);
564 maNames
.Insert( pPair
, LIST_APPEND
);
568 // -----------------------------------------------------------------------
569 OUString
SfxDocTplService_Impl::getLongName( const OUString
& rShortName
)
572 NamePair_Impl
*pPair
= maNames
.First();
576 if ( pPair
->maShortName
== rShortName
)
578 aRet
= pPair
->maLongName
;
582 pPair
= maNames
.Next();
585 if ( !aRet
.getLength() )
591 //-----------------------------------------------------------------------------
592 void SfxDocTplService_Impl::getDirList()
594 OUString
aPropName( RTL_CONSTASCII_USTRINGPARAM( PROPERTY_DIRLIST
) );
597 // Get the template dir list
598 // TODO/LATER: let use service, register listener
600 String aDirs
= SvtPathOptions().GetTemplatePath();
601 USHORT nCount
= aDirs
.GetTokenCount( C_DELIM
);
603 maTemplateDirs
= Sequence
< OUString
>( nCount
);
605 uno::Reference
< XComponentContext
> xCtx
;
606 uno::Reference
< util::XMacroExpander
> xExpander
;
607 uno::Reference
< XPropertySet
> xPropSet( mxFactory
, UNO_QUERY
);
608 const rtl::OUString
aPrefix(
609 RTL_CONSTASCII_USTRINGPARAM( "vnd.sun.star.expand:" ) );
613 xPropSet
->getPropertyValue(
615 RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ) ) )
621 xCtx
->getValueByName(
622 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
623 "/singletons/com.sun.star.util.theMacroExpander" ) ) )
626 OSL_ENSURE( xExpander
.is(),
627 "Unable to obtain macro expander singleton!" );
630 for ( USHORT i
=0; i
<nCount
; i
++ )
632 aURL
.SetSmartProtocol( INET_PROT_FILE
);
633 aURL
.SetURL( aDirs
.GetToken( i
, C_DELIM
) );
634 maTemplateDirs
[i
] = aURL
.GetMainURL( INetURLObject::NO_DECODE
);
636 sal_Int32 nIndex
= maTemplateDirs
[i
].indexOf( aPrefix
);
637 if ( nIndex
!= -1 && xExpander
.is() )
639 maTemplateDirs
[i
] = maTemplateDirs
[i
].replaceAt(nIndex
,
642 maTemplateDirs
[i
] = xExpander
->expandMacros( maTemplateDirs
[i
] );
646 aValue
<<= maTemplateDirs
;
648 // Store the template dir list
649 setProperty( maRootContent
, aPropName
, aValue
);
652 //-----------------------------------------------------------------------------
653 sal_Bool
SfxDocTplService_Impl::needsUpdate()
655 OUString
aPropName( RTL_CONSTASCII_USTRINGPARAM( PROPERTY_NEEDSUPDATE
) );
656 sal_Bool bHasProperty
= sal_False
;
657 sal_Bool bNeedsUpdate
= sal_True
;
660 // Get the template dir list
661 bHasProperty
= getProperty( maRootContent
, aPropName
, aValue
);
664 aValue
>>= bNeedsUpdate
;
666 // the old template component also checks this state, but it is initialized from this component
667 // so if this componend was already updated the old component does not need such an update
668 ::svt::TemplateFolderCache aTempCache
;
670 bNeedsUpdate
= aTempCache
.needsUpdate();
673 aTempCache
.storeState();
678 // -----------------------------------------------------------------------
679 sal_Bool
SfxDocTplService_Impl::setTitleForURL( const OUString
& rURL
, const OUString
& aTitle
)
681 sal_Bool bResult
= sal_False
;
686 mxInfo
->loadFromURL( rURL
);
687 uno::Reference
< XPropertySet
> xPropSet( mxInfo
, UNO_QUERY_THROW
);
688 OUString
aPropName( RTL_CONSTASCII_USTRINGPARAM( TITLE
) );
689 xPropSet
->setPropertyValue( aPropName
, uno::makeAny( aTitle
) );
690 mxInfo
->storeIntoURL( rURL
);
701 // -----------------------------------------------------------------------
702 sal_Bool
SfxDocTplService_Impl::getTitleFromURL( const OUString
& rURL
, OUString
& aTitle
, OUString
& aType
, sal_Bool
& bDocHasTitle
)
704 bDocHasTitle
= sal_False
;
710 mxInfo
->loadFromURL( rURL
);
714 // the document is not a StarOffice document
720 uno::Reference
< XPropertySet
> aPropSet( mxInfo
, UNO_QUERY
);
723 OUString
aPropName( RTL_CONSTASCII_USTRINGPARAM( TITLE
) );
724 Any aValue
= aPropSet
->getPropertyValue( aPropName
);
727 aPropName
= OUString( RTL_CONSTASCII_USTRINGPARAM( "MIMEType" ) );
728 aValue
= aPropSet
->getPropertyValue( aPropName
);
732 catch ( UnknownPropertyException
& ) {}
733 catch ( Exception
& ) {}
736 if ( ! aType
.getLength() && mxType
.is() )
738 ::rtl::OUString aDocType
= mxType
->queryTypeByURL( rURL
);
739 if ( aDocType
.getLength() )
742 uno::Reference
< container::XNameAccess
> xTypeDetection( mxType
, uno::UNO_QUERY_THROW
);
743 SequenceAsHashMap
aTypeProps( xTypeDetection
->getByName( aDocType
) );
744 aType
= aTypeProps
.getUnpackedValueOrDefault(
745 ::rtl::OUString::createFromAscii( "MediaType" ),
748 catch( uno::Exception
& )
752 if ( ! aTitle
.getLength() )
754 INetURLObject
aURL( rURL
);
756 aTitle
= aURL
.getName( INetURLObject::LAST_SEGMENT
, true,
757 INetURLObject::DECODE_WITH_CHARSET
);
760 bDocHasTitle
= sal_True
;
765 // -----------------------------------------------------------------------
766 sal_Bool
SfxDocTplService_Impl::addEntry( Content
& rParentFolder
,
767 const OUString
& rTitle
,
768 const OUString
& rTargetURL
,
769 const OUString
& rType
)
771 sal_Bool bAddedEntry
= sal_False
;
773 INetURLObject
aLinkObj( rParentFolder
.getURL() );
774 aLinkObj
.insertName( rTitle
, false,
775 INetURLObject::LAST_SEGMENT
, true,
776 INetURLObject::ENCODE_ALL
);
777 OUString aLinkURL
= aLinkObj
.GetMainURL( INetURLObject::NO_DECODE
);
781 if ( ! Content::create( aLinkURL
, maCmdEnv
, aLink
) )
783 Sequence
< OUString
> aNames(3);
784 aNames
[0] = OUString( RTL_CONSTASCII_USTRINGPARAM( TITLE
) );
785 aNames
[1] = OUString( RTL_CONSTASCII_USTRINGPARAM( IS_FOLDER
) );
786 aNames
[2] = OUString( RTL_CONSTASCII_USTRINGPARAM( TARGET_URL
) );
788 Sequence
< Any
> aValues(3);
789 aValues
[0] = makeAny( rTitle
);
790 aValues
[1] = makeAny( sal_Bool( sal_False
) );
791 aValues
[2] = makeAny( rTargetURL
);
793 OUString
aType( RTL_CONSTASCII_USTRINGPARAM( TYPE_LINK
) );
794 OUString
aAdditionalProp( RTL_CONSTASCII_USTRINGPARAM( PROPERTY_TYPE
) );
798 rParentFolder
.insertNewContent( aType
, aNames
, aValues
, aLink
);
799 setProperty( aLink
, aAdditionalProp
, makeAny( rType
) );
800 bAddedEntry
= sal_True
;
808 // -----------------------------------------------------------------------
809 sal_Bool
SfxDocTplService_Impl::createFolder( const OUString
& rNewFolderURL
,
810 sal_Bool bCreateParent
,
811 sal_Bool bFsysFolder
,
812 Content
&rNewFolder
)
815 sal_Bool bCreatedFolder
= sal_False
;
816 INetURLObject
aParentURL( rNewFolderURL
);
817 OUString aFolderName
= aParentURL
.getName( INetURLObject::LAST_SEGMENT
, true,
818 INetURLObject::DECODE_WITH_CHARSET
);
820 // compute the parent folder url from the new folder url
821 // and remove the final slash, because Content::create doesn't
823 aParentURL
.removeSegment();
824 if ( aParentURL
.getSegmentCount() >= 1 )
825 aParentURL
.removeFinalSlash();
827 // if the parent exists, we can continue with the creation of the
828 // new folder, we have to create the parent otherwise ( as long as
829 // bCreateParent is set to true )
830 if ( Content::create( aParentURL
.GetMainURL( INetURLObject::NO_DECODE
), maCmdEnv
, aParent
) )
834 Sequence
< OUString
> aNames(2);
835 aNames
[0] = OUString( RTL_CONSTASCII_USTRINGPARAM( TITLE
) );
836 aNames
[1] = OUString( RTL_CONSTASCII_USTRINGPARAM( IS_FOLDER
) );
838 Sequence
< Any
> aValues(2);
839 aValues
[0] = makeAny( aFolderName
);
840 aValues
[1] = makeAny( sal_Bool( sal_True
) );
845 aType
= OUString( RTL_CONSTASCII_USTRINGPARAM( TYPE_FSYS_FOLDER
) );
847 aType
= OUString( RTL_CONSTASCII_USTRINGPARAM( TYPE_FOLDER
) );
849 aParent
.insertNewContent( aType
, aNames
, aValues
, rNewFolder
);
850 bCreatedFolder
= sal_True
;
852 catch( RuntimeException
& )
854 DBG_ERRORFILE( "createFolder(): got runtime exception" );
858 DBG_ERRORFILE( "createFolder(): Could not create new folder" );
861 else if ( bCreateParent
)
863 // if the parent doesn't exists and bCreateParent is set to true,
864 // we try to create the parent and if this was successful, we
865 // try to create the new folder again ( but this time, we set
866 // bCreateParent to false to avoid endless recusions )
867 if ( ( aParentURL
.getSegmentCount() >= 1 ) &&
868 createFolder( aParentURL
.GetMainURL( INetURLObject::NO_DECODE
), bCreateParent
, bFsysFolder
, aParent
) )
870 bCreatedFolder
= createFolder( rNewFolderURL
, sal_False
, bFsysFolder
, rNewFolder
);
874 return bCreatedFolder
;
877 // -----------------------------------------------------------------------
878 sal_Bool
SfxDocTplService_Impl::CreateNewUniqueFolderWithPrefix( const ::rtl::OUString
& aPath
,
879 const ::rtl::OUString
& aPrefix
,
880 ::rtl::OUString
& aNewFolderName
,
881 ::rtl::OUString
& aNewFolderURL
,
882 Content
& aNewFolder
)
884 sal_Bool bCreated
= sal_False
;
885 INetURLObject
aDirPath( aPath
);
888 if ( Content::create( aDirPath
.GetMainURL( INetURLObject::NO_DECODE
), maCmdEnv
, aParent
) )
890 for ( sal_Int32 nInd
= 0; nInd
< 32000; nInd
++ )
892 ::rtl::OUString aTryName
= aPrefix
;
894 aTryName
+= ::rtl::OUString::valueOf( nInd
);
898 Sequence
< OUString
> aNames(2);
899 aNames
[0] = OUString( RTL_CONSTASCII_USTRINGPARAM( TITLE
) );
900 aNames
[1] = OUString( RTL_CONSTASCII_USTRINGPARAM( IS_FOLDER
) );
902 Sequence
< Any
> aValues(2);
903 aValues
[0] = makeAny( aTryName
);
904 aValues
[1] = makeAny( sal_Bool( sal_True
) );
906 OUString
aType( RTL_CONSTASCII_USTRINGPARAM( TYPE_FSYS_FOLDER
) );
908 bCreated
= aParent
.insertNewContent( aType
, aNames
, aValues
, aNewFolder
);
910 catch( ucb::NameClashException
& )
912 // if there is already an element, retry
916 INetURLObject
aObjPath( aDirPath
);
917 aObjPath
.insertName( aTryName
, false,
918 INetURLObject::LAST_SEGMENT
, true,
919 INetURLObject::ENCODE_ALL
);
920 // if there is already an element, retry
921 // if there was another error, do not try any more
922 if ( !::utl::UCBContentHelper::Exists( aObjPath
.GetMainURL( INetURLObject::NO_DECODE
) ) )
928 aNewFolderName
= aTryName
;
929 aNewFolderURL
= aNewFolder
.get()->getIdentifier()->getContentIdentifier();
938 // -----------------------------------------------------------------------
939 ::rtl::OUString
SfxDocTplService_Impl::CreateNewUniqueFileWithPrefix( const ::rtl::OUString
& aPath
,
940 const ::rtl::OUString
& aPrefix
,
941 const ::rtl::OUString
& aExt
)
943 ::rtl::OUString aNewFileURL
;
944 INetURLObject
aDirPath( aPath
);
948 if ( Content::create( aDirPath
.GetMainURL( INetURLObject::NO_DECODE
), maCmdEnv
, aParent
) )
950 for ( sal_Int32 nInd
= 0; nInd
< 32000; nInd
++ )
953 sal_Bool bCreated
= sal_False
;
954 ::rtl::OUString aTryName
= aPrefix
;
956 aTryName
+= ::rtl::OUString::valueOf( nInd
);
957 if ( aExt
.toChar() != '.' )
958 aTryName
+= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "." ) );
963 Sequence
< OUString
> aNames(2);
964 aNames
[0] = OUString( RTL_CONSTASCII_USTRINGPARAM( TITLE
) );
965 aNames
[1] = OUString( RTL_CONSTASCII_USTRINGPARAM( IS_DOCUMENT
) );
967 Sequence
< Any
> aValues(2);
968 aValues
[0] = makeAny( aTryName
);
969 aValues
[1] = makeAny( sal_Bool( sal_True
) );
971 OUString
aType( RTL_CONSTASCII_USTRINGPARAM( TYPE_FSYS_FILE
) );
973 bCreated
= aParent
.insertNewContent( aType
, aNames
, aValues
, aNewFile
);
975 catch( ucb::NameClashException
& )
977 // if there is already an element, retry
981 INetURLObject
aObjPath( aPath
);
982 aObjPath
.insertName( aTryName
, false,
983 INetURLObject::LAST_SEGMENT
, true,
984 INetURLObject::ENCODE_ALL
);
985 // if there is already an element, retry
986 // if there was another error, do not try any more
987 if ( !::utl::UCBContentHelper::Exists( aObjPath
.GetMainURL( INetURLObject::NO_DECODE
) ) )
993 aNewFileURL
= aNewFile
.get()->getIdentifier()->getContentIdentifier();
1002 // -----------------------------------------------------------------------
1003 sal_Bool
SfxDocTplService_Impl::removeContent( Content
& rContent
)
1005 sal_Bool bRemoved
= sal_False
;
1008 OUString
aCmd( RTL_CONSTASCII_USTRINGPARAM( COMMAND_DELETE
) );
1009 Any aArg
= makeAny( sal_Bool( sal_True
) );
1011 rContent
.executeCommand( aCmd
, aArg
);
1012 bRemoved
= sal_True
;
1014 catch ( RuntimeException
& ) {}
1015 catch ( Exception
& ) {}
1020 // -----------------------------------------------------------------------
1021 sal_Bool
SfxDocTplService_Impl::removeContent( const OUString
& rContentURL
)
1025 if ( Content::create( rContentURL
, maCmdEnv
, aContent
) )
1026 return removeContent( aContent
);
1031 // -----------------------------------------------------------------------
1032 sal_Bool
SfxDocTplService_Impl::setProperty( Content
& rContent
,
1033 const OUString
& rPropName
,
1034 const Any
& rPropValue
)
1036 sal_Bool bPropertySet
= sal_False
;
1038 // Store the property
1041 Any
aPropValue( rPropValue
);
1042 uno::Reference
< XPropertySetInfo
> aPropInfo
= rContent
.getProperties();
1044 // check, wether or not the property exists, create it, when not
1045 if ( !aPropInfo
.is() || !aPropInfo
->hasPropertyByName( rPropName
) )
1047 uno::Reference
< XPropertyContainer
> xProperties( rContent
.get(), UNO_QUERY
);
1048 if ( xProperties
.is() )
1052 xProperties
->addProperty( rPropName
, PropertyAttribute::MAYBEVOID
, rPropValue
);
1054 catch( PropertyExistException
& ) {}
1055 catch( IllegalTypeException
& ) { DBG_ERRORFILE( "IllegalTypeException" ); }
1056 catch( IllegalArgumentException
& ) { DBG_ERRORFILE( "IllegalArgumentException" ); }
1060 // To ensure a reloctable office installation, the path to the
1061 // office installtion directory must never be stored directly.
1062 if ( SfxURLRelocator_Impl::propertyCanContainOfficeDir( rPropName
) )
1065 if ( rPropValue
>>= aValue
)
1067 maRelocator
.makeRelocatableURL( aValue
);
1068 aPropValue
= makeAny( aValue
);
1072 Sequence
< OUString
> aValues
;
1073 if ( rPropValue
>>= aValues
)
1075 for ( sal_Int32 n
= 0; n
< aValues
.getLength(); n
++ )
1077 maRelocator
.makeRelocatableURL( aValues
[ n
] );
1079 aPropValue
= makeAny( aValues
);
1083 OSL_ENSURE( false, "Unsupported property value type" );
1088 // now set the property
1090 rContent
.setPropertyValue( rPropName
, aPropValue
);
1091 bPropertySet
= sal_True
;
1093 catch ( RuntimeException
& ) {}
1094 catch ( Exception
& ) {}
1096 return bPropertySet
;
1099 // -----------------------------------------------------------------------
1100 sal_Bool
SfxDocTplService_Impl::getProperty( Content
& rContent
,
1101 const OUString
& rPropName
,
1104 sal_Bool bGotProperty
= sal_False
;
1109 uno::Reference
< XPropertySetInfo
> aPropInfo
= rContent
.getProperties();
1111 // check, wether or not the property exists
1112 if ( !aPropInfo
.is() || !aPropInfo
->hasPropertyByName( rPropName
) )
1117 // now get the property
1119 rPropValue
= rContent
.getPropertyValue( rPropName
);
1121 // To ensure a reloctable office installation, the path to the
1122 // office installtion directory must never be stored directly.
1123 if ( SfxURLRelocator_Impl::propertyCanContainOfficeDir( rPropName
) )
1126 if ( rPropValue
>>= aValue
)
1128 maRelocator
.makeAbsoluteURL( aValue
);
1129 rPropValue
= makeAny( aValue
);
1133 Sequence
< OUString
> aValues
;
1134 if ( rPropValue
>>= aValues
)
1136 for ( sal_Int32 n
= 0; n
< aValues
.getLength(); n
++ )
1138 maRelocator
.makeAbsoluteURL( aValues
[ n
] );
1140 rPropValue
= makeAny( aValues
);
1144 OSL_ENSURE( false, "Unsupported property value type" );
1149 bGotProperty
= sal_True
;
1151 catch ( RuntimeException
& ) {}
1152 catch ( Exception
& ) {}
1154 return bGotProperty
;
1157 // -----------------------------------------------------------------------
1159 bool SfxURLRelocator_Impl::propertyCanContainOfficeDir(
1160 const rtl::OUString
& rPropName
)
1162 // Note: TargetURL is handled by UCB itself (because it is a property
1163 // with a predefined semantic). Additional Core properties introduced
1164 // be a client app must be handled by the client app itself, because
1165 // the UCB does not know the semantics of those properties.
1166 return ( rPropName
.equalsAsciiL(
1167 RTL_CONSTASCII_STRINGPARAM( TARGET_DIR_URL
) ) ||
1168 rPropName
.equalsAsciiL(
1169 RTL_CONSTASCII_STRINGPARAM( PROPERTY_DIRLIST
) ) );
1172 //-----------------------------------------------------------------------------
1173 // public SfxDocTplService_Impl
1174 //-----------------------------------------------------------------------------
1176 SfxDocTplService_Impl::SfxDocTplService_Impl( uno::Reference
< XMultiServiceFactory
> xFactory
)
1177 : maRelocator( xFactory
)
1179 mxFactory
= xFactory
;
1181 mbIsInitialized
= sal_False
;
1182 mbLocaleSet
= sal_False
;
1185 //-----------------------------------------------------------------------------
1186 SfxDocTplService_Impl::~SfxDocTplService_Impl()
1188 ::osl::MutexGuard
aGuard( maMutex
);
1197 //-----------------------------------------------------------------------------
1198 Locale
SfxDocTplService_Impl::getLocale()
1200 ::osl::MutexGuard
aGuard( maMutex
);
1208 //-----------------------------------------------------------------------------
1209 void SfxDocTplService_Impl::setLocale( const Locale
&rLocale
)
1211 ::osl::MutexGuard
aGuard( maMutex
);
1214 ( maLocale
.Language
!= rLocale
.Language
) &&
1215 ( maLocale
.Country
!= rLocale
.Country
) )
1216 mbIsInitialized
= sal_False
;
1219 mbLocaleSet
= sal_True
;
1222 //-----------------------------------------------------------------------------
1223 void SfxDocTplService_Impl::update( sal_Bool bUpdateNow
)
1225 ::osl::MutexGuard
aGuard( maMutex
);
1231 mpUpdater
= new Updater_Impl( this );
1232 mpUpdater
->create();
1236 //-----------------------------------------------------------------------------
1237 void SfxDocTplService_Impl::doUpdate()
1239 ::osl::MutexGuard
aGuard( maMutex
);
1241 OUString
aPropName( RTL_CONSTASCII_USTRINGPARAM( PROPERTY_NEEDSUPDATE
) );
1244 aValue
<<= sal_True
;
1245 setProperty( maRootContent
, aPropName
, aValue
);
1247 GroupList_Impl aGroupList
;
1249 // get the entries from the hierarchy
1250 createFromContent( aGroupList
, maRootContent
, sal_True
);
1252 // get the entries from the template directories
1253 sal_Int32 nCountDir
= maTemplateDirs
.getLength();
1254 OUString
* pDirs
= maTemplateDirs
.getArray();
1255 Content aDirContent
;
1257 // the last directory in the list must be writable
1258 sal_Bool bWriteableDirectory
= sal_True
;
1260 // the target folder might not exist, for this reason no interaction handler should be used
1261 uno::Reference
< XCommandEnvironment
> aQuietEnv
;
1266 osl::Directory
aDirectory (pDirs
[ nCountDir
]);
1267 osl::FileBase::RC nError
= aDirectory
.open();
1268 if (nError
== osl::FileBase::E_None
|| bWriteableDirectory
)
1270 if ( Content::create( pDirs
[ nCountDir
], aQuietEnv
, aDirContent
) )
1272 createFromContent( aGroupList
, aDirContent
, sal_False
, bWriteableDirectory
);
1276 bWriteableDirectory
= sal_False
;
1279 // now check the list
1280 GroupData_Impl
*pGroup
= aGroupList
.First();
1283 if ( pGroup
->getInUse() )
1285 if ( pGroup
->getInHierarchy() )
1288 if ( Content::create( pGroup
->getHierarchyURL(), maCmdEnv
, aGroup
) )
1289 setProperty( aGroup
,
1290 OUString( RTL_CONSTASCII_USTRINGPARAM( TARGET_DIR_URL
) ),
1291 makeAny( pGroup
->getTargetURL() ) );
1293 ULONG nCount
= pGroup
->count();
1294 for ( ULONG i
=0; i
<nCount
; i
++ )
1296 DocTemplates_EntryData_Impl
*pData
= pGroup
->getEntry( i
);
1297 if ( ! pData
->getInUse() )
1299 if ( pData
->getInHierarchy() )
1300 removeFromHierarchy( pData
); // delete entry in hierarchy
1302 addToHierarchy( pGroup
, pData
); // add entry to hierarchy
1304 else if ( pData
->getUpdateType() ||
1305 pData
->getUpdateLink() )
1307 updateData( pData
);
1313 addGroupToHierarchy( pGroup
); // add group to hierarchy
1317 removeFromHierarchy( pGroup
); // delete group from hierarchy
1320 pGroup
= aGroupList
.Next();
1323 aValue
<<= sal_False
;
1324 setProperty( maRootContent
, aPropName
, aValue
);
1327 //-----------------------------------------------------------------------------
1328 uno::Sequence
< beans::StringPair
> SfxDocTplService_Impl::ReadUINamesForTemplateDir_Impl( const ::rtl::OUString
& aUserPath
)
1330 INetURLObject
aLocObj( aUserPath
);
1331 aLocObj
.insertName( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "groupuinames.xml" ) ), false,
1332 INetURLObject::LAST_SEGMENT
, true,
1333 INetURLObject::ENCODE_ALL
);
1334 Content aLocContent
;
1336 // TODO/LATER: Use hashmap in future
1337 uno::Sequence
< beans::StringPair
> aUINames
;
1338 if ( Content::create( aLocObj
.GetMainURL( INetURLObject::NO_DECODE
), uno::Reference
< ucb::XCommandEnvironment
>(), aLocContent
) )
1342 uno::Reference
< io::XInputStream
> xLocStream
= aLocContent
.openStream();
1343 if ( xLocStream
.is() )
1344 aUINames
= DocTemplLocaleHelper::ReadGroupLocalizationSequence( xLocStream
, mxFactory
);
1346 catch( uno::Exception
& )
1353 //-----------------------------------------------------------------------------
1354 sal_Bool
SfxDocTplService_Impl::UpdateUINamesForTemplateDir_Impl( const ::rtl::OUString
& aUserPath
,
1355 const ::rtl::OUString
& aGroupName
,
1356 const ::rtl::OUString
& aNewFolderName
)
1358 uno::Sequence
< beans::StringPair
> aUINames
= ReadUINamesForTemplateDir_Impl( aUserPath
);
1359 sal_Int32 nLen
= aUINames
.getLength();
1361 // it is possible that the name is used already, but it should be checked before
1362 for ( sal_Int32 nInd
= 0; nInd
< nLen
; nInd
++ )
1363 if ( aUINames
[nInd
].First
.equals( aNewFolderName
) )
1366 aUINames
.realloc( ++nLen
);
1367 aUINames
[nLen
-1].First
= aNewFolderName
;
1368 aUINames
[nLen
-1].Second
= aGroupName
;
1370 return WriteUINamesForTemplateDir_Impl( aUserPath
, aUINames
);
1373 //-----------------------------------------------------------------------------
1374 sal_Bool
SfxDocTplService_Impl::ReplaceUINamesForTemplateDir_Impl( const ::rtl::OUString
& aUserPath
,
1375 const ::rtl::OUString
& aDefaultFsysGroupName
,
1376 const ::rtl::OUString
& aOldGroupName
,
1377 const ::rtl::OUString
& aNewGroupName
)
1379 uno::Sequence
< beans::StringPair
> aUINames
= ReadUINamesForTemplateDir_Impl( aUserPath
);
1380 sal_Int32 nLen
= aUINames
.getLength();
1382 sal_Bool bChanged
= sal_False
;
1383 for ( sal_Int32 nInd
= 0; nInd
< nLen
; nInd
++ )
1384 if ( aUINames
[nInd
].Second
.equals( aOldGroupName
) )
1386 aUINames
[nInd
].Second
= aNewGroupName
;
1387 bChanged
= sal_True
;
1392 aUINames
.realloc( ++nLen
);
1393 aUINames
[nLen
-1].First
= aDefaultFsysGroupName
;
1394 aUINames
[nLen
-1].Second
= aNewGroupName
;
1396 return WriteUINamesForTemplateDir_Impl( aUserPath
, aUINames
);
1399 //-----------------------------------------------------------------------------
1400 sal_Bool
SfxDocTplService_Impl::RemoveUINamesForTemplateDir_Impl( const ::rtl::OUString
& aUserPath
,
1401 const ::rtl::OUString
& aGroupName
)
1403 uno::Sequence
< beans::StringPair
> aUINames
= ReadUINamesForTemplateDir_Impl( aUserPath
);
1404 sal_Int32 nLen
= aUINames
.getLength();
1405 uno::Sequence
< beans::StringPair
> aNewUINames( nLen
);
1406 sal_Int32 nNewLen
= 0;
1408 sal_Bool bChanged
= sal_False
;
1409 for ( sal_Int32 nInd
= 0; nInd
< nLen
; nInd
++ )
1410 if ( aUINames
[nInd
].Second
.equals( aGroupName
) )
1411 bChanged
= sal_True
;
1415 aNewUINames
[nNewLen
-1].First
= aUINames
[nInd
].First
;
1416 aNewUINames
[nNewLen
-1].Second
= aUINames
[nInd
].Second
;
1419 aNewUINames
.realloc( nNewLen
);
1421 return bChanged
? WriteUINamesForTemplateDir_Impl( aUserPath
, aNewUINames
) : sal_True
;
1425 //-----------------------------------------------------------------------------
1426 sal_Bool
SfxDocTplService_Impl::WriteUINamesForTemplateDir_Impl( const ::rtl::OUString
& aUserPath
,
1427 const uno::Sequence
< beans::StringPair
>& aUINames
)
1429 sal_Bool bResult
= sal_False
;
1431 uno::Reference
< beans::XPropertySet
> xTempFile(
1432 mxFactory
->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.io.TempFile" ) ),
1433 uno::UNO_QUERY_THROW
);
1435 ::rtl::OUString aTempURL
;
1436 uno::Any aUrl
= xTempFile
->getPropertyValue( ::rtl::OUString::createFromAscii( "Uri" ) );
1439 uno::Reference
< io::XStream
> xStream( xTempFile
, uno::UNO_QUERY_THROW
);
1440 uno::Reference
< io::XOutputStream
> xOutStream
= xStream
->getOutputStream();
1441 if ( !xOutStream
.is() )
1442 throw uno::RuntimeException();
1444 DocTemplLocaleHelper::WriteGroupLocalizationSequence( xOutStream
, aUINames
, mxFactory
);
1446 // the SAX writer might close the stream
1447 xOutStream
->closeOutput();
1448 } catch( uno::Exception
& )
1451 Content
aTargetContent( aUserPath
, maCmdEnv
);
1452 Content
aSourceContent( aTempURL
, maCmdEnv
);
1453 aTargetContent
.transferContent( aSourceContent
,
1454 InsertOperation_COPY
,
1455 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "groupuinames.xml" ) ),
1456 ucb::NameClash::OVERWRITE
);
1459 catch ( uno::Exception
& )
1466 //-----------------------------------------------------------------------------
1467 ::rtl::OUString
SfxDocTplService_Impl::CreateNewGroupFsys( const ::rtl::OUString
& rGroupName
, Content
& aGroup
)
1469 ::rtl::OUString aResultURL
;
1471 if ( maTemplateDirs
.getLength() )
1473 ::rtl::OUString aTargetPath
= maTemplateDirs
[ maTemplateDirs
.getLength() - 1 ];
1475 // create a new folder with the given name
1477 ::rtl::OUString aNewFolderName
;
1479 // the Fsys name instead of GroupName should be used, the groupuinames must be added also
1480 if ( !CreateNewUniqueFolderWithPrefix( aTargetPath
,
1485 && !CreateNewUniqueFolderWithPrefix( aTargetPath
,
1486 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UserGroup" ) ),
1491 return ::rtl::OUString();
1493 if ( !UpdateUINamesForTemplateDir_Impl( aTargetPath
, rGroupName
, aNewFolderName
) )
1495 // we could not create the groupuinames for the folder, so we delete the group in the
1496 // the folder and return
1497 removeContent( aNewFolder
);
1498 return ::rtl::OUString();
1501 // Now set the target url for this group and we are done
1502 OUString
aPropName( RTL_CONSTASCII_USTRINGPARAM( TARGET_DIR_URL
) );
1503 Any aValue
= makeAny( aResultURL
);
1505 if ( ! setProperty( aGroup
, aPropName
, aValue
) )
1507 removeContent( aNewFolder
);
1508 return ::rtl::OUString();
1515 //-----------------------------------------------------------------------------
1516 sal_Bool
SfxDocTplService_Impl::addGroup( const OUString
& rGroupName
)
1518 ::osl::MutexGuard
aGuard( maMutex
);
1520 // Check, wether or not there is a group with this name
1522 OUString aNewGroupURL
;
1523 INetURLObject
aNewGroupObj( maRootURL
);
1525 aNewGroupObj
.insertName( rGroupName
, false,
1526 INetURLObject::LAST_SEGMENT
, true,
1527 INetURLObject::ENCODE_ALL
);
1529 aNewGroupURL
= aNewGroupObj
.GetMainURL( INetURLObject::NO_DECODE
);
1531 if ( Content::create( aNewGroupURL
, maCmdEnv
, aNewGroup
) ||
1532 ! createFolder( aNewGroupURL
, sal_False
, sal_False
, aNewGroup
) )
1534 // if there already was a group with this name or the new group
1535 // could not be created, we return here
1539 // Get the user template path entry ( new group will always
1540 // be added in the user template path )
1544 nIndex
= maTemplateDirs
.getLength();
1548 return sal_False
; // We don't know where to add the group
1550 aUserPath
= maTemplateDirs
[ nIndex
];
1552 // create a new folder with the given name
1554 OUString aNewFolderName
;
1555 OUString aNewFolderURL
;
1557 // the Fsys name instead of GroupName should be used, the groupuinames must be added also
1558 if ( !CreateNewUniqueFolderWithPrefix( aUserPath
,
1563 && !CreateNewUniqueFolderWithPrefix( aUserPath
,
1564 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UserGroup" ) ),
1569 // we could not create the folder, so we delete the group in the
1570 // hierarchy and return
1571 removeContent( aNewGroup
);
1575 if ( !UpdateUINamesForTemplateDir_Impl( aUserPath
, rGroupName
, aNewFolderName
) )
1577 // we could not create the groupuinames for the folder, so we delete the group in the
1578 // hierarchy, the folder and return
1579 removeContent( aNewGroup
);
1580 removeContent( aNewFolder
);
1584 // Now set the target url for this group and we are done
1585 OUString
aPropName( RTL_CONSTASCII_USTRINGPARAM( TARGET_DIR_URL
) );
1586 Any aValue
= makeAny( aNewFolderURL
);
1588 if ( ! setProperty( aNewGroup
, aPropName
, aValue
) )
1590 removeContent( aNewGroup
);
1591 removeContent( aNewFolder
);
1598 //-----------------------------------------------------------------------------
1599 sal_Bool
SfxDocTplService_Impl::removeGroup( const OUString
& rGroupName
)
1601 // remove all the elements that have the prefix aTargetURL
1602 // if the group does not have other elements remove it
1604 ::osl::MutexGuard
aGuard( maMutex
);
1606 sal_Bool bResult
= sal_False
;
1608 // create the group url
1609 INetURLObject
aGroupObj( maRootURL
);
1610 aGroupObj
.insertName( rGroupName
, false,
1611 INetURLObject::LAST_SEGMENT
, true,
1612 INetURLObject::ENCODE_ALL
);
1614 // Get the target url
1616 OUString aGroupURL
= aGroupObj
.GetMainURL( INetURLObject::NO_DECODE
);
1618 if ( Content::create( aGroupURL
, maCmdEnv
, aGroup
) )
1620 OUString
aPropName( RTL_CONSTASCII_USTRINGPARAM( TARGET_DIR_URL
) );
1623 OUString aGroupTargetURL
;
1624 if ( getProperty( aGroup
, aPropName
, aValue
) )
1625 aValue
>>= aGroupTargetURL
;
1627 if ( !aGroupTargetURL
.getLength() )
1628 return sal_False
; // nothing is allowed to be removed
1630 if ( !maTemplateDirs
.getLength() )
1632 ::rtl::OUString aGeneralTempPath
= maTemplateDirs
[ maTemplateDirs
.getLength() - 1 ];
1634 // check that the fs location is in writeble folder and this is not a "My templates" folder
1635 INetURLObject
aGroupParentFolder( aGroupTargetURL
);
1636 if ( !aGroupParentFolder
.removeSegment()
1637 || !::utl::UCBContentHelper::IsSubPath( aGeneralTempPath
,
1638 aGroupParentFolder
.GetMainURL( INetURLObject::NO_DECODE
) ) )
1641 // now get the content of the Group
1642 uno::Reference
< XResultSet
> xResultSet
;
1643 Sequence
< OUString
> aProps( 1 );
1645 aProps
[0] = OUString::createFromAscii( TARGET_URL
);
1649 sal_Bool bHasNonRemovable
= sal_False
;
1650 sal_Bool bHasShared
= sal_False
;
1652 ResultSetInclude eInclude
= INCLUDE_DOCUMENTS_ONLY
;
1653 xResultSet
= aGroup
.createCursor( aProps
, eInclude
);
1655 if ( xResultSet
.is() )
1657 uno::Reference
< XContentAccess
> xContentAccess( xResultSet
, UNO_QUERY_THROW
);
1658 uno::Reference
< XRow
> xRow( xResultSet
, UNO_QUERY_THROW
);
1660 while ( xResultSet
->next() )
1662 OUString
aTemplTargetURL( xRow
->getString( 1 ) );
1663 OUString aHierURL
= xContentAccess
->queryContentIdentifierString();
1665 if ( ::utl::UCBContentHelper::IsSubPath( aGroupTargetURL
, aTemplTargetURL
) )
1667 // this is a user template, and it can be removed
1668 if ( removeContent( aTemplTargetURL
) )
1669 removeContent( aHierURL
);
1671 bHasNonRemovable
= sal_True
;
1674 bHasShared
= sal_True
;
1677 if ( !bHasNonRemovable
&& !bHasShared
)
1679 if ( removeContent( aGroupTargetURL
)
1680 || !::utl::UCBContentHelper::Exists( aGroupTargetURL
) )
1682 removeContent( aGroupURL
);
1683 RemoveUINamesForTemplateDir_Impl( aGeneralTempPath
, rGroupName
);
1684 bResult
= sal_True
; // the operation is successful only if the whole group is removed
1687 else if ( !bHasNonRemovable
)
1689 if ( removeContent( aGroupTargetURL
)
1690 || !::utl::UCBContentHelper::Exists( aGroupTargetURL
) )
1692 RemoveUINamesForTemplateDir_Impl( aGeneralTempPath
, rGroupName
);
1693 setProperty( aGroup
, aPropName
, uno::makeAny( ::rtl::OUString() ) );
1698 catch ( Exception
& ) {}
1704 //-----------------------------------------------------------------------------
1705 sal_Bool
SfxDocTplService_Impl::renameGroup( const OUString
& rOldName
,
1706 const OUString
& rNewName
)
1708 ::osl::MutexGuard
aGuard( maMutex
);
1710 // create the group url
1712 INetURLObject
aGroupObj( maRootURL
);
1713 aGroupObj
.insertName( rNewName
, false,
1714 INetURLObject::LAST_SEGMENT
, true,
1715 INetURLObject::ENCODE_ALL
);
1716 OUString aGroupURL
= aGroupObj
.GetMainURL( INetURLObject::NO_DECODE
);
1718 // Check, if there is a group with the new name, return false
1720 if ( Content::create( aGroupURL
, maCmdEnv
, aGroup
) )
1723 aGroupObj
.removeSegment();
1724 aGroupObj
.insertName( rOldName
, false,
1725 INetURLObject::LAST_SEGMENT
, true,
1726 INetURLObject::ENCODE_ALL
);
1727 aGroupURL
= aGroupObj
.GetMainURL( INetURLObject::NO_DECODE
);
1729 // When there is no group with the old name, we can't rename it
1730 if ( ! Content::create( aGroupURL
, maCmdEnv
, aGroup
) )
1733 OUString aGroupTargetURL
;
1734 // there is no need to check whether target dir url is in target path, since if the target path is changed
1735 // the target dir url should be already generated new
1736 OUString
aPropName( RTL_CONSTASCII_USTRINGPARAM( TARGET_DIR_URL
) );
1738 if ( getProperty( aGroup
, aPropName
, aValue
) )
1739 aValue
>>= aGroupTargetURL
;
1741 if ( !aGroupTargetURL
.getLength() )
1744 if ( !maTemplateDirs
.getLength() )
1746 ::rtl::OUString aGeneralTempPath
= maTemplateDirs
[ maTemplateDirs
.getLength() - 1 ];
1748 // check that the fs location is in writeble folder and this is not a "My templates" folder
1749 INetURLObject
aGroupParentFolder( aGroupTargetURL
);
1750 if ( !aGroupParentFolder
.removeSegment()
1751 || !::utl::UCBContentHelper::IsSubPath( aGeneralTempPath
,
1752 aGroupParentFolder
.GetMainURL( INetURLObject::NO_DECODE
) ) )
1755 // check that the group can be renamed ( all the contents must be in target location )
1756 sal_Bool bCanBeRenamed
= sal_False
;
1759 uno::Reference
< XResultSet
> xResultSet
;
1760 Sequence
< OUString
> aProps( 1 );
1762 aProps
[0] = OUString::createFromAscii( TARGET_URL
);
1763 ResultSetInclude eInclude
= INCLUDE_DOCUMENTS_ONLY
;
1764 xResultSet
= aGroup
.createCursor( aProps
, eInclude
);
1766 if ( xResultSet
.is() )
1768 uno::Reference
< XContentAccess
> xContentAccess( xResultSet
, UNO_QUERY_THROW
);
1769 uno::Reference
< XRow
> xRow( xResultSet
, UNO_QUERY_THROW
);
1771 while ( xResultSet
->next() )
1773 OUString
aTemplTargetURL( xRow
->getString( 1 ) );
1775 if ( !::utl::UCBContentHelper::IsSubPath( aGroupTargetURL
, aTemplTargetURL
) )
1776 throw uno::Exception();
1779 bCanBeRenamed
= sal_True
;
1782 catch ( Exception
& ) {}
1784 if ( bCanBeRenamed
)
1786 INetURLObject
aGroupTargetObj( aGroupTargetURL
);
1787 ::rtl::OUString aFsysName
= aGroupTargetObj
.getName( INetURLObject::LAST_SEGMENT
, true, INetURLObject::DECODE_WITH_CHARSET
);
1789 if ( aGroupTargetObj
.removeSegment()
1790 && ReplaceUINamesForTemplateDir_Impl( aGroupTargetObj
.GetMainURL( INetURLObject::NO_DECODE
),
1795 // rename the group in the hierarchy
1796 OUString
aTitleProp( RTL_CONSTASCII_USTRINGPARAM( TITLE
) );
1798 aTitleValue
<<= rNewName
;
1800 return setProperty( aGroup
, aTitleProp
, aTitleValue
);
1807 //-----------------------------------------------------------------------------
1808 sal_Bool
SfxDocTplService_Impl::storeTemplate( const OUString
& rGroupName
,
1809 const OUString
& rTemplateName
,
1810 const uno::Reference
< XSTORABLE
>& rStorable
)
1812 ::osl::MutexGuard
aGuard( maMutex
);
1814 // Check, wether or not there is a group with this name
1815 // Return false, if there is no group with the given name
1816 Content aGroup
, aTemplate
, aTargetGroup
, aTemplateToRemove
;
1817 OUString aGroupURL
, aTemplateURL
, aTemplateToRemoveTargetURL
;
1818 INetURLObject
aGroupObj( maRootURL
);
1819 sal_Bool bRemoveOldTemplateContent
= sal_False
;
1820 ::rtl::OUString sDocServiceName
;
1822 aGroupObj
.insertName( rGroupName
, false,
1823 INetURLObject::LAST_SEGMENT
, true,
1824 INetURLObject::ENCODE_ALL
);
1825 aGroupURL
= aGroupObj
.GetMainURL( INetURLObject::NO_DECODE
);
1827 if ( ! Content::create( aGroupURL
, maCmdEnv
, aGroup
) )
1830 ::rtl::OUString aGroupTargetURL
;
1831 ::rtl::OUString
aPropName( RTL_CONSTASCII_USTRINGPARAM( TARGET_DIR_URL
) );
1833 if ( getProperty( aGroup
, aPropName
, aValue
) )
1834 aValue
>>= aGroupTargetURL
;
1837 // Check, if there's a template with the given name in this group
1838 // the target template should be overwritten if it is imported by user
1839 // in case the template is installed by office installation of by an add-in
1840 // it can not be replaced
1841 aGroupObj
.insertName( rTemplateName
, false,
1842 INetURLObject::LAST_SEGMENT
, true,
1843 INetURLObject::ENCODE_ALL
);
1844 aTemplateURL
= aGroupObj
.GetMainURL( INetURLObject::NO_DECODE
);
1846 if ( Content::create( aTemplateURL
, maCmdEnv
, aTemplateToRemove
) )
1848 OUString
aTargetTemplPropName( RTL_CONSTASCII_USTRINGPARAM( TARGET_URL
) );
1850 bRemoveOldTemplateContent
= sal_True
;
1851 if ( getProperty( aTemplateToRemove
, aTargetTemplPropName
, aValue
) )
1852 aValue
>>= aTemplateToRemoveTargetURL
;
1854 if ( !aGroupTargetURL
.getLength() || !maTemplateDirs
.getLength()
1855 || (aTemplateToRemoveTargetURL
.getLength() && !::utl::UCBContentHelper::IsSubPath( maTemplateDirs
[ maTemplateDirs
.getLength() - 1 ], aTemplateToRemoveTargetURL
)) )
1856 return sal_False
; // it is not allowed to remove the template
1861 uno::Reference
< lang::XMultiServiceFactory
> xFactory
= ::comphelper::getProcessServiceFactory();
1862 if ( !xFactory
.is() )
1863 throw uno::RuntimeException();
1865 // get document service name
1866 uno::Reference
< frame::XModuleManager
> xModuleManager(
1867 xFactory
->createInstance(
1868 ::rtl::OUString::createFromAscii( "com.sun.star.frame.ModuleManager" ) ),
1869 uno::UNO_QUERY_THROW
);
1870 sDocServiceName
= xModuleManager
->identify( uno::Reference
< uno::XInterface
>( rStorable
, uno::UNO_QUERY
) );
1871 if ( !sDocServiceName
.getLength() )
1872 throw uno::RuntimeException();
1874 // get the actual filter name
1875 ::rtl::OUString aFilterName
;
1877 uno::Reference
< lang::XMultiServiceFactory
> xConfigProvider(
1878 xFactory
->createInstance(
1879 ::rtl::OUString::createFromAscii( "com.sun.star.configuration.ConfigurationProvider" ) ),
1880 uno::UNO_QUERY_THROW
);
1882 uno::Sequence
< uno::Any
> aArgs( 1 );
1883 beans::PropertyValue aPathProp
;
1884 aPathProp
.Name
= ::rtl::OUString::createFromAscii( "nodepath" );
1885 aPathProp
.Value
<<= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Setup/Office/Factories/" ) );
1886 aArgs
[0] <<= aPathProp
;
1888 uno::Reference
< container::XNameAccess
> xSOFConfig(
1889 xConfigProvider
->createInstanceWithArguments(
1890 ::rtl::OUString::createFromAscii( "com.sun.star.configuration.ConfigurationAccess" ),
1892 uno::UNO_QUERY_THROW
);
1894 uno::Reference
< container::XNameAccess
> xApplConfig
;
1895 xSOFConfig
->getByName( sDocServiceName
) >>= xApplConfig
;
1896 if ( !xApplConfig
.is() )
1897 throw uno::RuntimeException();
1899 xApplConfig
->getByName( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ooSetupFactoryActualTemplateFilter" ) ) ) >>= aFilterName
;
1900 if ( !aFilterName
.getLength() )
1901 throw uno::RuntimeException();
1903 // find the related type name
1904 ::rtl::OUString aTypeName
;
1905 uno::Reference
< container::XNameAccess
> xFilterFactory(
1906 xFactory
->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.document.FilterFactory" ) ),
1907 uno::UNO_QUERY_THROW
);
1909 uno::Sequence
< beans::PropertyValue
> aFilterData
;
1910 xFilterFactory
->getByName( aFilterName
) >>= aFilterData
;
1911 for ( sal_Int32 nInd
= 0; nInd
< aFilterData
.getLength(); nInd
++ )
1912 if ( aFilterData
[nInd
].Name
.equalsAscii( "Type" ) )
1913 aFilterData
[nInd
].Value
>>= aTypeName
;
1915 if ( !aTypeName
.getLength() )
1916 throw uno::RuntimeException();
1918 // find the mediatype and extension
1919 uno::Reference
< container::XNameAccess
> xTypeDetection
=
1921 uno::Reference
< container::XNameAccess
>( mxType
, uno::UNO_QUERY_THROW
) :
1922 uno::Reference
< container::XNameAccess
>(
1923 xFactory
->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.document.TypeDetection" ) ),
1924 uno::UNO_QUERY_THROW
);
1926 SequenceAsHashMap
aTypeProps( xTypeDetection
->getByName( aTypeName
) );
1927 uno::Sequence
< ::rtl::OUString
> aAllExt
=
1928 aTypeProps
.getUnpackedValueOrDefault( ::rtl::OUString::createFromAscii( "Extensions" ), Sequence
< ::rtl::OUString
>() );
1929 if ( !aAllExt
.getLength() )
1930 throw uno::RuntimeException();
1932 ::rtl::OUString aMediaType
= aTypeProps
.getUnpackedValueOrDefault( ::rtl::OUString::createFromAscii( "MediaType" ), ::rtl::OUString() );
1933 ::rtl::OUString aExt
= aAllExt
[0];
1935 if ( !aMediaType
.getLength() || !aExt
.getLength() )
1936 throw uno::RuntimeException();
1938 // construct destination url
1939 if ( !aGroupTargetURL
.getLength() )
1941 aGroupTargetURL
= CreateNewGroupFsys( rGroupName
, aGroup
);
1943 if ( !aGroupTargetURL
.getLength() )
1944 throw uno::RuntimeException();
1947 ::rtl::OUString aNewTemplateTargetURL
= CreateNewUniqueFileWithPrefix( aGroupTargetURL
, rTemplateName
, aExt
);
1948 if ( !aNewTemplateTargetURL
.getLength() )
1950 aNewTemplateTargetURL
= CreateNewUniqueFileWithPrefix( aGroupTargetURL
, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UserTemplate" ) ), aExt
);
1952 if ( !aNewTemplateTargetURL
.getLength() )
1953 throw uno::RuntimeException();
1957 uno::Sequence
< PropertyValue
> aStoreArgs( 2 );
1958 aStoreArgs
[0].Name
= ::rtl::OUString::createFromAscii( "FilterName" );
1959 aStoreArgs
[0].Value
<<= aFilterName
;
1960 aStoreArgs
[1].Name
= ::rtl::OUString::createFromAscii( "DocumentTitle" );
1961 aStoreArgs
[1].Value
<<= rTemplateName
;
1963 rStorable
->storeToURL( aNewTemplateTargetURL
, aStoreArgs
);
1965 // the storing was successful, now the old template with the same name can be removed if it existed
1966 if ( aTemplateToRemoveTargetURL
.getLength() )
1968 removeContent( aTemplateToRemoveTargetURL
);
1972 * if the old template was the standard template
1973 * it is necessary to change the standard template with the new file name
1975 String sStdTmplFile
= SfxObjectFactory::GetStandardTemplate( sDocServiceName
);
1976 if ( INetURLObject( sStdTmplFile
) == INetURLObject( aTemplateToRemoveTargetURL
) )
1978 SfxObjectFactory::SetStandardTemplate( sDocServiceName
, aNewTemplateTargetURL
);
1982 if ( bRemoveOldTemplateContent
)
1983 removeContent( aTemplateToRemove
);
1985 // add the template to hierarchy
1986 return addEntry( aGroup
, rTemplateName
, aNewTemplateTargetURL
, aMediaType
);
1990 // the template was not stored
1995 //-----------------------------------------------------------------------------
1996 sal_Bool
SfxDocTplService_Impl::addTemplate( const OUString
& rGroupName
,
1997 const OUString
& rTemplateName
,
1998 const OUString
& rSourceURL
)
2000 ::osl::MutexGuard
aGuard( maMutex
);
2002 // Check, wether or not there is a group with this name
2003 // Return false, if there is no group with the given name
2004 Content aGroup
, aTemplate
, aTargetGroup
;
2005 OUString aGroupURL
, aTemplateURL
;
2006 INetURLObject
aGroupObj( maRootURL
);
2008 aGroupObj
.insertName( rGroupName
, false,
2009 INetURLObject::LAST_SEGMENT
, true,
2010 INetURLObject::ENCODE_ALL
);
2011 aGroupURL
= aGroupObj
.GetMainURL( INetURLObject::NO_DECODE
);
2013 if ( ! Content::create( aGroupURL
, maCmdEnv
, aGroup
) )
2016 // Check, if there's a template with the given name in this group
2017 // Return false, if there already is a template
2018 aGroupObj
.insertName( rTemplateName
, false,
2019 INetURLObject::LAST_SEGMENT
, true,
2020 INetURLObject::ENCODE_ALL
);
2021 aTemplateURL
= aGroupObj
.GetMainURL( INetURLObject::NO_DECODE
);
2023 if ( Content::create( aTemplateURL
, maCmdEnv
, aTemplate
) )
2026 // get the target url of the group
2027 OUString aTargetURL
;
2028 OUString
aPropName( RTL_CONSTASCII_USTRINGPARAM( TARGET_DIR_URL
) );
2031 if ( getProperty( aGroup
, aPropName
, aValue
) )
2032 aValue
>>= aTargetURL
;
2034 if ( !aTargetURL
.getLength() )
2036 aTargetURL
= CreateNewGroupFsys( rGroupName
, aGroup
);
2038 if ( !aTargetURL
.getLength() )
2042 // Get the content type
2043 OUString aTitle
, aType
, aTargetURL2
, aFullName
;
2045 // only StarOffice documents are acceptable
2046 sal_Bool bDocHasTitle
= sal_False
;
2047 if( !getTitleFromURL( rSourceURL
, aTitle
, aType
, bDocHasTitle
) )
2050 INetURLObject
aSourceObj( rSourceURL
);
2051 if ( rTemplateName
.equals( aTitle
) )
2053 /////////////////////////////////////////////////////
2054 // addTemplate will sometimes be called just to add an entry in the
2055 // hierarchy; the target URL and the source URL will be the same in
2057 // TODO/LATER: get rid of this old hack
2059 INetURLObject
aTargetObj( aTargetURL
);
2061 aTargetObj
.insertName( rTemplateName
, false,
2062 INetURLObject::LAST_SEGMENT
, true,
2063 INetURLObject::ENCODE_ALL
);
2064 aTargetObj
.setExtension( aSourceObj
.getExtension() );
2066 aTargetURL2
= aTargetObj
.GetMainURL( INetURLObject::NO_DECODE
);
2068 if ( aTargetURL2
== rSourceURL
)
2069 return addEntry( aGroup
, rTemplateName
, aTargetURL2
, aType
);
2072 /////////////////////////////////////////////////////
2073 // copy the template into the new group (targeturl)
2075 INetURLObject
aTmpURL( aSourceObj
);
2076 aTmpURL
.CutExtension();
2077 ::rtl::OUString aPattern
= aTmpURL
.getName( INetURLObject::LAST_SEGMENT
, true, INetURLObject::DECODE_WITH_CHARSET
);
2079 ::rtl::OUString aNewTemplateTargetURL
= CreateNewUniqueFileWithPrefix( aTargetURL
, aPattern
, aSourceObj
.getExtension() );
2080 INetURLObject
aNewTemplateTargetObj( aNewTemplateTargetURL
);
2081 ::rtl::OUString aNewTemplateTargetName
= aNewTemplateTargetObj
.getName( INetURLObject::LAST_SEGMENT
, true, INetURLObject::DECODE_WITH_CHARSET
);
2082 if ( !aNewTemplateTargetURL
.getLength() || !aNewTemplateTargetName
.getLength() )
2085 // get access to source file
2086 Content aSourceContent
;
2087 uno::Reference
< ucb::XCommandEnvironment
> xEnv
;
2088 INetURLObject
aSourceURL( rSourceURL
);
2089 if( ! Content::create( aSourceURL
.GetMainURL( INetURLObject::NO_DECODE
), xEnv
, aSourceContent
) )
2092 if( ! Content::create( aTargetURL
, xEnv
, aTargetGroup
) )
2095 // transfer source file
2098 if( ! aTargetGroup
.transferContent( aSourceContent
,
2099 InsertOperation_COPY
,
2100 aNewTemplateTargetName
,
2101 NameClash::OVERWRITE
) )
2104 // allow to edit the added template
2105 Content aResultContent
;
2106 if ( Content::create( aNewTemplateTargetURL
, xEnv
, aResultContent
) )
2108 ::rtl::OUString
aPropertyName( RTL_CONSTASCII_USTRINGPARAM( "IsReadOnly" ) );
2110 sal_Bool bReadOnly
= sal_False
;
2111 if ( getProperty( aResultContent
, aPropertyName
, aProperty
) && ( aProperty
>>= bReadOnly
) && bReadOnly
)
2112 setProperty( aResultContent
, aPropertyName
, uno::makeAny( (sal_Bool
)sal_False
) );
2115 catch ( ContentCreationException
& )
2116 { return sal_False
; }
2117 catch ( Exception
& )
2118 { return sal_False
; }
2121 // either the document has title and it is the same as requested, or we have to set it
2122 sal_Bool bCorrectTitle
= ( bDocHasTitle
&& aTitle
.equals( rTemplateName
) );
2123 if ( !bCorrectTitle
)
2125 if ( !bDocHasTitle
)
2127 INetURLObject
aNewTmpObj( aNewTemplateTargetObj
);
2128 aNewTmpObj
.CutExtension();
2129 bCorrectTitle
= ( aNewTmpObj
.getName( INetURLObject::LAST_SEGMENT
, true, INetURLObject::DECODE_WITH_CHARSET
).equals( rTemplateName
) );
2132 if ( !bCorrectTitle
)
2133 bCorrectTitle
= setTitleForURL( aNewTemplateTargetURL
, rTemplateName
);
2136 if ( bCorrectTitle
)
2138 // create a new entry in the hierarchy
2139 return addEntry( aGroup
, rTemplateName
, aNewTemplateTargetURL
, aType
);
2142 // TODO/LATER: The user could be notified here that the renaming has failed
2143 // create a new entry in the hierarchy
2144 addEntry( aGroup
, aTitle
, aNewTemplateTargetURL
, aType
);
2148 //-----------------------------------------------------------------------------
2149 sal_Bool
SfxDocTplService_Impl::removeTemplate( const OUString
& rGroupName
,
2150 const OUString
& rTemplateName
)
2152 ::osl::MutexGuard
aGuard( maMutex
);
2154 // Check, wether or not there is a group with this name
2155 // Return false, if there is no group with the given name
2156 Content aGroup
, aTemplate
;
2157 OUString aGroupURL
, aTemplateURL
;
2158 INetURLObject
aGroupObj( maRootURL
);
2160 aGroupObj
.insertName( rGroupName
, false,
2161 INetURLObject::LAST_SEGMENT
, true,
2162 INetURLObject::ENCODE_ALL
);
2163 aGroupURL
= aGroupObj
.GetMainURL( INetURLObject::NO_DECODE
);
2165 if ( ! Content::create( aGroupURL
, maCmdEnv
, aGroup
) )
2168 // Check, if there's a template with the given name in this group
2169 // Return false, if there is no template
2170 aGroupObj
.insertName( rTemplateName
, false,
2171 INetURLObject::LAST_SEGMENT
, true,
2172 INetURLObject::ENCODE_ALL
);
2173 aTemplateURL
= aGroupObj
.GetMainURL( INetURLObject::NO_DECODE
);
2175 if ( !Content::create( aTemplateURL
, maCmdEnv
, aTemplate
) )
2178 // get the target URL from the template
2179 OUString aTargetURL
;
2180 OUString
aPropName( RTL_CONSTASCII_USTRINGPARAM( TARGET_URL
) );
2183 if ( getProperty( aTemplate
, aPropName
, aValue
) )
2184 aValue
>>= aTargetURL
;
2186 // delete the target template
2187 if ( aTargetURL
.getLength() )
2189 if ( !maTemplateDirs
.getLength()
2190 || !::utl::UCBContentHelper::IsSubPath( maTemplateDirs
[ maTemplateDirs
.getLength() - 1 ], aTargetURL
) )
2193 removeContent( aTargetURL
);
2196 // delete the template entry
2197 return removeContent( aTemplate
);
2200 //-----------------------------------------------------------------------------
2201 sal_Bool
SfxDocTplService_Impl::renameTemplate( const OUString
& rGroupName
,
2202 const OUString
& rOldName
,
2203 const OUString
& rNewName
)
2205 ::osl::MutexGuard
aGuard( maMutex
);
2207 // Check, wether or not there is a group with this name
2208 // Return false, if there is no group with the given name
2209 Content aGroup
, aTemplate
;
2210 OUString aGroupURL
, aTemplateURL
;
2211 INetURLObject
aGroupObj( maRootURL
);
2213 aGroupObj
.insertName( rGroupName
, false,
2214 INetURLObject::LAST_SEGMENT
, true,
2215 INetURLObject::ENCODE_ALL
);
2216 aGroupURL
= aGroupObj
.GetMainURL( INetURLObject::NO_DECODE
);
2218 if ( ! Content::create( aGroupURL
, maCmdEnv
, aGroup
) )
2221 // Check, if there's a template with the new name in this group
2222 // Return false, if there is one
2223 aGroupObj
.insertName( rNewName
, false,
2224 INetURLObject::LAST_SEGMENT
, true,
2225 INetURLObject::ENCODE_ALL
);
2226 aTemplateURL
= aGroupObj
.GetMainURL( INetURLObject::NO_DECODE
);
2228 if ( Content::create( aTemplateURL
, maCmdEnv
, aTemplate
) )
2231 // Check, if there's a template with the old name in this group
2232 // Return false, if there is no template
2233 aGroupObj
.removeSegment();
2234 aGroupObj
.insertName( rOldName
, false,
2235 INetURLObject::LAST_SEGMENT
, true,
2236 INetURLObject::ENCODE_ALL
);
2237 aTemplateURL
= aGroupObj
.GetMainURL( INetURLObject::NO_DECODE
);
2239 if ( !Content::create( aTemplateURL
, maCmdEnv
, aTemplate
) )
2242 OUString aTemplateTargetURL
;
2243 OUString
aTargetProp( RTL_CONSTASCII_USTRINGPARAM( TARGET_URL
) );
2246 if ( getProperty( aTemplate
, aTargetProp
, aTargetValue
) )
2247 aTargetValue
>>= aTemplateTargetURL
;
2249 if ( !setTitleForURL( aTemplateTargetURL
, rNewName
) )
2252 // rename the template entry in the cache
2253 OUString
aTitleProp( RTL_CONSTASCII_USTRINGPARAM( TITLE
) );
2255 aTitleValue
<<= rNewName
;
2257 return setProperty( aTemplate
, aTitleProp
, aTitleValue
);
2260 //-----------------------------------------------------------------------------
2261 //-----------------------------------------------------------------------------
2262 //-----------------------------------------------------------------------------
2264 SFX_IMPL_XSERVICEINFO( SfxDocTplService
, TEMPLATE_SERVICE_NAME
, TEMPLATE_IMPLEMENTATION_NAME
)
2265 SFX_IMPL_SINGLEFACTORY( SfxDocTplService
)
2267 //-----------------------------------------------------------------------------
2268 SfxDocTplService::SfxDocTplService( const uno::Reference
< XMultiServiceFactory
>& xFactory
)
2270 pImp
= new SfxDocTplService_Impl( xFactory
);
2273 //-----------------------------------------------------------------------------
2275 SfxDocTplService::~SfxDocTplService()
2280 //-----------------------------------------------------------------------------
2281 //--- XLocalizable ---
2282 //-----------------------------------------------------------------------------
2284 Locale SAL_CALL
SfxDocTplService::getLocale()
2285 throw( RUNTIMEEXCEPTION
)
2287 return pImp
->getLocale();
2290 //-----------------------------------------------------------------------------
2292 void SAL_CALL
SfxDocTplService::setLocale( const Locale
& rLocale
)
2293 throw( RUNTIMEEXCEPTION
)
2295 pImp
->setLocale( rLocale
);
2298 //-----------------------------------------------------------------------------
2299 //--- XDocumentTemplates ---
2300 //-----------------------------------------------------------------------------
2301 uno::Reference
< XCONTENT
> SAL_CALL
SfxDocTplService::getContent()
2302 throw( RUNTIMEEXCEPTION
)
2305 return pImp
->getContent().get();
2310 //-----------------------------------------------------------------------------
2311 sal_Bool SAL_CALL
SfxDocTplService::storeTemplate( const OUString
& GroupName
,
2312 const OUString
& TemplateName
,
2313 const uno::Reference
< XSTORABLE
>& Storable
)
2314 throw( RUNTIMEEXCEPTION
)
2317 return pImp
->storeTemplate( GroupName
, TemplateName
, Storable
);
2322 //-----------------------------------------------------------------------------
2323 sal_Bool SAL_CALL
SfxDocTplService::addTemplate( const OUString
& rGroupName
,
2324 const OUString
& rTemplateName
,
2325 const OUString
& rSourceURL
)
2326 throw( RUNTIMEEXCEPTION
)
2329 return pImp
->addTemplate( rGroupName
, rTemplateName
, rSourceURL
);
2334 //-----------------------------------------------------------------------------
2335 sal_Bool SAL_CALL
SfxDocTplService::removeTemplate( const OUString
& rGroupName
,
2336 const OUString
& rTemplateName
)
2337 throw( RUNTIMEEXCEPTION
)
2340 return pImp
->removeTemplate( rGroupName
, rTemplateName
);
2345 //-----------------------------------------------------------------------------
2346 sal_Bool SAL_CALL
SfxDocTplService::renameTemplate( const OUString
& rGroupName
,
2347 const OUString
& rOldName
,
2348 const OUString
& rNewName
)
2349 throw( RUNTIMEEXCEPTION
)
2351 if ( rOldName
== rNewName
)
2355 return pImp
->renameTemplate( rGroupName
, rOldName
, rNewName
);
2360 //-----------------------------------------------------------------------------
2361 sal_Bool SAL_CALL
SfxDocTplService::addGroup( const OUString
& rGroupName
)
2362 throw( RUNTIMEEXCEPTION
)
2365 return pImp
->addGroup( rGroupName
);
2370 //-----------------------------------------------------------------------------
2371 sal_Bool SAL_CALL
SfxDocTplService::removeGroup( const OUString
& rGroupName
)
2372 throw( RUNTIMEEXCEPTION
)
2375 return pImp
->removeGroup( rGroupName
);
2380 //-----------------------------------------------------------------------------
2381 sal_Bool SAL_CALL
SfxDocTplService::renameGroup( const OUString
& rOldName
,
2382 const OUString
& rNewName
)
2383 throw( RUNTIMEEXCEPTION
)
2385 if ( rOldName
== rNewName
)
2389 return pImp
->renameGroup( rOldName
, rNewName
);
2394 //-----------------------------------------------------------------------------
2395 void SAL_CALL
SfxDocTplService::update()
2396 throw( RUNTIMEEXCEPTION
)
2399 pImp
->update( sal_True
);
2402 //-----------------------------------------------------------------------------
2403 //-----------------------------------------------------------------------------
2404 //------------------------------------------------------------------------
2406 Updater_Impl::Updater_Impl( SfxDocTplService_Impl
* pTemplates
)
2408 mpDocTemplates
= pTemplates
;
2411 //------------------------------------------------------------------------
2412 Updater_Impl::~Updater_Impl()
2416 //------------------------------------------------------------------------
2417 void SAL_CALL
Updater_Impl::run()
2419 mpDocTemplates
->doUpdate();
2422 //------------------------------------------------------------------------
2423 void SAL_CALL
Updater_Impl::onTerminated()
2425 mpDocTemplates
->finished();
2429 //-----------------------------------------------------------------------------
2430 //-----------------------------------------------------------------------------
2431 //-----------------------------------------------------------------------------
2432 WaitWindow_Impl::WaitWindow_Impl()
2433 : WorkWindow( NULL
, WB_BORDER
| WB_3DLOOK
)
2435 Rectangle aRect
= Rectangle( 0, 0, 300, 30000 );
2436 _nTextStyle
= TEXT_DRAW_CENTER
| TEXT_DRAW_VCENTER
| TEXT_DRAW_WORDBREAK
| TEXT_DRAW_MULTILINE
;
2437 _aText
= String( SfxResId( RID_CNT_STR_WAITING
) );
2438 _aRect
= GetTextRect( aRect
, _aText
, _nTextStyle
);
2440 aRect
.Right() += 2*X_OFFSET
;
2441 aRect
.Bottom() += 2*Y_OFFSET
;
2442 _aRect
.SetPos( Point( X_OFFSET
, Y_OFFSET
) );
2443 SetOutputSizePixel( aRect
.GetSize() );
2449 //-----------------------------------------------------------------------------
2450 WaitWindow_Impl::~WaitWindow_Impl()
2455 //-----------------------------------------------------------------------------
2456 void WaitWindow_Impl::Paint( const Rectangle
& /*rRect*/ )
2458 DrawText( _aRect
, _aText
, _nTextStyle
);
2461 //-----------------------------------------------------------------------------
2462 //-----------------------------------------------------------------------------
2463 //-----------------------------------------------------------------------------
2464 void SfxDocTplService_Impl::addHierGroup( GroupList_Impl
& rList
,
2465 const OUString
& rTitle
,
2466 const OUString
& rOwnURL
)
2468 // now get the content of the Group
2470 uno::Reference
< XResultSet
> xResultSet
;
2471 Sequence
< OUString
> aProps(3);
2473 aProps
[0] = OUString::createFromAscii( TITLE
);
2474 aProps
[1] = OUString::createFromAscii( TARGET_URL
);
2475 aProps
[2] = OUString::createFromAscii( PROPERTY_TYPE
);
2479 aContent
= Content( rOwnURL
, maCmdEnv
);
2480 ResultSetInclude eInclude
= INCLUDE_DOCUMENTS_ONLY
;
2481 xResultSet
= aContent
.createCursor( aProps
, eInclude
);
2483 catch ( ContentCreationException
& )
2485 DBG_ERRORFILE( "addHierGroup: ContentCreationException" );
2487 catch ( Exception
& ) {}
2489 if ( xResultSet
.is() )
2491 GroupData_Impl
*pGroup
= new GroupData_Impl( rTitle
);
2492 pGroup
->setHierarchy( sal_True
);
2493 pGroup
->setHierarchyURL( rOwnURL
);
2494 rList
.Insert( pGroup
);
2496 uno::Reference
< XContentAccess
> xContentAccess( xResultSet
, UNO_QUERY
);
2497 uno::Reference
< XRow
> xRow( xResultSet
, UNO_QUERY
);
2501 while ( xResultSet
->next() )
2503 BOOL bUpdateType
= sal_False
;
2504 DocTemplates_EntryData_Impl
*pData
;
2506 OUString
aTitle( xRow
->getString( 1 ) );
2507 OUString
aTargetDir( xRow
->getString( 2 ) );
2508 OUString
aType( xRow
->getString( 3 ) );
2509 OUString aHierURL
= xContentAccess
->queryContentIdentifierString();
2511 if ( !aType
.getLength() )
2515 sal_Bool bDocHasTitle
= sal_False
;
2516 if( !getTitleFromURL( aTargetDir
, aTmpTitle
, aType
, bDocHasTitle
) )
2518 DBG_ERRORFILE( "addHierGroup(): template of alien format" );
2522 if ( aType
.getLength() )
2523 bUpdateType
= sal_True
;
2526 pData
= pGroup
->addEntry( aTitle
, aTargetDir
, aType
, aHierURL
);
2527 pData
->setUpdateType( bUpdateType
);
2530 catch ( Exception
& ) {}
2534 //-----------------------------------------------------------------------------
2535 void SfxDocTplService_Impl::addFsysGroup( GroupList_Impl
& rList
,
2536 const OUString
& rTitle
,
2537 const OUString
& rUITitle
,
2538 const OUString
& rOwnURL
,
2539 sal_Bool bWriteableGroup
)
2541 ::rtl::OUString aTitle
;
2543 if ( !rUITitle
.getLength() )
2545 // reserved FS names that should not be used
2546 if ( rTitle
.compareToAscii( "wizard" ) == 0 )
2548 else if ( rTitle
.compareToAscii( "internal" ) == 0 )
2551 aTitle
= getLongName( rTitle
);
2556 if ( !aTitle
.getLength() )
2559 GroupData_Impl
*pGroup
= rList
.First();
2561 while ( pGroup
&& pGroup
->getTitle() != aTitle
)
2562 pGroup
= rList
.Next();
2566 pGroup
= new GroupData_Impl( aTitle
);
2567 rList
.Insert( pGroup
);
2570 if ( bWriteableGroup
)
2571 pGroup
->setTargetURL( rOwnURL
);
2575 // now get the content of the Group
2577 uno::Reference
< XResultSet
> xResultSet
;
2578 Sequence
< OUString
> aProps(1);
2579 aProps
[0] = OUString::createFromAscii( TITLE
);
2583 // this method is only used during checking of the available template-folders
2584 // that should happen quietly
2585 uno::Reference
< XCommandEnvironment
> aQuietEnv
;
2586 aContent
= Content( rOwnURL
, aQuietEnv
);
2587 ResultSetInclude eInclude
= INCLUDE_DOCUMENTS_ONLY
;
2588 xResultSet
= aContent
.createCursor( aProps
, eInclude
);
2590 catch ( Exception
& ) {}
2592 if ( xResultSet
.is() )
2594 uno::Reference
< XContentAccess
> xContentAccess( xResultSet
, UNO_QUERY
);
2595 uno::Reference
< XRow
> xRow( xResultSet
, UNO_QUERY
);
2599 while ( xResultSet
->next() )
2601 OUString
aChildTitle( xRow
->getString( 1 ) );
2602 OUString aTargetURL
= xContentAccess
->queryContentIdentifierString();
2606 if ( aChildTitle
.compareToAscii( "sfx.tlx" ) == 0
2607 || aChildTitle
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "groupuinames.xml" ) ) )
2610 // only StarOffice templates are accepted
2611 sal_Bool bDocHasTitle
= sal_False
;
2612 if( !getTitleFromURL( aTargetURL
, aChildTitle
, aType
, bDocHasTitle
) )
2615 pGroup
->addEntry( aChildTitle
, aTargetURL
, aType
, aHierURL
);
2618 catch ( Exception
& ) {}
2622 // -----------------------------------------------------------------------
2623 void SfxDocTplService_Impl::createFromContent( GroupList_Impl
& rList
,
2625 sal_Bool bHierarchy
,
2626 sal_Bool bWriteableContent
)
2628 OUString aTargetURL
= rContent
.get()->getIdentifier()->getContentIdentifier();
2630 // when scanning the file system, we have to add the 'standard' group, too
2633 OUString aUIStdTitle
= getLongName( OUString( RTL_CONSTASCII_USTRINGPARAM( STANDARD_FOLDER
) ) );
2634 addFsysGroup( rList
, ::rtl::OUString(), aUIStdTitle
, aTargetURL
, bWriteableContent
);
2637 // search for predefined UI names
2638 INetURLObject
aLayerObj( aTargetURL
);
2640 // TODO/LATER: Use hashmap in future
2641 uno::Sequence
< beans::StringPair
> aUINames
;
2643 aUINames
= ReadUINamesForTemplateDir_Impl( aLayerObj
.GetMainURL( INetURLObject::NO_DECODE
) );
2645 uno::Reference
< XResultSet
> xResultSet
;
2646 Sequence
< OUString
> aProps(1);
2647 aProps
[0] = OUString::createFromAscii( TITLE
);
2651 ResultSetInclude eInclude
= INCLUDE_FOLDERS_ONLY
;
2652 xResultSet
= rContent
.createCursor( aProps
, eInclude
);
2654 catch ( Exception
& ) {}
2656 if ( xResultSet
.is() )
2658 uno::Reference
< XContentAccess
> xContentAccess( xResultSet
, UNO_QUERY
);
2659 uno::Reference
< XRow
> xRow( xResultSet
, UNO_QUERY
);
2663 while ( xResultSet
->next() )
2665 // TODO/LATER: clarify the encoding of the Title
2666 OUString
aTitle( xRow
->getString( 1 ) );
2667 OUString
aTargetSubfolderURL( xContentAccess
->queryContentIdentifierString() );
2670 addHierGroup( rList
, aTitle
, aTargetSubfolderURL
);
2673 ::rtl::OUString aUITitle
;
2674 for ( sal_Int32 nInd
= 0; nInd
< aUINames
.getLength(); nInd
++ )
2675 if ( aUINames
[nInd
].First
.equals( aTitle
) )
2677 aUITitle
= aUINames
[nInd
].Second
;
2681 addFsysGroup( rList
, aTitle
, aUITitle
, aTargetSubfolderURL
, bWriteableContent
);
2685 catch ( Exception
& ) {}
2689 //-----------------------------------------------------------------------------
2690 void SfxDocTplService_Impl::removeFromHierarchy( DocTemplates_EntryData_Impl
*pData
)
2694 if ( Content::create( pData
->getHierarchyURL(), maCmdEnv
, aTemplate
) )
2696 removeContent( aTemplate
);
2700 //-----------------------------------------------------------------------------
2701 void SfxDocTplService_Impl::addToHierarchy( GroupData_Impl
*pGroup
,
2702 DocTemplates_EntryData_Impl
*pData
)
2704 Content aGroup
, aTemplate
;
2706 if ( ! Content::create( pGroup
->getHierarchyURL(), maCmdEnv
, aGroup
) )
2709 // Check, if there's a template with the given name in this group
2710 // Return if there is already a template
2711 INetURLObject
aGroupObj( pGroup
->getHierarchyURL() );
2713 aGroupObj
.insertName( pData
->getTitle(), false,
2714 INetURLObject::LAST_SEGMENT
, true,
2715 INetURLObject::ENCODE_ALL
);
2717 OUString aTemplateURL
= aGroupObj
.GetMainURL( INetURLObject::NO_DECODE
);
2719 if ( Content::create( aTemplateURL
, maCmdEnv
, aTemplate
) )
2722 addEntry( aGroup
, pData
->getTitle(),
2723 pData
->getTargetURL(),
2727 //-----------------------------------------------------------------------------
2728 void SfxDocTplService_Impl::updateData( DocTemplates_EntryData_Impl
*pData
)
2732 if ( ! Content::create( pData
->getHierarchyURL(), maCmdEnv
, aTemplate
) )
2737 if ( pData
->getUpdateType() )
2739 aPropName
= OUString( RTL_CONSTASCII_USTRINGPARAM( PROPERTY_TYPE
) );
2740 setProperty( aTemplate
, aPropName
, makeAny( pData
->getType() ) );
2743 if ( pData
->getUpdateLink() )
2745 aPropName
= OUString( RTL_CONSTASCII_USTRINGPARAM( TARGET_URL
) );
2746 setProperty( aTemplate
, aPropName
, makeAny( pData
->getTargetURL() ) );
2750 //-----------------------------------------------------------------------------
2751 void SfxDocTplService_Impl::addGroupToHierarchy( GroupData_Impl
*pGroup
)
2753 OUString
aAdditionalProp( RTL_CONSTASCII_USTRINGPARAM( TARGET_DIR_URL
) );
2756 INetURLObject
aNewGroupObj( maRootURL
);
2757 aNewGroupObj
.insertName( pGroup
->getTitle(), false,
2758 INetURLObject::LAST_SEGMENT
, true,
2759 INetURLObject::ENCODE_ALL
);
2761 OUString aNewGroupURL
= aNewGroupObj
.GetMainURL( INetURLObject::NO_DECODE
);
2763 if ( createFolder( aNewGroupURL
, sal_False
, sal_False
, aGroup
) )
2765 setProperty( aGroup
, aAdditionalProp
, makeAny( pGroup
->getTargetURL() ) );
2766 pGroup
->setHierarchyURL( aNewGroupURL
);
2768 ULONG nCount
= pGroup
->count();
2769 for ( ULONG i
=0; i
<nCount
; i
++ )
2771 DocTemplates_EntryData_Impl
*pData
= pGroup
->getEntry( i
);
2772 addToHierarchy( pGroup
, pData
); // add entry to hierarchy
2777 //-----------------------------------------------------------------------------
2778 void SfxDocTplService_Impl::removeFromHierarchy( GroupData_Impl
*pGroup
)
2782 if ( Content::create( pGroup
->getHierarchyURL(), maCmdEnv
, aGroup
) )
2784 removeContent( aGroup
);
2788 // -----------------------------------------------------------------------
2789 // -----------------------------------------------------------------------
2790 // -----------------------------------------------------------------------
2791 GroupData_Impl::GroupData_Impl( const OUString
& rTitle
)
2794 mbInUse
= sal_False
;
2795 mbInHierarchy
= sal_False
;
2798 // -----------------------------------------------------------------------
2799 GroupData_Impl::~GroupData_Impl()
2801 DocTemplates_EntryData_Impl
*pData
= maEntries
.First();
2805 pData
= maEntries
.Next();
2809 // -----------------------------------------------------------------------
2810 DocTemplates_EntryData_Impl
* GroupData_Impl::addEntry( const OUString
& rTitle
,
2811 const OUString
& rTargetURL
,
2812 const OUString
& rType
,
2813 const OUString
& rHierURL
)
2815 DocTemplates_EntryData_Impl
*pData
= maEntries
.First();
2817 while ( pData
&& pData
->getTitle() != rTitle
)
2818 pData
= maEntries
.Next();
2822 pData
= new DocTemplates_EntryData_Impl( rTitle
);
2823 pData
->setTargetURL( rTargetURL
);
2824 pData
->setType( rType
);
2825 if ( rHierURL
.getLength() )
2827 pData
->setHierarchyURL( rHierURL
);
2828 pData
->setHierarchy( sal_True
);
2830 maEntries
.Insert( pData
);
2834 if ( rHierURL
.getLength() )
2836 pData
->setHierarchyURL( rHierURL
);
2837 pData
->setHierarchy( sal_True
);
2840 if ( pData
->getInHierarchy() )
2843 if ( rTargetURL
!= pData
->getTargetURL() )
2845 pData
->setTargetURL( rTargetURL
);
2846 pData
->setUpdateLink( sal_True
);
2853 // -----------------------------------------------------------------------
2854 // -----------------------------------------------------------------------
2855 // -----------------------------------------------------------------------
2856 DocTemplates_EntryData_Impl::DocTemplates_EntryData_Impl( const OUString
& rTitle
)
2859 mbInUse
= sal_False
;
2860 mbInHierarchy
= sal_False
;
2861 mbUpdateType
= sal_False
;
2862 mbUpdateLink
= sal_False
;
2865 // -----------------------------------------------------------------------
2866 SfxURLRelocator_Impl::SfxURLRelocator_Impl( uno::Reference
< XMultiServiceFactory
> xFactory
)
2867 : mxFactory( xFactory
)
2871 // -----------------------------------------------------------------------
2872 SfxURLRelocator_Impl::~SfxURLRelocator_Impl()
2876 // -----------------------------------------------------------------------
2877 void SfxURLRelocator_Impl::initOfficeInstDirs()
2879 if ( !mxOfficeInstDirs
.is() )
2881 osl::MutexGuard
aGuard( maMutex
);
2882 if ( !mxOfficeInstDirs
.is() )
2884 OSL_ENSURE( mxFactory
.is(), "No service manager!" );
2886 uno::Reference
< XComponentContext
> xCtx
;
2887 uno::Reference
< XPropertySet
> xPropSet( mxFactory
, UNO_QUERY
);
2888 if ( xPropSet
.is() )
2890 xPropSet
->getPropertyValue(
2892 RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ) ) )
2896 OSL_ENSURE( xCtx
.is(),
2897 "Unable to obtain component context from "
2898 "service manager!" );
2902 xCtx
->getValueByName(
2903 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
2905 "com.sun.star.util.theOfficeInstallationDirectories" ) ) )
2906 >>= mxOfficeInstDirs
;
2909 OSL_ENSURE( mxOfficeInstDirs
.is(),
2910 "Unable to obtain office installation directory "
2916 // -----------------------------------------------------------------------
2917 void SfxURLRelocator_Impl::makeRelocatableURL( rtl::OUString
& rURL
)
2919 if ( rURL
.getLength() > 0 )
2921 initOfficeInstDirs();
2922 rURL
= mxOfficeInstDirs
->makeRelocatableURL( rURL
);
2926 // -----------------------------------------------------------------------
2927 void SfxURLRelocator_Impl::makeAbsoluteURL( rtl::OUString
& rURL
)
2929 if ( rURL
.getLength() > 0 )
2931 initOfficeInstDirs();
2932 rURL
= mxOfficeInstDirs
->makeAbsoluteURL( rURL
);