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>
77 #include <sfx2/docfile.hxx>
80 //-----------------------------------------------------------------------------
82 //=============================================================================
84 #define TEMPLATE_SERVICE_NAME "com.sun.star.frame.DocumentTemplates"
85 #define TEMPLATE_IMPLEMENTATION_NAME "com.sun.star.comp.sfx2.DocumentTemplates"
87 #define SERVICENAME_TYPEDETECTION "com.sun.star.document.TypeDetection"
88 #define SERVICENAME_DOCINFO "com.sun.star.document.StandaloneDocumentInfo"
90 #define TEMPLATE_ROOT_URL "vnd.sun.star.hier:/templates"
92 #define IS_FOLDER "IsFolder"
93 #define IS_DOCUMENT "IsDocument"
94 #define TARGET_URL "TargetURL"
95 #define TEMPLATE_VERSION "TemplateComponentVersion"
96 #define TEMPLATE_VERSION_VALUE "2"
97 #define TYPE_FOLDER "application/vnd.sun.star.hier-folder"
98 #define TYPE_LINK "application/vnd.sun.star.hier-link"
99 #define TYPE_FSYS_FOLDER "application/vnd.sun.staroffice.fsys-folder"
100 #define TYPE_FSYS_FILE "application/vnd.sun.staroffice.fsys-file"
102 #define PROPERTY_DIRLIST "DirectoryList"
103 #define PROPERTY_NEEDSUPDATE "NeedsUpdate"
104 #define PROPERTY_TYPE "TypeDescription"
106 #define TARGET_DIR_URL "TargetDirURL"
107 #define COMMAND_DELETE "delete"
108 #define COMMAND_TRANSFER "transfer"
110 #define STANDARD_FOLDER "standard"
114 //=============================================================================
116 using namespace ::com::sun::star
;
117 using namespace ::com::sun::star::beans
;
118 using namespace ::com::sun::star::document
;
119 using namespace ::com::sun::star::io
;
120 using namespace ::com::sun::star::lang
;
121 using namespace ::com::sun::star::sdbc
;
122 using namespace ::com::sun::star::ucb
;
123 using namespace ::com::sun::star::uno
;
124 using namespace ::com::sun::star::container
;
125 using namespace ::com::sun::star::util
;
127 using namespace ::rtl
;
128 using namespace ::ucbhelper
;
129 using namespace ::comphelper
;
131 //=============================================================================
133 class WaitWindow_Impl
: public WorkWindow
142 virtual void Paint( const Rectangle
& rRect
);
148 //=============================================================================
152 OUString maShortName
;
156 DECLARE_LIST( NameList_Impl
, NamePair_Impl
* )
159 class GroupList_Impl
;
160 class DocTemplates_EntryData_Impl
;
161 class GroupData_Impl
;
163 //=============================================================================
164 #include <com/sun/star/task/XInteractionHandler.hpp>
165 #include <com/sun/star/ucb/XProgressHandler.hpp>
166 #include <com/sun/star/ucb/XCommandEnvironment.hpp>
168 class TplTaskEnvironment
: public ::cppu::WeakImplHelper1
< ucb::XCommandEnvironment
>
170 uno::Reference
< task::XInteractionHandler
> m_xInteractionHandler
;
171 uno::Reference
< ucb::XProgressHandler
> m_xProgressHandler
;
174 TplTaskEnvironment( const uno::Reference
< task::XInteractionHandler
>& rxInteractionHandler
)
175 : m_xInteractionHandler( rxInteractionHandler
)
178 virtual uno::Reference
<task::XInteractionHandler
> SAL_CALL
getInteractionHandler() throw (uno::RuntimeException
)
179 { return m_xInteractionHandler
; }
181 virtual uno::Reference
<ucb::XProgressHandler
> SAL_CALL
getProgressHandler() throw (uno::RuntimeException
)
182 { return m_xProgressHandler
; }
185 class SfxDocTplService_Impl
187 uno::Reference
< XMultiServiceFactory
> mxFactory
;
188 uno::Reference
< XCommandEnvironment
> maCmdEnv
;
189 uno::Reference
< XStandaloneDocumentInfo
> mxInfo
;
190 uno::Reference
< XTypeDetection
> mxType
;
192 ::osl::Mutex maMutex
;
193 Sequence
< OUString
> maTemplateDirs
;
195 NameList_Impl maNames
;
197 Content maRootContent
;
198 Updater_Impl
* mpUpdater
;
199 sal_Bool mbIsInitialized
: 1;
200 sal_Bool mbLocaleSet
: 1;
202 SfxURLRelocator_Impl maRelocator
;
205 void getDefaultLocale();
207 void readFolderList();
208 sal_Bool
needsUpdate();
209 OUString
getLongName( const OUString
& rShortName
);
210 sal_Bool
setTitleForURL( const OUString
& rURL
, const OUString
& aTitle
);
211 sal_Bool
getTitleFromURL( const OUString
& rURL
, OUString
& aTitle
, OUString
& aType
, sal_Bool
& bDocHasTitle
);
213 sal_Bool
addEntry( Content
& rParentFolder
,
214 const OUString
& rTitle
,
215 const OUString
& rTargetURL
,
216 const OUString
& rType
);
218 sal_Bool
createFolder( const OUString
& rNewFolderURL
,
219 sal_Bool bCreateParent
,
220 sal_Bool bFsysFolder
,
221 Content
&rNewFolder
);
223 sal_Bool
CreateNewUniqueFolderWithPrefix( const ::rtl::OUString
& aPath
,
224 const ::rtl::OUString
& aPrefix
,
225 ::rtl::OUString
& aNewFolderName
,
226 ::rtl::OUString
& aNewFolderURL
,
227 Content
& aNewFolder
);
228 ::rtl::OUString
CreateNewUniqueFileWithPrefix( const ::rtl::OUString
& aPath
,
229 const ::rtl::OUString
& aPrefix
,
230 const ::rtl::OUString
& aExt
);
232 uno::Sequence
< beans::StringPair
> ReadUINamesForTemplateDir_Impl( const ::rtl::OUString
& aUserPath
);
233 sal_Bool
UpdateUINamesForTemplateDir_Impl( const ::rtl::OUString
& aUserPath
,
234 const ::rtl::OUString
& aGroupName
,
235 const ::rtl::OUString
& aNewFolderName
);
236 sal_Bool
ReplaceUINamesForTemplateDir_Impl( const ::rtl::OUString
& aUserPath
,
237 const ::rtl::OUString
& aFsysGroupName
,
238 const ::rtl::OUString
& aOldGroupName
,
239 const ::rtl::OUString
& aNewGroupName
);
240 sal_Bool
RemoveUINamesForTemplateDir_Impl( const ::rtl::OUString
& aUserPath
,
241 const ::rtl::OUString
& aGroupName
);
242 sal_Bool
WriteUINamesForTemplateDir_Impl( const ::rtl::OUString
& aUserPath
,
243 const uno::Sequence
< beans::StringPair
>& aUINames
);
245 ::rtl::OUString
CreateNewGroupFsys( const ::rtl::OUString
& rGroupName
, Content
& aGroup
);
247 sal_Bool
removeContent( Content
& rContent
);
248 sal_Bool
removeContent( const OUString
& rContentURL
);
250 sal_Bool
setProperty( Content
& rContent
,
251 const OUString
& rPropName
,
252 const Any
& rPropValue
);
253 sal_Bool
getProperty( Content
& rContent
,
254 const OUString
& rPropName
,
257 void createFromContent( GroupList_Impl
& rList
,
260 sal_Bool bWriteableContent
= sal_False
);
261 void addHierGroup( GroupList_Impl
& rList
,
262 const OUString
& rTitle
,
263 const OUString
& rOwnURL
);
264 void addFsysGroup( GroupList_Impl
& rList
,
265 const OUString
& rTitle
,
266 const OUString
& rUITitle
,
267 const OUString
& rOwnURL
,
268 sal_Bool bWriteableGroup
= sal_False
);
269 void removeFromHierarchy( DocTemplates_EntryData_Impl
*pData
);
270 void addToHierarchy( GroupData_Impl
*pGroup
,
271 DocTemplates_EntryData_Impl
*pData
);
273 void removeFromHierarchy( GroupData_Impl
*pGroup
);
274 void addGroupToHierarchy( GroupData_Impl
*pGroup
);
276 void updateData( DocTemplates_EntryData_Impl
*pData
);
279 SfxDocTplService_Impl( uno::Reference
< XMultiServiceFactory
> xFactory
);
280 ~SfxDocTplService_Impl();
282 sal_Bool
init() { if ( !mbIsInitialized
) init_Impl(); return mbIsInitialized
; }
283 Content
getContent() { return maRootContent
; }
285 void setLocale( const Locale
& rLocale
);
288 sal_Bool
storeTemplate( const OUString
& rGroupName
,
289 const OUString
& rTemplateName
,
290 const uno::Reference
< XSTORABLE
>& rStorable
);
292 sal_Bool
addTemplate( const OUString
& rGroupName
,
293 const OUString
& rTemplateName
,
294 const OUString
& rSourceURL
);
295 sal_Bool
removeTemplate( const OUString
& rGroupName
,
296 const OUString
& rTemplateName
);
297 sal_Bool
renameTemplate( const OUString
& rGroupName
,
298 const OUString
& rOldName
,
299 const OUString
& rNewName
);
301 sal_Bool
addGroup( const OUString
& rGroupName
);
302 sal_Bool
removeGroup( const OUString
& rGroupName
);
303 sal_Bool
renameGroup( const OUString
& rOldName
,
304 const OUString
& rNewName
);
306 void update( sal_Bool bUpdateNow
);
308 void finished() { mpUpdater
= NULL
; }
311 //=============================================================================
313 class Updater_Impl
: public ::vos::OThread
316 SfxDocTplService_Impl
*mpDocTemplates
;
319 Updater_Impl( SfxDocTplService_Impl
* pTemplates
);
322 virtual void SAL_CALL
run();
323 virtual void SAL_CALL
onTerminated();
326 //=============================================================================
328 class DocTemplates_EntryData_Impl
332 OUString maTargetURL
;
333 OUString maHierarchyURL
;
335 sal_Bool mbInHierarchy
: 1;
336 sal_Bool mbInUse
: 1;
337 sal_Bool mbUpdateType
: 1;
338 sal_Bool mbUpdateLink
: 1;
341 DocTemplates_EntryData_Impl( const OUString
& rTitle
);
343 void setInUse() { mbInUse
= sal_True
; }
344 void setHierarchy( sal_Bool bInHierarchy
) { mbInHierarchy
= bInHierarchy
; }
345 void setUpdateLink( sal_Bool bUpdateLink
) { mbUpdateLink
= bUpdateLink
; }
346 void setUpdateType( sal_Bool bUpdateType
) { mbUpdateType
= bUpdateType
; }
348 sal_Bool
getInUse() const { return mbInUse
; }
349 sal_Bool
getInHierarchy() const { return mbInHierarchy
; }
350 sal_Bool
getUpdateLink() const { return mbUpdateLink
; }
351 sal_Bool
getUpdateType() const { return mbUpdateType
; }
353 const OUString
& getHierarchyURL() const { return maHierarchyURL
; }
354 const OUString
& getTargetURL() const { return maTargetURL
; }
355 const OUString
& getTitle() const { return maTitle
; }
356 const OUString
& getType() const { return maType
; }
358 void setHierarchyURL( const OUString
& rURL
) { maHierarchyURL
= rURL
; }
359 void setTargetURL( const OUString
& rURL
) { maTargetURL
= rURL
; }
360 void setType( const OUString
& rType
) { maType
= rType
; }
363 //=============================================================================
367 DECLARE_LIST( EntryList_Impl
, DocTemplates_EntryData_Impl
* )
368 EntryList_Impl maEntries
;
370 OUString maHierarchyURL
;
371 OUString maTargetURL
;
372 sal_Bool mbInUse
: 1;
373 sal_Bool mbInHierarchy
: 1;
376 GroupData_Impl( const OUString
& rTitle
);
379 void setInUse() { mbInUse
= sal_True
; }
380 void setHierarchy( sal_Bool bInHierarchy
) { mbInHierarchy
= bInHierarchy
; }
381 void setHierarchyURL( const OUString
& rURL
) { maHierarchyURL
= rURL
; }
382 void setTargetURL( const OUString
& rURL
) { maTargetURL
= rURL
; }
384 sal_Bool
getInUse() { return mbInUse
; }
385 sal_Bool
getInHierarchy() { return mbInHierarchy
; }
386 const OUString
& getHierarchyURL() const { return maHierarchyURL
; }
387 const OUString
& getTargetURL() const { return maTargetURL
; }
388 const OUString
& getTitle() const { return maTitle
; }
390 DocTemplates_EntryData_Impl
* addEntry( const OUString
& rTitle
,
391 const OUString
& rTargetURL
,
392 const OUString
& rType
,
393 const OUString
& rHierURL
);
394 ULONG
count() { return maEntries
.Count(); }
395 DocTemplates_EntryData_Impl
* getEntry( ULONG nPos
) { return maEntries
.GetObject( nPos
); }
398 DECLARE_LIST( GroupList_Impl
, GroupData_Impl
* )
400 //=============================================================================
401 //=============================================================================
402 //=============================================================================
404 //-----------------------------------------------------------------------------
405 // private SfxDocTplService_Impl
406 //-----------------------------------------------------------------------------
407 void SfxDocTplService_Impl::init_Impl()
409 uno::Reference
< lang::XMultiServiceFactory
> xFactory
= ::comphelper::getProcessServiceFactory();
412 uno::Reference
< task::XInteractionHandler
> xInteractionHandler( xFactory
->createInstance( DEFINE_CONST_UNICODE("com.sun.star.task.InteractionHandler") ), uno::UNO_QUERY
);
413 maCmdEnv
= new TplTaskEnvironment( xInteractionHandler
);
416 ::osl::ClearableMutexGuard
aGuard( maMutex
);
417 sal_Bool bIsInitialized
= sal_False
;
418 sal_Bool bNeedsUpdate
= sal_False
;
423 // convert locale to string
424 OUString aLang
= maLocale
.Language
;
425 aLang
+= String( '-' );
426 aLang
+= maLocale
.Country
;
428 // set maRootContent to the root of the templates hierarchy. Create the
429 // entry if necessary
431 maRootURL
= OUString( RTL_CONSTASCII_USTRINGPARAM( TEMPLATE_ROOT_URL
) );
432 maRootURL
+= String( '/' );
435 ::rtl::OUString
aTemplVersPropName( RTL_CONSTASCII_USTRINGPARAM( TEMPLATE_VERSION
) );
436 ::rtl::OUString
aTemplVers( RTL_CONSTASCII_USTRINGPARAM( TEMPLATE_VERSION_VALUE
) );
437 if ( Content::create( maRootURL
, maCmdEnv
, maRootContent
) )
440 ::rtl::OUString aPropValue
;
441 if ( getProperty( maRootContent
, aTemplVersPropName
, aValue
)
442 && ( aValue
>>= aPropValue
)
443 && aPropValue
.equals( aTemplVers
) )
445 bIsInitialized
= sal_True
;
448 removeContent( maRootContent
);
451 if ( !bIsInitialized
)
453 if ( createFolder( maRootURL
, sal_True
, sal_False
, maRootContent
)
454 && setProperty( maRootContent
, aTemplVersPropName
, uno::makeAny( aTemplVers
) ) )
455 bIsInitialized
= sal_True
;
457 bNeedsUpdate
= sal_True
;
460 if ( bIsInitialized
)
462 OUString
aService( RTL_CONSTASCII_USTRINGPARAM( SERVICENAME_DOCINFO
) );
464 mxInfo
= uno::Reference
< XStandaloneDocumentInfo
> (
465 mxFactory
->createInstance( aService
), UNO_QUERY
);
466 } catch (uno::RuntimeException
&) {
467 OSL_ENSURE(false, "SfxDocTplService_Impl::init_Impl: "
468 "cannot create DocumentProperties service");
471 aService
= OUString( RTL_CONSTASCII_USTRINGPARAM( SERVICENAME_TYPEDETECTION
) );
472 mxType
= uno::Reference
< XTypeDetection
> ( mxFactory
->createInstance( aService
), UNO_QUERY
);
480 ::vos::OClearableGuard
aSolarGuard( Application::GetSolarMutex() );
482 WaitWindow_Impl
* pWin
= new WaitWindow_Impl();
485 ::osl::ClearableMutexGuard
anotherGuard( maMutex
);
489 anotherGuard
.clear();
490 ::vos::OGuard
aSecondSolarGuard( Application::GetSolarMutex() );
494 else if ( needsUpdate() )
495 // the UI should be shown only on the first update
500 DBG_ERRORFILE( "init_Impl(): Could not create root" );
503 mbIsInitialized
= bIsInitialized
;
506 //-----------------------------------------------------------------------------
507 void SfxDocTplService_Impl::getDefaultLocale()
511 ::osl::MutexGuard
aGuard( maMutex
);
514 rtl::OUString aLocale
;
515 utl::ConfigManager::GetDirectConfigProperty( utl::ConfigManager::LOCALE
)
518 if ( aLocale
.getLength() > 0 )
520 sal_Int32 nPos
= aLocale
.indexOf( sal_Unicode( '-' ) );
523 maLocale
.Language
= aLocale
.copy( 0, nPos
);
524 nPos
= aLocale
.indexOf( sal_Unicode( '_' ), nPos
+ 1 );
528 = aLocale
.copy( maLocale
.Language
.getLength() + 1,
529 nPos
- maLocale
.Language
.getLength() - 1 );
531 = aLocale
.copy( nPos
+ 1 );
536 = aLocale
.copy( maLocale
.Language
.getLength() + 1 );
542 mbLocaleSet
= sal_True
;
547 // -----------------------------------------------------------------------
548 void SfxDocTplService_Impl::readFolderList()
550 ::vos::OGuard
aGuard( Application::GetSolarMutex() );
552 ResStringArray
aShortNames( SfxResId( TEMPLATE_SHORT_NAMES_ARY
) );
553 ResStringArray
aLongNames( SfxResId( TEMPLATE_LONG_NAMES_ARY
) );
555 NamePair_Impl
* pPair
;
557 USHORT nCount
= (USHORT
)( Min( aShortNames
.Count(), aLongNames
.Count() ) );
559 for ( USHORT i
=0; i
<nCount
; i
++ )
561 pPair
= new NamePair_Impl
;
562 pPair
->maShortName
= aShortNames
.GetString( i
);
563 pPair
->maLongName
= aLongNames
.GetString( i
);
565 maNames
.Insert( pPair
, LIST_APPEND
);
569 // -----------------------------------------------------------------------
570 OUString
SfxDocTplService_Impl::getLongName( const OUString
& rShortName
)
573 NamePair_Impl
*pPair
= maNames
.First();
577 if ( pPair
->maShortName
== rShortName
)
579 aRet
= pPair
->maLongName
;
583 pPair
= maNames
.Next();
586 if ( !aRet
.getLength() )
592 //-----------------------------------------------------------------------------
593 void SfxDocTplService_Impl::getDirList()
595 OUString
aPropName( RTL_CONSTASCII_USTRINGPARAM( PROPERTY_DIRLIST
) );
598 // Get the template dir list
599 // TODO/LATER: let use service, register listener
601 String aDirs
= SvtPathOptions().GetTemplatePath();
602 USHORT nCount
= aDirs
.GetTokenCount( C_DELIM
);
604 maTemplateDirs
= Sequence
< OUString
>( nCount
);
606 uno::Reference
< XComponentContext
> xCtx
;
607 uno::Reference
< util::XMacroExpander
> xExpander
;
608 uno::Reference
< XPropertySet
> xPropSet( mxFactory
, UNO_QUERY
);
609 const rtl::OUString
aPrefix(
610 RTL_CONSTASCII_USTRINGPARAM( "vnd.sun.star.expand:" ) );
614 xPropSet
->getPropertyValue(
616 RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ) ) )
622 xCtx
->getValueByName(
623 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
624 "/singletons/com.sun.star.util.theMacroExpander" ) ) )
627 OSL_ENSURE( xExpander
.is(),
628 "Unable to obtain macro expander singleton!" );
631 for ( USHORT i
=0; i
<nCount
; i
++ )
633 aURL
.SetSmartProtocol( INET_PROT_FILE
);
634 aURL
.SetURL( aDirs
.GetToken( i
, C_DELIM
) );
635 maTemplateDirs
[i
] = aURL
.GetMainURL( INetURLObject::NO_DECODE
);
637 sal_Int32 nIndex
= maTemplateDirs
[i
].indexOf( aPrefix
);
638 if ( nIndex
!= -1 && xExpander
.is() )
640 maTemplateDirs
[i
] = maTemplateDirs
[i
].replaceAt(nIndex
,
643 maTemplateDirs
[i
] = xExpander
->expandMacros( maTemplateDirs
[i
] );
647 aValue
<<= maTemplateDirs
;
649 // Store the template dir list
650 setProperty( maRootContent
, aPropName
, aValue
);
653 //-----------------------------------------------------------------------------
654 sal_Bool
SfxDocTplService_Impl::needsUpdate()
656 OUString
aPropName( RTL_CONSTASCII_USTRINGPARAM( PROPERTY_NEEDSUPDATE
) );
657 sal_Bool bHasProperty
= sal_False
;
658 sal_Bool bNeedsUpdate
= sal_True
;
661 // Get the template dir list
662 bHasProperty
= getProperty( maRootContent
, aPropName
, aValue
);
665 aValue
>>= bNeedsUpdate
;
667 // the old template component also checks this state, but it is initialized from this component
668 // so if this componend was already updated the old component does not need such an update
669 ::svt::TemplateFolderCache aTempCache
;
671 bNeedsUpdate
= aTempCache
.needsUpdate();
674 aTempCache
.storeState();
679 // -----------------------------------------------------------------------
680 sal_Bool
SfxDocTplService_Impl::setTitleForURL( const OUString
& rURL
, const OUString
& aTitle
)
682 sal_Bool bResult
= sal_False
;
687 mxInfo
->loadFromURL( rURL
);
688 uno::Reference
< XPropertySet
> xPropSet( mxInfo
, UNO_QUERY_THROW
);
689 OUString
aPropName( RTL_CONSTASCII_USTRINGPARAM( TITLE
) );
690 xPropSet
->setPropertyValue( aPropName
, uno::makeAny( aTitle
) );
691 mxInfo
->storeIntoURL( rURL
);
702 // -----------------------------------------------------------------------
703 sal_Bool
SfxDocTplService_Impl::getTitleFromURL( const OUString
& rURL
, OUString
& aTitle
, OUString
& aType
, sal_Bool
& bDocHasTitle
)
705 bDocHasTitle
= sal_False
;
711 mxInfo
->loadFromURL( rURL
);
715 // the document is not a StarOffice document
721 uno::Reference
< XPropertySet
> aPropSet( mxInfo
, UNO_QUERY
);
724 OUString
aPropName( RTL_CONSTASCII_USTRINGPARAM( TITLE
) );
725 Any aValue
= aPropSet
->getPropertyValue( aPropName
);
728 aPropName
= OUString( RTL_CONSTASCII_USTRINGPARAM( "MIMEType" ) );
729 aValue
= aPropSet
->getPropertyValue( aPropName
);
733 catch ( UnknownPropertyException
& ) {}
734 catch ( Exception
& ) {}
737 if ( ! aType
.getLength() && mxType
.is() )
739 ::rtl::OUString aDocType
= mxType
->queryTypeByURL( rURL
);
740 if ( aDocType
.getLength() )
743 uno::Reference
< container::XNameAccess
> xTypeDetection( mxType
, uno::UNO_QUERY_THROW
);
744 SequenceAsHashMap
aTypeProps( xTypeDetection
->getByName( aDocType
) );
745 aType
= aTypeProps
.getUnpackedValueOrDefault(
746 ::rtl::OUString::createFromAscii( "MediaType" ),
749 catch( uno::Exception
& )
753 if ( ! aTitle
.getLength() )
755 INetURLObject
aURL( rURL
);
757 aTitle
= aURL
.getName( INetURLObject::LAST_SEGMENT
, true,
758 INetURLObject::DECODE_WITH_CHARSET
);
761 bDocHasTitle
= sal_True
;
766 // -----------------------------------------------------------------------
767 sal_Bool
SfxDocTplService_Impl::addEntry( Content
& rParentFolder
,
768 const OUString
& rTitle
,
769 const OUString
& rTargetURL
,
770 const OUString
& rType
)
772 sal_Bool bAddedEntry
= sal_False
;
774 INetURLObject
aLinkObj( rParentFolder
.getURL() );
775 aLinkObj
.insertName( rTitle
, false,
776 INetURLObject::LAST_SEGMENT
, true,
777 INetURLObject::ENCODE_ALL
);
778 OUString aLinkURL
= aLinkObj
.GetMainURL( INetURLObject::NO_DECODE
);
782 if ( ! Content::create( aLinkURL
, maCmdEnv
, aLink
) )
784 Sequence
< OUString
> aNames(3);
785 aNames
[0] = OUString( RTL_CONSTASCII_USTRINGPARAM( TITLE
) );
786 aNames
[1] = OUString( RTL_CONSTASCII_USTRINGPARAM( IS_FOLDER
) );
787 aNames
[2] = OUString( RTL_CONSTASCII_USTRINGPARAM( TARGET_URL
) );
789 Sequence
< Any
> aValues(3);
790 aValues
[0] = makeAny( rTitle
);
791 aValues
[1] = makeAny( sal_Bool( sal_False
) );
792 aValues
[2] = makeAny( rTargetURL
);
794 OUString
aType( RTL_CONSTASCII_USTRINGPARAM( TYPE_LINK
) );
795 OUString
aAdditionalProp( RTL_CONSTASCII_USTRINGPARAM( PROPERTY_TYPE
) );
799 rParentFolder
.insertNewContent( aType
, aNames
, aValues
, aLink
);
800 setProperty( aLink
, aAdditionalProp
, makeAny( rType
) );
801 bAddedEntry
= sal_True
;
809 // -----------------------------------------------------------------------
810 sal_Bool
SfxDocTplService_Impl::createFolder( const OUString
& rNewFolderURL
,
811 sal_Bool bCreateParent
,
812 sal_Bool bFsysFolder
,
813 Content
&rNewFolder
)
816 sal_Bool bCreatedFolder
= sal_False
;
817 INetURLObject
aParentURL( rNewFolderURL
);
818 OUString aFolderName
= aParentURL
.getName( INetURLObject::LAST_SEGMENT
, true,
819 INetURLObject::DECODE_WITH_CHARSET
);
821 // compute the parent folder url from the new folder url
822 // and remove the final slash, because Content::create doesn't
824 aParentURL
.removeSegment();
825 if ( aParentURL
.getSegmentCount() >= 1 )
826 aParentURL
.removeFinalSlash();
828 // if the parent exists, we can continue with the creation of the
829 // new folder, we have to create the parent otherwise ( as long as
830 // bCreateParent is set to true )
831 if ( Content::create( aParentURL
.GetMainURL( INetURLObject::NO_DECODE
), maCmdEnv
, aParent
) )
835 Sequence
< OUString
> aNames(2);
836 aNames
[0] = OUString( RTL_CONSTASCII_USTRINGPARAM( TITLE
) );
837 aNames
[1] = OUString( RTL_CONSTASCII_USTRINGPARAM( IS_FOLDER
) );
839 Sequence
< Any
> aValues(2);
840 aValues
[0] = makeAny( aFolderName
);
841 aValues
[1] = makeAny( sal_Bool( sal_True
) );
846 aType
= OUString( RTL_CONSTASCII_USTRINGPARAM( TYPE_FSYS_FOLDER
) );
848 aType
= OUString( RTL_CONSTASCII_USTRINGPARAM( TYPE_FOLDER
) );
850 aParent
.insertNewContent( aType
, aNames
, aValues
, rNewFolder
);
851 bCreatedFolder
= sal_True
;
853 catch( RuntimeException
& )
855 DBG_ERRORFILE( "createFolder(): got runtime exception" );
859 DBG_ERRORFILE( "createFolder(): Could not create new folder" );
862 else if ( bCreateParent
)
864 // if the parent doesn't exists and bCreateParent is set to true,
865 // we try to create the parent and if this was successful, we
866 // try to create the new folder again ( but this time, we set
867 // bCreateParent to false to avoid endless recusions )
868 if ( ( aParentURL
.getSegmentCount() >= 1 ) &&
869 createFolder( aParentURL
.GetMainURL( INetURLObject::NO_DECODE
), bCreateParent
, bFsysFolder
, aParent
) )
871 bCreatedFolder
= createFolder( rNewFolderURL
, sal_False
, bFsysFolder
, rNewFolder
);
875 return bCreatedFolder
;
878 // -----------------------------------------------------------------------
879 sal_Bool
SfxDocTplService_Impl::CreateNewUniqueFolderWithPrefix( const ::rtl::OUString
& aPath
,
880 const ::rtl::OUString
& aPrefix
,
881 ::rtl::OUString
& aNewFolderName
,
882 ::rtl::OUString
& aNewFolderURL
,
883 Content
& aNewFolder
)
885 sal_Bool bCreated
= sal_False
;
886 INetURLObject
aDirPath( aPath
);
889 if ( Content::create( aDirPath
.GetMainURL( INetURLObject::NO_DECODE
), maCmdEnv
, aParent
) )
891 for ( sal_Int32 nInd
= 0; nInd
< 32000; nInd
++ )
893 ::rtl::OUString aTryName
= aPrefix
;
895 aTryName
+= ::rtl::OUString::valueOf( nInd
);
899 Sequence
< OUString
> aNames(2);
900 aNames
[0] = OUString( RTL_CONSTASCII_USTRINGPARAM( TITLE
) );
901 aNames
[1] = OUString( RTL_CONSTASCII_USTRINGPARAM( IS_FOLDER
) );
903 Sequence
< Any
> aValues(2);
904 aValues
[0] = makeAny( aTryName
);
905 aValues
[1] = makeAny( sal_Bool( sal_True
) );
907 OUString
aType( RTL_CONSTASCII_USTRINGPARAM( TYPE_FSYS_FOLDER
) );
909 bCreated
= aParent
.insertNewContent( aType
, aNames
, aValues
, aNewFolder
);
911 catch( ucb::NameClashException
& )
913 // if there is already an element, retry
917 INetURLObject
aObjPath( aDirPath
);
918 aObjPath
.insertName( aTryName
, false,
919 INetURLObject::LAST_SEGMENT
, true,
920 INetURLObject::ENCODE_ALL
);
921 // if there is already an element, retry
922 // if there was another error, do not try any more
923 if ( !::utl::UCBContentHelper::Exists( aObjPath
.GetMainURL( INetURLObject::NO_DECODE
) ) )
929 aNewFolderName
= aTryName
;
930 aNewFolderURL
= aNewFolder
.get()->getIdentifier()->getContentIdentifier();
939 // -----------------------------------------------------------------------
940 ::rtl::OUString
SfxDocTplService_Impl::CreateNewUniqueFileWithPrefix( const ::rtl::OUString
& aPath
,
941 const ::rtl::OUString
& aPrefix
,
942 const ::rtl::OUString
& aExt
)
944 ::rtl::OUString aNewFileURL
;
945 INetURLObject
aDirPath( aPath
);
949 uno::Reference
< XCommandEnvironment
> aQuietEnv
;
950 if ( Content::create( aDirPath
.GetMainURL( INetURLObject::NO_DECODE
), aQuietEnv
, aParent
) )
952 for ( sal_Int32 nInd
= 0; nInd
< 32000; nInd
++ )
955 sal_Bool bCreated
= sal_False
;
956 ::rtl::OUString aTryName
= aPrefix
;
958 aTryName
+= ::rtl::OUString::valueOf( nInd
);
959 if ( aExt
.toChar() != '.' )
960 aTryName
+= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "." ) );
965 Sequence
< OUString
> aNames(2);
966 aNames
[0] = OUString( RTL_CONSTASCII_USTRINGPARAM( TITLE
) );
967 aNames
[1] = OUString( RTL_CONSTASCII_USTRINGPARAM( IS_DOCUMENT
) );
969 Sequence
< Any
> aValues(2);
970 aValues
[0] = makeAny( aTryName
);
971 aValues
[1] = makeAny( sal_Bool( sal_True
) );
973 OUString
aType( RTL_CONSTASCII_USTRINGPARAM( TYPE_FSYS_FILE
) );
975 bCreated
= aParent
.insertNewContent( aType
, aNames
, aValues
, aNewFile
);
977 catch( ucb::NameClashException
& )
979 // if there is already an element, retry
983 INetURLObject
aObjPath( aPath
);
984 aObjPath
.insertName( aTryName
, false,
985 INetURLObject::LAST_SEGMENT
, true,
986 INetURLObject::ENCODE_ALL
);
987 // if there is already an element, retry
988 // if there was another error, do not try any more
989 if ( !::utl::UCBContentHelper::Exists( aObjPath
.GetMainURL( INetURLObject::NO_DECODE
) ) )
995 aNewFileURL
= aNewFile
.get()->getIdentifier()->getContentIdentifier();
1004 // -----------------------------------------------------------------------
1005 sal_Bool
SfxDocTplService_Impl::removeContent( Content
& rContent
)
1007 sal_Bool bRemoved
= sal_False
;
1010 OUString
aCmd( RTL_CONSTASCII_USTRINGPARAM( COMMAND_DELETE
) );
1011 Any aArg
= makeAny( sal_Bool( sal_True
) );
1013 rContent
.executeCommand( aCmd
, aArg
);
1014 bRemoved
= sal_True
;
1016 catch ( RuntimeException
& ) {}
1017 catch ( Exception
& ) {}
1022 // -----------------------------------------------------------------------
1023 sal_Bool
SfxDocTplService_Impl::removeContent( const OUString
& rContentURL
)
1027 if ( Content::create( rContentURL
, maCmdEnv
, aContent
) )
1028 return removeContent( aContent
);
1033 // -----------------------------------------------------------------------
1034 sal_Bool
SfxDocTplService_Impl::setProperty( Content
& rContent
,
1035 const OUString
& rPropName
,
1036 const Any
& rPropValue
)
1038 sal_Bool bPropertySet
= sal_False
;
1040 // Store the property
1043 Any
aPropValue( rPropValue
);
1044 uno::Reference
< XPropertySetInfo
> aPropInfo
= rContent
.getProperties();
1046 // check, wether or not the property exists, create it, when not
1047 if ( !aPropInfo
.is() || !aPropInfo
->hasPropertyByName( rPropName
) )
1049 uno::Reference
< XPropertyContainer
> xProperties( rContent
.get(), UNO_QUERY
);
1050 if ( xProperties
.is() )
1054 xProperties
->addProperty( rPropName
, PropertyAttribute::MAYBEVOID
, rPropValue
);
1056 catch( PropertyExistException
& ) {}
1057 catch( IllegalTypeException
& ) { DBG_ERRORFILE( "IllegalTypeException" ); }
1058 catch( IllegalArgumentException
& ) { DBG_ERRORFILE( "IllegalArgumentException" ); }
1062 // To ensure a reloctable office installation, the path to the
1063 // office installtion directory must never be stored directly.
1064 if ( SfxURLRelocator_Impl::propertyCanContainOfficeDir( rPropName
) )
1067 if ( rPropValue
>>= aValue
)
1069 maRelocator
.makeRelocatableURL( aValue
);
1070 aPropValue
= makeAny( aValue
);
1074 Sequence
< OUString
> aValues
;
1075 if ( rPropValue
>>= aValues
)
1077 for ( sal_Int32 n
= 0; n
< aValues
.getLength(); n
++ )
1079 maRelocator
.makeRelocatableURL( aValues
[ n
] );
1081 aPropValue
= makeAny( aValues
);
1085 OSL_ENSURE( false, "Unsupported property value type" );
1090 // now set the property
1092 rContent
.setPropertyValue( rPropName
, aPropValue
);
1093 bPropertySet
= sal_True
;
1095 catch ( RuntimeException
& ) {}
1096 catch ( Exception
& ) {}
1098 return bPropertySet
;
1101 // -----------------------------------------------------------------------
1102 sal_Bool
SfxDocTplService_Impl::getProperty( Content
& rContent
,
1103 const OUString
& rPropName
,
1106 sal_Bool bGotProperty
= sal_False
;
1111 uno::Reference
< XPropertySetInfo
> aPropInfo
= rContent
.getProperties();
1113 // check, wether or not the property exists
1114 if ( !aPropInfo
.is() || !aPropInfo
->hasPropertyByName( rPropName
) )
1119 // now get the property
1121 rPropValue
= rContent
.getPropertyValue( rPropName
);
1123 // To ensure a reloctable office installation, the path to the
1124 // office installtion directory must never be stored directly.
1125 if ( SfxURLRelocator_Impl::propertyCanContainOfficeDir( rPropName
) )
1128 if ( rPropValue
>>= aValue
)
1130 maRelocator
.makeAbsoluteURL( aValue
);
1131 rPropValue
= makeAny( aValue
);
1135 Sequence
< OUString
> aValues
;
1136 if ( rPropValue
>>= aValues
)
1138 for ( sal_Int32 n
= 0; n
< aValues
.getLength(); n
++ )
1140 maRelocator
.makeAbsoluteURL( aValues
[ n
] );
1142 rPropValue
= makeAny( aValues
);
1146 OSL_ENSURE( false, "Unsupported property value type" );
1151 bGotProperty
= sal_True
;
1153 catch ( RuntimeException
& ) {}
1154 catch ( Exception
& ) {}
1156 return bGotProperty
;
1159 // -----------------------------------------------------------------------
1161 bool SfxURLRelocator_Impl::propertyCanContainOfficeDir(
1162 const rtl::OUString
& rPropName
)
1164 // Note: TargetURL is handled by UCB itself (because it is a property
1165 // with a predefined semantic). Additional Core properties introduced
1166 // be a client app must be handled by the client app itself, because
1167 // the UCB does not know the semantics of those properties.
1168 return ( rPropName
.equalsAsciiL(
1169 RTL_CONSTASCII_STRINGPARAM( TARGET_DIR_URL
) ) ||
1170 rPropName
.equalsAsciiL(
1171 RTL_CONSTASCII_STRINGPARAM( PROPERTY_DIRLIST
) ) );
1174 //-----------------------------------------------------------------------------
1175 // public SfxDocTplService_Impl
1176 //-----------------------------------------------------------------------------
1178 SfxDocTplService_Impl::SfxDocTplService_Impl( uno::Reference
< XMultiServiceFactory
> xFactory
)
1179 : maRelocator( xFactory
)
1181 mxFactory
= xFactory
;
1183 mbIsInitialized
= sal_False
;
1184 mbLocaleSet
= sal_False
;
1187 //-----------------------------------------------------------------------------
1188 SfxDocTplService_Impl::~SfxDocTplService_Impl()
1190 ::osl::MutexGuard
aGuard( maMutex
);
1199 //-----------------------------------------------------------------------------
1200 Locale
SfxDocTplService_Impl::getLocale()
1202 ::osl::MutexGuard
aGuard( maMutex
);
1210 //-----------------------------------------------------------------------------
1211 void SfxDocTplService_Impl::setLocale( const Locale
&rLocale
)
1213 ::osl::MutexGuard
aGuard( maMutex
);
1216 ( maLocale
.Language
!= rLocale
.Language
) &&
1217 ( maLocale
.Country
!= rLocale
.Country
) )
1218 mbIsInitialized
= sal_False
;
1221 mbLocaleSet
= sal_True
;
1224 //-----------------------------------------------------------------------------
1225 void SfxDocTplService_Impl::update( sal_Bool bUpdateNow
)
1227 ::osl::MutexGuard
aGuard( maMutex
);
1233 mpUpdater
= new Updater_Impl( this );
1234 mpUpdater
->create();
1238 //-----------------------------------------------------------------------------
1239 void SfxDocTplService_Impl::doUpdate()
1241 ::osl::MutexGuard
aGuard( maMutex
);
1243 OUString
aPropName( RTL_CONSTASCII_USTRINGPARAM( PROPERTY_NEEDSUPDATE
) );
1246 aValue
<<= sal_True
;
1247 setProperty( maRootContent
, aPropName
, aValue
);
1249 GroupList_Impl aGroupList
;
1251 // get the entries from the hierarchy
1252 createFromContent( aGroupList
, maRootContent
, sal_True
);
1254 // get the entries from the template directories
1255 sal_Int32 nCountDir
= maTemplateDirs
.getLength();
1256 OUString
* pDirs
= maTemplateDirs
.getArray();
1257 Content aDirContent
;
1259 // the last directory in the list must be writable
1260 sal_Bool bWriteableDirectory
= sal_True
;
1262 // the target folder might not exist, for this reason no interaction handler should be used
1263 uno::Reference
< XCommandEnvironment
> aQuietEnv
;
1268 osl::Directory
aDirectory (pDirs
[ nCountDir
]);
1269 osl::FileBase::RC nError
= aDirectory
.open();
1270 if (nError
== osl::FileBase::E_None
|| bWriteableDirectory
)
1272 if ( Content::create( pDirs
[ nCountDir
], aQuietEnv
, aDirContent
) )
1274 createFromContent( aGroupList
, aDirContent
, sal_False
, bWriteableDirectory
);
1278 bWriteableDirectory
= sal_False
;
1281 // now check the list
1282 GroupData_Impl
*pGroup
= aGroupList
.First();
1285 if ( pGroup
->getInUse() )
1287 if ( pGroup
->getInHierarchy() )
1290 if ( Content::create( pGroup
->getHierarchyURL(), maCmdEnv
, aGroup
) )
1291 setProperty( aGroup
,
1292 OUString( RTL_CONSTASCII_USTRINGPARAM( TARGET_DIR_URL
) ),
1293 makeAny( pGroup
->getTargetURL() ) );
1295 ULONG nCount
= pGroup
->count();
1296 for ( ULONG i
=0; i
<nCount
; i
++ )
1298 DocTemplates_EntryData_Impl
*pData
= pGroup
->getEntry( i
);
1299 if ( ! pData
->getInUse() )
1301 if ( pData
->getInHierarchy() )
1302 removeFromHierarchy( pData
); // delete entry in hierarchy
1304 addToHierarchy( pGroup
, pData
); // add entry to hierarchy
1306 else if ( pData
->getUpdateType() ||
1307 pData
->getUpdateLink() )
1309 updateData( pData
);
1315 addGroupToHierarchy( pGroup
); // add group to hierarchy
1319 removeFromHierarchy( pGroup
); // delete group from hierarchy
1322 pGroup
= aGroupList
.Next();
1325 aValue
<<= sal_False
;
1326 setProperty( maRootContent
, aPropName
, aValue
);
1329 //-----------------------------------------------------------------------------
1330 uno::Sequence
< beans::StringPair
> SfxDocTplService_Impl::ReadUINamesForTemplateDir_Impl( const ::rtl::OUString
& aUserPath
)
1332 INetURLObject
aLocObj( aUserPath
);
1333 aLocObj
.insertName( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "groupuinames.xml" ) ), false,
1334 INetURLObject::LAST_SEGMENT
, true,
1335 INetURLObject::ENCODE_ALL
);
1336 Content aLocContent
;
1338 // TODO/LATER: Use hashmap in future
1339 uno::Sequence
< beans::StringPair
> aUINames
;
1340 if ( Content::create( aLocObj
.GetMainURL( INetURLObject::NO_DECODE
), uno::Reference
< ucb::XCommandEnvironment
>(), aLocContent
) )
1344 uno::Reference
< io::XInputStream
> xLocStream
= aLocContent
.openStream();
1345 if ( xLocStream
.is() )
1346 aUINames
= DocTemplLocaleHelper::ReadGroupLocalizationSequence( xLocStream
, mxFactory
);
1348 catch( uno::Exception
& )
1355 //-----------------------------------------------------------------------------
1356 sal_Bool
SfxDocTplService_Impl::UpdateUINamesForTemplateDir_Impl( const ::rtl::OUString
& aUserPath
,
1357 const ::rtl::OUString
& aGroupName
,
1358 const ::rtl::OUString
& aNewFolderName
)
1360 uno::Sequence
< beans::StringPair
> aUINames
= ReadUINamesForTemplateDir_Impl( aUserPath
);
1361 sal_Int32 nLen
= aUINames
.getLength();
1363 // it is possible that the name is used already, but it should be checked before
1364 for ( sal_Int32 nInd
= 0; nInd
< nLen
; nInd
++ )
1365 if ( aUINames
[nInd
].First
.equals( aNewFolderName
) )
1368 aUINames
.realloc( ++nLen
);
1369 aUINames
[nLen
-1].First
= aNewFolderName
;
1370 aUINames
[nLen
-1].Second
= aGroupName
;
1372 return WriteUINamesForTemplateDir_Impl( aUserPath
, aUINames
);
1375 //-----------------------------------------------------------------------------
1376 sal_Bool
SfxDocTplService_Impl::ReplaceUINamesForTemplateDir_Impl( const ::rtl::OUString
& aUserPath
,
1377 const ::rtl::OUString
& aDefaultFsysGroupName
,
1378 const ::rtl::OUString
& aOldGroupName
,
1379 const ::rtl::OUString
& aNewGroupName
)
1381 uno::Sequence
< beans::StringPair
> aUINames
= ReadUINamesForTemplateDir_Impl( aUserPath
);
1382 sal_Int32 nLen
= aUINames
.getLength();
1384 sal_Bool bChanged
= sal_False
;
1385 for ( sal_Int32 nInd
= 0; nInd
< nLen
; nInd
++ )
1386 if ( aUINames
[nInd
].Second
.equals( aOldGroupName
) )
1388 aUINames
[nInd
].Second
= aNewGroupName
;
1389 bChanged
= sal_True
;
1394 aUINames
.realloc( ++nLen
);
1395 aUINames
[nLen
-1].First
= aDefaultFsysGroupName
;
1396 aUINames
[nLen
-1].Second
= aNewGroupName
;
1398 return WriteUINamesForTemplateDir_Impl( aUserPath
, aUINames
);
1401 //-----------------------------------------------------------------------------
1402 sal_Bool
SfxDocTplService_Impl::RemoveUINamesForTemplateDir_Impl( const ::rtl::OUString
& aUserPath
,
1403 const ::rtl::OUString
& aGroupName
)
1405 uno::Sequence
< beans::StringPair
> aUINames
= ReadUINamesForTemplateDir_Impl( aUserPath
);
1406 sal_Int32 nLen
= aUINames
.getLength();
1407 uno::Sequence
< beans::StringPair
> aNewUINames( nLen
);
1408 sal_Int32 nNewLen
= 0;
1410 sal_Bool bChanged
= sal_False
;
1411 for ( sal_Int32 nInd
= 0; nInd
< nLen
; nInd
++ )
1412 if ( aUINames
[nInd
].Second
.equals( aGroupName
) )
1413 bChanged
= sal_True
;
1417 aNewUINames
[nNewLen
-1].First
= aUINames
[nInd
].First
;
1418 aNewUINames
[nNewLen
-1].Second
= aUINames
[nInd
].Second
;
1421 aNewUINames
.realloc( nNewLen
);
1423 return bChanged
? WriteUINamesForTemplateDir_Impl( aUserPath
, aNewUINames
) : sal_True
;
1427 //-----------------------------------------------------------------------------
1428 sal_Bool
SfxDocTplService_Impl::WriteUINamesForTemplateDir_Impl( const ::rtl::OUString
& aUserPath
,
1429 const uno::Sequence
< beans::StringPair
>& aUINames
)
1431 sal_Bool bResult
= sal_False
;
1433 uno::Reference
< beans::XPropertySet
> xTempFile(
1434 mxFactory
->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.io.TempFile" ) ),
1435 uno::UNO_QUERY_THROW
);
1437 ::rtl::OUString aTempURL
;
1438 uno::Any aUrl
= xTempFile
->getPropertyValue( ::rtl::OUString::createFromAscii( "Uri" ) );
1441 uno::Reference
< io::XStream
> xStream( xTempFile
, uno::UNO_QUERY_THROW
);
1442 uno::Reference
< io::XOutputStream
> xOutStream
= xStream
->getOutputStream();
1443 if ( !xOutStream
.is() )
1444 throw uno::RuntimeException();
1446 DocTemplLocaleHelper::WriteGroupLocalizationSequence( xOutStream
, aUINames
, mxFactory
);
1448 // the SAX writer might close the stream
1449 xOutStream
->closeOutput();
1450 } catch( uno::Exception
& )
1453 Content
aTargetContent( aUserPath
, maCmdEnv
);
1454 Content
aSourceContent( aTempURL
, maCmdEnv
);
1455 aTargetContent
.transferContent( aSourceContent
,
1456 InsertOperation_COPY
,
1457 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "groupuinames.xml" ) ),
1458 ucb::NameClash::OVERWRITE
);
1461 catch ( uno::Exception
& )
1468 //-----------------------------------------------------------------------------
1469 ::rtl::OUString
SfxDocTplService_Impl::CreateNewGroupFsys( const ::rtl::OUString
& rGroupName
, Content
& aGroup
)
1471 ::rtl::OUString aResultURL
;
1473 if ( maTemplateDirs
.getLength() )
1475 ::rtl::OUString aTargetPath
= maTemplateDirs
[ maTemplateDirs
.getLength() - 1 ];
1477 // create a new folder with the given name
1479 ::rtl::OUString aNewFolderName
;
1481 // the Fsys name instead of GroupName should be used, the groupuinames must be added also
1482 if ( !CreateNewUniqueFolderWithPrefix( aTargetPath
,
1487 && !CreateNewUniqueFolderWithPrefix( aTargetPath
,
1488 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UserGroup" ) ),
1493 return ::rtl::OUString();
1495 if ( !UpdateUINamesForTemplateDir_Impl( aTargetPath
, rGroupName
, aNewFolderName
) )
1497 // we could not create the groupuinames for the folder, so we delete the group in the
1498 // the folder and return
1499 removeContent( aNewFolder
);
1500 return ::rtl::OUString();
1503 // Now set the target url for this group and we are done
1504 OUString
aPropName( RTL_CONSTASCII_USTRINGPARAM( TARGET_DIR_URL
) );
1505 Any aValue
= makeAny( aResultURL
);
1507 if ( ! setProperty( aGroup
, aPropName
, aValue
) )
1509 removeContent( aNewFolder
);
1510 return ::rtl::OUString();
1517 //-----------------------------------------------------------------------------
1518 sal_Bool
SfxDocTplService_Impl::addGroup( const OUString
& rGroupName
)
1520 ::osl::MutexGuard
aGuard( maMutex
);
1522 // Check, wether or not there is a group with this name
1524 OUString aNewGroupURL
;
1525 INetURLObject
aNewGroupObj( maRootURL
);
1527 aNewGroupObj
.insertName( rGroupName
, false,
1528 INetURLObject::LAST_SEGMENT
, true,
1529 INetURLObject::ENCODE_ALL
);
1531 aNewGroupURL
= aNewGroupObj
.GetMainURL( INetURLObject::NO_DECODE
);
1533 if ( Content::create( aNewGroupURL
, maCmdEnv
, aNewGroup
) ||
1534 ! createFolder( aNewGroupURL
, sal_False
, sal_False
, aNewGroup
) )
1536 // if there already was a group with this name or the new group
1537 // could not be created, we return here
1541 // Get the user template path entry ( new group will always
1542 // be added in the user template path )
1546 nIndex
= maTemplateDirs
.getLength();
1550 return sal_False
; // We don't know where to add the group
1552 aUserPath
= maTemplateDirs
[ nIndex
];
1554 // create a new folder with the given name
1556 OUString aNewFolderName
;
1557 OUString aNewFolderURL
;
1559 // the Fsys name instead of GroupName should be used, the groupuinames must be added also
1560 if ( !CreateNewUniqueFolderWithPrefix( aUserPath
,
1565 && !CreateNewUniqueFolderWithPrefix( aUserPath
,
1566 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UserGroup" ) ),
1571 // we could not create the folder, so we delete the group in the
1572 // hierarchy and return
1573 removeContent( aNewGroup
);
1577 if ( !UpdateUINamesForTemplateDir_Impl( aUserPath
, rGroupName
, aNewFolderName
) )
1579 // we could not create the groupuinames for the folder, so we delete the group in the
1580 // hierarchy, the folder and return
1581 removeContent( aNewGroup
);
1582 removeContent( aNewFolder
);
1586 // Now set the target url for this group and we are done
1587 OUString
aPropName( RTL_CONSTASCII_USTRINGPARAM( TARGET_DIR_URL
) );
1588 Any aValue
= makeAny( aNewFolderURL
);
1590 if ( ! setProperty( aNewGroup
, aPropName
, aValue
) )
1592 removeContent( aNewGroup
);
1593 removeContent( aNewFolder
);
1600 //-----------------------------------------------------------------------------
1601 sal_Bool
SfxDocTplService_Impl::removeGroup( const OUString
& rGroupName
)
1603 // remove all the elements that have the prefix aTargetURL
1604 // if the group does not have other elements remove it
1606 ::osl::MutexGuard
aGuard( maMutex
);
1608 sal_Bool bResult
= sal_False
;
1610 // create the group url
1611 INetURLObject
aGroupObj( maRootURL
);
1612 aGroupObj
.insertName( rGroupName
, false,
1613 INetURLObject::LAST_SEGMENT
, true,
1614 INetURLObject::ENCODE_ALL
);
1616 // Get the target url
1618 OUString aGroupURL
= aGroupObj
.GetMainURL( INetURLObject::NO_DECODE
);
1620 if ( Content::create( aGroupURL
, maCmdEnv
, aGroup
) )
1622 OUString
aPropName( RTL_CONSTASCII_USTRINGPARAM( TARGET_DIR_URL
) );
1625 OUString aGroupTargetURL
;
1626 if ( getProperty( aGroup
, aPropName
, aValue
) )
1627 aValue
>>= aGroupTargetURL
;
1629 if ( !aGroupTargetURL
.getLength() )
1630 return sal_False
; // nothing is allowed to be removed
1632 if ( !maTemplateDirs
.getLength() )
1634 ::rtl::OUString aGeneralTempPath
= maTemplateDirs
[ maTemplateDirs
.getLength() - 1 ];
1636 // check that the fs location is in writeble folder and this is not a "My templates" folder
1637 INetURLObject
aGroupParentFolder( aGroupTargetURL
);
1638 if ( !aGroupParentFolder
.removeSegment()
1639 || !::utl::UCBContentHelper::IsSubPath( aGeneralTempPath
,
1640 aGroupParentFolder
.GetMainURL( INetURLObject::NO_DECODE
) ) )
1643 // now get the content of the Group
1644 uno::Reference
< XResultSet
> xResultSet
;
1645 Sequence
< OUString
> aProps( 1 );
1647 aProps
[0] = OUString::createFromAscii( TARGET_URL
);
1651 sal_Bool bHasNonRemovable
= sal_False
;
1652 sal_Bool bHasShared
= sal_False
;
1654 ResultSetInclude eInclude
= INCLUDE_DOCUMENTS_ONLY
;
1655 xResultSet
= aGroup
.createCursor( aProps
, eInclude
);
1657 if ( xResultSet
.is() )
1659 uno::Reference
< XContentAccess
> xContentAccess( xResultSet
, UNO_QUERY_THROW
);
1660 uno::Reference
< XRow
> xRow( xResultSet
, UNO_QUERY_THROW
);
1662 while ( xResultSet
->next() )
1664 OUString
aTemplTargetURL( xRow
->getString( 1 ) );
1665 OUString aHierURL
= xContentAccess
->queryContentIdentifierString();
1667 if ( ::utl::UCBContentHelper::IsSubPath( aGroupTargetURL
, aTemplTargetURL
) )
1669 // this is a user template, and it can be removed
1670 if ( removeContent( aTemplTargetURL
) )
1671 removeContent( aHierURL
);
1673 bHasNonRemovable
= sal_True
;
1676 bHasShared
= sal_True
;
1679 if ( !bHasNonRemovable
&& !bHasShared
)
1681 if ( removeContent( aGroupTargetURL
)
1682 || !::utl::UCBContentHelper::Exists( aGroupTargetURL
) )
1684 removeContent( aGroupURL
);
1685 RemoveUINamesForTemplateDir_Impl( aGeneralTempPath
, rGroupName
);
1686 bResult
= sal_True
; // the operation is successful only if the whole group is removed
1689 else if ( !bHasNonRemovable
)
1691 if ( removeContent( aGroupTargetURL
)
1692 || !::utl::UCBContentHelper::Exists( aGroupTargetURL
) )
1694 RemoveUINamesForTemplateDir_Impl( aGeneralTempPath
, rGroupName
);
1695 setProperty( aGroup
, aPropName
, uno::makeAny( ::rtl::OUString() ) );
1700 catch ( Exception
& ) {}
1706 //-----------------------------------------------------------------------------
1707 sal_Bool
SfxDocTplService_Impl::renameGroup( const OUString
& rOldName
,
1708 const OUString
& rNewName
)
1710 ::osl::MutexGuard
aGuard( maMutex
);
1712 // create the group url
1714 INetURLObject
aGroupObj( maRootURL
);
1715 aGroupObj
.insertName( rNewName
, false,
1716 INetURLObject::LAST_SEGMENT
, true,
1717 INetURLObject::ENCODE_ALL
);
1718 OUString aGroupURL
= aGroupObj
.GetMainURL( INetURLObject::NO_DECODE
);
1720 // Check, if there is a group with the new name, return false
1722 if ( Content::create( aGroupURL
, maCmdEnv
, aGroup
) )
1725 aGroupObj
.removeSegment();
1726 aGroupObj
.insertName( rOldName
, false,
1727 INetURLObject::LAST_SEGMENT
, true,
1728 INetURLObject::ENCODE_ALL
);
1729 aGroupURL
= aGroupObj
.GetMainURL( INetURLObject::NO_DECODE
);
1731 // When there is no group with the old name, we can't rename it
1732 if ( ! Content::create( aGroupURL
, maCmdEnv
, aGroup
) )
1735 OUString aGroupTargetURL
;
1736 // there is no need to check whether target dir url is in target path, since if the target path is changed
1737 // the target dir url should be already generated new
1738 OUString
aPropName( RTL_CONSTASCII_USTRINGPARAM( TARGET_DIR_URL
) );
1740 if ( getProperty( aGroup
, aPropName
, aValue
) )
1741 aValue
>>= aGroupTargetURL
;
1743 if ( !aGroupTargetURL
.getLength() )
1746 if ( !maTemplateDirs
.getLength() )
1748 ::rtl::OUString aGeneralTempPath
= maTemplateDirs
[ maTemplateDirs
.getLength() - 1 ];
1750 // check that the fs location is in writeble folder and this is not a "My templates" folder
1751 INetURLObject
aGroupParentFolder( aGroupTargetURL
);
1752 if ( !aGroupParentFolder
.removeSegment()
1753 || !::utl::UCBContentHelper::IsSubPath( aGeneralTempPath
,
1754 aGroupParentFolder
.GetMainURL( INetURLObject::NO_DECODE
) ) )
1757 // check that the group can be renamed ( all the contents must be in target location )
1758 sal_Bool bCanBeRenamed
= sal_False
;
1761 uno::Reference
< XResultSet
> xResultSet
;
1762 Sequence
< OUString
> aProps( 1 );
1764 aProps
[0] = OUString::createFromAscii( TARGET_URL
);
1765 ResultSetInclude eInclude
= INCLUDE_DOCUMENTS_ONLY
;
1766 xResultSet
= aGroup
.createCursor( aProps
, eInclude
);
1768 if ( xResultSet
.is() )
1770 uno::Reference
< XContentAccess
> xContentAccess( xResultSet
, UNO_QUERY_THROW
);
1771 uno::Reference
< XRow
> xRow( xResultSet
, UNO_QUERY_THROW
);
1773 while ( xResultSet
->next() )
1775 OUString
aTemplTargetURL( xRow
->getString( 1 ) );
1777 if ( !::utl::UCBContentHelper::IsSubPath( aGroupTargetURL
, aTemplTargetURL
) )
1778 throw uno::Exception();
1781 bCanBeRenamed
= sal_True
;
1784 catch ( Exception
& ) {}
1786 if ( bCanBeRenamed
)
1788 INetURLObject
aGroupTargetObj( aGroupTargetURL
);
1789 ::rtl::OUString aFsysName
= aGroupTargetObj
.getName( INetURLObject::LAST_SEGMENT
, true, INetURLObject::DECODE_WITH_CHARSET
);
1791 if ( aGroupTargetObj
.removeSegment()
1792 && ReplaceUINamesForTemplateDir_Impl( aGroupTargetObj
.GetMainURL( INetURLObject::NO_DECODE
),
1797 // rename the group in the hierarchy
1798 OUString
aTitleProp( RTL_CONSTASCII_USTRINGPARAM( TITLE
) );
1800 aTitleValue
<<= rNewName
;
1802 return setProperty( aGroup
, aTitleProp
, aTitleValue
);
1809 //-----------------------------------------------------------------------------
1810 sal_Bool
SfxDocTplService_Impl::storeTemplate( const OUString
& rGroupName
,
1811 const OUString
& rTemplateName
,
1812 const uno::Reference
< XSTORABLE
>& rStorable
)
1814 ::osl::MutexGuard
aGuard( maMutex
);
1816 // Check, wether or not there is a group with this name
1817 // Return false, if there is no group with the given name
1818 Content aGroup
, aTemplate
, aTargetGroup
, aTemplateToRemove
;
1819 OUString aGroupURL
, aTemplateURL
, aTemplateToRemoveTargetURL
;
1820 INetURLObject
aGroupObj( maRootURL
);
1821 sal_Bool bRemoveOldTemplateContent
= sal_False
;
1822 ::rtl::OUString sDocServiceName
;
1824 aGroupObj
.insertName( rGroupName
, false,
1825 INetURLObject::LAST_SEGMENT
, true,
1826 INetURLObject::ENCODE_ALL
);
1827 aGroupURL
= aGroupObj
.GetMainURL( INetURLObject::NO_DECODE
);
1829 if ( ! Content::create( aGroupURL
, maCmdEnv
, aGroup
) )
1832 ::rtl::OUString aGroupTargetURL
;
1833 ::rtl::OUString
aPropName( RTL_CONSTASCII_USTRINGPARAM( TARGET_DIR_URL
) );
1835 if ( getProperty( aGroup
, aPropName
, aValue
) )
1836 aValue
>>= aGroupTargetURL
;
1839 // Check, if there's a template with the given name in this group
1840 // the target template should be overwritten if it is imported by user
1841 // in case the template is installed by office installation of by an add-in
1842 // it can not be replaced
1843 aGroupObj
.insertName( rTemplateName
, false,
1844 INetURLObject::LAST_SEGMENT
, true,
1845 INetURLObject::ENCODE_ALL
);
1846 aTemplateURL
= aGroupObj
.GetMainURL( INetURLObject::NO_DECODE
);
1848 if ( Content::create( aTemplateURL
, maCmdEnv
, aTemplateToRemove
) )
1850 OUString
aTargetTemplPropName( RTL_CONSTASCII_USTRINGPARAM( TARGET_URL
) );
1852 bRemoveOldTemplateContent
= sal_True
;
1853 if ( getProperty( aTemplateToRemove
, aTargetTemplPropName
, aValue
) )
1854 aValue
>>= aTemplateToRemoveTargetURL
;
1856 if ( !aGroupTargetURL
.getLength() || !maTemplateDirs
.getLength()
1857 || (aTemplateToRemoveTargetURL
.getLength() && !::utl::UCBContentHelper::IsSubPath( maTemplateDirs
[ maTemplateDirs
.getLength() - 1 ], aTemplateToRemoveTargetURL
)) )
1858 return sal_False
; // it is not allowed to remove the template
1863 uno::Reference
< lang::XMultiServiceFactory
> xFactory
= ::comphelper::getProcessServiceFactory();
1864 if ( !xFactory
.is() )
1865 throw uno::RuntimeException();
1867 // get document service name
1868 uno::Reference
< frame::XModuleManager
> xModuleManager(
1869 xFactory
->createInstance(
1870 ::rtl::OUString::createFromAscii( "com.sun.star.frame.ModuleManager" ) ),
1871 uno::UNO_QUERY_THROW
);
1872 sDocServiceName
= xModuleManager
->identify( uno::Reference
< uno::XInterface
>( rStorable
, uno::UNO_QUERY
) );
1873 if ( !sDocServiceName
.getLength() )
1874 throw uno::RuntimeException();
1876 // get the actual filter name
1877 ::rtl::OUString aFilterName
;
1879 uno::Reference
< lang::XMultiServiceFactory
> xConfigProvider(
1880 xFactory
->createInstance(
1881 ::rtl::OUString::createFromAscii( "com.sun.star.configuration.ConfigurationProvider" ) ),
1882 uno::UNO_QUERY_THROW
);
1884 uno::Sequence
< uno::Any
> aArgs( 1 );
1885 beans::PropertyValue aPathProp
;
1886 aPathProp
.Name
= ::rtl::OUString::createFromAscii( "nodepath" );
1887 aPathProp
.Value
<<= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Setup/Office/Factories/" ) );
1888 aArgs
[0] <<= aPathProp
;
1890 uno::Reference
< container::XNameAccess
> xSOFConfig(
1891 xConfigProvider
->createInstanceWithArguments(
1892 ::rtl::OUString::createFromAscii( "com.sun.star.configuration.ConfigurationAccess" ),
1894 uno::UNO_QUERY_THROW
);
1896 uno::Reference
< container::XNameAccess
> xApplConfig
;
1897 xSOFConfig
->getByName( sDocServiceName
) >>= xApplConfig
;
1898 if ( !xApplConfig
.is() )
1899 throw uno::RuntimeException();
1901 xApplConfig
->getByName( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ooSetupFactoryActualTemplateFilter" ) ) ) >>= aFilterName
;
1902 if ( !aFilterName
.getLength() )
1903 throw uno::RuntimeException();
1905 // find the related type name
1906 ::rtl::OUString aTypeName
;
1907 uno::Reference
< container::XNameAccess
> xFilterFactory(
1908 xFactory
->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.document.FilterFactory" ) ),
1909 uno::UNO_QUERY_THROW
);
1911 uno::Sequence
< beans::PropertyValue
> aFilterData
;
1912 xFilterFactory
->getByName( aFilterName
) >>= aFilterData
;
1913 for ( sal_Int32 nInd
= 0; nInd
< aFilterData
.getLength(); nInd
++ )
1914 if ( aFilterData
[nInd
].Name
.equalsAscii( "Type" ) )
1915 aFilterData
[nInd
].Value
>>= aTypeName
;
1917 if ( !aTypeName
.getLength() )
1918 throw uno::RuntimeException();
1920 // find the mediatype and extension
1921 uno::Reference
< container::XNameAccess
> xTypeDetection
=
1923 uno::Reference
< container::XNameAccess
>( mxType
, uno::UNO_QUERY_THROW
) :
1924 uno::Reference
< container::XNameAccess
>(
1925 xFactory
->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.document.TypeDetection" ) ),
1926 uno::UNO_QUERY_THROW
);
1928 SequenceAsHashMap
aTypeProps( xTypeDetection
->getByName( aTypeName
) );
1929 uno::Sequence
< ::rtl::OUString
> aAllExt
=
1930 aTypeProps
.getUnpackedValueOrDefault( ::rtl::OUString::createFromAscii( "Extensions" ), Sequence
< ::rtl::OUString
>() );
1931 if ( !aAllExt
.getLength() )
1932 throw uno::RuntimeException();
1934 ::rtl::OUString aMediaType
= aTypeProps
.getUnpackedValueOrDefault( ::rtl::OUString::createFromAscii( "MediaType" ), ::rtl::OUString() );
1935 ::rtl::OUString aExt
= aAllExt
[0];
1937 if ( !aMediaType
.getLength() || !aExt
.getLength() )
1938 throw uno::RuntimeException();
1940 // construct destination url
1941 if ( !aGroupTargetURL
.getLength() )
1943 aGroupTargetURL
= CreateNewGroupFsys( rGroupName
, aGroup
);
1945 if ( !aGroupTargetURL
.getLength() )
1946 throw uno::RuntimeException();
1949 ::rtl::OUString aNewTemplateTargetURL
= CreateNewUniqueFileWithPrefix( aGroupTargetURL
, rTemplateName
, aExt
);
1950 if ( !aNewTemplateTargetURL
.getLength() )
1952 aNewTemplateTargetURL
= CreateNewUniqueFileWithPrefix( aGroupTargetURL
, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UserTemplate" ) ), aExt
);
1954 if ( !aNewTemplateTargetURL
.getLength() )
1955 throw uno::RuntimeException();
1959 uno::Sequence
< PropertyValue
> aStoreArgs( 2 );
1960 aStoreArgs
[0].Name
= ::rtl::OUString::createFromAscii( "FilterName" );
1961 aStoreArgs
[0].Value
<<= aFilterName
;
1962 aStoreArgs
[1].Name
= ::rtl::OUString::createFromAscii( "DocumentTitle" );
1963 aStoreArgs
[1].Value
<<= rTemplateName
;
1965 ::rtl::OUString aCurrentDocumentURL
= rStorable
->getLocation();
1966 if( !SfxMedium::EqualURLs( aNewTemplateTargetURL
, rStorable
->getLocation() ))
1967 rStorable
->storeToURL( aNewTemplateTargetURL
, aStoreArgs
);
1971 // the storing was successful, now the old template with the same name can be removed if it existed
1972 if ( aTemplateToRemoveTargetURL
.getLength() )
1974 removeContent( aTemplateToRemoveTargetURL
);
1978 * if the old template was the standard template
1979 * it is necessary to change the standard template with the new file name
1981 String sStdTmplFile
= SfxObjectFactory::GetStandardTemplate( sDocServiceName
);
1982 if ( INetURLObject( sStdTmplFile
) == INetURLObject( aTemplateToRemoveTargetURL
) )
1984 SfxObjectFactory::SetStandardTemplate( sDocServiceName
, aNewTemplateTargetURL
);
1988 if ( bRemoveOldTemplateContent
)
1989 removeContent( aTemplateToRemove
);
1991 // add the template to hierarchy
1992 return addEntry( aGroup
, rTemplateName
, aNewTemplateTargetURL
, aMediaType
);
1996 // the template was not stored
2001 //-----------------------------------------------------------------------------
2002 sal_Bool
SfxDocTplService_Impl::addTemplate( const OUString
& rGroupName
,
2003 const OUString
& rTemplateName
,
2004 const OUString
& rSourceURL
)
2006 ::osl::MutexGuard
aGuard( maMutex
);
2008 // Check, wether or not there is a group with this name
2009 // Return false, if there is no group with the given name
2010 Content aGroup
, aTemplate
, aTargetGroup
;
2011 OUString aGroupURL
, aTemplateURL
;
2012 INetURLObject
aGroupObj( maRootURL
);
2014 aGroupObj
.insertName( rGroupName
, false,
2015 INetURLObject::LAST_SEGMENT
, true,
2016 INetURLObject::ENCODE_ALL
);
2017 aGroupURL
= aGroupObj
.GetMainURL( INetURLObject::NO_DECODE
);
2019 if ( ! Content::create( aGroupURL
, maCmdEnv
, aGroup
) )
2022 // Check, if there's a template with the given name in this group
2023 // Return false, if there already is a template
2024 aGroupObj
.insertName( rTemplateName
, false,
2025 INetURLObject::LAST_SEGMENT
, true,
2026 INetURLObject::ENCODE_ALL
);
2027 aTemplateURL
= aGroupObj
.GetMainURL( INetURLObject::NO_DECODE
);
2029 if ( Content::create( aTemplateURL
, maCmdEnv
, aTemplate
) )
2032 // get the target url of the group
2033 OUString aTargetURL
;
2034 OUString
aPropName( RTL_CONSTASCII_USTRINGPARAM( TARGET_DIR_URL
) );
2037 if ( getProperty( aGroup
, aPropName
, aValue
) )
2038 aValue
>>= aTargetURL
;
2040 if ( !aTargetURL
.getLength() )
2042 aTargetURL
= CreateNewGroupFsys( rGroupName
, aGroup
);
2044 if ( !aTargetURL
.getLength() )
2048 // Get the content type
2049 OUString aTitle
, aType
, aTargetURL2
, aFullName
;
2051 // only StarOffice documents are acceptable
2052 sal_Bool bDocHasTitle
= sal_False
;
2053 if( !getTitleFromURL( rSourceURL
, aTitle
, aType
, bDocHasTitle
) )
2056 INetURLObject
aSourceObj( rSourceURL
);
2057 if ( rTemplateName
.equals( aTitle
) )
2059 /////////////////////////////////////////////////////
2060 // addTemplate will sometimes be called just to add an entry in the
2061 // hierarchy; the target URL and the source URL will be the same in
2063 // TODO/LATER: get rid of this old hack
2065 INetURLObject
aTargetObj( aTargetURL
);
2067 aTargetObj
.insertName( rTemplateName
, false,
2068 INetURLObject::LAST_SEGMENT
, true,
2069 INetURLObject::ENCODE_ALL
);
2070 aTargetObj
.setExtension( aSourceObj
.getExtension() );
2072 aTargetURL2
= aTargetObj
.GetMainURL( INetURLObject::NO_DECODE
);
2074 if ( aTargetURL2
== rSourceURL
)
2075 return addEntry( aGroup
, rTemplateName
, aTargetURL2
, aType
);
2078 /////////////////////////////////////////////////////
2079 // copy the template into the new group (targeturl)
2081 INetURLObject
aTmpURL( aSourceObj
);
2082 aTmpURL
.CutExtension();
2083 ::rtl::OUString aPattern
= aTmpURL
.getName( INetURLObject::LAST_SEGMENT
, true, INetURLObject::DECODE_WITH_CHARSET
);
2085 ::rtl::OUString aNewTemplateTargetURL
= CreateNewUniqueFileWithPrefix( aTargetURL
, aPattern
, aSourceObj
.getExtension() );
2086 INetURLObject
aNewTemplateTargetObj( aNewTemplateTargetURL
);
2087 ::rtl::OUString aNewTemplateTargetName
= aNewTemplateTargetObj
.getName( INetURLObject::LAST_SEGMENT
, true, INetURLObject::DECODE_WITH_CHARSET
);
2088 if ( !aNewTemplateTargetURL
.getLength() || !aNewTemplateTargetName
.getLength() )
2091 // get access to source file
2092 Content aSourceContent
;
2093 uno::Reference
< ucb::XCommandEnvironment
> xEnv
;
2094 INetURLObject
aSourceURL( rSourceURL
);
2095 if( ! Content::create( aSourceURL
.GetMainURL( INetURLObject::NO_DECODE
), xEnv
, aSourceContent
) )
2098 if( ! Content::create( aTargetURL
, xEnv
, aTargetGroup
) )
2101 // transfer source file
2104 if( ! aTargetGroup
.transferContent( aSourceContent
,
2105 InsertOperation_COPY
,
2106 aNewTemplateTargetName
,
2107 NameClash::OVERWRITE
) )
2110 // allow to edit the added template
2111 Content aResultContent
;
2112 if ( Content::create( aNewTemplateTargetURL
, xEnv
, aResultContent
) )
2114 ::rtl::OUString
aPropertyName( RTL_CONSTASCII_USTRINGPARAM( "IsReadOnly" ) );
2116 sal_Bool bReadOnly
= sal_False
;
2117 if ( getProperty( aResultContent
, aPropertyName
, aProperty
) && ( aProperty
>>= bReadOnly
) && bReadOnly
)
2118 setProperty( aResultContent
, aPropertyName
, uno::makeAny( (sal_Bool
)sal_False
) );
2121 catch ( ContentCreationException
& )
2122 { return sal_False
; }
2123 catch ( Exception
& )
2124 { return sal_False
; }
2127 // either the document has title and it is the same as requested, or we have to set it
2128 sal_Bool bCorrectTitle
= ( bDocHasTitle
&& aTitle
.equals( rTemplateName
) );
2129 if ( !bCorrectTitle
)
2131 if ( !bDocHasTitle
)
2133 INetURLObject
aNewTmpObj( aNewTemplateTargetObj
);
2134 aNewTmpObj
.CutExtension();
2135 bCorrectTitle
= ( aNewTmpObj
.getName( INetURLObject::LAST_SEGMENT
, true, INetURLObject::DECODE_WITH_CHARSET
).equals( rTemplateName
) );
2138 if ( !bCorrectTitle
)
2139 bCorrectTitle
= setTitleForURL( aNewTemplateTargetURL
, rTemplateName
);
2142 if ( bCorrectTitle
)
2144 // create a new entry in the hierarchy
2145 return addEntry( aGroup
, rTemplateName
, aNewTemplateTargetURL
, aType
);
2148 // TODO/LATER: The user could be notified here that the renaming has failed
2149 // create a new entry in the hierarchy
2150 addEntry( aGroup
, aTitle
, aNewTemplateTargetURL
, aType
);
2154 //-----------------------------------------------------------------------------
2155 sal_Bool
SfxDocTplService_Impl::removeTemplate( const OUString
& rGroupName
,
2156 const OUString
& rTemplateName
)
2158 ::osl::MutexGuard
aGuard( maMutex
);
2160 // Check, wether or not there is a group with this name
2161 // Return false, if there is no group with the given name
2162 Content aGroup
, aTemplate
;
2163 OUString aGroupURL
, aTemplateURL
;
2164 INetURLObject
aGroupObj( maRootURL
);
2166 aGroupObj
.insertName( rGroupName
, false,
2167 INetURLObject::LAST_SEGMENT
, true,
2168 INetURLObject::ENCODE_ALL
);
2169 aGroupURL
= aGroupObj
.GetMainURL( INetURLObject::NO_DECODE
);
2171 if ( ! Content::create( aGroupURL
, maCmdEnv
, aGroup
) )
2174 // Check, if there's a template with the given name in this group
2175 // Return false, if there is no template
2176 aGroupObj
.insertName( rTemplateName
, false,
2177 INetURLObject::LAST_SEGMENT
, true,
2178 INetURLObject::ENCODE_ALL
);
2179 aTemplateURL
= aGroupObj
.GetMainURL( INetURLObject::NO_DECODE
);
2181 if ( !Content::create( aTemplateURL
, maCmdEnv
, aTemplate
) )
2184 // get the target URL from the template
2185 OUString aTargetURL
;
2186 OUString
aPropName( RTL_CONSTASCII_USTRINGPARAM( TARGET_URL
) );
2189 if ( getProperty( aTemplate
, aPropName
, aValue
) )
2190 aValue
>>= aTargetURL
;
2192 // delete the target template
2193 if ( aTargetURL
.getLength() )
2195 if ( !maTemplateDirs
.getLength()
2196 || !::utl::UCBContentHelper::IsSubPath( maTemplateDirs
[ maTemplateDirs
.getLength() - 1 ], aTargetURL
) )
2199 removeContent( aTargetURL
);
2202 // delete the template entry
2203 return removeContent( aTemplate
);
2206 //-----------------------------------------------------------------------------
2207 sal_Bool
SfxDocTplService_Impl::renameTemplate( const OUString
& rGroupName
,
2208 const OUString
& rOldName
,
2209 const OUString
& rNewName
)
2211 ::osl::MutexGuard
aGuard( maMutex
);
2213 // Check, wether or not there is a group with this name
2214 // Return false, if there is no group with the given name
2215 Content aGroup
, aTemplate
;
2216 OUString aGroupURL
, aTemplateURL
;
2217 INetURLObject
aGroupObj( maRootURL
);
2219 aGroupObj
.insertName( rGroupName
, false,
2220 INetURLObject::LAST_SEGMENT
, true,
2221 INetURLObject::ENCODE_ALL
);
2222 aGroupURL
= aGroupObj
.GetMainURL( INetURLObject::NO_DECODE
);
2224 if ( ! Content::create( aGroupURL
, maCmdEnv
, aGroup
) )
2227 // Check, if there's a template with the new name in this group
2228 // Return false, if there is one
2229 aGroupObj
.insertName( rNewName
, false,
2230 INetURLObject::LAST_SEGMENT
, true,
2231 INetURLObject::ENCODE_ALL
);
2232 aTemplateURL
= aGroupObj
.GetMainURL( INetURLObject::NO_DECODE
);
2234 if ( Content::create( aTemplateURL
, maCmdEnv
, aTemplate
) )
2237 // Check, if there's a template with the old name in this group
2238 // Return false, if there is no template
2239 aGroupObj
.removeSegment();
2240 aGroupObj
.insertName( rOldName
, false,
2241 INetURLObject::LAST_SEGMENT
, true,
2242 INetURLObject::ENCODE_ALL
);
2243 aTemplateURL
= aGroupObj
.GetMainURL( INetURLObject::NO_DECODE
);
2245 if ( !Content::create( aTemplateURL
, maCmdEnv
, aTemplate
) )
2248 OUString aTemplateTargetURL
;
2249 OUString
aTargetProp( RTL_CONSTASCII_USTRINGPARAM( TARGET_URL
) );
2252 if ( getProperty( aTemplate
, aTargetProp
, aTargetValue
) )
2253 aTargetValue
>>= aTemplateTargetURL
;
2255 if ( !setTitleForURL( aTemplateTargetURL
, rNewName
) )
2258 // rename the template entry in the cache
2259 OUString
aTitleProp( RTL_CONSTASCII_USTRINGPARAM( TITLE
) );
2261 aTitleValue
<<= rNewName
;
2263 return setProperty( aTemplate
, aTitleProp
, aTitleValue
);
2266 //-----------------------------------------------------------------------------
2267 //-----------------------------------------------------------------------------
2268 //-----------------------------------------------------------------------------
2270 SFX_IMPL_XSERVICEINFO( SfxDocTplService
, TEMPLATE_SERVICE_NAME
, TEMPLATE_IMPLEMENTATION_NAME
)
2271 SFX_IMPL_SINGLEFACTORY( SfxDocTplService
)
2273 //-----------------------------------------------------------------------------
2274 SfxDocTplService::SfxDocTplService( const uno::Reference
< XMultiServiceFactory
>& xFactory
)
2276 pImp
= new SfxDocTplService_Impl( xFactory
);
2279 //-----------------------------------------------------------------------------
2281 SfxDocTplService::~SfxDocTplService()
2286 //-----------------------------------------------------------------------------
2287 //--- XLocalizable ---
2288 //-----------------------------------------------------------------------------
2290 Locale SAL_CALL
SfxDocTplService::getLocale()
2291 throw( RUNTIMEEXCEPTION
)
2293 return pImp
->getLocale();
2296 //-----------------------------------------------------------------------------
2298 void SAL_CALL
SfxDocTplService::setLocale( const Locale
& rLocale
)
2299 throw( RUNTIMEEXCEPTION
)
2301 pImp
->setLocale( rLocale
);
2304 //-----------------------------------------------------------------------------
2305 //--- XDocumentTemplates ---
2306 //-----------------------------------------------------------------------------
2307 uno::Reference
< XCONTENT
> SAL_CALL
SfxDocTplService::getContent()
2308 throw( RUNTIMEEXCEPTION
)
2311 return pImp
->getContent().get();
2316 //-----------------------------------------------------------------------------
2317 sal_Bool SAL_CALL
SfxDocTplService::storeTemplate( const OUString
& GroupName
,
2318 const OUString
& TemplateName
,
2319 const uno::Reference
< XSTORABLE
>& Storable
)
2320 throw( RUNTIMEEXCEPTION
)
2323 return pImp
->storeTemplate( GroupName
, TemplateName
, Storable
);
2328 //-----------------------------------------------------------------------------
2329 sal_Bool SAL_CALL
SfxDocTplService::addTemplate( const OUString
& rGroupName
,
2330 const OUString
& rTemplateName
,
2331 const OUString
& rSourceURL
)
2332 throw( RUNTIMEEXCEPTION
)
2335 return pImp
->addTemplate( rGroupName
, rTemplateName
, rSourceURL
);
2340 //-----------------------------------------------------------------------------
2341 sal_Bool SAL_CALL
SfxDocTplService::removeTemplate( const OUString
& rGroupName
,
2342 const OUString
& rTemplateName
)
2343 throw( RUNTIMEEXCEPTION
)
2346 return pImp
->removeTemplate( rGroupName
, rTemplateName
);
2351 //-----------------------------------------------------------------------------
2352 sal_Bool SAL_CALL
SfxDocTplService::renameTemplate( const OUString
& rGroupName
,
2353 const OUString
& rOldName
,
2354 const OUString
& rNewName
)
2355 throw( RUNTIMEEXCEPTION
)
2357 if ( rOldName
== rNewName
)
2361 return pImp
->renameTemplate( rGroupName
, rOldName
, rNewName
);
2366 //-----------------------------------------------------------------------------
2367 sal_Bool SAL_CALL
SfxDocTplService::addGroup( const OUString
& rGroupName
)
2368 throw( RUNTIMEEXCEPTION
)
2371 return pImp
->addGroup( rGroupName
);
2376 //-----------------------------------------------------------------------------
2377 sal_Bool SAL_CALL
SfxDocTplService::removeGroup( const OUString
& rGroupName
)
2378 throw( RUNTIMEEXCEPTION
)
2381 return pImp
->removeGroup( rGroupName
);
2386 //-----------------------------------------------------------------------------
2387 sal_Bool SAL_CALL
SfxDocTplService::renameGroup( const OUString
& rOldName
,
2388 const OUString
& rNewName
)
2389 throw( RUNTIMEEXCEPTION
)
2391 if ( rOldName
== rNewName
)
2395 return pImp
->renameGroup( rOldName
, rNewName
);
2400 //-----------------------------------------------------------------------------
2401 void SAL_CALL
SfxDocTplService::update()
2402 throw( RUNTIMEEXCEPTION
)
2405 pImp
->update( sal_True
);
2408 //-----------------------------------------------------------------------------
2409 //-----------------------------------------------------------------------------
2410 //------------------------------------------------------------------------
2412 Updater_Impl::Updater_Impl( SfxDocTplService_Impl
* pTemplates
)
2414 mpDocTemplates
= pTemplates
;
2417 //------------------------------------------------------------------------
2418 Updater_Impl::~Updater_Impl()
2422 //------------------------------------------------------------------------
2423 void SAL_CALL
Updater_Impl::run()
2425 mpDocTemplates
->doUpdate();
2428 //------------------------------------------------------------------------
2429 void SAL_CALL
Updater_Impl::onTerminated()
2431 mpDocTemplates
->finished();
2435 //-----------------------------------------------------------------------------
2436 //-----------------------------------------------------------------------------
2437 //-----------------------------------------------------------------------------
2438 WaitWindow_Impl::WaitWindow_Impl()
2439 : WorkWindow( NULL
, WB_BORDER
| WB_3DLOOK
)
2441 Rectangle aRect
= Rectangle( 0, 0, 300, 30000 );
2442 _nTextStyle
= TEXT_DRAW_CENTER
| TEXT_DRAW_VCENTER
| TEXT_DRAW_WORDBREAK
| TEXT_DRAW_MULTILINE
;
2443 _aText
= String( SfxResId( RID_CNT_STR_WAITING
) );
2444 _aRect
= GetTextRect( aRect
, _aText
, _nTextStyle
);
2446 aRect
.Right() += 2*X_OFFSET
;
2447 aRect
.Bottom() += 2*Y_OFFSET
;
2448 _aRect
.SetPos( Point( X_OFFSET
, Y_OFFSET
) );
2449 SetOutputSizePixel( aRect
.GetSize() );
2455 //-----------------------------------------------------------------------------
2456 WaitWindow_Impl::~WaitWindow_Impl()
2461 //-----------------------------------------------------------------------------
2462 void WaitWindow_Impl::Paint( const Rectangle
& /*rRect*/ )
2464 DrawText( _aRect
, _aText
, _nTextStyle
);
2467 //-----------------------------------------------------------------------------
2468 //-----------------------------------------------------------------------------
2469 //-----------------------------------------------------------------------------
2470 void SfxDocTplService_Impl::addHierGroup( GroupList_Impl
& rList
,
2471 const OUString
& rTitle
,
2472 const OUString
& rOwnURL
)
2474 // now get the content of the Group
2476 uno::Reference
< XResultSet
> xResultSet
;
2477 Sequence
< OUString
> aProps(3);
2479 aProps
[0] = OUString::createFromAscii( TITLE
);
2480 aProps
[1] = OUString::createFromAscii( TARGET_URL
);
2481 aProps
[2] = OUString::createFromAscii( PROPERTY_TYPE
);
2485 aContent
= Content( rOwnURL
, maCmdEnv
);
2486 ResultSetInclude eInclude
= INCLUDE_DOCUMENTS_ONLY
;
2487 xResultSet
= aContent
.createCursor( aProps
, eInclude
);
2489 catch ( ContentCreationException
& )
2491 DBG_ERRORFILE( "addHierGroup: ContentCreationException" );
2493 catch ( Exception
& ) {}
2495 if ( xResultSet
.is() )
2497 GroupData_Impl
*pGroup
= new GroupData_Impl( rTitle
);
2498 pGroup
->setHierarchy( sal_True
);
2499 pGroup
->setHierarchyURL( rOwnURL
);
2500 rList
.Insert( pGroup
);
2502 uno::Reference
< XContentAccess
> xContentAccess( xResultSet
, UNO_QUERY
);
2503 uno::Reference
< XRow
> xRow( xResultSet
, UNO_QUERY
);
2507 while ( xResultSet
->next() )
2509 BOOL bUpdateType
= sal_False
;
2510 DocTemplates_EntryData_Impl
*pData
;
2512 OUString
aTitle( xRow
->getString( 1 ) );
2513 OUString
aTargetDir( xRow
->getString( 2 ) );
2514 OUString
aType( xRow
->getString( 3 ) );
2515 OUString aHierURL
= xContentAccess
->queryContentIdentifierString();
2517 if ( !aType
.getLength() )
2521 sal_Bool bDocHasTitle
= sal_False
;
2522 if( !getTitleFromURL( aTargetDir
, aTmpTitle
, aType
, bDocHasTitle
) )
2524 DBG_ERRORFILE( "addHierGroup(): template of alien format" );
2528 if ( aType
.getLength() )
2529 bUpdateType
= sal_True
;
2532 pData
= pGroup
->addEntry( aTitle
, aTargetDir
, aType
, aHierURL
);
2533 pData
->setUpdateType( bUpdateType
);
2536 catch ( Exception
& ) {}
2540 //-----------------------------------------------------------------------------
2541 void SfxDocTplService_Impl::addFsysGroup( GroupList_Impl
& rList
,
2542 const OUString
& rTitle
,
2543 const OUString
& rUITitle
,
2544 const OUString
& rOwnURL
,
2545 sal_Bool bWriteableGroup
)
2547 ::rtl::OUString aTitle
;
2549 if ( !rUITitle
.getLength() )
2551 // reserved FS names that should not be used
2552 if ( rTitle
.compareToAscii( "wizard" ) == 0 )
2554 else if ( rTitle
.compareToAscii( "internal" ) == 0 )
2557 aTitle
= getLongName( rTitle
);
2562 if ( !aTitle
.getLength() )
2565 GroupData_Impl
*pGroup
= rList
.First();
2567 while ( pGroup
&& pGroup
->getTitle() != aTitle
)
2568 pGroup
= rList
.Next();
2572 pGroup
= new GroupData_Impl( aTitle
);
2573 rList
.Insert( pGroup
);
2576 if ( bWriteableGroup
)
2577 pGroup
->setTargetURL( rOwnURL
);
2581 // now get the content of the Group
2583 uno::Reference
< XResultSet
> xResultSet
;
2584 Sequence
< OUString
> aProps(1);
2585 aProps
[0] = OUString::createFromAscii( TITLE
);
2589 // this method is only used during checking of the available template-folders
2590 // that should happen quietly
2591 uno::Reference
< XCommandEnvironment
> aQuietEnv
;
2592 aContent
= Content( rOwnURL
, aQuietEnv
);
2593 ResultSetInclude eInclude
= INCLUDE_DOCUMENTS_ONLY
;
2594 xResultSet
= aContent
.createCursor( aProps
, eInclude
);
2596 catch ( Exception
& ) {}
2598 if ( xResultSet
.is() )
2600 uno::Reference
< XContentAccess
> xContentAccess( xResultSet
, UNO_QUERY
);
2601 uno::Reference
< XRow
> xRow( xResultSet
, UNO_QUERY
);
2605 while ( xResultSet
->next() )
2607 OUString
aChildTitle( xRow
->getString( 1 ) );
2608 OUString aTargetURL
= xContentAccess
->queryContentIdentifierString();
2612 if ( aChildTitle
.compareToAscii( "sfx.tlx" ) == 0
2613 || aChildTitle
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "groupuinames.xml" ) ) )
2616 // only StarOffice templates are accepted
2617 sal_Bool bDocHasTitle
= sal_False
;
2618 if( !getTitleFromURL( aTargetURL
, aChildTitle
, aType
, bDocHasTitle
) )
2621 pGroup
->addEntry( aChildTitle
, aTargetURL
, aType
, aHierURL
);
2624 catch ( Exception
& ) {}
2628 // -----------------------------------------------------------------------
2629 void SfxDocTplService_Impl::createFromContent( GroupList_Impl
& rList
,
2631 sal_Bool bHierarchy
,
2632 sal_Bool bWriteableContent
)
2634 OUString aTargetURL
= rContent
.get()->getIdentifier()->getContentIdentifier();
2636 // when scanning the file system, we have to add the 'standard' group, too
2639 OUString aUIStdTitle
= getLongName( OUString( RTL_CONSTASCII_USTRINGPARAM( STANDARD_FOLDER
) ) );
2640 addFsysGroup( rList
, ::rtl::OUString(), aUIStdTitle
, aTargetURL
, bWriteableContent
);
2643 // search for predefined UI names
2644 INetURLObject
aLayerObj( aTargetURL
);
2646 // TODO/LATER: Use hashmap in future
2647 uno::Sequence
< beans::StringPair
> aUINames
;
2649 aUINames
= ReadUINamesForTemplateDir_Impl( aLayerObj
.GetMainURL( INetURLObject::NO_DECODE
) );
2651 uno::Reference
< XResultSet
> xResultSet
;
2652 Sequence
< OUString
> aProps(1);
2653 aProps
[0] = OUString::createFromAscii( TITLE
);
2657 ResultSetInclude eInclude
= INCLUDE_FOLDERS_ONLY
;
2658 xResultSet
= rContent
.createCursor( aProps
, eInclude
);
2660 catch ( Exception
& ) {}
2662 if ( xResultSet
.is() )
2664 uno::Reference
< XContentAccess
> xContentAccess( xResultSet
, UNO_QUERY
);
2665 uno::Reference
< XRow
> xRow( xResultSet
, UNO_QUERY
);
2669 while ( xResultSet
->next() )
2671 // TODO/LATER: clarify the encoding of the Title
2672 OUString
aTitle( xRow
->getString( 1 ) );
2673 OUString
aTargetSubfolderURL( xContentAccess
->queryContentIdentifierString() );
2676 addHierGroup( rList
, aTitle
, aTargetSubfolderURL
);
2679 ::rtl::OUString aUITitle
;
2680 for ( sal_Int32 nInd
= 0; nInd
< aUINames
.getLength(); nInd
++ )
2681 if ( aUINames
[nInd
].First
.equals( aTitle
) )
2683 aUITitle
= aUINames
[nInd
].Second
;
2687 addFsysGroup( rList
, aTitle
, aUITitle
, aTargetSubfolderURL
, bWriteableContent
);
2691 catch ( Exception
& ) {}
2695 //-----------------------------------------------------------------------------
2696 void SfxDocTplService_Impl::removeFromHierarchy( DocTemplates_EntryData_Impl
*pData
)
2700 if ( Content::create( pData
->getHierarchyURL(), maCmdEnv
, aTemplate
) )
2702 removeContent( aTemplate
);
2706 //-----------------------------------------------------------------------------
2707 void SfxDocTplService_Impl::addToHierarchy( GroupData_Impl
*pGroup
,
2708 DocTemplates_EntryData_Impl
*pData
)
2710 Content aGroup
, aTemplate
;
2712 if ( ! Content::create( pGroup
->getHierarchyURL(), maCmdEnv
, aGroup
) )
2715 // Check, if there's a template with the given name in this group
2716 // Return if there is already a template
2717 INetURLObject
aGroupObj( pGroup
->getHierarchyURL() );
2719 aGroupObj
.insertName( pData
->getTitle(), false,
2720 INetURLObject::LAST_SEGMENT
, true,
2721 INetURLObject::ENCODE_ALL
);
2723 OUString aTemplateURL
= aGroupObj
.GetMainURL( INetURLObject::NO_DECODE
);
2725 if ( Content::create( aTemplateURL
, maCmdEnv
, aTemplate
) )
2728 addEntry( aGroup
, pData
->getTitle(),
2729 pData
->getTargetURL(),
2733 //-----------------------------------------------------------------------------
2734 void SfxDocTplService_Impl::updateData( DocTemplates_EntryData_Impl
*pData
)
2738 if ( ! Content::create( pData
->getHierarchyURL(), maCmdEnv
, aTemplate
) )
2743 if ( pData
->getUpdateType() )
2745 aPropName
= OUString( RTL_CONSTASCII_USTRINGPARAM( PROPERTY_TYPE
) );
2746 setProperty( aTemplate
, aPropName
, makeAny( pData
->getType() ) );
2749 if ( pData
->getUpdateLink() )
2751 aPropName
= OUString( RTL_CONSTASCII_USTRINGPARAM( TARGET_URL
) );
2752 setProperty( aTemplate
, aPropName
, makeAny( pData
->getTargetURL() ) );
2756 //-----------------------------------------------------------------------------
2757 void SfxDocTplService_Impl::addGroupToHierarchy( GroupData_Impl
*pGroup
)
2759 OUString
aAdditionalProp( RTL_CONSTASCII_USTRINGPARAM( TARGET_DIR_URL
) );
2762 INetURLObject
aNewGroupObj( maRootURL
);
2763 aNewGroupObj
.insertName( pGroup
->getTitle(), false,
2764 INetURLObject::LAST_SEGMENT
, true,
2765 INetURLObject::ENCODE_ALL
);
2767 OUString aNewGroupURL
= aNewGroupObj
.GetMainURL( INetURLObject::NO_DECODE
);
2769 if ( createFolder( aNewGroupURL
, sal_False
, sal_False
, aGroup
) )
2771 setProperty( aGroup
, aAdditionalProp
, makeAny( pGroup
->getTargetURL() ) );
2772 pGroup
->setHierarchyURL( aNewGroupURL
);
2774 ULONG nCount
= pGroup
->count();
2775 for ( ULONG i
=0; i
<nCount
; i
++ )
2777 DocTemplates_EntryData_Impl
*pData
= pGroup
->getEntry( i
);
2778 addToHierarchy( pGroup
, pData
); // add entry to hierarchy
2783 //-----------------------------------------------------------------------------
2784 void SfxDocTplService_Impl::removeFromHierarchy( GroupData_Impl
*pGroup
)
2788 if ( Content::create( pGroup
->getHierarchyURL(), maCmdEnv
, aGroup
) )
2790 removeContent( aGroup
);
2794 // -----------------------------------------------------------------------
2795 // -----------------------------------------------------------------------
2796 // -----------------------------------------------------------------------
2797 GroupData_Impl::GroupData_Impl( const OUString
& rTitle
)
2800 mbInUse
= sal_False
;
2801 mbInHierarchy
= sal_False
;
2804 // -----------------------------------------------------------------------
2805 GroupData_Impl::~GroupData_Impl()
2807 DocTemplates_EntryData_Impl
*pData
= maEntries
.First();
2811 pData
= maEntries
.Next();
2815 // -----------------------------------------------------------------------
2816 DocTemplates_EntryData_Impl
* GroupData_Impl::addEntry( const OUString
& rTitle
,
2817 const OUString
& rTargetURL
,
2818 const OUString
& rType
,
2819 const OUString
& rHierURL
)
2821 DocTemplates_EntryData_Impl
*pData
= maEntries
.First();
2823 while ( pData
&& pData
->getTitle() != rTitle
)
2824 pData
= maEntries
.Next();
2828 pData
= new DocTemplates_EntryData_Impl( rTitle
);
2829 pData
->setTargetURL( rTargetURL
);
2830 pData
->setType( rType
);
2831 if ( rHierURL
.getLength() )
2833 pData
->setHierarchyURL( rHierURL
);
2834 pData
->setHierarchy( sal_True
);
2836 maEntries
.Insert( pData
);
2840 if ( rHierURL
.getLength() )
2842 pData
->setHierarchyURL( rHierURL
);
2843 pData
->setHierarchy( sal_True
);
2846 if ( pData
->getInHierarchy() )
2849 if ( rTargetURL
!= pData
->getTargetURL() )
2851 pData
->setTargetURL( rTargetURL
);
2852 pData
->setUpdateLink( sal_True
);
2859 // -----------------------------------------------------------------------
2860 // -----------------------------------------------------------------------
2861 // -----------------------------------------------------------------------
2862 DocTemplates_EntryData_Impl::DocTemplates_EntryData_Impl( const OUString
& rTitle
)
2865 mbInUse
= sal_False
;
2866 mbInHierarchy
= sal_False
;
2867 mbUpdateType
= sal_False
;
2868 mbUpdateLink
= sal_False
;
2871 // -----------------------------------------------------------------------
2872 SfxURLRelocator_Impl::SfxURLRelocator_Impl( uno::Reference
< XMultiServiceFactory
> xFactory
)
2873 : mxFactory( xFactory
)
2877 // -----------------------------------------------------------------------
2878 SfxURLRelocator_Impl::~SfxURLRelocator_Impl()
2882 // -----------------------------------------------------------------------
2883 void SfxURLRelocator_Impl::initOfficeInstDirs()
2885 if ( !mxOfficeInstDirs
.is() )
2887 osl::MutexGuard
aGuard( maMutex
);
2888 if ( !mxOfficeInstDirs
.is() )
2890 OSL_ENSURE( mxFactory
.is(), "No service manager!" );
2892 uno::Reference
< XComponentContext
> xCtx
;
2893 uno::Reference
< XPropertySet
> xPropSet( mxFactory
, UNO_QUERY
);
2894 if ( xPropSet
.is() )
2896 xPropSet
->getPropertyValue(
2898 RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ) ) )
2902 OSL_ENSURE( xCtx
.is(),
2903 "Unable to obtain component context from "
2904 "service manager!" );
2908 xCtx
->getValueByName(
2909 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
2911 "com.sun.star.util.theOfficeInstallationDirectories" ) ) )
2912 >>= mxOfficeInstDirs
;
2915 OSL_ENSURE( mxOfficeInstDirs
.is(),
2916 "Unable to obtain office installation directory "
2922 // -----------------------------------------------------------------------
2923 void SfxURLRelocator_Impl::makeRelocatableURL( rtl::OUString
& rURL
)
2925 if ( rURL
.getLength() > 0 )
2927 initOfficeInstDirs();
2928 rURL
= mxOfficeInstDirs
->makeRelocatableURL( rURL
);
2932 // -----------------------------------------------------------------------
2933 void SfxURLRelocator_Impl::makeAbsoluteURL( rtl::OUString
& rURL
)
2935 if ( rURL
.getLength() > 0 )
2937 initOfficeInstDirs();
2938 rURL
= mxOfficeInstDirs
->makeAbsoluteURL( rURL
);