xref: /AOO41X/main/sfx2/source/doc/doctemplates.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_sfx2.hxx"
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir #include "doctemplates.hxx"
32*cdf0e10cSrcweir #include <vos/mutex.hxx>
33*cdf0e10cSrcweir #include <tools/debug.hxx>
34*cdf0e10cSrcweir #include <tools/diagnose_ex.h>
35*cdf0e10cSrcweir #include <tools/urlobj.hxx>
36*cdf0e10cSrcweir #include <rtl/ustring.hxx>
37*cdf0e10cSrcweir #include <rtl/ustrbuf.hxx>
38*cdf0e10cSrcweir #ifndef _SV_RESARY_HXX
39*cdf0e10cSrcweir #include <tools/resary.hxx>
40*cdf0e10cSrcweir #endif
41*cdf0e10cSrcweir #include <vcl/svapp.hxx>
42*cdf0e10cSrcweir #include <vcl/wrkwin.hxx>
43*cdf0e10cSrcweir #include <comphelper/sequenceashashmap.hxx>
44*cdf0e10cSrcweir #include <unotools/pathoptions.hxx>
45*cdf0e10cSrcweir #include <comphelper/processfactory.hxx>
46*cdf0e10cSrcweir #include <comphelper/componentcontext.hxx>
47*cdf0e10cSrcweir #include <com/sun/star/beans/PropertyAttribute.hpp>
48*cdf0e10cSrcweir #include <com/sun/star/beans/XPropertySet.hpp>
49*cdf0e10cSrcweir #include <com/sun/star/beans/XPropertySetInfo.hpp>
50*cdf0e10cSrcweir #include <com/sun/star/beans/XPropertyContainer.hpp>
51*cdf0e10cSrcweir #include <com/sun/star/beans/StringPair.hpp>
52*cdf0e10cSrcweir #include <com/sun/star/container/XContainerQuery.hpp>
53*cdf0e10cSrcweir #include <com/sun/star/document/XTypeDetection.hpp>
54*cdf0e10cSrcweir #include <com/sun/star/document/XStandaloneDocumentInfo.hpp>
55*cdf0e10cSrcweir #include <com/sun/star/sdbc/XResultSet.hpp>
56*cdf0e10cSrcweir #include <com/sun/star/sdbc/XRow.hpp>
57*cdf0e10cSrcweir #include <com/sun/star/ucb/NameClash.hpp>
58*cdf0e10cSrcweir #include <com/sun/star/ucb/NameClashException.hpp>
59*cdf0e10cSrcweir #include <com/sun/star/ucb/TransferInfo.hpp>
60*cdf0e10cSrcweir #include <com/sun/star/ucb/XCommandEnvironment.hpp>
61*cdf0e10cSrcweir #include <com/sun/star/ucb/XContentAccess.hpp>
62*cdf0e10cSrcweir #include <com/sun/star/frame/XModuleManager.hpp>
63*cdf0e10cSrcweir #include <com/sun/star/uno/Exception.hpp>
64*cdf0e10cSrcweir 
65*cdf0e10cSrcweir #include <svtools/templatefoldercache.hxx>
66*cdf0e10cSrcweir #include <unotools/configmgr.hxx>
67*cdf0e10cSrcweir #include <unotools/ucbhelper.hxx>
68*cdf0e10cSrcweir 
69*cdf0e10cSrcweir #include "sfx2/sfxresid.hxx"
70*cdf0e10cSrcweir #include "sfxurlrelocator.hxx"
71*cdf0e10cSrcweir #include "doctemplateslocal.hxx"
72*cdf0e10cSrcweir #include <sfx2/docfac.hxx>
73*cdf0e10cSrcweir #include <sfx2/docfile.hxx>
74*cdf0e10cSrcweir #include "doc.hrc"
75*cdf0e10cSrcweir 
76*cdf0e10cSrcweir //-----------------------------------------------------------------------------
77*cdf0e10cSrcweir 
78*cdf0e10cSrcweir //=============================================================================
79*cdf0e10cSrcweir 
80*cdf0e10cSrcweir #define TEMPLATE_SERVICE_NAME				"com.sun.star.frame.DocumentTemplates"
81*cdf0e10cSrcweir #define TEMPLATE_IMPLEMENTATION_NAME		"com.sun.star.comp.sfx2.DocumentTemplates"
82*cdf0e10cSrcweir 
83*cdf0e10cSrcweir #define SERVICENAME_TYPEDETECTION			"com.sun.star.document.TypeDetection"
84*cdf0e10cSrcweir #define SERVICENAME_DOCINFO					"com.sun.star.document.StandaloneDocumentInfo"
85*cdf0e10cSrcweir 
86*cdf0e10cSrcweir #define TEMPLATE_ROOT_URL		"vnd.sun.star.hier:/templates"
87*cdf0e10cSrcweir #define TITLE					"Title"
88*cdf0e10cSrcweir #define IS_FOLDER				"IsFolder"
89*cdf0e10cSrcweir #define IS_DOCUMENT				"IsDocument"
90*cdf0e10cSrcweir #define TARGET_URL				"TargetURL"
91*cdf0e10cSrcweir #define TEMPLATE_VERSION		"TemplateComponentVersion"
92*cdf0e10cSrcweir #define TEMPLATE_VERSION_VALUE	"2"
93*cdf0e10cSrcweir #define TYPE_FOLDER				"application/vnd.sun.star.hier-folder"
94*cdf0e10cSrcweir #define TYPE_LINK				"application/vnd.sun.star.hier-link"
95*cdf0e10cSrcweir #define TYPE_FSYS_FOLDER		"application/vnd.sun.staroffice.fsys-folder"
96*cdf0e10cSrcweir #define TYPE_FSYS_FILE			"application/vnd.sun.staroffice.fsys-file"
97*cdf0e10cSrcweir 
98*cdf0e10cSrcweir #define PROPERTY_DIRLIST		"DirectoryList"
99*cdf0e10cSrcweir #define PROPERTY_NEEDSUPDATE	"NeedsUpdate"
100*cdf0e10cSrcweir #define PROPERTY_TYPE			"TypeDescription"
101*cdf0e10cSrcweir 
102*cdf0e10cSrcweir #define TARGET_DIR_URL			"TargetDirURL"
103*cdf0e10cSrcweir #define COMMAND_DELETE			"delete"
104*cdf0e10cSrcweir #define COMMAND_TRANSFER		"transfer"
105*cdf0e10cSrcweir 
106*cdf0e10cSrcweir #define STANDARD_FOLDER			"standard"
107*cdf0e10cSrcweir 
108*cdf0e10cSrcweir #define	C_DELIM					';'
109*cdf0e10cSrcweir 
110*cdf0e10cSrcweir //=============================================================================
111*cdf0e10cSrcweir 
112*cdf0e10cSrcweir using namespace ::com::sun::star;
113*cdf0e10cSrcweir using namespace ::com::sun::star::beans;
114*cdf0e10cSrcweir using namespace ::com::sun::star::document;
115*cdf0e10cSrcweir using namespace ::com::sun::star::io;
116*cdf0e10cSrcweir using namespace ::com::sun::star::lang;
117*cdf0e10cSrcweir using namespace ::com::sun::star::sdbc;
118*cdf0e10cSrcweir using namespace ::com::sun::star::ucb;
119*cdf0e10cSrcweir using namespace ::com::sun::star::uno;
120*cdf0e10cSrcweir using namespace ::com::sun::star::container;
121*cdf0e10cSrcweir using namespace ::com::sun::star::util;
122*cdf0e10cSrcweir 
123*cdf0e10cSrcweir using namespace ::rtl;
124*cdf0e10cSrcweir using namespace ::ucbhelper;
125*cdf0e10cSrcweir using namespace ::comphelper;
126*cdf0e10cSrcweir 
127*cdf0e10cSrcweir //=============================================================================
128*cdf0e10cSrcweir 
129*cdf0e10cSrcweir class WaitWindow_Impl : public WorkWindow
130*cdf0e10cSrcweir {
131*cdf0e10cSrcweir     Rectangle   _aRect;
132*cdf0e10cSrcweir     sal_uInt16      _nTextStyle;
133*cdf0e10cSrcweir     String      _aText;
134*cdf0e10cSrcweir 
135*cdf0e10cSrcweir     public:
136*cdf0e10cSrcweir                      WaitWindow_Impl();
137*cdf0e10cSrcweir                     ~WaitWindow_Impl();
138*cdf0e10cSrcweir     virtual void     Paint( const Rectangle& rRect );
139*cdf0e10cSrcweir };
140*cdf0e10cSrcweir 
141*cdf0e10cSrcweir #define X_OFFSET 15
142*cdf0e10cSrcweir #define Y_OFFSET 15
143*cdf0e10cSrcweir 
144*cdf0e10cSrcweir //=============================================================================
145*cdf0e10cSrcweir 
146*cdf0e10cSrcweir struct NamePair_Impl
147*cdf0e10cSrcweir {
148*cdf0e10cSrcweir     OUString maShortName;
149*cdf0e10cSrcweir     OUString maLongName;
150*cdf0e10cSrcweir };
151*cdf0e10cSrcweir 
152*cdf0e10cSrcweir DECLARE_LIST( NameList_Impl, NamePair_Impl* )
153*cdf0e10cSrcweir 
154*cdf0e10cSrcweir class Updater_Impl;
155*cdf0e10cSrcweir class GroupList_Impl;
156*cdf0e10cSrcweir class DocTemplates_EntryData_Impl;
157*cdf0e10cSrcweir class GroupData_Impl;
158*cdf0e10cSrcweir 
159*cdf0e10cSrcweir //=============================================================================
160*cdf0e10cSrcweir #include <com/sun/star/task/XInteractionHandler.hpp>
161*cdf0e10cSrcweir #include <com/sun/star/ucb/XProgressHandler.hpp>
162*cdf0e10cSrcweir #include <com/sun/star/ucb/XCommandEnvironment.hpp>
163*cdf0e10cSrcweir 
164*cdf0e10cSrcweir class TplTaskEnvironment : public ::cppu::WeakImplHelper1< ucb::XCommandEnvironment >
165*cdf0e10cSrcweir {
166*cdf0e10cSrcweir 	uno::Reference< task::XInteractionHandler >               m_xInteractionHandler;
167*cdf0e10cSrcweir 	uno::Reference< ucb::XProgressHandler >                   m_xProgressHandler;
168*cdf0e10cSrcweir 
169*cdf0e10cSrcweir public:
170*cdf0e10cSrcweir 	TplTaskEnvironment( const uno::Reference< task::XInteractionHandler>& rxInteractionHandler )
171*cdf0e10cSrcweir                                 : m_xInteractionHandler( rxInteractionHandler )
172*cdf0e10cSrcweir                             {}
173*cdf0e10cSrcweir 
174*cdf0e10cSrcweir 	virtual uno::Reference<task::XInteractionHandler> SAL_CALL getInteractionHandler() throw (uno::RuntimeException)
175*cdf0e10cSrcweir 	{ return m_xInteractionHandler; }
176*cdf0e10cSrcweir 
177*cdf0e10cSrcweir 	virtual uno::Reference<ucb::XProgressHandler> SAL_CALL    getProgressHandler() throw (uno::RuntimeException)
178*cdf0e10cSrcweir 	{ return m_xProgressHandler; }
179*cdf0e10cSrcweir };
180*cdf0e10cSrcweir 
181*cdf0e10cSrcweir class SfxDocTplService_Impl
182*cdf0e10cSrcweir {
183*cdf0e10cSrcweir     uno::Reference< XMultiServiceFactory >           mxFactory;
184*cdf0e10cSrcweir     uno::Reference< XCommandEnvironment >            maCmdEnv;
185*cdf0e10cSrcweir     uno::Reference< XStandaloneDocumentInfo >        mxInfo;
186*cdf0e10cSrcweir     uno::Reference< XTypeDetection >                 mxType;
187*cdf0e10cSrcweir 
188*cdf0e10cSrcweir 	::osl::Mutex				maMutex;
189*cdf0e10cSrcweir 	Sequence< OUString >		maTemplateDirs;
190*cdf0e10cSrcweir 	OUString					maRootURL;
191*cdf0e10cSrcweir 	NameList_Impl				maNames;
192*cdf0e10cSrcweir 	Locale						maLocale;
193*cdf0e10cSrcweir 	Content						maRootContent;
194*cdf0e10cSrcweir 	Updater_Impl*				mpUpdater;
195*cdf0e10cSrcweir 	sal_Bool					mbIsInitialized : 1;
196*cdf0e10cSrcweir 	sal_Bool					mbLocaleSet		: 1;
197*cdf0e10cSrcweir 
198*cdf0e10cSrcweir 	SfxURLRelocator_Impl		maRelocator;
199*cdf0e10cSrcweir 
200*cdf0e10cSrcweir 	void						init_Impl();
201*cdf0e10cSrcweir 	void						getDefaultLocale();
202*cdf0e10cSrcweir 	void						getDirList();
203*cdf0e10cSrcweir 	void						readFolderList();
204*cdf0e10cSrcweir     sal_Bool                    needsUpdate();
205*cdf0e10cSrcweir 	OUString					getLongName( const OUString& rShortName );
206*cdf0e10cSrcweir 	sal_Bool					setTitleForURL( const OUString& rURL, const OUString& aTitle );
207*cdf0e10cSrcweir 	sal_Bool					getTitleFromURL( const OUString& rURL, OUString& aTitle, OUString& aType, sal_Bool& bDocHasTitle );
208*cdf0e10cSrcweir 
209*cdf0e10cSrcweir 	sal_Bool					addEntry( Content& rParentFolder,
210*cdf0e10cSrcweir                                           const OUString& rTitle,
211*cdf0e10cSrcweir                                           const OUString& rTargetURL,
212*cdf0e10cSrcweir                                           const OUString& rType );
213*cdf0e10cSrcweir 
214*cdf0e10cSrcweir     sal_Bool                    createFolder( const OUString& rNewFolderURL,
215*cdf0e10cSrcweir                                               sal_Bool  bCreateParent,
216*cdf0e10cSrcweir                                               sal_Bool  bFsysFolder,
217*cdf0e10cSrcweir                                               Content   &rNewFolder );
218*cdf0e10cSrcweir 
219*cdf0e10cSrcweir 	sal_Bool					CreateNewUniqueFolderWithPrefix( const ::rtl::OUString& aPath,
220*cdf0e10cSrcweir 																const ::rtl::OUString& aPrefix,
221*cdf0e10cSrcweir 																::rtl::OUString& aNewFolderName,
222*cdf0e10cSrcweir 																::rtl::OUString& aNewFolderURL,
223*cdf0e10cSrcweir 																Content& aNewFolder );
224*cdf0e10cSrcweir 	::rtl::OUString				CreateNewUniqueFileWithPrefix( const ::rtl::OUString& aPath,
225*cdf0e10cSrcweir 																const ::rtl::OUString& aPrefix,
226*cdf0e10cSrcweir 																const ::rtl::OUString& aExt );
227*cdf0e10cSrcweir 
228*cdf0e10cSrcweir 	uno::Sequence< beans::StringPair > ReadUINamesForTemplateDir_Impl( const ::rtl::OUString& aUserPath );
229*cdf0e10cSrcweir 	sal_Bool					UpdateUINamesForTemplateDir_Impl( const ::rtl::OUString& aUserPath,
230*cdf0e10cSrcweir 																  const ::rtl::OUString& aGroupName,
231*cdf0e10cSrcweir 																  const ::rtl::OUString& aNewFolderName );
232*cdf0e10cSrcweir 	sal_Bool					ReplaceUINamesForTemplateDir_Impl( const ::rtl::OUString& aUserPath,
233*cdf0e10cSrcweir 																  const ::rtl::OUString& aFsysGroupName,
234*cdf0e10cSrcweir 																  const ::rtl::OUString& aOldGroupName,
235*cdf0e10cSrcweir 																  const ::rtl::OUString& aNewGroupName );
236*cdf0e10cSrcweir 	sal_Bool					RemoveUINamesForTemplateDir_Impl( const ::rtl::OUString& aUserPath,
237*cdf0e10cSrcweir 																  const ::rtl::OUString& aGroupName );
238*cdf0e10cSrcweir 	sal_Bool					WriteUINamesForTemplateDir_Impl( const ::rtl::OUString& aUserPath,
239*cdf0e10cSrcweir 																const uno::Sequence< beans::StringPair >& aUINames );
240*cdf0e10cSrcweir 
241*cdf0e10cSrcweir 	::rtl::OUString				CreateNewGroupFsys( const ::rtl::OUString& rGroupName, Content& aGroup );
242*cdf0e10cSrcweir 
243*cdf0e10cSrcweir     sal_Bool                    removeContent( Content& rContent );
244*cdf0e10cSrcweir     sal_Bool                    removeContent( const OUString& rContentURL );
245*cdf0e10cSrcweir 
246*cdf0e10cSrcweir     sal_Bool                    setProperty( Content& rContent,
247*cdf0e10cSrcweir                                              const OUString& rPropName,
248*cdf0e10cSrcweir                                              const Any& rPropValue );
249*cdf0e10cSrcweir     sal_Bool                    getProperty( Content& rContent,
250*cdf0e10cSrcweir                                              const OUString& rPropName,
251*cdf0e10cSrcweir                                              Any& rPropValue );
252*cdf0e10cSrcweir 
253*cdf0e10cSrcweir     void                        createFromContent( GroupList_Impl& rList,
254*cdf0e10cSrcweir                                                    Content &rContent,
255*cdf0e10cSrcweir                                                    sal_Bool bHierarchy,
256*cdf0e10cSrcweir 												   sal_Bool bWriteableContent = sal_False );
257*cdf0e10cSrcweir     void                        addHierGroup( GroupList_Impl& rList,
258*cdf0e10cSrcweir                                               const OUString& rTitle,
259*cdf0e10cSrcweir                                               const OUString& rOwnURL );
260*cdf0e10cSrcweir     void                        addFsysGroup( GroupList_Impl& rList,
261*cdf0e10cSrcweir                                               const OUString& rTitle,
262*cdf0e10cSrcweir 											  const OUString& rUITitle,
263*cdf0e10cSrcweir                                               const OUString& rOwnURL,
264*cdf0e10cSrcweir 											  sal_Bool bWriteableGroup = sal_False );
265*cdf0e10cSrcweir     void                        removeFromHierarchy( DocTemplates_EntryData_Impl *pData );
266*cdf0e10cSrcweir     void                        addToHierarchy( GroupData_Impl *pGroup,
267*cdf0e10cSrcweir                                                 DocTemplates_EntryData_Impl *pData );
268*cdf0e10cSrcweir 
269*cdf0e10cSrcweir     void                        removeFromHierarchy( GroupData_Impl *pGroup );
270*cdf0e10cSrcweir     void                        addGroupToHierarchy( GroupData_Impl *pGroup );
271*cdf0e10cSrcweir 
272*cdf0e10cSrcweir     void                        updateData( DocTemplates_EntryData_Impl *pData );
273*cdf0e10cSrcweir 
274*cdf0e10cSrcweir public:
275*cdf0e10cSrcweir                                  SfxDocTplService_Impl( uno::Reference< XMultiServiceFactory > xFactory );
276*cdf0e10cSrcweir                                 ~SfxDocTplService_Impl();
277*cdf0e10cSrcweir 
278*cdf0e10cSrcweir     sal_Bool                    init() { if ( !mbIsInitialized ) init_Impl(); return mbIsInitialized; }
279*cdf0e10cSrcweir     Content                     getContent() { return maRootContent; }
280*cdf0e10cSrcweir 
281*cdf0e10cSrcweir     void                        setLocale( const Locale & rLocale );
282*cdf0e10cSrcweir     Locale                      getLocale();
283*cdf0e10cSrcweir 
284*cdf0e10cSrcweir 	sal_Bool 					storeTemplate( const OUString& rGroupName,
285*cdf0e10cSrcweir                                                const OUString& rTemplateName,
286*cdf0e10cSrcweir                                                const uno::Reference< XSTORABLE >& rStorable );
287*cdf0e10cSrcweir 
288*cdf0e10cSrcweir     sal_Bool                    addTemplate( const OUString& rGroupName,
289*cdf0e10cSrcweir                                              const OUString& rTemplateName,
290*cdf0e10cSrcweir                                              const OUString& rSourceURL );
291*cdf0e10cSrcweir     sal_Bool                    removeTemplate( const OUString& rGroupName,
292*cdf0e10cSrcweir                                                 const OUString& rTemplateName );
293*cdf0e10cSrcweir     sal_Bool                    renameTemplate( const OUString& rGroupName,
294*cdf0e10cSrcweir                                                 const OUString& rOldName,
295*cdf0e10cSrcweir                                                 const OUString& rNewName );
296*cdf0e10cSrcweir 
297*cdf0e10cSrcweir     sal_Bool                    addGroup( const OUString& rGroupName );
298*cdf0e10cSrcweir     sal_Bool                    removeGroup( const OUString& rGroupName );
299*cdf0e10cSrcweir     sal_Bool                    renameGroup( const OUString& rOldName,
300*cdf0e10cSrcweir                                              const OUString& rNewName );
301*cdf0e10cSrcweir 
302*cdf0e10cSrcweir     void                        update( sal_Bool bUpdateNow );
303*cdf0e10cSrcweir     void                        doUpdate();
304*cdf0e10cSrcweir     void                        finished() { mpUpdater = NULL; }
305*cdf0e10cSrcweir };
306*cdf0e10cSrcweir 
307*cdf0e10cSrcweir //=============================================================================
308*cdf0e10cSrcweir 
309*cdf0e10cSrcweir class Updater_Impl : public ::vos::OThread
310*cdf0e10cSrcweir {
311*cdf0e10cSrcweir private:
312*cdf0e10cSrcweir     SfxDocTplService_Impl   *mpDocTemplates;
313*cdf0e10cSrcweir 
314*cdf0e10cSrcweir public:
315*cdf0e10cSrcweir                              Updater_Impl( SfxDocTplService_Impl* pTemplates );
316*cdf0e10cSrcweir                             ~Updater_Impl();
317*cdf0e10cSrcweir 
318*cdf0e10cSrcweir     virtual void SAL_CALL   run();
319*cdf0e10cSrcweir     virtual void SAL_CALL   onTerminated();
320*cdf0e10cSrcweir };
321*cdf0e10cSrcweir 
322*cdf0e10cSrcweir //=============================================================================
323*cdf0e10cSrcweir 
324*cdf0e10cSrcweir class DocTemplates_EntryData_Impl
325*cdf0e10cSrcweir {
326*cdf0e10cSrcweir     OUString            maTitle;
327*cdf0e10cSrcweir     OUString            maType;
328*cdf0e10cSrcweir     OUString            maTargetURL;
329*cdf0e10cSrcweir     OUString            maHierarchyURL;
330*cdf0e10cSrcweir 
331*cdf0e10cSrcweir     sal_Bool            mbInHierarchy   : 1;
332*cdf0e10cSrcweir     sal_Bool            mbInUse         : 1;
333*cdf0e10cSrcweir     sal_Bool            mbUpdateType    : 1;
334*cdf0e10cSrcweir     sal_Bool            mbUpdateLink    : 1;
335*cdf0e10cSrcweir 
336*cdf0e10cSrcweir public:
337*cdf0e10cSrcweir                         DocTemplates_EntryData_Impl( const OUString& rTitle );
338*cdf0e10cSrcweir 
339*cdf0e10cSrcweir     void                setInUse() { mbInUse = sal_True; }
340*cdf0e10cSrcweir     void                setHierarchy( sal_Bool bInHierarchy ) { mbInHierarchy = bInHierarchy; }
341*cdf0e10cSrcweir     void                setUpdateLink( sal_Bool bUpdateLink ) { mbUpdateLink = bUpdateLink; }
342*cdf0e10cSrcweir     void                setUpdateType( sal_Bool bUpdateType ) { mbUpdateType = bUpdateType; }
343*cdf0e10cSrcweir 
344*cdf0e10cSrcweir     sal_Bool            getInUse() const { return mbInUse; }
345*cdf0e10cSrcweir     sal_Bool            getInHierarchy() const { return mbInHierarchy; }
346*cdf0e10cSrcweir     sal_Bool            getUpdateLink() const { return mbUpdateLink; }
347*cdf0e10cSrcweir     sal_Bool            getUpdateType() const { return mbUpdateType; }
348*cdf0e10cSrcweir 
349*cdf0e10cSrcweir     const OUString&     getHierarchyURL() const { return maHierarchyURL; }
350*cdf0e10cSrcweir     const OUString&     getTargetURL() const { return maTargetURL; }
351*cdf0e10cSrcweir     const OUString&     getTitle() const { return maTitle; }
352*cdf0e10cSrcweir     const OUString&     getType() const { return maType; }
353*cdf0e10cSrcweir 
354*cdf0e10cSrcweir     void                setHierarchyURL( const OUString& rURL ) { maHierarchyURL = rURL; }
355*cdf0e10cSrcweir     void                setTargetURL( const OUString& rURL ) { maTargetURL = rURL; }
356*cdf0e10cSrcweir     void                setType( const OUString& rType ) { maType = rType; }
357*cdf0e10cSrcweir };
358*cdf0e10cSrcweir 
359*cdf0e10cSrcweir //=============================================================================
360*cdf0e10cSrcweir 
361*cdf0e10cSrcweir class GroupData_Impl
362*cdf0e10cSrcweir {
363*cdf0e10cSrcweir     DECLARE_LIST( EntryList_Impl, DocTemplates_EntryData_Impl* )
364*cdf0e10cSrcweir     EntryList_Impl      maEntries;
365*cdf0e10cSrcweir     OUString            maTitle;
366*cdf0e10cSrcweir     OUString            maHierarchyURL;
367*cdf0e10cSrcweir     OUString            maTargetURL;
368*cdf0e10cSrcweir     sal_Bool            mbInUse         : 1;
369*cdf0e10cSrcweir     sal_Bool            mbInHierarchy   : 1;
370*cdf0e10cSrcweir 
371*cdf0e10cSrcweir public:
372*cdf0e10cSrcweir                         GroupData_Impl( const OUString& rTitle );
373*cdf0e10cSrcweir                         ~GroupData_Impl();
374*cdf0e10cSrcweir 
375*cdf0e10cSrcweir     void                setInUse() { mbInUse = sal_True; }
376*cdf0e10cSrcweir     void                setHierarchy( sal_Bool bInHierarchy ) { mbInHierarchy = bInHierarchy; }
377*cdf0e10cSrcweir     void                setHierarchyURL( const OUString& rURL ) { maHierarchyURL = rURL; }
378*cdf0e10cSrcweir     void                setTargetURL( const OUString& rURL ) { maTargetURL = rURL; }
379*cdf0e10cSrcweir 
380*cdf0e10cSrcweir     sal_Bool            getInUse() { return mbInUse; }
381*cdf0e10cSrcweir     sal_Bool            getInHierarchy() { return mbInHierarchy; }
382*cdf0e10cSrcweir     const OUString&     getHierarchyURL() const { return maHierarchyURL; }
383*cdf0e10cSrcweir     const OUString&     getTargetURL() const { return maTargetURL; }
384*cdf0e10cSrcweir     const OUString&     getTitle() const { return maTitle; }
385*cdf0e10cSrcweir 
386*cdf0e10cSrcweir     DocTemplates_EntryData_Impl*     addEntry( const OUString& rTitle,
387*cdf0e10cSrcweir                                   const OUString& rTargetURL,
388*cdf0e10cSrcweir                                   const OUString& rType,
389*cdf0e10cSrcweir                                   const OUString& rHierURL );
390*cdf0e10cSrcweir     sal_uIntPtr               count() { return maEntries.Count(); }
391*cdf0e10cSrcweir     DocTemplates_EntryData_Impl*     getEntry( sal_uIntPtr nPos ) { return maEntries.GetObject( nPos ); }
392*cdf0e10cSrcweir };
393*cdf0e10cSrcweir 
394*cdf0e10cSrcweir DECLARE_LIST( GroupList_Impl, GroupData_Impl* )
395*cdf0e10cSrcweir 
396*cdf0e10cSrcweir //=============================================================================
397*cdf0e10cSrcweir //=============================================================================
398*cdf0e10cSrcweir //=============================================================================
399*cdf0e10cSrcweir 
400*cdf0e10cSrcweir //-----------------------------------------------------------------------------
401*cdf0e10cSrcweir // private SfxDocTplService_Impl
402*cdf0e10cSrcweir //-----------------------------------------------------------------------------
403*cdf0e10cSrcweir void SfxDocTplService_Impl::init_Impl()
404*cdf0e10cSrcweir {
405*cdf0e10cSrcweir     uno::Reference< lang::XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory();
406*cdf0e10cSrcweir     if ( xFactory.is() )
407*cdf0e10cSrcweir     {
408*cdf0e10cSrcweir 		uno::Reference < task::XInteractionHandler > xInteractionHandler( xFactory->createInstance( DEFINE_CONST_UNICODE("com.sun.star.task.InteractionHandler") ), uno::UNO_QUERY );
409*cdf0e10cSrcweir 		maCmdEnv = new TplTaskEnvironment( xInteractionHandler );
410*cdf0e10cSrcweir 	}
411*cdf0e10cSrcweir 
412*cdf0e10cSrcweir     ::osl::ClearableMutexGuard aGuard( maMutex );
413*cdf0e10cSrcweir 	sal_Bool bIsInitialized = sal_False;
414*cdf0e10cSrcweir 	sal_Bool bNeedsUpdate   = sal_False;
415*cdf0e10cSrcweir 
416*cdf0e10cSrcweir     if ( !mbLocaleSet )
417*cdf0e10cSrcweir         getDefaultLocale();
418*cdf0e10cSrcweir 
419*cdf0e10cSrcweir     // convert locale to string
420*cdf0e10cSrcweir     OUString aLang = maLocale.Language;
421*cdf0e10cSrcweir     aLang += String( '-' );
422*cdf0e10cSrcweir     aLang += maLocale.Country;
423*cdf0e10cSrcweir 
424*cdf0e10cSrcweir     // set maRootContent to the root of the templates hierarchy. Create the
425*cdf0e10cSrcweir     // entry if necessary
426*cdf0e10cSrcweir 
427*cdf0e10cSrcweir     maRootURL = OUString( RTL_CONSTASCII_USTRINGPARAM( TEMPLATE_ROOT_URL ) );
428*cdf0e10cSrcweir     maRootURL += String( '/' );
429*cdf0e10cSrcweir     maRootURL += aLang;
430*cdf0e10cSrcweir 
431*cdf0e10cSrcweir 	::rtl::OUString aTemplVersPropName( RTL_CONSTASCII_USTRINGPARAM( TEMPLATE_VERSION ) );
432*cdf0e10cSrcweir 	::rtl::OUString aTemplVers( RTL_CONSTASCII_USTRINGPARAM( TEMPLATE_VERSION_VALUE ) );
433*cdf0e10cSrcweir     if ( Content::create( maRootURL, maCmdEnv, maRootContent ) )
434*cdf0e10cSrcweir 	{
435*cdf0e10cSrcweir 		uno::Any aValue;
436*cdf0e10cSrcweir 		::rtl::OUString aPropValue;
437*cdf0e10cSrcweir 		if ( getProperty( maRootContent, aTemplVersPropName, aValue )
438*cdf0e10cSrcweir 		  && ( aValue >>= aPropValue )
439*cdf0e10cSrcweir 		  && aPropValue.equals( aTemplVers ) )
440*cdf0e10cSrcweir 		{
441*cdf0e10cSrcweir 			bIsInitialized = sal_True;
442*cdf0e10cSrcweir 		}
443*cdf0e10cSrcweir 		else
444*cdf0e10cSrcweir 			removeContent( maRootContent );
445*cdf0e10cSrcweir 	}
446*cdf0e10cSrcweir 
447*cdf0e10cSrcweir 	if ( !bIsInitialized )
448*cdf0e10cSrcweir     {
449*cdf0e10cSrcweir 		if ( createFolder( maRootURL, sal_True, sal_False, maRootContent )
450*cdf0e10cSrcweir 		  && setProperty( maRootContent, aTemplVersPropName, uno::makeAny( aTemplVers ) ) )
451*cdf0e10cSrcweir 			bIsInitialized = sal_True;
452*cdf0e10cSrcweir 
453*cdf0e10cSrcweir         bNeedsUpdate = sal_True;
454*cdf0e10cSrcweir     }
455*cdf0e10cSrcweir 
456*cdf0e10cSrcweir 	if ( bIsInitialized )
457*cdf0e10cSrcweir     {
458*cdf0e10cSrcweir         OUString aService( RTL_CONSTASCII_USTRINGPARAM( SERVICENAME_DOCINFO ) );
459*cdf0e10cSrcweir         try {
460*cdf0e10cSrcweir             mxInfo = uno::Reference< XStandaloneDocumentInfo > (
461*cdf0e10cSrcweir                 mxFactory->createInstance( aService ), UNO_QUERY );
462*cdf0e10cSrcweir         } catch (uno::RuntimeException &) {
463*cdf0e10cSrcweir             OSL_ENSURE(false, "SfxDocTplService_Impl::init_Impl: "
464*cdf0e10cSrcweir                 "cannot create DocumentProperties service");
465*cdf0e10cSrcweir         }
466*cdf0e10cSrcweir 
467*cdf0e10cSrcweir         aService = OUString( RTL_CONSTASCII_USTRINGPARAM( SERVICENAME_TYPEDETECTION ) );
468*cdf0e10cSrcweir         mxType = uno::Reference< XTypeDetection > ( mxFactory->createInstance( aService ), UNO_QUERY );
469*cdf0e10cSrcweir 
470*cdf0e10cSrcweir         getDirList();
471*cdf0e10cSrcweir         readFolderList();
472*cdf0e10cSrcweir 
473*cdf0e10cSrcweir 		if ( bNeedsUpdate )
474*cdf0e10cSrcweir 		{
475*cdf0e10cSrcweir             aGuard.clear();
476*cdf0e10cSrcweir             ::vos::OClearableGuard aSolarGuard( Application::GetSolarMutex() );
477*cdf0e10cSrcweir 
478*cdf0e10cSrcweir             WaitWindow_Impl* pWin = new WaitWindow_Impl();
479*cdf0e10cSrcweir 
480*cdf0e10cSrcweir             aSolarGuard.clear();
481*cdf0e10cSrcweir             ::osl::ClearableMutexGuard anotherGuard( maMutex );
482*cdf0e10cSrcweir 
483*cdf0e10cSrcweir 			update( sal_True );
484*cdf0e10cSrcweir 
485*cdf0e10cSrcweir             anotherGuard.clear();
486*cdf0e10cSrcweir             ::vos::OGuard aSecondSolarGuard( Application::GetSolarMutex() );
487*cdf0e10cSrcweir 
488*cdf0e10cSrcweir             delete pWin;
489*cdf0e10cSrcweir         }
490*cdf0e10cSrcweir 		else if ( needsUpdate() )
491*cdf0e10cSrcweir 			// the UI should be shown only on the first update
492*cdf0e10cSrcweir 			update( sal_True );
493*cdf0e10cSrcweir     }
494*cdf0e10cSrcweir     else
495*cdf0e10cSrcweir     {
496*cdf0e10cSrcweir         DBG_ERRORFILE( "init_Impl(): Could not create root" );
497*cdf0e10cSrcweir     }
498*cdf0e10cSrcweir 
499*cdf0e10cSrcweir     mbIsInitialized = bIsInitialized;
500*cdf0e10cSrcweir }
501*cdf0e10cSrcweir 
502*cdf0e10cSrcweir //-----------------------------------------------------------------------------
503*cdf0e10cSrcweir void SfxDocTplService_Impl::getDefaultLocale()
504*cdf0e10cSrcweir {
505*cdf0e10cSrcweir     if ( !mbLocaleSet )
506*cdf0e10cSrcweir     {
507*cdf0e10cSrcweir         ::osl::MutexGuard aGuard( maMutex );
508*cdf0e10cSrcweir         if ( !mbLocaleSet )
509*cdf0e10cSrcweir         {
510*cdf0e10cSrcweir             rtl::OUString aLocale;
511*cdf0e10cSrcweir             utl::ConfigManager::GetDirectConfigProperty( utl::ConfigManager::LOCALE )
512*cdf0e10cSrcweir                 >>= aLocale;
513*cdf0e10cSrcweir 
514*cdf0e10cSrcweir             if ( aLocale.getLength() > 0 )
515*cdf0e10cSrcweir             {
516*cdf0e10cSrcweir                 sal_Int32 nPos = aLocale.indexOf( sal_Unicode( '-' ) );
517*cdf0e10cSrcweir                 if ( nPos != -1 )
518*cdf0e10cSrcweir                 {
519*cdf0e10cSrcweir                     maLocale.Language = aLocale.copy( 0, nPos );
520*cdf0e10cSrcweir                     nPos = aLocale.indexOf( sal_Unicode( '_' ), nPos + 1 );
521*cdf0e10cSrcweir                     if ( nPos != -1 )
522*cdf0e10cSrcweir                     {
523*cdf0e10cSrcweir                         maLocale.Country
524*cdf0e10cSrcweir                             = aLocale.copy( maLocale.Language.getLength() + 1,
525*cdf0e10cSrcweir                                             nPos - maLocale.Language.getLength() - 1 );
526*cdf0e10cSrcweir                         maLocale.Variant
527*cdf0e10cSrcweir                             = aLocale.copy( nPos + 1 );
528*cdf0e10cSrcweir                     }
529*cdf0e10cSrcweir                     else
530*cdf0e10cSrcweir                     {
531*cdf0e10cSrcweir                         maLocale.Country
532*cdf0e10cSrcweir                             = aLocale.copy( maLocale.Language.getLength() + 1 );
533*cdf0e10cSrcweir                     }
534*cdf0e10cSrcweir                 }
535*cdf0e10cSrcweir 
536*cdf0e10cSrcweir             }
537*cdf0e10cSrcweir 
538*cdf0e10cSrcweir             mbLocaleSet = sal_True;
539*cdf0e10cSrcweir         }
540*cdf0e10cSrcweir     }
541*cdf0e10cSrcweir }
542*cdf0e10cSrcweir 
543*cdf0e10cSrcweir // -----------------------------------------------------------------------
544*cdf0e10cSrcweir void SfxDocTplService_Impl::readFolderList()
545*cdf0e10cSrcweir {
546*cdf0e10cSrcweir     ::vos::OGuard aGuard( Application::GetSolarMutex() );
547*cdf0e10cSrcweir 
548*cdf0e10cSrcweir     ResStringArray  aShortNames( SfxResId( TEMPLATE_SHORT_NAMES_ARY ) );
549*cdf0e10cSrcweir     ResStringArray  aLongNames( SfxResId( TEMPLATE_LONG_NAMES_ARY ) );
550*cdf0e10cSrcweir 
551*cdf0e10cSrcweir     NamePair_Impl*  pPair;
552*cdf0e10cSrcweir 
553*cdf0e10cSrcweir     sal_uInt16 nCount = (sal_uInt16)( Min( aShortNames.Count(), aLongNames.Count() ) );
554*cdf0e10cSrcweir 
555*cdf0e10cSrcweir     for ( sal_uInt16 i=0; i<nCount; i++ )
556*cdf0e10cSrcweir     {
557*cdf0e10cSrcweir         pPair = new NamePair_Impl;
558*cdf0e10cSrcweir         pPair->maShortName  = aShortNames.GetString( i );
559*cdf0e10cSrcweir         pPair->maLongName   = aLongNames.GetString( i );
560*cdf0e10cSrcweir 
561*cdf0e10cSrcweir         maNames.Insert( pPair, LIST_APPEND );
562*cdf0e10cSrcweir     }
563*cdf0e10cSrcweir }
564*cdf0e10cSrcweir 
565*cdf0e10cSrcweir // -----------------------------------------------------------------------
566*cdf0e10cSrcweir OUString SfxDocTplService_Impl::getLongName( const OUString& rShortName )
567*cdf0e10cSrcweir {
568*cdf0e10cSrcweir     OUString         aRet;
569*cdf0e10cSrcweir     NamePair_Impl   *pPair = maNames.First();
570*cdf0e10cSrcweir 
571*cdf0e10cSrcweir     while ( pPair )
572*cdf0e10cSrcweir     {
573*cdf0e10cSrcweir         if ( pPair->maShortName == rShortName )
574*cdf0e10cSrcweir         {
575*cdf0e10cSrcweir             aRet = pPair->maLongName;
576*cdf0e10cSrcweir             break;
577*cdf0e10cSrcweir         }
578*cdf0e10cSrcweir         else
579*cdf0e10cSrcweir             pPair = maNames.Next();
580*cdf0e10cSrcweir     }
581*cdf0e10cSrcweir 
582*cdf0e10cSrcweir     if ( !aRet.getLength() )
583*cdf0e10cSrcweir         aRet = rShortName;
584*cdf0e10cSrcweir 
585*cdf0e10cSrcweir     return aRet;
586*cdf0e10cSrcweir }
587*cdf0e10cSrcweir 
588*cdf0e10cSrcweir //-----------------------------------------------------------------------------
589*cdf0e10cSrcweir void SfxDocTplService_Impl::getDirList()
590*cdf0e10cSrcweir {
591*cdf0e10cSrcweir     OUString aPropName( RTL_CONSTASCII_USTRINGPARAM( PROPERTY_DIRLIST ) );
592*cdf0e10cSrcweir     Any      aValue;
593*cdf0e10cSrcweir 
594*cdf0e10cSrcweir     // Get the template dir list
595*cdf0e10cSrcweir 	// TODO/LATER: let use service, register listener
596*cdf0e10cSrcweir     INetURLObject   aURL;
597*cdf0e10cSrcweir     String          aDirs = SvtPathOptions().GetTemplatePath();
598*cdf0e10cSrcweir     sal_uInt16          nCount = aDirs.GetTokenCount( C_DELIM );
599*cdf0e10cSrcweir 
600*cdf0e10cSrcweir     maTemplateDirs = Sequence< OUString >( nCount );
601*cdf0e10cSrcweir 
602*cdf0e10cSrcweir     for ( sal_uInt16 i=0; i<nCount; i++ )
603*cdf0e10cSrcweir     {
604*cdf0e10cSrcweir         aURL.SetSmartProtocol( INET_PROT_FILE );
605*cdf0e10cSrcweir         aURL.SetURL( aDirs.GetToken( i, C_DELIM ) );
606*cdf0e10cSrcweir         maTemplateDirs[i] = aURL.GetMainURL( INetURLObject::NO_DECODE );
607*cdf0e10cSrcweir     }
608*cdf0e10cSrcweir 
609*cdf0e10cSrcweir     aValue <<= maTemplateDirs;
610*cdf0e10cSrcweir 
611*cdf0e10cSrcweir     // Store the template dir list
612*cdf0e10cSrcweir     setProperty( maRootContent, aPropName, aValue );
613*cdf0e10cSrcweir }
614*cdf0e10cSrcweir 
615*cdf0e10cSrcweir //-----------------------------------------------------------------------------
616*cdf0e10cSrcweir sal_Bool SfxDocTplService_Impl::needsUpdate()
617*cdf0e10cSrcweir {
618*cdf0e10cSrcweir 	OUString aPropName( RTL_CONSTASCII_USTRINGPARAM( PROPERTY_NEEDSUPDATE ) );
619*cdf0e10cSrcweir 	sal_Bool bHasProperty = sal_False;
620*cdf0e10cSrcweir     sal_Bool bNeedsUpdate = sal_True;
621*cdf0e10cSrcweir 	Any		 aValue;
622*cdf0e10cSrcweir 
623*cdf0e10cSrcweir 	// Get the template dir list
624*cdf0e10cSrcweir 	bHasProperty = getProperty( maRootContent, aPropName, aValue );
625*cdf0e10cSrcweir 
626*cdf0e10cSrcweir 	if ( bHasProperty )
627*cdf0e10cSrcweir 		aValue >>= bNeedsUpdate;
628*cdf0e10cSrcweir 
629*cdf0e10cSrcweir 	// the old template component also checks this state, but it is initialized from this component
630*cdf0e10cSrcweir 	// so if this componend was already updated the old component does not need such an update
631*cdf0e10cSrcweir 	::svt::TemplateFolderCache aTempCache;
632*cdf0e10cSrcweir 	if ( !bNeedsUpdate )
633*cdf0e10cSrcweir 		bNeedsUpdate = aTempCache.needsUpdate();
634*cdf0e10cSrcweir 
635*cdf0e10cSrcweir 	if ( bNeedsUpdate )
636*cdf0e10cSrcweir 		aTempCache.storeState();
637*cdf0e10cSrcweir 
638*cdf0e10cSrcweir     return bNeedsUpdate;
639*cdf0e10cSrcweir }
640*cdf0e10cSrcweir 
641*cdf0e10cSrcweir // -----------------------------------------------------------------------
642*cdf0e10cSrcweir sal_Bool SfxDocTplService_Impl::setTitleForURL( const OUString& rURL, const OUString& aTitle )
643*cdf0e10cSrcweir {
644*cdf0e10cSrcweir 	sal_Bool bResult = sal_False;
645*cdf0e10cSrcweir     if ( mxInfo.is() )
646*cdf0e10cSrcweir     {
647*cdf0e10cSrcweir         try
648*cdf0e10cSrcweir         {
649*cdf0e10cSrcweir             mxInfo->loadFromURL( rURL );
650*cdf0e10cSrcweir             uno::Reference< XPropertySet > xPropSet( mxInfo, UNO_QUERY_THROW );
651*cdf0e10cSrcweir             OUString aPropName( RTL_CONSTASCII_USTRINGPARAM( TITLE ) );
652*cdf0e10cSrcweir 			xPropSet->setPropertyValue( aPropName, uno::makeAny( aTitle ) );
653*cdf0e10cSrcweir 			mxInfo->storeIntoURL( rURL );
654*cdf0e10cSrcweir 			bResult = sal_True;
655*cdf0e10cSrcweir 		}
656*cdf0e10cSrcweir         catch ( Exception& )
657*cdf0e10cSrcweir 		{
658*cdf0e10cSrcweir 		}
659*cdf0e10cSrcweir     }
660*cdf0e10cSrcweir 
661*cdf0e10cSrcweir 	return bResult;
662*cdf0e10cSrcweir }
663*cdf0e10cSrcweir 
664*cdf0e10cSrcweir // -----------------------------------------------------------------------
665*cdf0e10cSrcweir sal_Bool SfxDocTplService_Impl::getTitleFromURL( const OUString& rURL, OUString& aTitle, OUString& aType, sal_Bool& bDocHasTitle )
666*cdf0e10cSrcweir {
667*cdf0e10cSrcweir 	bDocHasTitle = sal_False;
668*cdf0e10cSrcweir 
669*cdf0e10cSrcweir     if ( mxInfo.is() )
670*cdf0e10cSrcweir     {
671*cdf0e10cSrcweir         try
672*cdf0e10cSrcweir         {
673*cdf0e10cSrcweir             mxInfo->loadFromURL( rURL );
674*cdf0e10cSrcweir 		}
675*cdf0e10cSrcweir         catch ( Exception& )
676*cdf0e10cSrcweir 		{
677*cdf0e10cSrcweir 			// the document is not a StarOffice document
678*cdf0e10cSrcweir 			return sal_False;
679*cdf0e10cSrcweir 		}
680*cdf0e10cSrcweir 
681*cdf0e10cSrcweir         try
682*cdf0e10cSrcweir 		{
683*cdf0e10cSrcweir             uno::Reference< XPropertySet > aPropSet( mxInfo, UNO_QUERY );
684*cdf0e10cSrcweir             if ( aPropSet.is() )
685*cdf0e10cSrcweir             {
686*cdf0e10cSrcweir                 OUString aPropName( RTL_CONSTASCII_USTRINGPARAM( TITLE ) );
687*cdf0e10cSrcweir                 Any aValue = aPropSet->getPropertyValue( aPropName );
688*cdf0e10cSrcweir                 aValue >>= aTitle;
689*cdf0e10cSrcweir 
690*cdf0e10cSrcweir                 aPropName = OUString( RTL_CONSTASCII_USTRINGPARAM( "MIMEType" ) );
691*cdf0e10cSrcweir                 aValue = aPropSet->getPropertyValue( aPropName );
692*cdf0e10cSrcweir                 aValue >>= aType;
693*cdf0e10cSrcweir             }
694*cdf0e10cSrcweir         }
695*cdf0e10cSrcweir         catch ( UnknownPropertyException& ) {}
696*cdf0e10cSrcweir         catch ( Exception& ) {}
697*cdf0e10cSrcweir     }
698*cdf0e10cSrcweir 
699*cdf0e10cSrcweir     if ( ! aType.getLength() && mxType.is() )
700*cdf0e10cSrcweir     {
701*cdf0e10cSrcweir 		::rtl::OUString aDocType = mxType->queryTypeByURL( rURL );
702*cdf0e10cSrcweir 		if ( aDocType.getLength() )
703*cdf0e10cSrcweir 			try
704*cdf0e10cSrcweir 			{
705*cdf0e10cSrcweir 				uno::Reference< container::XNameAccess > xTypeDetection( mxType, uno::UNO_QUERY_THROW );
706*cdf0e10cSrcweir 				SequenceAsHashMap aTypeProps( xTypeDetection->getByName( aDocType ) );
707*cdf0e10cSrcweir 				aType = aTypeProps.getUnpackedValueOrDefault(
708*cdf0e10cSrcweir 							::rtl::OUString::createFromAscii( "MediaType" ),
709*cdf0e10cSrcweir 							::rtl::OUString() );
710*cdf0e10cSrcweir 			}
711*cdf0e10cSrcweir 			catch( uno::Exception& )
712*cdf0e10cSrcweir 			{}
713*cdf0e10cSrcweir     }
714*cdf0e10cSrcweir 
715*cdf0e10cSrcweir     if ( ! aTitle.getLength() )
716*cdf0e10cSrcweir     {
717*cdf0e10cSrcweir         INetURLObject aURL( rURL );
718*cdf0e10cSrcweir         aURL.CutExtension();
719*cdf0e10cSrcweir         aTitle = aURL.getName( INetURLObject::LAST_SEGMENT, true,
720*cdf0e10cSrcweir                                INetURLObject::DECODE_WITH_CHARSET );
721*cdf0e10cSrcweir     }
722*cdf0e10cSrcweir 	else
723*cdf0e10cSrcweir 		bDocHasTitle = sal_True;
724*cdf0e10cSrcweir 
725*cdf0e10cSrcweir 	return sal_True;
726*cdf0e10cSrcweir }
727*cdf0e10cSrcweir 
728*cdf0e10cSrcweir // -----------------------------------------------------------------------
729*cdf0e10cSrcweir sal_Bool SfxDocTplService_Impl::addEntry( Content& rParentFolder,
730*cdf0e10cSrcweir                                           const OUString& rTitle,
731*cdf0e10cSrcweir                                           const OUString& rTargetURL,
732*cdf0e10cSrcweir                                           const OUString& rType )
733*cdf0e10cSrcweir {
734*cdf0e10cSrcweir     sal_Bool bAddedEntry = sal_False;
735*cdf0e10cSrcweir 
736*cdf0e10cSrcweir     INetURLObject aLinkObj( rParentFolder.getURL() );
737*cdf0e10cSrcweir     aLinkObj.insertName( rTitle, false,
738*cdf0e10cSrcweir                       INetURLObject::LAST_SEGMENT, true,
739*cdf0e10cSrcweir                       INetURLObject::ENCODE_ALL );
740*cdf0e10cSrcweir     OUString aLinkURL = aLinkObj.GetMainURL( INetURLObject::NO_DECODE );
741*cdf0e10cSrcweir 
742*cdf0e10cSrcweir     Content aLink;
743*cdf0e10cSrcweir 
744*cdf0e10cSrcweir     if ( ! Content::create( aLinkURL, maCmdEnv, aLink ) )
745*cdf0e10cSrcweir     {
746*cdf0e10cSrcweir         Sequence< OUString > aNames(3);
747*cdf0e10cSrcweir         aNames[0] = OUString( RTL_CONSTASCII_USTRINGPARAM( TITLE ) );
748*cdf0e10cSrcweir         aNames[1] = OUString( RTL_CONSTASCII_USTRINGPARAM( IS_FOLDER ) );
749*cdf0e10cSrcweir         aNames[2] = OUString( RTL_CONSTASCII_USTRINGPARAM( TARGET_URL ) );
750*cdf0e10cSrcweir 
751*cdf0e10cSrcweir         Sequence< Any > aValues(3);
752*cdf0e10cSrcweir         aValues[0] = makeAny( rTitle );
753*cdf0e10cSrcweir         aValues[1] = makeAny( sal_Bool( sal_False ) );
754*cdf0e10cSrcweir         aValues[2] = makeAny( rTargetURL );
755*cdf0e10cSrcweir 
756*cdf0e10cSrcweir         OUString aType( RTL_CONSTASCII_USTRINGPARAM( TYPE_LINK ) );
757*cdf0e10cSrcweir         OUString aAdditionalProp( RTL_CONSTASCII_USTRINGPARAM( PROPERTY_TYPE ) );
758*cdf0e10cSrcweir 
759*cdf0e10cSrcweir         try
760*cdf0e10cSrcweir         {
761*cdf0e10cSrcweir             rParentFolder.insertNewContent( aType, aNames, aValues, aLink );
762*cdf0e10cSrcweir             setProperty( aLink, aAdditionalProp, makeAny( rType ) );
763*cdf0e10cSrcweir             bAddedEntry = sal_True;
764*cdf0e10cSrcweir         }
765*cdf0e10cSrcweir         catch( Exception& )
766*cdf0e10cSrcweir         {}
767*cdf0e10cSrcweir     }
768*cdf0e10cSrcweir     return bAddedEntry;
769*cdf0e10cSrcweir }
770*cdf0e10cSrcweir 
771*cdf0e10cSrcweir // -----------------------------------------------------------------------
772*cdf0e10cSrcweir sal_Bool SfxDocTplService_Impl::createFolder( const OUString& rNewFolderURL,
773*cdf0e10cSrcweir                                               sal_Bool  bCreateParent,
774*cdf0e10cSrcweir                                               sal_Bool  bFsysFolder,
775*cdf0e10cSrcweir                                               Content   &rNewFolder )
776*cdf0e10cSrcweir {
777*cdf0e10cSrcweir     Content         aParent;
778*cdf0e10cSrcweir     sal_Bool        bCreatedFolder = sal_False;
779*cdf0e10cSrcweir     INetURLObject   aParentURL( rNewFolderURL );
780*cdf0e10cSrcweir     OUString        aFolderName = aParentURL.getName( INetURLObject::LAST_SEGMENT, true,
781*cdf0e10cSrcweir                                                       INetURLObject::DECODE_WITH_CHARSET );
782*cdf0e10cSrcweir 
783*cdf0e10cSrcweir     // compute the parent folder url from the new folder url
784*cdf0e10cSrcweir     // and remove the final slash, because Content::create doesn't
785*cdf0e10cSrcweir     // like it
786*cdf0e10cSrcweir     aParentURL.removeSegment();
787*cdf0e10cSrcweir     if ( aParentURL.getSegmentCount() >= 1 )
788*cdf0e10cSrcweir         aParentURL.removeFinalSlash();
789*cdf0e10cSrcweir 
790*cdf0e10cSrcweir     // if the parent exists, we can continue with the creation of the
791*cdf0e10cSrcweir     // new folder, we have to create the parent otherwise ( as long as
792*cdf0e10cSrcweir     // bCreateParent is set to true )
793*cdf0e10cSrcweir     if ( Content::create( aParentURL.GetMainURL( INetURLObject::NO_DECODE ), maCmdEnv, aParent ) )
794*cdf0e10cSrcweir     {
795*cdf0e10cSrcweir         try
796*cdf0e10cSrcweir         {
797*cdf0e10cSrcweir             Sequence< OUString > aNames(2);
798*cdf0e10cSrcweir             aNames[0] = OUString( RTL_CONSTASCII_USTRINGPARAM( TITLE ) );
799*cdf0e10cSrcweir             aNames[1] = OUString( RTL_CONSTASCII_USTRINGPARAM( IS_FOLDER ) );
800*cdf0e10cSrcweir 
801*cdf0e10cSrcweir             Sequence< Any > aValues(2);
802*cdf0e10cSrcweir             aValues[0] = makeAny( aFolderName );
803*cdf0e10cSrcweir             aValues[1] = makeAny( sal_Bool( sal_True ) );
804*cdf0e10cSrcweir 
805*cdf0e10cSrcweir             OUString aType;
806*cdf0e10cSrcweir 
807*cdf0e10cSrcweir             if ( bFsysFolder )
808*cdf0e10cSrcweir                 aType = OUString( RTL_CONSTASCII_USTRINGPARAM( TYPE_FSYS_FOLDER ) );
809*cdf0e10cSrcweir             else
810*cdf0e10cSrcweir                 aType = OUString( RTL_CONSTASCII_USTRINGPARAM( TYPE_FOLDER ) );
811*cdf0e10cSrcweir 
812*cdf0e10cSrcweir             aParent.insertNewContent( aType, aNames, aValues, rNewFolder );
813*cdf0e10cSrcweir             bCreatedFolder = sal_True;
814*cdf0e10cSrcweir         }
815*cdf0e10cSrcweir         catch( RuntimeException& )
816*cdf0e10cSrcweir         {
817*cdf0e10cSrcweir             DBG_ERRORFILE( "createFolder(): got runtime exception" );
818*cdf0e10cSrcweir         }
819*cdf0e10cSrcweir         catch( Exception& )
820*cdf0e10cSrcweir         {
821*cdf0e10cSrcweir             DBG_ERRORFILE( "createFolder(): Could not create new folder" );
822*cdf0e10cSrcweir         }
823*cdf0e10cSrcweir     }
824*cdf0e10cSrcweir     else if ( bCreateParent )
825*cdf0e10cSrcweir     {
826*cdf0e10cSrcweir         // if the parent doesn't exists and bCreateParent is set to true,
827*cdf0e10cSrcweir         // we try to create the parent and if this was successful, we
828*cdf0e10cSrcweir         // try to create the new folder again ( but this time, we set
829*cdf0e10cSrcweir         // bCreateParent to false to avoid endless recusions )
830*cdf0e10cSrcweir         if ( ( aParentURL.getSegmentCount() >= 1 ) &&
831*cdf0e10cSrcweir                createFolder( aParentURL.GetMainURL( INetURLObject::NO_DECODE ), bCreateParent, bFsysFolder, aParent ) )
832*cdf0e10cSrcweir         {
833*cdf0e10cSrcweir             bCreatedFolder = createFolder( rNewFolderURL, sal_False, bFsysFolder, rNewFolder );
834*cdf0e10cSrcweir         }
835*cdf0e10cSrcweir     }
836*cdf0e10cSrcweir 
837*cdf0e10cSrcweir     return bCreatedFolder;
838*cdf0e10cSrcweir }
839*cdf0e10cSrcweir 
840*cdf0e10cSrcweir // -----------------------------------------------------------------------
841*cdf0e10cSrcweir sal_Bool SfxDocTplService_Impl::CreateNewUniqueFolderWithPrefix( const ::rtl::OUString& aPath,
842*cdf0e10cSrcweir 																const ::rtl::OUString& aPrefix,
843*cdf0e10cSrcweir 																::rtl::OUString& aNewFolderName,
844*cdf0e10cSrcweir 																::rtl::OUString& aNewFolderURL,
845*cdf0e10cSrcweir 																Content& aNewFolder )
846*cdf0e10cSrcweir {
847*cdf0e10cSrcweir 	sal_Bool bCreated = sal_False;
848*cdf0e10cSrcweir 	INetURLObject aDirPath( aPath );
849*cdf0e10cSrcweir 
850*cdf0e10cSrcweir     Content aParent;
851*cdf0e10cSrcweir    	if ( Content::create( aDirPath.GetMainURL( INetURLObject::NO_DECODE ), maCmdEnv, aParent ) )
852*cdf0e10cSrcweir    	{
853*cdf0e10cSrcweir 		for ( sal_Int32 nInd = 0; nInd < 32000; nInd++ )
854*cdf0e10cSrcweir 		{
855*cdf0e10cSrcweir 			::rtl::OUString aTryName = aPrefix;
856*cdf0e10cSrcweir 			if ( nInd )
857*cdf0e10cSrcweir 				aTryName += ::rtl::OUString::valueOf( nInd );
858*cdf0e10cSrcweir 
859*cdf0e10cSrcweir         	try
860*cdf0e10cSrcweir         	{
861*cdf0e10cSrcweir             	Sequence< OUString > aNames(2);
862*cdf0e10cSrcweir             	aNames[0] = OUString( RTL_CONSTASCII_USTRINGPARAM( TITLE ) );
863*cdf0e10cSrcweir             	aNames[1] = OUString( RTL_CONSTASCII_USTRINGPARAM( IS_FOLDER ) );
864*cdf0e10cSrcweir 
865*cdf0e10cSrcweir             	Sequence< Any > aValues(2);
866*cdf0e10cSrcweir             	aValues[0] = makeAny( aTryName );
867*cdf0e10cSrcweir             	aValues[1] = makeAny( sal_Bool( sal_True ) );
868*cdf0e10cSrcweir 
869*cdf0e10cSrcweir             	OUString aType( RTL_CONSTASCII_USTRINGPARAM( TYPE_FSYS_FOLDER ) );
870*cdf0e10cSrcweir 
871*cdf0e10cSrcweir             	bCreated = aParent.insertNewContent( aType, aNames, aValues, aNewFolder );
872*cdf0e10cSrcweir         	}
873*cdf0e10cSrcweir         	catch( ucb::NameClashException& )
874*cdf0e10cSrcweir         	{
875*cdf0e10cSrcweir 				// if there is already an element, retry
876*cdf0e10cSrcweir         	}
877*cdf0e10cSrcweir         	catch( Exception& )
878*cdf0e10cSrcweir         	{
879*cdf0e10cSrcweir 				INetURLObject aObjPath( aDirPath );
880*cdf0e10cSrcweir 				aObjPath.insertName( aTryName, false,
881*cdf0e10cSrcweir                       INetURLObject::LAST_SEGMENT, true,
882*cdf0e10cSrcweir                       INetURLObject::ENCODE_ALL );
883*cdf0e10cSrcweir 				// if there is already an element, retry
884*cdf0e10cSrcweir 				// if there was another error, do not try any more
885*cdf0e10cSrcweir 				if ( !::utl::UCBContentHelper::Exists( aObjPath.GetMainURL( INetURLObject::NO_DECODE ) ) )
886*cdf0e10cSrcweir 					break;
887*cdf0e10cSrcweir         	}
888*cdf0e10cSrcweir 
889*cdf0e10cSrcweir 			if ( bCreated )
890*cdf0e10cSrcweir 			{
891*cdf0e10cSrcweir 				aNewFolderName = aTryName;
892*cdf0e10cSrcweir 				aNewFolderURL = aNewFolder.get()->getIdentifier()->getContentIdentifier();
893*cdf0e10cSrcweir 				break;
894*cdf0e10cSrcweir 			}
895*cdf0e10cSrcweir 		}
896*cdf0e10cSrcweir 	}
897*cdf0e10cSrcweir 
898*cdf0e10cSrcweir 	return bCreated;
899*cdf0e10cSrcweir }
900*cdf0e10cSrcweir 
901*cdf0e10cSrcweir // -----------------------------------------------------------------------
902*cdf0e10cSrcweir ::rtl::OUString SfxDocTplService_Impl::CreateNewUniqueFileWithPrefix( const ::rtl::OUString& aPath,
903*cdf0e10cSrcweir 																		const ::rtl::OUString& aPrefix,
904*cdf0e10cSrcweir 																		const ::rtl::OUString& aExt )
905*cdf0e10cSrcweir {
906*cdf0e10cSrcweir 	::rtl::OUString aNewFileURL;
907*cdf0e10cSrcweir 	INetURLObject aDirPath( aPath );
908*cdf0e10cSrcweir 
909*cdf0e10cSrcweir    	Content aParent;
910*cdf0e10cSrcweir 
911*cdf0e10cSrcweir 	uno::Reference< XCommandEnvironment > aQuietEnv;
912*cdf0e10cSrcweir 	if ( Content::create( aDirPath.GetMainURL( INetURLObject::NO_DECODE ), aQuietEnv, aParent ) )
913*cdf0e10cSrcweir    	{
914*cdf0e10cSrcweir 		for ( sal_Int32 nInd = 0; nInd < 32000; nInd++ )
915*cdf0e10cSrcweir 		{
916*cdf0e10cSrcweir 			Content aNewFile;
917*cdf0e10cSrcweir 			sal_Bool bCreated = sal_False;
918*cdf0e10cSrcweir 			::rtl::OUString aTryName = aPrefix;
919*cdf0e10cSrcweir 			if ( nInd )
920*cdf0e10cSrcweir 				aTryName += ::rtl::OUString::valueOf( nInd );
921*cdf0e10cSrcweir 			if ( aExt.toChar() != '.' )
922*cdf0e10cSrcweir 				aTryName += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "." ) );
923*cdf0e10cSrcweir 			aTryName += aExt;
924*cdf0e10cSrcweir 
925*cdf0e10cSrcweir         	try
926*cdf0e10cSrcweir         	{
927*cdf0e10cSrcweir             	Sequence< OUString > aNames(2);
928*cdf0e10cSrcweir             	aNames[0] = OUString( RTL_CONSTASCII_USTRINGPARAM( TITLE ) );
929*cdf0e10cSrcweir             	aNames[1] = OUString( RTL_CONSTASCII_USTRINGPARAM( IS_DOCUMENT ) );
930*cdf0e10cSrcweir 
931*cdf0e10cSrcweir             	Sequence< Any > aValues(2);
932*cdf0e10cSrcweir             	aValues[0] = makeAny( aTryName );
933*cdf0e10cSrcweir             	aValues[1] = makeAny( sal_Bool( sal_True ) );
934*cdf0e10cSrcweir 
935*cdf0e10cSrcweir             	OUString aType( RTL_CONSTASCII_USTRINGPARAM( TYPE_FSYS_FILE ) );
936*cdf0e10cSrcweir 
937*cdf0e10cSrcweir             	bCreated = aParent.insertNewContent( aType, aNames, aValues, aNewFile );
938*cdf0e10cSrcweir         	}
939*cdf0e10cSrcweir         	catch( ucb::NameClashException& )
940*cdf0e10cSrcweir         	{
941*cdf0e10cSrcweir 				// if there is already an element, retry
942*cdf0e10cSrcweir         	}
943*cdf0e10cSrcweir         	catch( Exception& )
944*cdf0e10cSrcweir         	{
945*cdf0e10cSrcweir 				INetURLObject aObjPath( aPath );
946*cdf0e10cSrcweir 				aObjPath.insertName( aTryName, false,
947*cdf0e10cSrcweir                       INetURLObject::LAST_SEGMENT, true,
948*cdf0e10cSrcweir                       INetURLObject::ENCODE_ALL );
949*cdf0e10cSrcweir 				// if there is already an element, retry
950*cdf0e10cSrcweir 				// if there was another error, do not try any more
951*cdf0e10cSrcweir 				if ( !::utl::UCBContentHelper::Exists( aObjPath.GetMainURL( INetURLObject::NO_DECODE ) ) )
952*cdf0e10cSrcweir 					break;
953*cdf0e10cSrcweir         	}
954*cdf0e10cSrcweir 
955*cdf0e10cSrcweir 			if ( bCreated )
956*cdf0e10cSrcweir 			{
957*cdf0e10cSrcweir 				aNewFileURL = aNewFile.get()->getIdentifier()->getContentIdentifier();
958*cdf0e10cSrcweir 				break;
959*cdf0e10cSrcweir 			}
960*cdf0e10cSrcweir 		}
961*cdf0e10cSrcweir 	}
962*cdf0e10cSrcweir 
963*cdf0e10cSrcweir 	return aNewFileURL;
964*cdf0e10cSrcweir }
965*cdf0e10cSrcweir 
966*cdf0e10cSrcweir // -----------------------------------------------------------------------
967*cdf0e10cSrcweir sal_Bool SfxDocTplService_Impl::removeContent( Content& rContent )
968*cdf0e10cSrcweir {
969*cdf0e10cSrcweir     sal_Bool bRemoved = sal_False;
970*cdf0e10cSrcweir     try
971*cdf0e10cSrcweir     {
972*cdf0e10cSrcweir         OUString aCmd( RTL_CONSTASCII_USTRINGPARAM( COMMAND_DELETE ) );
973*cdf0e10cSrcweir         Any aArg = makeAny( sal_Bool( sal_True ) );
974*cdf0e10cSrcweir 
975*cdf0e10cSrcweir         rContent.executeCommand( aCmd, aArg );
976*cdf0e10cSrcweir         bRemoved = sal_True;
977*cdf0e10cSrcweir     }
978*cdf0e10cSrcweir     catch ( RuntimeException& ) {}
979*cdf0e10cSrcweir     catch ( Exception& ) {}
980*cdf0e10cSrcweir 
981*cdf0e10cSrcweir     return bRemoved;
982*cdf0e10cSrcweir }
983*cdf0e10cSrcweir 
984*cdf0e10cSrcweir // -----------------------------------------------------------------------
985*cdf0e10cSrcweir sal_Bool SfxDocTplService_Impl::removeContent( const OUString& rContentURL )
986*cdf0e10cSrcweir {
987*cdf0e10cSrcweir     Content aContent;
988*cdf0e10cSrcweir 
989*cdf0e10cSrcweir     if ( Content::create( rContentURL, maCmdEnv, aContent ) )
990*cdf0e10cSrcweir         return removeContent( aContent );
991*cdf0e10cSrcweir     else
992*cdf0e10cSrcweir         return sal_False;
993*cdf0e10cSrcweir }
994*cdf0e10cSrcweir 
995*cdf0e10cSrcweir // -----------------------------------------------------------------------
996*cdf0e10cSrcweir sal_Bool SfxDocTplService_Impl::setProperty( Content& rContent,
997*cdf0e10cSrcweir                                              const OUString& rPropName,
998*cdf0e10cSrcweir                                              const Any& rPropValue )
999*cdf0e10cSrcweir {
1000*cdf0e10cSrcweir     sal_Bool bPropertySet = sal_False;
1001*cdf0e10cSrcweir 
1002*cdf0e10cSrcweir     // Store the property
1003*cdf0e10cSrcweir     try
1004*cdf0e10cSrcweir     {
1005*cdf0e10cSrcweir         Any aPropValue( rPropValue );
1006*cdf0e10cSrcweir         uno::Reference< XPropertySetInfo > aPropInfo = rContent.getProperties();
1007*cdf0e10cSrcweir 
1008*cdf0e10cSrcweir         // check, wether or not the property exists, create it, when not
1009*cdf0e10cSrcweir         if ( !aPropInfo.is() || !aPropInfo->hasPropertyByName( rPropName ) )
1010*cdf0e10cSrcweir         {
1011*cdf0e10cSrcweir             uno::Reference< XPropertyContainer > xProperties( rContent.get(), UNO_QUERY );
1012*cdf0e10cSrcweir             if ( xProperties.is() )
1013*cdf0e10cSrcweir             {
1014*cdf0e10cSrcweir                 try
1015*cdf0e10cSrcweir                 {
1016*cdf0e10cSrcweir                     xProperties->addProperty( rPropName, PropertyAttribute::MAYBEVOID, rPropValue );
1017*cdf0e10cSrcweir                 }
1018*cdf0e10cSrcweir                 catch( PropertyExistException& ) {}
1019*cdf0e10cSrcweir                 catch( IllegalTypeException& ) { DBG_ERRORFILE( "IllegalTypeException" ); }
1020*cdf0e10cSrcweir                 catch( IllegalArgumentException& ) { DBG_ERRORFILE( "IllegalArgumentException" ); }
1021*cdf0e10cSrcweir             }
1022*cdf0e10cSrcweir         }
1023*cdf0e10cSrcweir 
1024*cdf0e10cSrcweir         // To ensure a reloctable office installation, the path to the
1025*cdf0e10cSrcweir         // office installtion directory must never be stored directly.
1026*cdf0e10cSrcweir         if ( SfxURLRelocator_Impl::propertyCanContainOfficeDir( rPropName ) )
1027*cdf0e10cSrcweir         {
1028*cdf0e10cSrcweir             OUString aValue;
1029*cdf0e10cSrcweir             if ( rPropValue >>= aValue )
1030*cdf0e10cSrcweir             {
1031*cdf0e10cSrcweir                 maRelocator.makeRelocatableURL( aValue );
1032*cdf0e10cSrcweir                 aPropValue = makeAny( aValue );
1033*cdf0e10cSrcweir             }
1034*cdf0e10cSrcweir             else
1035*cdf0e10cSrcweir             {
1036*cdf0e10cSrcweir                 Sequence< OUString > aValues;
1037*cdf0e10cSrcweir                 if ( rPropValue >>= aValues )
1038*cdf0e10cSrcweir                 {
1039*cdf0e10cSrcweir                     for ( sal_Int32 n = 0; n < aValues.getLength(); n++ )
1040*cdf0e10cSrcweir                     {
1041*cdf0e10cSrcweir                         maRelocator.makeRelocatableURL( aValues[ n ] );
1042*cdf0e10cSrcweir                     }
1043*cdf0e10cSrcweir                     aPropValue = makeAny( aValues );
1044*cdf0e10cSrcweir                 }
1045*cdf0e10cSrcweir                 else
1046*cdf0e10cSrcweir                 {
1047*cdf0e10cSrcweir                     OSL_ENSURE( false, "Unsupported property value type" );
1048*cdf0e10cSrcweir                 }
1049*cdf0e10cSrcweir             }
1050*cdf0e10cSrcweir         }
1051*cdf0e10cSrcweir 
1052*cdf0e10cSrcweir         // now set the property
1053*cdf0e10cSrcweir 
1054*cdf0e10cSrcweir         rContent.setPropertyValue( rPropName, aPropValue );
1055*cdf0e10cSrcweir         bPropertySet = sal_True;
1056*cdf0e10cSrcweir     }
1057*cdf0e10cSrcweir     catch ( RuntimeException& ) {}
1058*cdf0e10cSrcweir     catch ( Exception& ) {}
1059*cdf0e10cSrcweir 
1060*cdf0e10cSrcweir     return bPropertySet;
1061*cdf0e10cSrcweir }
1062*cdf0e10cSrcweir 
1063*cdf0e10cSrcweir // -----------------------------------------------------------------------
1064*cdf0e10cSrcweir sal_Bool SfxDocTplService_Impl::getProperty( Content& rContent,
1065*cdf0e10cSrcweir                                              const OUString& rPropName,
1066*cdf0e10cSrcweir                                              Any& rPropValue )
1067*cdf0e10cSrcweir {
1068*cdf0e10cSrcweir     sal_Bool bGotProperty = sal_False;
1069*cdf0e10cSrcweir 
1070*cdf0e10cSrcweir     // Get the property
1071*cdf0e10cSrcweir     try
1072*cdf0e10cSrcweir     {
1073*cdf0e10cSrcweir         uno::Reference< XPropertySetInfo > aPropInfo = rContent.getProperties();
1074*cdf0e10cSrcweir 
1075*cdf0e10cSrcweir         // check, wether or not the property exists
1076*cdf0e10cSrcweir         if ( !aPropInfo.is() || !aPropInfo->hasPropertyByName( rPropName ) )
1077*cdf0e10cSrcweir         {
1078*cdf0e10cSrcweir             return sal_False;
1079*cdf0e10cSrcweir         }
1080*cdf0e10cSrcweir 
1081*cdf0e10cSrcweir         // now get the property
1082*cdf0e10cSrcweir 
1083*cdf0e10cSrcweir         rPropValue = rContent.getPropertyValue( rPropName );
1084*cdf0e10cSrcweir 
1085*cdf0e10cSrcweir         // To ensure a reloctable office installation, the path to the
1086*cdf0e10cSrcweir         // office installtion directory must never be stored directly.
1087*cdf0e10cSrcweir         if ( SfxURLRelocator_Impl::propertyCanContainOfficeDir( rPropName ) )
1088*cdf0e10cSrcweir         {
1089*cdf0e10cSrcweir             OUString aValue;
1090*cdf0e10cSrcweir             if ( rPropValue >>= aValue )
1091*cdf0e10cSrcweir             {
1092*cdf0e10cSrcweir                 maRelocator.makeAbsoluteURL( aValue );
1093*cdf0e10cSrcweir                 rPropValue = makeAny( aValue );
1094*cdf0e10cSrcweir             }
1095*cdf0e10cSrcweir             else
1096*cdf0e10cSrcweir             {
1097*cdf0e10cSrcweir                 Sequence< OUString > aValues;
1098*cdf0e10cSrcweir                 if ( rPropValue >>= aValues )
1099*cdf0e10cSrcweir                 {
1100*cdf0e10cSrcweir                     for ( sal_Int32 n = 0; n < aValues.getLength(); n++ )
1101*cdf0e10cSrcweir                     {
1102*cdf0e10cSrcweir                         maRelocator.makeAbsoluteURL( aValues[ n ] );
1103*cdf0e10cSrcweir                     }
1104*cdf0e10cSrcweir                     rPropValue = makeAny( aValues );
1105*cdf0e10cSrcweir                 }
1106*cdf0e10cSrcweir                 else
1107*cdf0e10cSrcweir                 {
1108*cdf0e10cSrcweir                     OSL_ENSURE( false, "Unsupported property value type" );
1109*cdf0e10cSrcweir                 }
1110*cdf0e10cSrcweir             }
1111*cdf0e10cSrcweir         }
1112*cdf0e10cSrcweir 
1113*cdf0e10cSrcweir         bGotProperty = sal_True;
1114*cdf0e10cSrcweir     }
1115*cdf0e10cSrcweir     catch ( RuntimeException& ) {}
1116*cdf0e10cSrcweir     catch ( Exception& ) {}
1117*cdf0e10cSrcweir 
1118*cdf0e10cSrcweir     return bGotProperty;
1119*cdf0e10cSrcweir }
1120*cdf0e10cSrcweir 
1121*cdf0e10cSrcweir // -----------------------------------------------------------------------
1122*cdf0e10cSrcweir // static
1123*cdf0e10cSrcweir bool SfxURLRelocator_Impl::propertyCanContainOfficeDir(
1124*cdf0e10cSrcweir                                         const rtl::OUString & rPropName )
1125*cdf0e10cSrcweir {
1126*cdf0e10cSrcweir     // Note: TargetURL is handled by UCB itself (because it is a property
1127*cdf0e10cSrcweir     //       with a predefined semantic). Additional Core properties introduced
1128*cdf0e10cSrcweir     //       be a client app must be handled by the client app itself, because
1129*cdf0e10cSrcweir     //       the UCB does not know the semantics of those properties.
1130*cdf0e10cSrcweir     return ( rPropName.equalsAsciiL(
1131*cdf0e10cSrcweir                 RTL_CONSTASCII_STRINGPARAM( TARGET_DIR_URL ) ) ||
1132*cdf0e10cSrcweir              rPropName.equalsAsciiL(
1133*cdf0e10cSrcweir                 RTL_CONSTASCII_STRINGPARAM( PROPERTY_DIRLIST ) ) );
1134*cdf0e10cSrcweir }
1135*cdf0e10cSrcweir 
1136*cdf0e10cSrcweir //-----------------------------------------------------------------------------
1137*cdf0e10cSrcweir // public SfxDocTplService_Impl
1138*cdf0e10cSrcweir //-----------------------------------------------------------------------------
1139*cdf0e10cSrcweir 
1140*cdf0e10cSrcweir SfxDocTplService_Impl::SfxDocTplService_Impl( uno::Reference< XMultiServiceFactory > xFactory )
1141*cdf0e10cSrcweir : maRelocator( xFactory )
1142*cdf0e10cSrcweir {
1143*cdf0e10cSrcweir     mxFactory       = xFactory;
1144*cdf0e10cSrcweir     mpUpdater       = NULL;
1145*cdf0e10cSrcweir     mbIsInitialized = sal_False;
1146*cdf0e10cSrcweir     mbLocaleSet     = sal_False;
1147*cdf0e10cSrcweir }
1148*cdf0e10cSrcweir 
1149*cdf0e10cSrcweir //-----------------------------------------------------------------------------
1150*cdf0e10cSrcweir SfxDocTplService_Impl::~SfxDocTplService_Impl()
1151*cdf0e10cSrcweir {
1152*cdf0e10cSrcweir 	::osl::MutexGuard aGuard( maMutex );
1153*cdf0e10cSrcweir 
1154*cdf0e10cSrcweir     if ( mpUpdater )
1155*cdf0e10cSrcweir     {
1156*cdf0e10cSrcweir         mpUpdater->kill();
1157*cdf0e10cSrcweir         delete mpUpdater;
1158*cdf0e10cSrcweir     }
1159*cdf0e10cSrcweir }
1160*cdf0e10cSrcweir 
1161*cdf0e10cSrcweir //-----------------------------------------------------------------------------
1162*cdf0e10cSrcweir Locale SfxDocTplService_Impl::getLocale()
1163*cdf0e10cSrcweir {
1164*cdf0e10cSrcweir     ::osl::MutexGuard aGuard( maMutex );
1165*cdf0e10cSrcweir 
1166*cdf0e10cSrcweir     if ( !mbLocaleSet )
1167*cdf0e10cSrcweir         getDefaultLocale();
1168*cdf0e10cSrcweir 
1169*cdf0e10cSrcweir     return maLocale;
1170*cdf0e10cSrcweir }
1171*cdf0e10cSrcweir 
1172*cdf0e10cSrcweir //-----------------------------------------------------------------------------
1173*cdf0e10cSrcweir void SfxDocTplService_Impl::setLocale( const Locale &rLocale )
1174*cdf0e10cSrcweir {
1175*cdf0e10cSrcweir     ::osl::MutexGuard aGuard( maMutex );
1176*cdf0e10cSrcweir 
1177*cdf0e10cSrcweir     if ( mbLocaleSet &&
1178*cdf0e10cSrcweir          ( maLocale.Language != rLocale.Language ) &&
1179*cdf0e10cSrcweir          ( maLocale.Country != rLocale.Country ) )
1180*cdf0e10cSrcweir         mbIsInitialized = sal_False;
1181*cdf0e10cSrcweir 
1182*cdf0e10cSrcweir     maLocale    = rLocale;
1183*cdf0e10cSrcweir     mbLocaleSet = sal_True;
1184*cdf0e10cSrcweir }
1185*cdf0e10cSrcweir 
1186*cdf0e10cSrcweir //-----------------------------------------------------------------------------
1187*cdf0e10cSrcweir void SfxDocTplService_Impl::update( sal_Bool bUpdateNow )
1188*cdf0e10cSrcweir {
1189*cdf0e10cSrcweir     ::osl::MutexGuard aGuard( maMutex );
1190*cdf0e10cSrcweir 
1191*cdf0e10cSrcweir     if ( bUpdateNow )
1192*cdf0e10cSrcweir         doUpdate();
1193*cdf0e10cSrcweir     else
1194*cdf0e10cSrcweir     {
1195*cdf0e10cSrcweir         mpUpdater = new Updater_Impl( this );
1196*cdf0e10cSrcweir         mpUpdater->create();
1197*cdf0e10cSrcweir     }
1198*cdf0e10cSrcweir }
1199*cdf0e10cSrcweir 
1200*cdf0e10cSrcweir //-----------------------------------------------------------------------------
1201*cdf0e10cSrcweir void SfxDocTplService_Impl::doUpdate()
1202*cdf0e10cSrcweir {
1203*cdf0e10cSrcweir     ::osl::MutexGuard aGuard( maMutex );
1204*cdf0e10cSrcweir 
1205*cdf0e10cSrcweir 	OUString aPropName( RTL_CONSTASCII_USTRINGPARAM( PROPERTY_NEEDSUPDATE ) );
1206*cdf0e10cSrcweir 	Any		 aValue;
1207*cdf0e10cSrcweir 
1208*cdf0e10cSrcweir 	aValue <<= sal_True;
1209*cdf0e10cSrcweir     setProperty( maRootContent, aPropName, aValue );
1210*cdf0e10cSrcweir 
1211*cdf0e10cSrcweir     GroupList_Impl	aGroupList;
1212*cdf0e10cSrcweir 
1213*cdf0e10cSrcweir     // get the entries from the hierarchy
1214*cdf0e10cSrcweir     createFromContent( aGroupList, maRootContent, sal_True );
1215*cdf0e10cSrcweir 
1216*cdf0e10cSrcweir     // get the entries from the template directories
1217*cdf0e10cSrcweir     sal_Int32   nCountDir = maTemplateDirs.getLength();
1218*cdf0e10cSrcweir     OUString*   pDirs = maTemplateDirs.getArray();
1219*cdf0e10cSrcweir     Content     aDirContent;
1220*cdf0e10cSrcweir 
1221*cdf0e10cSrcweir 	// the last directory in the list must be writable
1222*cdf0e10cSrcweir 	sal_Bool bWriteableDirectory = sal_True;
1223*cdf0e10cSrcweir 
1224*cdf0e10cSrcweir     // the target folder might not exist, for this reason no interaction handler should be used
1225*cdf0e10cSrcweir     uno::Reference< XCommandEnvironment > aQuietEnv;
1226*cdf0e10cSrcweir 
1227*cdf0e10cSrcweir     while ( nCountDir )
1228*cdf0e10cSrcweir     {
1229*cdf0e10cSrcweir         nCountDir--;
1230*cdf0e10cSrcweir         if ( Content::create( pDirs[ nCountDir ], aQuietEnv, aDirContent ) )
1231*cdf0e10cSrcweir         {
1232*cdf0e10cSrcweir             createFromContent( aGroupList, aDirContent, sal_False, bWriteableDirectory );
1233*cdf0e10cSrcweir         }
1234*cdf0e10cSrcweir 
1235*cdf0e10cSrcweir 		bWriteableDirectory = sal_False;
1236*cdf0e10cSrcweir     }
1237*cdf0e10cSrcweir 
1238*cdf0e10cSrcweir     // now check the list
1239*cdf0e10cSrcweir     GroupData_Impl *pGroup = aGroupList.First();
1240*cdf0e10cSrcweir     while ( pGroup )
1241*cdf0e10cSrcweir     {
1242*cdf0e10cSrcweir         if ( pGroup->getInUse() )
1243*cdf0e10cSrcweir         {
1244*cdf0e10cSrcweir             if ( pGroup->getInHierarchy() )
1245*cdf0e10cSrcweir             {
1246*cdf0e10cSrcweir 				Content aGroup;
1247*cdf0e10cSrcweir     			if ( Content::create( pGroup->getHierarchyURL(), maCmdEnv, aGroup ) )
1248*cdf0e10cSrcweir         			setProperty( aGroup,
1249*cdf0e10cSrcweir 								 OUString( RTL_CONSTASCII_USTRINGPARAM( TARGET_DIR_URL ) ),
1250*cdf0e10cSrcweir 								 makeAny( pGroup->getTargetURL() ) );
1251*cdf0e10cSrcweir 
1252*cdf0e10cSrcweir                 sal_uIntPtr nCount = pGroup->count();
1253*cdf0e10cSrcweir                 for ( sal_uIntPtr i=0; i<nCount; i++ )
1254*cdf0e10cSrcweir                 {
1255*cdf0e10cSrcweir                     DocTemplates_EntryData_Impl *pData = pGroup->getEntry( i );
1256*cdf0e10cSrcweir                     if ( ! pData->getInUse() )
1257*cdf0e10cSrcweir                     {
1258*cdf0e10cSrcweir                         if ( pData->getInHierarchy() )
1259*cdf0e10cSrcweir                             removeFromHierarchy( pData ); // delete entry in hierarchy
1260*cdf0e10cSrcweir                         else
1261*cdf0e10cSrcweir                             addToHierarchy( pGroup, pData ); // add entry to hierarchy
1262*cdf0e10cSrcweir                     }
1263*cdf0e10cSrcweir                     else if ( pData->getUpdateType() ||
1264*cdf0e10cSrcweir                               pData->getUpdateLink() )
1265*cdf0e10cSrcweir                     {
1266*cdf0e10cSrcweir                         updateData( pData );
1267*cdf0e10cSrcweir                     }
1268*cdf0e10cSrcweir                 }
1269*cdf0e10cSrcweir             }
1270*cdf0e10cSrcweir             else
1271*cdf0e10cSrcweir             {
1272*cdf0e10cSrcweir                 addGroupToHierarchy( pGroup ); // add group to hierarchy
1273*cdf0e10cSrcweir             }
1274*cdf0e10cSrcweir         }
1275*cdf0e10cSrcweir         else
1276*cdf0e10cSrcweir             removeFromHierarchy( pGroup ); // delete group from hierarchy
1277*cdf0e10cSrcweir 
1278*cdf0e10cSrcweir         delete pGroup;
1279*cdf0e10cSrcweir         pGroup = aGroupList.Next();
1280*cdf0e10cSrcweir     }
1281*cdf0e10cSrcweir 
1282*cdf0e10cSrcweir    	aValue <<= sal_False;
1283*cdf0e10cSrcweir     setProperty( maRootContent, aPropName, aValue );
1284*cdf0e10cSrcweir }
1285*cdf0e10cSrcweir 
1286*cdf0e10cSrcweir //-----------------------------------------------------------------------------
1287*cdf0e10cSrcweir uno::Sequence< beans::StringPair > SfxDocTplService_Impl::ReadUINamesForTemplateDir_Impl( const ::rtl::OUString& aUserPath )
1288*cdf0e10cSrcweir {
1289*cdf0e10cSrcweir 	INetURLObject aLocObj( aUserPath );
1290*cdf0e10cSrcweir     aLocObj.insertName( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "groupuinames.xml" ) ), false,
1291*cdf0e10cSrcweir                       INetURLObject::LAST_SEGMENT, true,
1292*cdf0e10cSrcweir                       INetURLObject::ENCODE_ALL );
1293*cdf0e10cSrcweir 	Content aLocContent;
1294*cdf0e10cSrcweir 
1295*cdf0e10cSrcweir 	// TODO/LATER: Use hashmap in future
1296*cdf0e10cSrcweir 	uno::Sequence< beans::StringPair > aUINames;
1297*cdf0e10cSrcweir 	if ( Content::create( aLocObj.GetMainURL( INetURLObject::NO_DECODE ), uno::Reference < ucb::XCommandEnvironment >(), aLocContent ) )
1298*cdf0e10cSrcweir 	{
1299*cdf0e10cSrcweir 		try
1300*cdf0e10cSrcweir 		{
1301*cdf0e10cSrcweir 			uno::Reference< io::XInputStream > xLocStream = aLocContent.openStream();
1302*cdf0e10cSrcweir 			if ( xLocStream.is() )
1303*cdf0e10cSrcweir 				aUINames = DocTemplLocaleHelper::ReadGroupLocalizationSequence( xLocStream, mxFactory );
1304*cdf0e10cSrcweir 		}
1305*cdf0e10cSrcweir 		catch( uno::Exception& )
1306*cdf0e10cSrcweir 		{}
1307*cdf0e10cSrcweir 	}
1308*cdf0e10cSrcweir 
1309*cdf0e10cSrcweir 	return aUINames;
1310*cdf0e10cSrcweir }
1311*cdf0e10cSrcweir 
1312*cdf0e10cSrcweir //-----------------------------------------------------------------------------
1313*cdf0e10cSrcweir sal_Bool SfxDocTplService_Impl::UpdateUINamesForTemplateDir_Impl( const ::rtl::OUString& aUserPath,
1314*cdf0e10cSrcweir 																  const ::rtl::OUString& aGroupName,
1315*cdf0e10cSrcweir 																  const ::rtl::OUString& aNewFolderName )
1316*cdf0e10cSrcweir {
1317*cdf0e10cSrcweir 	uno::Sequence< beans::StringPair > aUINames = ReadUINamesForTemplateDir_Impl( aUserPath );
1318*cdf0e10cSrcweir 	sal_Int32 nLen = aUINames.getLength();
1319*cdf0e10cSrcweir 
1320*cdf0e10cSrcweir 	// it is possible that the name is used already, but it should be checked before
1321*cdf0e10cSrcweir 	for ( sal_Int32 nInd = 0; nInd < nLen; nInd++ )
1322*cdf0e10cSrcweir 		if ( aUINames[nInd].First.equals( aNewFolderName ) )
1323*cdf0e10cSrcweir 			return sal_False;
1324*cdf0e10cSrcweir 
1325*cdf0e10cSrcweir 	aUINames.realloc( ++nLen );
1326*cdf0e10cSrcweir 	aUINames[nLen-1].First = aNewFolderName;
1327*cdf0e10cSrcweir 	aUINames[nLen-1].Second = aGroupName;
1328*cdf0e10cSrcweir 
1329*cdf0e10cSrcweir 	return WriteUINamesForTemplateDir_Impl( aUserPath, aUINames );
1330*cdf0e10cSrcweir }
1331*cdf0e10cSrcweir 
1332*cdf0e10cSrcweir //-----------------------------------------------------------------------------
1333*cdf0e10cSrcweir sal_Bool SfxDocTplService_Impl::ReplaceUINamesForTemplateDir_Impl( const ::rtl::OUString& aUserPath,
1334*cdf0e10cSrcweir 																  const ::rtl::OUString& aDefaultFsysGroupName,
1335*cdf0e10cSrcweir 																  const ::rtl::OUString& aOldGroupName,
1336*cdf0e10cSrcweir 																  const ::rtl::OUString& aNewGroupName )
1337*cdf0e10cSrcweir {
1338*cdf0e10cSrcweir 	uno::Sequence< beans::StringPair > aUINames = ReadUINamesForTemplateDir_Impl( aUserPath );
1339*cdf0e10cSrcweir 	sal_Int32 nLen = aUINames.getLength();
1340*cdf0e10cSrcweir 
1341*cdf0e10cSrcweir 	sal_Bool bChanged = sal_False;
1342*cdf0e10cSrcweir 	for ( sal_Int32 nInd = 0; nInd < nLen; nInd++ )
1343*cdf0e10cSrcweir 		if ( aUINames[nInd].Second.equals( aOldGroupName ) )
1344*cdf0e10cSrcweir 		{
1345*cdf0e10cSrcweir 			aUINames[nInd].Second = aNewGroupName;
1346*cdf0e10cSrcweir 			bChanged = sal_True;
1347*cdf0e10cSrcweir 		}
1348*cdf0e10cSrcweir 
1349*cdf0e10cSrcweir 	if ( !bChanged )
1350*cdf0e10cSrcweir 	{
1351*cdf0e10cSrcweir 		aUINames.realloc( ++nLen );
1352*cdf0e10cSrcweir 		aUINames[nLen-1].First = aDefaultFsysGroupName;
1353*cdf0e10cSrcweir 		aUINames[nLen-1].Second = aNewGroupName;
1354*cdf0e10cSrcweir 	}
1355*cdf0e10cSrcweir 	return WriteUINamesForTemplateDir_Impl( aUserPath, aUINames );
1356*cdf0e10cSrcweir }
1357*cdf0e10cSrcweir 
1358*cdf0e10cSrcweir //-----------------------------------------------------------------------------
1359*cdf0e10cSrcweir sal_Bool SfxDocTplService_Impl::RemoveUINamesForTemplateDir_Impl( const ::rtl::OUString& aUserPath,
1360*cdf0e10cSrcweir 																  const ::rtl::OUString& aGroupName )
1361*cdf0e10cSrcweir {
1362*cdf0e10cSrcweir 	uno::Sequence< beans::StringPair > aUINames = ReadUINamesForTemplateDir_Impl( aUserPath );
1363*cdf0e10cSrcweir 	sal_Int32 nLen = aUINames.getLength();
1364*cdf0e10cSrcweir 	uno::Sequence< beans::StringPair > aNewUINames( nLen );
1365*cdf0e10cSrcweir 	sal_Int32 nNewLen = 0;
1366*cdf0e10cSrcweir 
1367*cdf0e10cSrcweir 	sal_Bool bChanged = sal_False;
1368*cdf0e10cSrcweir 	for ( sal_Int32 nInd = 0; nInd < nLen; nInd++ )
1369*cdf0e10cSrcweir 		if ( aUINames[nInd].Second.equals( aGroupName ) )
1370*cdf0e10cSrcweir 			bChanged = sal_True;
1371*cdf0e10cSrcweir 		else
1372*cdf0e10cSrcweir 		{
1373*cdf0e10cSrcweir 			nNewLen++;
1374*cdf0e10cSrcweir 			aNewUINames[nNewLen-1].First = aUINames[nInd].First;
1375*cdf0e10cSrcweir 			aNewUINames[nNewLen-1].Second = aUINames[nInd].Second;
1376*cdf0e10cSrcweir 		}
1377*cdf0e10cSrcweir 
1378*cdf0e10cSrcweir 	aNewUINames.realloc( nNewLen );
1379*cdf0e10cSrcweir 
1380*cdf0e10cSrcweir 	return bChanged ? WriteUINamesForTemplateDir_Impl( aUserPath, aNewUINames ) : sal_True;
1381*cdf0e10cSrcweir }
1382*cdf0e10cSrcweir 
1383*cdf0e10cSrcweir 
1384*cdf0e10cSrcweir //-----------------------------------------------------------------------------
1385*cdf0e10cSrcweir sal_Bool SfxDocTplService_Impl::WriteUINamesForTemplateDir_Impl( const ::rtl::OUString& aUserPath,
1386*cdf0e10cSrcweir 																const uno::Sequence< beans::StringPair >& aUINames )
1387*cdf0e10cSrcweir {
1388*cdf0e10cSrcweir 	sal_Bool bResult = sal_False;
1389*cdf0e10cSrcweir 	try {
1390*cdf0e10cSrcweir 		uno::Reference< beans::XPropertySet > xTempFile(
1391*cdf0e10cSrcweir 				mxFactory->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.io.TempFile" ) ),
1392*cdf0e10cSrcweir 				uno::UNO_QUERY_THROW );
1393*cdf0e10cSrcweir 
1394*cdf0e10cSrcweir 		::rtl::OUString aTempURL;
1395*cdf0e10cSrcweir 		uno::Any aUrl = xTempFile->getPropertyValue( ::rtl::OUString::createFromAscii( "Uri" ) );
1396*cdf0e10cSrcweir 		aUrl >>= aTempURL;
1397*cdf0e10cSrcweir 
1398*cdf0e10cSrcweir 		uno::Reference< io::XStream > xStream( xTempFile, uno::UNO_QUERY_THROW );
1399*cdf0e10cSrcweir 		uno::Reference< io::XOutputStream > xOutStream = xStream->getOutputStream();
1400*cdf0e10cSrcweir 		if ( !xOutStream.is() )
1401*cdf0e10cSrcweir 			throw uno::RuntimeException();
1402*cdf0e10cSrcweir 
1403*cdf0e10cSrcweir 		DocTemplLocaleHelper::WriteGroupLocalizationSequence( xOutStream, aUINames, mxFactory );
1404*cdf0e10cSrcweir 		try {
1405*cdf0e10cSrcweir 			// the SAX writer might close the stream
1406*cdf0e10cSrcweir 			xOutStream->closeOutput();
1407*cdf0e10cSrcweir 		} catch( uno::Exception& )
1408*cdf0e10cSrcweir 		{}
1409*cdf0e10cSrcweir 
1410*cdf0e10cSrcweir 		Content aTargetContent( aUserPath, maCmdEnv );
1411*cdf0e10cSrcweir 		Content aSourceContent( aTempURL, maCmdEnv );
1412*cdf0e10cSrcweir 		aTargetContent.transferContent( aSourceContent,
1413*cdf0e10cSrcweir 										InsertOperation_COPY,
1414*cdf0e10cSrcweir 										::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "groupuinames.xml" ) ),
1415*cdf0e10cSrcweir 										ucb::NameClash::OVERWRITE );
1416*cdf0e10cSrcweir 		bResult = sal_True;
1417*cdf0e10cSrcweir 	}
1418*cdf0e10cSrcweir 	catch ( uno::Exception& )
1419*cdf0e10cSrcweir 	{
1420*cdf0e10cSrcweir 	}
1421*cdf0e10cSrcweir 
1422*cdf0e10cSrcweir 	return bResult;
1423*cdf0e10cSrcweir }
1424*cdf0e10cSrcweir 
1425*cdf0e10cSrcweir //-----------------------------------------------------------------------------
1426*cdf0e10cSrcweir ::rtl::OUString SfxDocTplService_Impl::CreateNewGroupFsys( const ::rtl::OUString& rGroupName, Content& aGroup )
1427*cdf0e10cSrcweir {
1428*cdf0e10cSrcweir 	::rtl::OUString aResultURL;
1429*cdf0e10cSrcweir 
1430*cdf0e10cSrcweir 	if ( maTemplateDirs.getLength() )
1431*cdf0e10cSrcweir 	{
1432*cdf0e10cSrcweir 		::rtl::OUString aTargetPath = maTemplateDirs[ maTemplateDirs.getLength() - 1 ];
1433*cdf0e10cSrcweir 
1434*cdf0e10cSrcweir 		// create a new folder with the given name
1435*cdf0e10cSrcweir 		Content aNewFolder;
1436*cdf0e10cSrcweir 		::rtl::OUString aNewFolderName;
1437*cdf0e10cSrcweir 
1438*cdf0e10cSrcweir 		// the Fsys name instead of GroupName should be used, the groupuinames must be added also
1439*cdf0e10cSrcweir 		if ( !CreateNewUniqueFolderWithPrefix( aTargetPath,
1440*cdf0e10cSrcweir 												rGroupName,
1441*cdf0e10cSrcweir 												aNewFolderName,
1442*cdf0e10cSrcweir 												aResultURL,
1443*cdf0e10cSrcweir 												aNewFolder )
1444*cdf0e10cSrcweir 		  && !CreateNewUniqueFolderWithPrefix( aTargetPath,
1445*cdf0e10cSrcweir 												::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UserGroup" ) ),
1446*cdf0e10cSrcweir 												aNewFolderName,
1447*cdf0e10cSrcweir 												aResultURL,
1448*cdf0e10cSrcweir 												aNewFolder ) )
1449*cdf0e10cSrcweir 
1450*cdf0e10cSrcweir 			return ::rtl::OUString();
1451*cdf0e10cSrcweir 
1452*cdf0e10cSrcweir 		if ( !UpdateUINamesForTemplateDir_Impl( aTargetPath, rGroupName, aNewFolderName ) )
1453*cdf0e10cSrcweir 		{
1454*cdf0e10cSrcweir 			// we could not create the groupuinames for the folder, so we delete the group in the
1455*cdf0e10cSrcweir 			// the folder and return
1456*cdf0e10cSrcweir 			removeContent( aNewFolder );
1457*cdf0e10cSrcweir 			return ::rtl::OUString();
1458*cdf0e10cSrcweir 		}
1459*cdf0e10cSrcweir 
1460*cdf0e10cSrcweir 		// Now set the target url for this group and we are done
1461*cdf0e10cSrcweir 		OUString aPropName( RTL_CONSTASCII_USTRINGPARAM( TARGET_DIR_URL ) );
1462*cdf0e10cSrcweir 		Any aValue = makeAny( aResultURL );
1463*cdf0e10cSrcweir 
1464*cdf0e10cSrcweir 		if ( ! setProperty( aGroup, aPropName, aValue ) )
1465*cdf0e10cSrcweir 		{
1466*cdf0e10cSrcweir 			removeContent( aNewFolder );
1467*cdf0e10cSrcweir 			return ::rtl::OUString();
1468*cdf0e10cSrcweir 		}
1469*cdf0e10cSrcweir 	}
1470*cdf0e10cSrcweir 
1471*cdf0e10cSrcweir 	return aResultURL;
1472*cdf0e10cSrcweir }
1473*cdf0e10cSrcweir 
1474*cdf0e10cSrcweir //-----------------------------------------------------------------------------
1475*cdf0e10cSrcweir sal_Bool SfxDocTplService_Impl::addGroup( const OUString& rGroupName )
1476*cdf0e10cSrcweir {
1477*cdf0e10cSrcweir 	::osl::MutexGuard aGuard( maMutex );
1478*cdf0e10cSrcweir 
1479*cdf0e10cSrcweir 	// Check, wether or not there is a group with this name
1480*cdf0e10cSrcweir 	Content		 aNewGroup;
1481*cdf0e10cSrcweir 	OUString		aNewGroupURL;
1482*cdf0e10cSrcweir 	INetURLObject   aNewGroupObj( maRootURL );
1483*cdf0e10cSrcweir 
1484*cdf0e10cSrcweir 	aNewGroupObj.insertName( rGroupName, false,
1485*cdf0e10cSrcweir 					  INetURLObject::LAST_SEGMENT, true,
1486*cdf0e10cSrcweir 					  INetURLObject::ENCODE_ALL );
1487*cdf0e10cSrcweir 
1488*cdf0e10cSrcweir 	aNewGroupURL = aNewGroupObj.GetMainURL( INetURLObject::NO_DECODE );
1489*cdf0e10cSrcweir 
1490*cdf0e10cSrcweir 	if ( Content::create( aNewGroupURL, maCmdEnv, aNewGroup ) ||
1491*cdf0e10cSrcweir 		 ! createFolder( aNewGroupURL, sal_False, sal_False, aNewGroup ) )
1492*cdf0e10cSrcweir 	{
1493*cdf0e10cSrcweir 		// if there already was a group with this name or the new group
1494*cdf0e10cSrcweir 		// could not be created, we return here
1495*cdf0e10cSrcweir 		return sal_False;
1496*cdf0e10cSrcweir 	}
1497*cdf0e10cSrcweir 
1498*cdf0e10cSrcweir 	// Get the user template path entry ( new group will always
1499*cdf0e10cSrcweir 	// be added in the user template path )
1500*cdf0e10cSrcweir 	sal_Int32   nIndex;
1501*cdf0e10cSrcweir 	OUString	aUserPath;
1502*cdf0e10cSrcweir 
1503*cdf0e10cSrcweir 	nIndex = maTemplateDirs.getLength();
1504*cdf0e10cSrcweir 	if ( nIndex )
1505*cdf0e10cSrcweir 		nIndex--;
1506*cdf0e10cSrcweir 	else
1507*cdf0e10cSrcweir 		return sal_False;   // We don't know where to add the group
1508*cdf0e10cSrcweir 
1509*cdf0e10cSrcweir 	aUserPath = maTemplateDirs[ nIndex ];
1510*cdf0e10cSrcweir 
1511*cdf0e10cSrcweir 	// create a new folder with the given name
1512*cdf0e10cSrcweir 	Content		 aNewFolder;
1513*cdf0e10cSrcweir 	OUString		aNewFolderName;
1514*cdf0e10cSrcweir 	OUString		aNewFolderURL;
1515*cdf0e10cSrcweir 
1516*cdf0e10cSrcweir 	// the Fsys name instead of GroupName should be used, the groupuinames must be added also
1517*cdf0e10cSrcweir 	if ( !CreateNewUniqueFolderWithPrefix( aUserPath,
1518*cdf0e10cSrcweir 											rGroupName,
1519*cdf0e10cSrcweir 											aNewFolderName,
1520*cdf0e10cSrcweir 											aNewFolderURL,
1521*cdf0e10cSrcweir 											aNewFolder )
1522*cdf0e10cSrcweir 	  && !CreateNewUniqueFolderWithPrefix( aUserPath,
1523*cdf0e10cSrcweir 											::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UserGroup" ) ),
1524*cdf0e10cSrcweir 											aNewFolderName,
1525*cdf0e10cSrcweir 											aNewFolderURL,
1526*cdf0e10cSrcweir 											aNewFolder ) )
1527*cdf0e10cSrcweir 	{
1528*cdf0e10cSrcweir 		// we could not create the folder, so we delete the group in the
1529*cdf0e10cSrcweir 		// hierarchy and return
1530*cdf0e10cSrcweir 		removeContent( aNewGroup );
1531*cdf0e10cSrcweir 		return sal_False;
1532*cdf0e10cSrcweir 	}
1533*cdf0e10cSrcweir 
1534*cdf0e10cSrcweir 	if ( !UpdateUINamesForTemplateDir_Impl( aUserPath, rGroupName, aNewFolderName ) )
1535*cdf0e10cSrcweir 	{
1536*cdf0e10cSrcweir 		// we could not create the groupuinames for the folder, so we delete the group in the
1537*cdf0e10cSrcweir 		// hierarchy, the folder and return
1538*cdf0e10cSrcweir 		removeContent( aNewGroup );
1539*cdf0e10cSrcweir 		removeContent( aNewFolder );
1540*cdf0e10cSrcweir 		return sal_False;
1541*cdf0e10cSrcweir 	}
1542*cdf0e10cSrcweir 
1543*cdf0e10cSrcweir 	// Now set the target url for this group and we are done
1544*cdf0e10cSrcweir 	OUString aPropName( RTL_CONSTASCII_USTRINGPARAM( TARGET_DIR_URL ) );
1545*cdf0e10cSrcweir 	Any aValue = makeAny( aNewFolderURL );
1546*cdf0e10cSrcweir 
1547*cdf0e10cSrcweir 	if ( ! setProperty( aNewGroup, aPropName, aValue ) )
1548*cdf0e10cSrcweir 	{
1549*cdf0e10cSrcweir 		removeContent( aNewGroup );
1550*cdf0e10cSrcweir 		removeContent( aNewFolder );
1551*cdf0e10cSrcweir 		return sal_False;
1552*cdf0e10cSrcweir 	}
1553*cdf0e10cSrcweir 
1554*cdf0e10cSrcweir 	return sal_True;
1555*cdf0e10cSrcweir }
1556*cdf0e10cSrcweir 
1557*cdf0e10cSrcweir //-----------------------------------------------------------------------------
1558*cdf0e10cSrcweir sal_Bool SfxDocTplService_Impl::removeGroup( const OUString& rGroupName )
1559*cdf0e10cSrcweir {
1560*cdf0e10cSrcweir 	// remove all the elements that have the prefix aTargetURL
1561*cdf0e10cSrcweir 	// if the group does not have other elements remove it
1562*cdf0e10cSrcweir 
1563*cdf0e10cSrcweir 	::osl::MutexGuard aGuard( maMutex );
1564*cdf0e10cSrcweir 
1565*cdf0e10cSrcweir 	sal_Bool bResult = sal_False;
1566*cdf0e10cSrcweir 
1567*cdf0e10cSrcweir 	// create the group url
1568*cdf0e10cSrcweir 	INetURLObject aGroupObj( maRootURL );
1569*cdf0e10cSrcweir 	aGroupObj.insertName( rGroupName, false,
1570*cdf0e10cSrcweir 					  INetURLObject::LAST_SEGMENT, true,
1571*cdf0e10cSrcweir 					  INetURLObject::ENCODE_ALL );
1572*cdf0e10cSrcweir 
1573*cdf0e10cSrcweir 	// Get the target url
1574*cdf0e10cSrcweir 	Content	 aGroup;
1575*cdf0e10cSrcweir 	OUString	aGroupURL = aGroupObj.GetMainURL( INetURLObject::NO_DECODE );
1576*cdf0e10cSrcweir 
1577*cdf0e10cSrcweir 	if ( Content::create( aGroupURL, maCmdEnv, aGroup ) )
1578*cdf0e10cSrcweir 	{
1579*cdf0e10cSrcweir 		OUString	aPropName( RTL_CONSTASCII_USTRINGPARAM( TARGET_DIR_URL ) );
1580*cdf0e10cSrcweir 		Any		 aValue;
1581*cdf0e10cSrcweir 
1582*cdf0e10cSrcweir 		OUString	aGroupTargetURL;
1583*cdf0e10cSrcweir 		if ( getProperty( aGroup, aPropName, aValue ) )
1584*cdf0e10cSrcweir 			aValue >>= aGroupTargetURL;
1585*cdf0e10cSrcweir 
1586*cdf0e10cSrcweir 		if ( !aGroupTargetURL.getLength() )
1587*cdf0e10cSrcweir 			return sal_False; // nothing is allowed to be removed
1588*cdf0e10cSrcweir 
1589*cdf0e10cSrcweir 		if ( !maTemplateDirs.getLength() )
1590*cdf0e10cSrcweir 			return sal_False;
1591*cdf0e10cSrcweir 		::rtl::OUString aGeneralTempPath = maTemplateDirs[ maTemplateDirs.getLength() - 1 ];
1592*cdf0e10cSrcweir 
1593*cdf0e10cSrcweir 		// check that the fs location is in writeble folder and this is not a "My templates" folder
1594*cdf0e10cSrcweir 		INetURLObject aGroupParentFolder( aGroupTargetURL );
1595*cdf0e10cSrcweir 		if ( !aGroupParentFolder.removeSegment()
1596*cdf0e10cSrcweir 		  || !::utl::UCBContentHelper::IsSubPath( aGeneralTempPath,
1597*cdf0e10cSrcweir 		  											aGroupParentFolder.GetMainURL( INetURLObject::NO_DECODE ) ) )
1598*cdf0e10cSrcweir 			return sal_False;
1599*cdf0e10cSrcweir 
1600*cdf0e10cSrcweir 		// now get the content of the Group
1601*cdf0e10cSrcweir 		uno::Reference< XResultSet > xResultSet;
1602*cdf0e10cSrcweir 		Sequence< OUString > aProps( 1 );
1603*cdf0e10cSrcweir 
1604*cdf0e10cSrcweir 		aProps[0] = OUString::createFromAscii( TARGET_URL );
1605*cdf0e10cSrcweir 
1606*cdf0e10cSrcweir 		try
1607*cdf0e10cSrcweir 		{
1608*cdf0e10cSrcweir 			sal_Bool bHasNonRemovable = sal_False;
1609*cdf0e10cSrcweir 			sal_Bool bHasShared = sal_False;
1610*cdf0e10cSrcweir 
1611*cdf0e10cSrcweir 			ResultSetInclude eInclude = INCLUDE_DOCUMENTS_ONLY;
1612*cdf0e10cSrcweir 			xResultSet = aGroup.createCursor( aProps, eInclude );
1613*cdf0e10cSrcweir 
1614*cdf0e10cSrcweir 			if ( xResultSet.is() )
1615*cdf0e10cSrcweir 			{
1616*cdf0e10cSrcweir 				uno::Reference< XContentAccess > xContentAccess( xResultSet, UNO_QUERY_THROW );
1617*cdf0e10cSrcweir 				uno::Reference< XRow > xRow( xResultSet, UNO_QUERY_THROW );
1618*cdf0e10cSrcweir 
1619*cdf0e10cSrcweir 				while ( xResultSet->next() )
1620*cdf0e10cSrcweir 				{
1621*cdf0e10cSrcweir 					OUString aTemplTargetURL( xRow->getString( 1 ) );
1622*cdf0e10cSrcweir 					OUString aHierURL = xContentAccess->queryContentIdentifierString();
1623*cdf0e10cSrcweir 
1624*cdf0e10cSrcweir 					if ( ::utl::UCBContentHelper::IsSubPath( aGroupTargetURL, aTemplTargetURL ) )
1625*cdf0e10cSrcweir 					{
1626*cdf0e10cSrcweir 						// this is a user template, and it can be removed
1627*cdf0e10cSrcweir 						if ( removeContent( aTemplTargetURL ) )
1628*cdf0e10cSrcweir 							removeContent( aHierURL );
1629*cdf0e10cSrcweir 						else
1630*cdf0e10cSrcweir 							bHasNonRemovable = sal_True;
1631*cdf0e10cSrcweir 					}
1632*cdf0e10cSrcweir 					else
1633*cdf0e10cSrcweir 						bHasShared = sal_True;
1634*cdf0e10cSrcweir 				}
1635*cdf0e10cSrcweir 
1636*cdf0e10cSrcweir 				if ( !bHasNonRemovable && !bHasShared )
1637*cdf0e10cSrcweir 				{
1638*cdf0e10cSrcweir 					if ( removeContent( aGroupTargetURL )
1639*cdf0e10cSrcweir 					  || !::utl::UCBContentHelper::Exists( aGroupTargetURL ) )
1640*cdf0e10cSrcweir 					{
1641*cdf0e10cSrcweir 						removeContent( aGroupURL );
1642*cdf0e10cSrcweir 						RemoveUINamesForTemplateDir_Impl( aGeneralTempPath, rGroupName );
1643*cdf0e10cSrcweir 						bResult = sal_True; // the operation is successful only if the whole group is removed
1644*cdf0e10cSrcweir 					}
1645*cdf0e10cSrcweir 				}
1646*cdf0e10cSrcweir 				else if ( !bHasNonRemovable )
1647*cdf0e10cSrcweir 				{
1648*cdf0e10cSrcweir 					if ( removeContent( aGroupTargetURL )
1649*cdf0e10cSrcweir 					  || !::utl::UCBContentHelper::Exists( aGroupTargetURL ) )
1650*cdf0e10cSrcweir 					{
1651*cdf0e10cSrcweir 						RemoveUINamesForTemplateDir_Impl( aGeneralTempPath, rGroupName );
1652*cdf0e10cSrcweir 						setProperty( aGroup, aPropName, uno::makeAny( ::rtl::OUString() ) );
1653*cdf0e10cSrcweir 					}
1654*cdf0e10cSrcweir 				}
1655*cdf0e10cSrcweir 			}
1656*cdf0e10cSrcweir 		}
1657*cdf0e10cSrcweir 		catch ( Exception& ) {}
1658*cdf0e10cSrcweir 	}
1659*cdf0e10cSrcweir 
1660*cdf0e10cSrcweir 	return bResult;
1661*cdf0e10cSrcweir }
1662*cdf0e10cSrcweir 
1663*cdf0e10cSrcweir //-----------------------------------------------------------------------------
1664*cdf0e10cSrcweir sal_Bool SfxDocTplService_Impl::renameGroup( const OUString& rOldName,
1665*cdf0e10cSrcweir                                              const OUString& rNewName )
1666*cdf0e10cSrcweir {
1667*cdf0e10cSrcweir     ::osl::MutexGuard aGuard( maMutex );
1668*cdf0e10cSrcweir 
1669*cdf0e10cSrcweir     // create the group url
1670*cdf0e10cSrcweir     Content         aGroup;
1671*cdf0e10cSrcweir     INetURLObject   aGroupObj( maRootURL );
1672*cdf0e10cSrcweir                     aGroupObj.insertName( rNewName, false,
1673*cdf0e10cSrcweir                                           INetURLObject::LAST_SEGMENT, true,
1674*cdf0e10cSrcweir                                           INetURLObject::ENCODE_ALL );
1675*cdf0e10cSrcweir     OUString        aGroupURL = aGroupObj.GetMainURL( INetURLObject::NO_DECODE );
1676*cdf0e10cSrcweir 
1677*cdf0e10cSrcweir     // Check, if there is a group with the new name, return false
1678*cdf0e10cSrcweir     // if there is one.
1679*cdf0e10cSrcweir     if ( Content::create( aGroupURL, maCmdEnv, aGroup ) )
1680*cdf0e10cSrcweir         return sal_False;
1681*cdf0e10cSrcweir 
1682*cdf0e10cSrcweir     aGroupObj.removeSegment();
1683*cdf0e10cSrcweir     aGroupObj.insertName( rOldName, false,
1684*cdf0e10cSrcweir                       INetURLObject::LAST_SEGMENT, true,
1685*cdf0e10cSrcweir                       INetURLObject::ENCODE_ALL );
1686*cdf0e10cSrcweir     aGroupURL = aGroupObj.GetMainURL( INetURLObject::NO_DECODE );
1687*cdf0e10cSrcweir 
1688*cdf0e10cSrcweir     // When there is no group with the old name, we can't rename it
1689*cdf0e10cSrcweir     if ( ! Content::create( aGroupURL, maCmdEnv, aGroup ) )
1690*cdf0e10cSrcweir         return sal_False;
1691*cdf0e10cSrcweir 
1692*cdf0e10cSrcweir 	OUString aGroupTargetURL;
1693*cdf0e10cSrcweir 	// there is no need to check whether target dir url is in target path, since if the target path is changed
1694*cdf0e10cSrcweir 	// the target dir url should be already generated new
1695*cdf0e10cSrcweir 	OUString	aPropName( RTL_CONSTASCII_USTRINGPARAM( TARGET_DIR_URL ) );
1696*cdf0e10cSrcweir 	Any		 aValue;
1697*cdf0e10cSrcweir 	if ( getProperty( aGroup, aPropName, aValue ) )
1698*cdf0e10cSrcweir 		aValue >>= aGroupTargetURL;
1699*cdf0e10cSrcweir 
1700*cdf0e10cSrcweir 	if ( !aGroupTargetURL.getLength() )
1701*cdf0e10cSrcweir 		return sal_False;
1702*cdf0e10cSrcweir 
1703*cdf0e10cSrcweir 	if ( !maTemplateDirs.getLength() )
1704*cdf0e10cSrcweir 		return sal_False;
1705*cdf0e10cSrcweir 	::rtl::OUString aGeneralTempPath = maTemplateDirs[ maTemplateDirs.getLength() - 1 ];
1706*cdf0e10cSrcweir 
1707*cdf0e10cSrcweir 	// check that the fs location is in writeble folder and this is not a "My templates" folder
1708*cdf0e10cSrcweir 	INetURLObject aGroupParentFolder( aGroupTargetURL );
1709*cdf0e10cSrcweir 	if ( !aGroupParentFolder.removeSegment()
1710*cdf0e10cSrcweir 	  || !::utl::UCBContentHelper::IsSubPath( aGeneralTempPath,
1711*cdf0e10cSrcweir 		  										aGroupParentFolder.GetMainURL( INetURLObject::NO_DECODE ) ) )
1712*cdf0e10cSrcweir 		return sal_False;
1713*cdf0e10cSrcweir 
1714*cdf0e10cSrcweir 	// check that the group can be renamed ( all the contents must be in target location )
1715*cdf0e10cSrcweir 	sal_Bool bCanBeRenamed = sal_False;
1716*cdf0e10cSrcweir    	try
1717*cdf0e10cSrcweir    	{
1718*cdf0e10cSrcweir 		uno::Reference< XResultSet > xResultSet;
1719*cdf0e10cSrcweir 		Sequence< OUString > aProps( 1 );
1720*cdf0e10cSrcweir 
1721*cdf0e10cSrcweir 		aProps[0] = OUString::createFromAscii( TARGET_URL );
1722*cdf0e10cSrcweir 		ResultSetInclude eInclude = INCLUDE_DOCUMENTS_ONLY;
1723*cdf0e10cSrcweir 		xResultSet = aGroup.createCursor( aProps, eInclude );
1724*cdf0e10cSrcweir 
1725*cdf0e10cSrcweir 		if ( xResultSet.is() )
1726*cdf0e10cSrcweir 		{
1727*cdf0e10cSrcweir 	   		uno::Reference< XContentAccess > xContentAccess( xResultSet, UNO_QUERY_THROW );
1728*cdf0e10cSrcweir 	   		uno::Reference< XRow > xRow( xResultSet, UNO_QUERY_THROW );
1729*cdf0e10cSrcweir 
1730*cdf0e10cSrcweir 	   		while ( xResultSet->next() )
1731*cdf0e10cSrcweir 	   		{
1732*cdf0e10cSrcweir 		   		OUString aTemplTargetURL( xRow->getString( 1 ) );
1733*cdf0e10cSrcweir 
1734*cdf0e10cSrcweir 				if ( !::utl::UCBContentHelper::IsSubPath( aGroupTargetURL, aTemplTargetURL ) )
1735*cdf0e10cSrcweir 					throw uno::Exception();
1736*cdf0e10cSrcweir 			}
1737*cdf0e10cSrcweir 
1738*cdf0e10cSrcweir 			bCanBeRenamed = sal_True;
1739*cdf0e10cSrcweir 		}
1740*cdf0e10cSrcweir 	}
1741*cdf0e10cSrcweir 	catch ( Exception& ) {}
1742*cdf0e10cSrcweir 
1743*cdf0e10cSrcweir 	if ( bCanBeRenamed )
1744*cdf0e10cSrcweir 	{
1745*cdf0e10cSrcweir     	INetURLObject aGroupTargetObj( aGroupTargetURL );
1746*cdf0e10cSrcweir 		::rtl::OUString aFsysName = aGroupTargetObj.getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET );
1747*cdf0e10cSrcweir 
1748*cdf0e10cSrcweir 		if ( aGroupTargetObj.removeSegment()
1749*cdf0e10cSrcweir 		  && ReplaceUINamesForTemplateDir_Impl( aGroupTargetObj.GetMainURL( INetURLObject::NO_DECODE ),
1750*cdf0e10cSrcweir 		  										aFsysName,
1751*cdf0e10cSrcweir 												rOldName,
1752*cdf0e10cSrcweir 												rNewName ) )
1753*cdf0e10cSrcweir 		{
1754*cdf0e10cSrcweir 			// rename the group in the hierarchy
1755*cdf0e10cSrcweir 			OUString aTitleProp( RTL_CONSTASCII_USTRINGPARAM( TITLE ) );
1756*cdf0e10cSrcweir 			Any aTitleValue;
1757*cdf0e10cSrcweir 			aTitleValue <<= rNewName;
1758*cdf0e10cSrcweir 
1759*cdf0e10cSrcweir 			return setProperty( aGroup, aTitleProp, aTitleValue );
1760*cdf0e10cSrcweir 		}
1761*cdf0e10cSrcweir 	}
1762*cdf0e10cSrcweir 
1763*cdf0e10cSrcweir 	return sal_False;
1764*cdf0e10cSrcweir }
1765*cdf0e10cSrcweir 
1766*cdf0e10cSrcweir //-----------------------------------------------------------------------------
1767*cdf0e10cSrcweir sal_Bool SfxDocTplService_Impl::storeTemplate( const OUString& rGroupName,
1768*cdf0e10cSrcweir                                                const OUString& rTemplateName,
1769*cdf0e10cSrcweir                                                const uno::Reference< XSTORABLE >& rStorable )
1770*cdf0e10cSrcweir {
1771*cdf0e10cSrcweir     ::osl::MutexGuard aGuard( maMutex );
1772*cdf0e10cSrcweir 
1773*cdf0e10cSrcweir     // Check, wether or not there is a group with this name
1774*cdf0e10cSrcweir     // Return false, if there is no group with the given name
1775*cdf0e10cSrcweir     Content         aGroup, aTemplate, aTargetGroup, aTemplateToRemove;
1776*cdf0e10cSrcweir     OUString        aGroupURL, aTemplateURL, aTemplateToRemoveTargetURL;
1777*cdf0e10cSrcweir     INetURLObject   aGroupObj( maRootURL );
1778*cdf0e10cSrcweir 	sal_Bool		bRemoveOldTemplateContent = sal_False;
1779*cdf0e10cSrcweir     ::rtl::OUString sDocServiceName;
1780*cdf0e10cSrcweir 
1781*cdf0e10cSrcweir     aGroupObj.insertName( rGroupName, false,
1782*cdf0e10cSrcweir                       INetURLObject::LAST_SEGMENT, true,
1783*cdf0e10cSrcweir                       INetURLObject::ENCODE_ALL );
1784*cdf0e10cSrcweir     aGroupURL = aGroupObj.GetMainURL( INetURLObject::NO_DECODE );
1785*cdf0e10cSrcweir 
1786*cdf0e10cSrcweir     if ( ! Content::create( aGroupURL, maCmdEnv, aGroup ) )
1787*cdf0e10cSrcweir         return sal_False;
1788*cdf0e10cSrcweir 
1789*cdf0e10cSrcweir 	::rtl::OUString	aGroupTargetURL;
1790*cdf0e10cSrcweir 	::rtl::OUString	aPropName( RTL_CONSTASCII_USTRINGPARAM( TARGET_DIR_URL ) );
1791*cdf0e10cSrcweir 	Any		 aValue;
1792*cdf0e10cSrcweir 	if ( getProperty( aGroup, aPropName, aValue ) )
1793*cdf0e10cSrcweir 		aValue >>= aGroupTargetURL;
1794*cdf0e10cSrcweir 
1795*cdf0e10cSrcweir 
1796*cdf0e10cSrcweir     // Check, if there's a template with the given name in this group
1797*cdf0e10cSrcweir     // the target template should be overwritten if it is imported by user
1798*cdf0e10cSrcweir 	// in case the template is installed by office installation of by an add-in
1799*cdf0e10cSrcweir 	// it can not be replaced
1800*cdf0e10cSrcweir     aGroupObj.insertName( rTemplateName, false,
1801*cdf0e10cSrcweir                       INetURLObject::LAST_SEGMENT, true,
1802*cdf0e10cSrcweir                       INetURLObject::ENCODE_ALL );
1803*cdf0e10cSrcweir     aTemplateURL = aGroupObj.GetMainURL( INetURLObject::NO_DECODE );
1804*cdf0e10cSrcweir 
1805*cdf0e10cSrcweir     if ( Content::create( aTemplateURL, maCmdEnv, aTemplateToRemove ) )
1806*cdf0e10cSrcweir 	{
1807*cdf0e10cSrcweir 		OUString    aTargetTemplPropName( RTL_CONSTASCII_USTRINGPARAM( TARGET_URL ) );
1808*cdf0e10cSrcweir 
1809*cdf0e10cSrcweir 		bRemoveOldTemplateContent = sal_True;
1810*cdf0e10cSrcweir 		if ( getProperty( aTemplateToRemove, aTargetTemplPropName, aValue ) )
1811*cdf0e10cSrcweir 			aValue >>= aTemplateToRemoveTargetURL;
1812*cdf0e10cSrcweir 
1813*cdf0e10cSrcweir 		if ( !aGroupTargetURL.getLength() || !maTemplateDirs.getLength()
1814*cdf0e10cSrcweir 		  || (aTemplateToRemoveTargetURL.getLength() && !::utl::UCBContentHelper::IsSubPath( maTemplateDirs[ maTemplateDirs.getLength() - 1 ], aTemplateToRemoveTargetURL )) )
1815*cdf0e10cSrcweir         	return sal_False; // it is not allowed to remove the template
1816*cdf0e10cSrcweir 	}
1817*cdf0e10cSrcweir 
1818*cdf0e10cSrcweir 	try
1819*cdf0e10cSrcweir 	{
1820*cdf0e10cSrcweir 		uno::Reference< lang::XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory();
1821*cdf0e10cSrcweir 		if ( !xFactory.is() )
1822*cdf0e10cSrcweir 			throw uno::RuntimeException();
1823*cdf0e10cSrcweir 
1824*cdf0e10cSrcweir 		// get document service name
1825*cdf0e10cSrcweir 		uno::Reference< frame::XModuleManager > xModuleManager(
1826*cdf0e10cSrcweir 			xFactory->createInstance(
1827*cdf0e10cSrcweir 					::rtl::OUString::createFromAscii( "com.sun.star.frame.ModuleManager" ) ),
1828*cdf0e10cSrcweir 			uno::UNO_QUERY_THROW );
1829*cdf0e10cSrcweir         sDocServiceName = xModuleManager->identify( uno::Reference< uno::XInterface >( rStorable, uno::UNO_QUERY ) );
1830*cdf0e10cSrcweir         if ( !sDocServiceName.getLength() )
1831*cdf0e10cSrcweir 			throw uno::RuntimeException();
1832*cdf0e10cSrcweir 
1833*cdf0e10cSrcweir 		// get the actual filter name
1834*cdf0e10cSrcweir 		::rtl::OUString aFilterName;
1835*cdf0e10cSrcweir 
1836*cdf0e10cSrcweir 		uno::Reference< lang::XMultiServiceFactory > xConfigProvider(
1837*cdf0e10cSrcweir 				xFactory->createInstance(
1838*cdf0e10cSrcweir 					::rtl::OUString::createFromAscii( "com.sun.star.configuration.ConfigurationProvider" ) ),
1839*cdf0e10cSrcweir 				uno::UNO_QUERY_THROW );
1840*cdf0e10cSrcweir 
1841*cdf0e10cSrcweir 		uno::Sequence< uno::Any > aArgs( 1 );
1842*cdf0e10cSrcweir 		beans::PropertyValue aPathProp;
1843*cdf0e10cSrcweir 		aPathProp.Name = ::rtl::OUString::createFromAscii( "nodepath" );
1844*cdf0e10cSrcweir 		aPathProp.Value <<= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Setup/Office/Factories/" ) );
1845*cdf0e10cSrcweir 		aArgs[0] <<= aPathProp;
1846*cdf0e10cSrcweir 
1847*cdf0e10cSrcweir 		uno::Reference< container::XNameAccess > xSOFConfig(
1848*cdf0e10cSrcweir 			xConfigProvider->createInstanceWithArguments(
1849*cdf0e10cSrcweir 									::rtl::OUString::createFromAscii( "com.sun.star.configuration.ConfigurationAccess" ),
1850*cdf0e10cSrcweir 									aArgs ),
1851*cdf0e10cSrcweir 			uno::UNO_QUERY_THROW );
1852*cdf0e10cSrcweir 
1853*cdf0e10cSrcweir 		uno::Reference< container::XNameAccess > xApplConfig;
1854*cdf0e10cSrcweir         xSOFConfig->getByName( sDocServiceName ) >>= xApplConfig;
1855*cdf0e10cSrcweir 		if ( !xApplConfig.is() )
1856*cdf0e10cSrcweir 			throw uno::RuntimeException();
1857*cdf0e10cSrcweir 
1858*cdf0e10cSrcweir 		xApplConfig->getByName( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ooSetupFactoryActualTemplateFilter" ) ) ) >>= aFilterName;
1859*cdf0e10cSrcweir 		if ( !aFilterName.getLength() )
1860*cdf0e10cSrcweir 			throw uno::RuntimeException();
1861*cdf0e10cSrcweir 
1862*cdf0e10cSrcweir 		// find the related type name
1863*cdf0e10cSrcweir 		::rtl::OUString aTypeName;
1864*cdf0e10cSrcweir 		uno::Reference< container::XNameAccess > xFilterFactory(
1865*cdf0e10cSrcweir 			xFactory->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.document.FilterFactory" ) ),
1866*cdf0e10cSrcweir 			uno::UNO_QUERY_THROW );
1867*cdf0e10cSrcweir 
1868*cdf0e10cSrcweir 		uno::Sequence< beans::PropertyValue > aFilterData;
1869*cdf0e10cSrcweir 		xFilterFactory->getByName( aFilterName ) >>= aFilterData;
1870*cdf0e10cSrcweir 		for ( sal_Int32 nInd = 0; nInd < aFilterData.getLength(); nInd++ )
1871*cdf0e10cSrcweir 			if ( aFilterData[nInd].Name.equalsAscii( "Type" ) )
1872*cdf0e10cSrcweir 				aFilterData[nInd].Value >>= aTypeName;
1873*cdf0e10cSrcweir 
1874*cdf0e10cSrcweir 		if ( !aTypeName.getLength() )
1875*cdf0e10cSrcweir 			throw uno::RuntimeException();
1876*cdf0e10cSrcweir 
1877*cdf0e10cSrcweir 		// find the mediatype and extension
1878*cdf0e10cSrcweir 		uno::Reference< container::XNameAccess > xTypeDetection	=
1879*cdf0e10cSrcweir 			mxType.is() ?
1880*cdf0e10cSrcweir 				uno::Reference< container::XNameAccess >( mxType, uno::UNO_QUERY_THROW ) :
1881*cdf0e10cSrcweir 				uno::Reference< container::XNameAccess >(
1882*cdf0e10cSrcweir 					xFactory->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.document.TypeDetection" ) ),
1883*cdf0e10cSrcweir 					uno::UNO_QUERY_THROW );
1884*cdf0e10cSrcweir 
1885*cdf0e10cSrcweir 		SequenceAsHashMap aTypeProps( xTypeDetection->getByName( aTypeName ) );
1886*cdf0e10cSrcweir 		uno::Sequence< ::rtl::OUString > aAllExt =
1887*cdf0e10cSrcweir 			aTypeProps.getUnpackedValueOrDefault( ::rtl::OUString::createFromAscii( "Extensions" ), Sequence< ::rtl::OUString >() );
1888*cdf0e10cSrcweir 		if ( !aAllExt.getLength() )
1889*cdf0e10cSrcweir 			throw uno::RuntimeException();
1890*cdf0e10cSrcweir 
1891*cdf0e10cSrcweir 		::rtl::OUString aMediaType = aTypeProps.getUnpackedValueOrDefault( ::rtl::OUString::createFromAscii( "MediaType"  ), ::rtl::OUString() );
1892*cdf0e10cSrcweir 		::rtl::OUString aExt = aAllExt[0];
1893*cdf0e10cSrcweir 
1894*cdf0e10cSrcweir 		if ( !aMediaType.getLength() || !aExt.getLength() )
1895*cdf0e10cSrcweir 			throw uno::RuntimeException();
1896*cdf0e10cSrcweir 
1897*cdf0e10cSrcweir 		// construct destination url
1898*cdf0e10cSrcweir 		if ( !aGroupTargetURL.getLength() )
1899*cdf0e10cSrcweir 		{
1900*cdf0e10cSrcweir 			aGroupTargetURL = CreateNewGroupFsys( rGroupName, aGroup );
1901*cdf0e10cSrcweir 
1902*cdf0e10cSrcweir 			if ( !aGroupTargetURL.getLength() )
1903*cdf0e10cSrcweir 				throw uno::RuntimeException();
1904*cdf0e10cSrcweir 		}
1905*cdf0e10cSrcweir 
1906*cdf0e10cSrcweir 		::rtl::OUString aNewTemplateTargetURL = CreateNewUniqueFileWithPrefix( aGroupTargetURL, rTemplateName, aExt );
1907*cdf0e10cSrcweir 		if ( !aNewTemplateTargetURL.getLength() )
1908*cdf0e10cSrcweir 		{
1909*cdf0e10cSrcweir 			aNewTemplateTargetURL = CreateNewUniqueFileWithPrefix( aGroupTargetURL, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UserTemplate" ) ), aExt );
1910*cdf0e10cSrcweir 
1911*cdf0e10cSrcweir 			if ( !aNewTemplateTargetURL.getLength() )
1912*cdf0e10cSrcweir 				throw uno::RuntimeException();
1913*cdf0e10cSrcweir 		}
1914*cdf0e10cSrcweir 
1915*cdf0e10cSrcweir 		// store template
1916*cdf0e10cSrcweir 		uno::Sequence< PropertyValue > aStoreArgs( 2 );
1917*cdf0e10cSrcweir 		aStoreArgs[0].Name = ::rtl::OUString::createFromAscii( "FilterName" );
1918*cdf0e10cSrcweir 		aStoreArgs[0].Value <<= aFilterName;
1919*cdf0e10cSrcweir 		aStoreArgs[1].Name = ::rtl::OUString::createFromAscii( "DocumentTitle" );
1920*cdf0e10cSrcweir 		aStoreArgs[1].Value <<= rTemplateName;
1921*cdf0e10cSrcweir 
1922*cdf0e10cSrcweir 		::rtl::OUString aCurrentDocumentURL = rStorable->getLocation();
1923*cdf0e10cSrcweir 		if( !::utl::UCBContentHelper::EqualURLs( aNewTemplateTargetURL, rStorable->getLocation() ))
1924*cdf0e10cSrcweir 			rStorable->storeToURL( aNewTemplateTargetURL, aStoreArgs );
1925*cdf0e10cSrcweir 		else
1926*cdf0e10cSrcweir 			rStorable->store();
1927*cdf0e10cSrcweir 
1928*cdf0e10cSrcweir 		// the storing was successful, now the old template with the same name can be removed if it existed
1929*cdf0e10cSrcweir 		if ( aTemplateToRemoveTargetURL.getLength() )
1930*cdf0e10cSrcweir         {
1931*cdf0e10cSrcweir 			removeContent( aTemplateToRemoveTargetURL );
1932*cdf0e10cSrcweir 
1933*cdf0e10cSrcweir             /*
1934*cdf0e10cSrcweir              * pb: #i79496#
1935*cdf0e10cSrcweir              * if the old template was the standard template
1936*cdf0e10cSrcweir              * it is necessary to change the standard template with the new file name
1937*cdf0e10cSrcweir              */
1938*cdf0e10cSrcweir             String sStdTmplFile = SfxObjectFactory::GetStandardTemplate( sDocServiceName );
1939*cdf0e10cSrcweir             if ( INetURLObject( sStdTmplFile ) == INetURLObject( aTemplateToRemoveTargetURL ) )
1940*cdf0e10cSrcweir             {
1941*cdf0e10cSrcweir                 SfxObjectFactory::SetStandardTemplate( sDocServiceName, aNewTemplateTargetURL );
1942*cdf0e10cSrcweir             }
1943*cdf0e10cSrcweir         }
1944*cdf0e10cSrcweir 
1945*cdf0e10cSrcweir 		if ( bRemoveOldTemplateContent )
1946*cdf0e10cSrcweir 			removeContent( aTemplateToRemove );
1947*cdf0e10cSrcweir 
1948*cdf0e10cSrcweir 		// add the template to hierarchy
1949*cdf0e10cSrcweir 		return addEntry( aGroup, rTemplateName, aNewTemplateTargetURL, aMediaType );
1950*cdf0e10cSrcweir 	}
1951*cdf0e10cSrcweir 	catch( Exception& )
1952*cdf0e10cSrcweir 	{
1953*cdf0e10cSrcweir 		// the template was not stored
1954*cdf0e10cSrcweir 		return sal_False;
1955*cdf0e10cSrcweir 	}
1956*cdf0e10cSrcweir }
1957*cdf0e10cSrcweir 
1958*cdf0e10cSrcweir //-----------------------------------------------------------------------------
1959*cdf0e10cSrcweir sal_Bool SfxDocTplService_Impl::addTemplate( const OUString& rGroupName,
1960*cdf0e10cSrcweir                                              const OUString& rTemplateName,
1961*cdf0e10cSrcweir                                              const OUString& rSourceURL )
1962*cdf0e10cSrcweir {
1963*cdf0e10cSrcweir     ::osl::MutexGuard aGuard( maMutex );
1964*cdf0e10cSrcweir 
1965*cdf0e10cSrcweir     // Check, wether or not there is a group with this name
1966*cdf0e10cSrcweir     // Return false, if there is no group with the given name
1967*cdf0e10cSrcweir     Content         aGroup, aTemplate, aTargetGroup;
1968*cdf0e10cSrcweir     OUString        aGroupURL, aTemplateURL;
1969*cdf0e10cSrcweir     INetURLObject   aGroupObj( maRootURL );
1970*cdf0e10cSrcweir 
1971*cdf0e10cSrcweir     aGroupObj.insertName( rGroupName, false,
1972*cdf0e10cSrcweir                       INetURLObject::LAST_SEGMENT, true,
1973*cdf0e10cSrcweir                       INetURLObject::ENCODE_ALL );
1974*cdf0e10cSrcweir     aGroupURL = aGroupObj.GetMainURL( INetURLObject::NO_DECODE );
1975*cdf0e10cSrcweir 
1976*cdf0e10cSrcweir     if ( ! Content::create( aGroupURL, maCmdEnv, aGroup ) )
1977*cdf0e10cSrcweir         return sal_False;
1978*cdf0e10cSrcweir 
1979*cdf0e10cSrcweir     // Check, if there's a template with the given name in this group
1980*cdf0e10cSrcweir     // Return false, if there already is a template
1981*cdf0e10cSrcweir     aGroupObj.insertName( rTemplateName, false,
1982*cdf0e10cSrcweir                       INetURLObject::LAST_SEGMENT, true,
1983*cdf0e10cSrcweir                       INetURLObject::ENCODE_ALL );
1984*cdf0e10cSrcweir     aTemplateURL = aGroupObj.GetMainURL( INetURLObject::NO_DECODE );
1985*cdf0e10cSrcweir 
1986*cdf0e10cSrcweir     if ( Content::create( aTemplateURL, maCmdEnv, aTemplate ) )
1987*cdf0e10cSrcweir         return sal_False;
1988*cdf0e10cSrcweir 
1989*cdf0e10cSrcweir     // get the target url of the group
1990*cdf0e10cSrcweir     OUString    aTargetURL;
1991*cdf0e10cSrcweir     OUString    aPropName( RTL_CONSTASCII_USTRINGPARAM( TARGET_DIR_URL ) );
1992*cdf0e10cSrcweir     Any         aValue;
1993*cdf0e10cSrcweir 
1994*cdf0e10cSrcweir     if ( getProperty( aGroup, aPropName, aValue ) )
1995*cdf0e10cSrcweir         aValue >>= aTargetURL;
1996*cdf0e10cSrcweir 
1997*cdf0e10cSrcweir     if ( !aTargetURL.getLength() )
1998*cdf0e10cSrcweir 	{
1999*cdf0e10cSrcweir 		aTargetURL = CreateNewGroupFsys( rGroupName, aGroup );
2000*cdf0e10cSrcweir 
2001*cdf0e10cSrcweir 		if ( !aTargetURL.getLength() )
2002*cdf0e10cSrcweir 			return sal_False;
2003*cdf0e10cSrcweir 	}
2004*cdf0e10cSrcweir 
2005*cdf0e10cSrcweir     // Get the content type
2006*cdf0e10cSrcweir     OUString aTitle, aType, aTargetURL2, aFullName;
2007*cdf0e10cSrcweir 
2008*cdf0e10cSrcweir 	// only StarOffice documents are acceptable
2009*cdf0e10cSrcweir 	sal_Bool bDocHasTitle = sal_False;
2010*cdf0e10cSrcweir     if( !getTitleFromURL( rSourceURL, aTitle, aType, bDocHasTitle ) )
2011*cdf0e10cSrcweir 		return sal_False;
2012*cdf0e10cSrcweir 
2013*cdf0e10cSrcweir     INetURLObject   aSourceObj( rSourceURL );
2014*cdf0e10cSrcweir 	if ( rTemplateName.equals( aTitle ) )
2015*cdf0e10cSrcweir 	{
2016*cdf0e10cSrcweir 		/////////////////////////////////////////////////////
2017*cdf0e10cSrcweir     	// addTemplate will sometimes be called just to add an entry in the
2018*cdf0e10cSrcweir     	// hierarchy; the target URL and the source URL will be the same in
2019*cdf0e10cSrcweir     	// this scenario
2020*cdf0e10cSrcweir 		// TODO/LATER: get rid of this old hack
2021*cdf0e10cSrcweir 
2022*cdf0e10cSrcweir     	INetURLObject   aTargetObj( aTargetURL );
2023*cdf0e10cSrcweir 
2024*cdf0e10cSrcweir     	aTargetObj.insertName( rTemplateName, false,
2025*cdf0e10cSrcweir                       INetURLObject::LAST_SEGMENT, true,
2026*cdf0e10cSrcweir                       INetURLObject::ENCODE_ALL );
2027*cdf0e10cSrcweir     	aTargetObj.setExtension( aSourceObj.getExtension() );
2028*cdf0e10cSrcweir 
2029*cdf0e10cSrcweir     	aTargetURL2 = aTargetObj.GetMainURL( INetURLObject::NO_DECODE );
2030*cdf0e10cSrcweir 
2031*cdf0e10cSrcweir     	if ( aTargetURL2 == rSourceURL )
2032*cdf0e10cSrcweir         	return addEntry( aGroup, rTemplateName, aTargetURL2, aType );
2033*cdf0e10cSrcweir 	}
2034*cdf0e10cSrcweir 
2035*cdf0e10cSrcweir 	/////////////////////////////////////////////////////
2036*cdf0e10cSrcweir     // copy the template into the new group (targeturl)
2037*cdf0e10cSrcweir 
2038*cdf0e10cSrcweir 	INetURLObject aTmpURL( aSourceObj );
2039*cdf0e10cSrcweir 	aTmpURL.CutExtension();
2040*cdf0e10cSrcweir 	::rtl::OUString aPattern = aTmpURL.getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET );
2041*cdf0e10cSrcweir 
2042*cdf0e10cSrcweir 	::rtl::OUString aNewTemplateTargetURL = CreateNewUniqueFileWithPrefix( aTargetURL, aPattern, aSourceObj.getExtension() );
2043*cdf0e10cSrcweir 	INetURLObject aNewTemplateTargetObj( aNewTemplateTargetURL );
2044*cdf0e10cSrcweir 	::rtl::OUString aNewTemplateTargetName = aNewTemplateTargetObj.getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET );
2045*cdf0e10cSrcweir 	if ( !aNewTemplateTargetURL.getLength() || !aNewTemplateTargetName.getLength() )
2046*cdf0e10cSrcweir 		return sal_False;
2047*cdf0e10cSrcweir 
2048*cdf0e10cSrcweir 	// get access to source file
2049*cdf0e10cSrcweir 	Content aSourceContent;
2050*cdf0e10cSrcweir 	uno::Reference < ucb::XCommandEnvironment > xEnv;
2051*cdf0e10cSrcweir 	INetURLObject   aSourceURL( rSourceURL );
2052*cdf0e10cSrcweir 	if( ! Content::create( aSourceURL.GetMainURL( INetURLObject::NO_DECODE ), xEnv, aSourceContent ) )
2053*cdf0e10cSrcweir 		return sal_False;
2054*cdf0e10cSrcweir 
2055*cdf0e10cSrcweir 	if( ! Content::create( aTargetURL, xEnv, aTargetGroup ) )
2056*cdf0e10cSrcweir 		return sal_False;
2057*cdf0e10cSrcweir 
2058*cdf0e10cSrcweir 	// transfer source file
2059*cdf0e10cSrcweir     try
2060*cdf0e10cSrcweir     {
2061*cdf0e10cSrcweir 		if( ! aTargetGroup.transferContent( aSourceContent,
2062*cdf0e10cSrcweir 												InsertOperation_COPY,
2063*cdf0e10cSrcweir 												aNewTemplateTargetName,
2064*cdf0e10cSrcweir 												NameClash::OVERWRITE ) )
2065*cdf0e10cSrcweir 			return sal_False;
2066*cdf0e10cSrcweir 
2067*cdf0e10cSrcweir 		// allow to edit the added template
2068*cdf0e10cSrcweir 		Content aResultContent;
2069*cdf0e10cSrcweir 		if ( Content::create( aNewTemplateTargetURL, xEnv, aResultContent ) )
2070*cdf0e10cSrcweir 		{
2071*cdf0e10cSrcweir 			::rtl::OUString aPropertyName( RTL_CONSTASCII_USTRINGPARAM( "IsReadOnly" ) );
2072*cdf0e10cSrcweir 			uno::Any aProperty;
2073*cdf0e10cSrcweir 			sal_Bool bReadOnly = sal_False;
2074*cdf0e10cSrcweir 			if ( getProperty( aResultContent, aPropertyName, aProperty ) && ( aProperty >>= bReadOnly ) && bReadOnly )
2075*cdf0e10cSrcweir 				setProperty( aResultContent, aPropertyName, uno::makeAny( (sal_Bool)sal_False ) );
2076*cdf0e10cSrcweir 		}
2077*cdf0e10cSrcweir     }
2078*cdf0e10cSrcweir     catch ( ContentCreationException& )
2079*cdf0e10cSrcweir     { return sal_False; }
2080*cdf0e10cSrcweir     catch ( Exception& )
2081*cdf0e10cSrcweir     { return sal_False; }
2082*cdf0e10cSrcweir 
2083*cdf0e10cSrcweir 
2084*cdf0e10cSrcweir 	// either the document has title and it is the same as requested, or we have to set it
2085*cdf0e10cSrcweir 	sal_Bool bCorrectTitle = ( bDocHasTitle && aTitle.equals( rTemplateName ) );
2086*cdf0e10cSrcweir 	if ( !bCorrectTitle )
2087*cdf0e10cSrcweir 	{
2088*cdf0e10cSrcweir 		if ( !bDocHasTitle )
2089*cdf0e10cSrcweir 		{
2090*cdf0e10cSrcweir 			INetURLObject aNewTmpObj( aNewTemplateTargetObj );
2091*cdf0e10cSrcweir 			aNewTmpObj.CutExtension();
2092*cdf0e10cSrcweir 			bCorrectTitle = ( aNewTmpObj.getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET ).equals( rTemplateName ) );
2093*cdf0e10cSrcweir 		}
2094*cdf0e10cSrcweir 
2095*cdf0e10cSrcweir 		if ( !bCorrectTitle )
2096*cdf0e10cSrcweir 			bCorrectTitle = setTitleForURL( aNewTemplateTargetURL, rTemplateName );
2097*cdf0e10cSrcweir 	}
2098*cdf0e10cSrcweir 
2099*cdf0e10cSrcweir     if ( bCorrectTitle )
2100*cdf0e10cSrcweir 	{
2101*cdf0e10cSrcweir     	// create a new entry in the hierarchy
2102*cdf0e10cSrcweir     	return addEntry( aGroup, rTemplateName, aNewTemplateTargetURL, aType );
2103*cdf0e10cSrcweir 	}
2104*cdf0e10cSrcweir 
2105*cdf0e10cSrcweir 	// TODO/LATER: The user could be notified here that the renaming has failed
2106*cdf0e10cSrcweir     // create a new entry in the hierarchy
2107*cdf0e10cSrcweir     addEntry( aGroup, aTitle, aNewTemplateTargetURL, aType );
2108*cdf0e10cSrcweir 	return sal_False;
2109*cdf0e10cSrcweir }
2110*cdf0e10cSrcweir 
2111*cdf0e10cSrcweir //-----------------------------------------------------------------------------
2112*cdf0e10cSrcweir sal_Bool SfxDocTplService_Impl::removeTemplate( const OUString& rGroupName,
2113*cdf0e10cSrcweir                                                 const OUString& rTemplateName )
2114*cdf0e10cSrcweir {
2115*cdf0e10cSrcweir     ::osl::MutexGuard aGuard( maMutex );
2116*cdf0e10cSrcweir 
2117*cdf0e10cSrcweir     // Check, wether or not there is a group with this name
2118*cdf0e10cSrcweir     // Return false, if there is no group with the given name
2119*cdf0e10cSrcweir     Content         aGroup, aTemplate;
2120*cdf0e10cSrcweir     OUString        aGroupURL, aTemplateURL;
2121*cdf0e10cSrcweir     INetURLObject   aGroupObj( maRootURL );
2122*cdf0e10cSrcweir 
2123*cdf0e10cSrcweir     aGroupObj.insertName( rGroupName, false,
2124*cdf0e10cSrcweir                       INetURLObject::LAST_SEGMENT, true,
2125*cdf0e10cSrcweir                       INetURLObject::ENCODE_ALL );
2126*cdf0e10cSrcweir     aGroupURL = aGroupObj.GetMainURL( INetURLObject::NO_DECODE );
2127*cdf0e10cSrcweir 
2128*cdf0e10cSrcweir     if ( ! Content::create( aGroupURL, maCmdEnv, aGroup ) )
2129*cdf0e10cSrcweir         return sal_False;
2130*cdf0e10cSrcweir 
2131*cdf0e10cSrcweir     // Check, if there's a template with the given name in this group
2132*cdf0e10cSrcweir     // Return false, if there is no template
2133*cdf0e10cSrcweir     aGroupObj.insertName( rTemplateName, false,
2134*cdf0e10cSrcweir                       INetURLObject::LAST_SEGMENT, true,
2135*cdf0e10cSrcweir                       INetURLObject::ENCODE_ALL );
2136*cdf0e10cSrcweir     aTemplateURL = aGroupObj.GetMainURL( INetURLObject::NO_DECODE );
2137*cdf0e10cSrcweir 
2138*cdf0e10cSrcweir     if ( !Content::create( aTemplateURL, maCmdEnv, aTemplate ) )
2139*cdf0e10cSrcweir         return sal_False;
2140*cdf0e10cSrcweir 
2141*cdf0e10cSrcweir     // get the target URL from the template
2142*cdf0e10cSrcweir     OUString    aTargetURL;
2143*cdf0e10cSrcweir     OUString    aPropName( RTL_CONSTASCII_USTRINGPARAM( TARGET_URL ) );
2144*cdf0e10cSrcweir     Any         aValue;
2145*cdf0e10cSrcweir 
2146*cdf0e10cSrcweir     if ( getProperty( aTemplate, aPropName, aValue ) )
2147*cdf0e10cSrcweir         aValue >>= aTargetURL;
2148*cdf0e10cSrcweir 
2149*cdf0e10cSrcweir     // delete the target template
2150*cdf0e10cSrcweir     if ( aTargetURL.getLength() )
2151*cdf0e10cSrcweir     {
2152*cdf0e10cSrcweir 		if ( !maTemplateDirs.getLength()
2153*cdf0e10cSrcweir 		  || !::utl::UCBContentHelper::IsSubPath( maTemplateDirs[ maTemplateDirs.getLength() - 1 ], aTargetURL ) )
2154*cdf0e10cSrcweir 			return sal_False;
2155*cdf0e10cSrcweir 
2156*cdf0e10cSrcweir         removeContent( aTargetURL );
2157*cdf0e10cSrcweir     }
2158*cdf0e10cSrcweir 
2159*cdf0e10cSrcweir     // delete the template entry
2160*cdf0e10cSrcweir     return removeContent( aTemplate );
2161*cdf0e10cSrcweir }
2162*cdf0e10cSrcweir 
2163*cdf0e10cSrcweir //-----------------------------------------------------------------------------
2164*cdf0e10cSrcweir sal_Bool SfxDocTplService_Impl::renameTemplate( const OUString& rGroupName,
2165*cdf0e10cSrcweir                                                 const OUString& rOldName,
2166*cdf0e10cSrcweir                                                 const OUString& rNewName )
2167*cdf0e10cSrcweir {
2168*cdf0e10cSrcweir     ::osl::MutexGuard aGuard( maMutex );
2169*cdf0e10cSrcweir 
2170*cdf0e10cSrcweir     // Check, wether or not there is a group with this name
2171*cdf0e10cSrcweir     // Return false, if there is no group with the given name
2172*cdf0e10cSrcweir     Content         aGroup, aTemplate;
2173*cdf0e10cSrcweir     OUString        aGroupURL, aTemplateURL;
2174*cdf0e10cSrcweir     INetURLObject   aGroupObj( maRootURL );
2175*cdf0e10cSrcweir 
2176*cdf0e10cSrcweir     aGroupObj.insertName( rGroupName, false,
2177*cdf0e10cSrcweir                       INetURLObject::LAST_SEGMENT, true,
2178*cdf0e10cSrcweir                       INetURLObject::ENCODE_ALL );
2179*cdf0e10cSrcweir     aGroupURL = aGroupObj.GetMainURL( INetURLObject::NO_DECODE );
2180*cdf0e10cSrcweir 
2181*cdf0e10cSrcweir     if ( ! Content::create( aGroupURL, maCmdEnv, aGroup ) )
2182*cdf0e10cSrcweir         return sal_False;
2183*cdf0e10cSrcweir 
2184*cdf0e10cSrcweir     // Check, if there's a template with the new name in this group
2185*cdf0e10cSrcweir     // Return false, if there is one
2186*cdf0e10cSrcweir     aGroupObj.insertName( rNewName, false,
2187*cdf0e10cSrcweir                       INetURLObject::LAST_SEGMENT, true,
2188*cdf0e10cSrcweir                       INetURLObject::ENCODE_ALL );
2189*cdf0e10cSrcweir     aTemplateURL = aGroupObj.GetMainURL( INetURLObject::NO_DECODE );
2190*cdf0e10cSrcweir 
2191*cdf0e10cSrcweir     if ( Content::create( aTemplateURL, maCmdEnv, aTemplate ) )
2192*cdf0e10cSrcweir         return sal_False;
2193*cdf0e10cSrcweir 
2194*cdf0e10cSrcweir     // Check, if there's a template with the old name in this group
2195*cdf0e10cSrcweir     // Return false, if there is no template
2196*cdf0e10cSrcweir     aGroupObj.removeSegment();
2197*cdf0e10cSrcweir     aGroupObj.insertName( rOldName, false,
2198*cdf0e10cSrcweir                       INetURLObject::LAST_SEGMENT, true,
2199*cdf0e10cSrcweir                       INetURLObject::ENCODE_ALL );
2200*cdf0e10cSrcweir     aTemplateURL = aGroupObj.GetMainURL( INetURLObject::NO_DECODE );
2201*cdf0e10cSrcweir 
2202*cdf0e10cSrcweir     if ( !Content::create( aTemplateURL, maCmdEnv, aTemplate ) )
2203*cdf0e10cSrcweir         return sal_False;
2204*cdf0e10cSrcweir 
2205*cdf0e10cSrcweir 	OUString    aTemplateTargetURL;
2206*cdf0e10cSrcweir 	OUString    aTargetProp( RTL_CONSTASCII_USTRINGPARAM( TARGET_URL ) );
2207*cdf0e10cSrcweir 	Any         aTargetValue;
2208*cdf0e10cSrcweir 
2209*cdf0e10cSrcweir 	if ( getProperty( aTemplate, aTargetProp, aTargetValue ) )
2210*cdf0e10cSrcweir 		aTargetValue >>= aTemplateTargetURL;
2211*cdf0e10cSrcweir 
2212*cdf0e10cSrcweir     if ( !setTitleForURL( aTemplateTargetURL, rNewName ) )
2213*cdf0e10cSrcweir 		return sal_False;
2214*cdf0e10cSrcweir 
2215*cdf0e10cSrcweir     // rename the template entry in the cache
2216*cdf0e10cSrcweir     OUString    aTitleProp( RTL_CONSTASCII_USTRINGPARAM( TITLE ) );
2217*cdf0e10cSrcweir     Any         aTitleValue;
2218*cdf0e10cSrcweir     aTitleValue <<= rNewName;
2219*cdf0e10cSrcweir 
2220*cdf0e10cSrcweir     return setProperty( aTemplate, aTitleProp, aTitleValue );
2221*cdf0e10cSrcweir }
2222*cdf0e10cSrcweir 
2223*cdf0e10cSrcweir //-----------------------------------------------------------------------------
2224*cdf0e10cSrcweir //-----------------------------------------------------------------------------
2225*cdf0e10cSrcweir //-----------------------------------------------------------------------------
2226*cdf0e10cSrcweir 
2227*cdf0e10cSrcweir SFX_IMPL_XSERVICEINFO( SfxDocTplService, TEMPLATE_SERVICE_NAME, TEMPLATE_IMPLEMENTATION_NAME )
2228*cdf0e10cSrcweir SFX_IMPL_SINGLEFACTORY( SfxDocTplService )
2229*cdf0e10cSrcweir 
2230*cdf0e10cSrcweir //-----------------------------------------------------------------------------
2231*cdf0e10cSrcweir SfxDocTplService::SfxDocTplService( const uno::Reference< XMultiServiceFactory >& xFactory )
2232*cdf0e10cSrcweir {
2233*cdf0e10cSrcweir     pImp = new SfxDocTplService_Impl( xFactory );
2234*cdf0e10cSrcweir }
2235*cdf0e10cSrcweir 
2236*cdf0e10cSrcweir //-----------------------------------------------------------------------------
2237*cdf0e10cSrcweir 
2238*cdf0e10cSrcweir SfxDocTplService::~SfxDocTplService()
2239*cdf0e10cSrcweir {
2240*cdf0e10cSrcweir     delete pImp;
2241*cdf0e10cSrcweir }
2242*cdf0e10cSrcweir 
2243*cdf0e10cSrcweir //-----------------------------------------------------------------------------
2244*cdf0e10cSrcweir //--- XLocalizable ---
2245*cdf0e10cSrcweir //-----------------------------------------------------------------------------
2246*cdf0e10cSrcweir 
2247*cdf0e10cSrcweir Locale SAL_CALL SfxDocTplService::getLocale()
2248*cdf0e10cSrcweir     throw( RUNTIMEEXCEPTION )
2249*cdf0e10cSrcweir {
2250*cdf0e10cSrcweir     return pImp->getLocale();
2251*cdf0e10cSrcweir }
2252*cdf0e10cSrcweir 
2253*cdf0e10cSrcweir //-----------------------------------------------------------------------------
2254*cdf0e10cSrcweir 
2255*cdf0e10cSrcweir void SAL_CALL SfxDocTplService::setLocale( const Locale & rLocale )
2256*cdf0e10cSrcweir     throw( RUNTIMEEXCEPTION )
2257*cdf0e10cSrcweir {
2258*cdf0e10cSrcweir     pImp->setLocale( rLocale );
2259*cdf0e10cSrcweir }
2260*cdf0e10cSrcweir 
2261*cdf0e10cSrcweir //-----------------------------------------------------------------------------
2262*cdf0e10cSrcweir //--- XDocumentTemplates ---
2263*cdf0e10cSrcweir //-----------------------------------------------------------------------------
2264*cdf0e10cSrcweir uno::Reference< XCONTENT > SAL_CALL SfxDocTplService::getContent()
2265*cdf0e10cSrcweir     throw( RUNTIMEEXCEPTION )
2266*cdf0e10cSrcweir {
2267*cdf0e10cSrcweir     if ( pImp->init() )
2268*cdf0e10cSrcweir         return pImp->getContent().get();
2269*cdf0e10cSrcweir     else
2270*cdf0e10cSrcweir         return NULL;
2271*cdf0e10cSrcweir }
2272*cdf0e10cSrcweir 
2273*cdf0e10cSrcweir //-----------------------------------------------------------------------------
2274*cdf0e10cSrcweir sal_Bool SAL_CALL SfxDocTplService::storeTemplate( const OUString& GroupName,
2275*cdf0e10cSrcweir                                                    const OUString& TemplateName,
2276*cdf0e10cSrcweir                                                    const uno::Reference< XSTORABLE >& Storable )
2277*cdf0e10cSrcweir     throw( RUNTIMEEXCEPTION )
2278*cdf0e10cSrcweir {
2279*cdf0e10cSrcweir 	if ( pImp->init() )
2280*cdf0e10cSrcweir 		return pImp->storeTemplate( GroupName, TemplateName, Storable );
2281*cdf0e10cSrcweir 	else
2282*cdf0e10cSrcweir     	return sal_False;
2283*cdf0e10cSrcweir }
2284*cdf0e10cSrcweir 
2285*cdf0e10cSrcweir //-----------------------------------------------------------------------------
2286*cdf0e10cSrcweir sal_Bool SAL_CALL SfxDocTplService::addTemplate( const OUString& rGroupName,
2287*cdf0e10cSrcweir                                                  const OUString& rTemplateName,
2288*cdf0e10cSrcweir                                                  const OUString& rSourceURL )
2289*cdf0e10cSrcweir     throw( RUNTIMEEXCEPTION )
2290*cdf0e10cSrcweir {
2291*cdf0e10cSrcweir     if ( pImp->init() )
2292*cdf0e10cSrcweir         return pImp->addTemplate( rGroupName, rTemplateName, rSourceURL );
2293*cdf0e10cSrcweir     else
2294*cdf0e10cSrcweir         return sal_False;
2295*cdf0e10cSrcweir }
2296*cdf0e10cSrcweir 
2297*cdf0e10cSrcweir //-----------------------------------------------------------------------------
2298*cdf0e10cSrcweir sal_Bool SAL_CALL SfxDocTplService::removeTemplate( const OUString& rGroupName,
2299*cdf0e10cSrcweir                                                     const OUString& rTemplateName )
2300*cdf0e10cSrcweir     throw( RUNTIMEEXCEPTION )
2301*cdf0e10cSrcweir {
2302*cdf0e10cSrcweir     if ( pImp->init() )
2303*cdf0e10cSrcweir         return pImp->removeTemplate( rGroupName, rTemplateName );
2304*cdf0e10cSrcweir     else
2305*cdf0e10cSrcweir         return sal_False;
2306*cdf0e10cSrcweir }
2307*cdf0e10cSrcweir 
2308*cdf0e10cSrcweir //-----------------------------------------------------------------------------
2309*cdf0e10cSrcweir sal_Bool SAL_CALL SfxDocTplService::renameTemplate( const OUString& rGroupName,
2310*cdf0e10cSrcweir                                                     const OUString& rOldName,
2311*cdf0e10cSrcweir                                                     const OUString& rNewName )
2312*cdf0e10cSrcweir     throw( RUNTIMEEXCEPTION )
2313*cdf0e10cSrcweir {
2314*cdf0e10cSrcweir     if ( rOldName == rNewName )
2315*cdf0e10cSrcweir         return sal_True;
2316*cdf0e10cSrcweir 
2317*cdf0e10cSrcweir     if ( pImp->init() )
2318*cdf0e10cSrcweir         return pImp->renameTemplate( rGroupName, rOldName, rNewName );
2319*cdf0e10cSrcweir     else
2320*cdf0e10cSrcweir         return sal_False;
2321*cdf0e10cSrcweir }
2322*cdf0e10cSrcweir 
2323*cdf0e10cSrcweir //-----------------------------------------------------------------------------
2324*cdf0e10cSrcweir sal_Bool SAL_CALL SfxDocTplService::addGroup( const OUString& rGroupName )
2325*cdf0e10cSrcweir     throw( RUNTIMEEXCEPTION )
2326*cdf0e10cSrcweir {
2327*cdf0e10cSrcweir     if ( pImp->init() )
2328*cdf0e10cSrcweir         return pImp->addGroup( rGroupName );
2329*cdf0e10cSrcweir     else
2330*cdf0e10cSrcweir         return sal_False;
2331*cdf0e10cSrcweir }
2332*cdf0e10cSrcweir 
2333*cdf0e10cSrcweir //-----------------------------------------------------------------------------
2334*cdf0e10cSrcweir sal_Bool SAL_CALL SfxDocTplService::removeGroup( const OUString& rGroupName )
2335*cdf0e10cSrcweir     throw( RUNTIMEEXCEPTION )
2336*cdf0e10cSrcweir {
2337*cdf0e10cSrcweir     if ( pImp->init() )
2338*cdf0e10cSrcweir         return pImp->removeGroup( rGroupName );
2339*cdf0e10cSrcweir     else
2340*cdf0e10cSrcweir         return sal_False;
2341*cdf0e10cSrcweir }
2342*cdf0e10cSrcweir 
2343*cdf0e10cSrcweir //-----------------------------------------------------------------------------
2344*cdf0e10cSrcweir sal_Bool SAL_CALL SfxDocTplService::renameGroup( const OUString& rOldName,
2345*cdf0e10cSrcweir                                                  const OUString& rNewName )
2346*cdf0e10cSrcweir     throw( RUNTIMEEXCEPTION )
2347*cdf0e10cSrcweir {
2348*cdf0e10cSrcweir     if ( rOldName == rNewName )
2349*cdf0e10cSrcweir         return sal_True;
2350*cdf0e10cSrcweir 
2351*cdf0e10cSrcweir     if ( pImp->init() )
2352*cdf0e10cSrcweir         return pImp->renameGroup( rOldName, rNewName );
2353*cdf0e10cSrcweir     else
2354*cdf0e10cSrcweir         return sal_False;
2355*cdf0e10cSrcweir }
2356*cdf0e10cSrcweir 
2357*cdf0e10cSrcweir //-----------------------------------------------------------------------------
2358*cdf0e10cSrcweir void SAL_CALL SfxDocTplService::update()
2359*cdf0e10cSrcweir     throw( RUNTIMEEXCEPTION )
2360*cdf0e10cSrcweir {
2361*cdf0e10cSrcweir     if ( pImp->init() )
2362*cdf0e10cSrcweir         pImp->update( sal_True );
2363*cdf0e10cSrcweir }
2364*cdf0e10cSrcweir 
2365*cdf0e10cSrcweir //-----------------------------------------------------------------------------
2366*cdf0e10cSrcweir //-----------------------------------------------------------------------------
2367*cdf0e10cSrcweir //------------------------------------------------------------------------
2368*cdf0e10cSrcweir 
2369*cdf0e10cSrcweir Updater_Impl::Updater_Impl( SfxDocTplService_Impl* pTemplates )
2370*cdf0e10cSrcweir {
2371*cdf0e10cSrcweir     mpDocTemplates = pTemplates;
2372*cdf0e10cSrcweir }
2373*cdf0e10cSrcweir 
2374*cdf0e10cSrcweir //------------------------------------------------------------------------
2375*cdf0e10cSrcweir Updater_Impl::~Updater_Impl()
2376*cdf0e10cSrcweir {
2377*cdf0e10cSrcweir }
2378*cdf0e10cSrcweir 
2379*cdf0e10cSrcweir //------------------------------------------------------------------------
2380*cdf0e10cSrcweir void SAL_CALL Updater_Impl::run()
2381*cdf0e10cSrcweir {
2382*cdf0e10cSrcweir     mpDocTemplates->doUpdate();
2383*cdf0e10cSrcweir }
2384*cdf0e10cSrcweir 
2385*cdf0e10cSrcweir //------------------------------------------------------------------------
2386*cdf0e10cSrcweir void SAL_CALL Updater_Impl::onTerminated()
2387*cdf0e10cSrcweir {
2388*cdf0e10cSrcweir     mpDocTemplates->finished();
2389*cdf0e10cSrcweir     delete this;
2390*cdf0e10cSrcweir }
2391*cdf0e10cSrcweir 
2392*cdf0e10cSrcweir //-----------------------------------------------------------------------------
2393*cdf0e10cSrcweir //-----------------------------------------------------------------------------
2394*cdf0e10cSrcweir //-----------------------------------------------------------------------------
2395*cdf0e10cSrcweir WaitWindow_Impl::WaitWindow_Impl()
2396*cdf0e10cSrcweir     : WorkWindow( NULL, WB_BORDER | WB_3DLOOK )
2397*cdf0e10cSrcweir {
2398*cdf0e10cSrcweir     Rectangle aRect = Rectangle( 0, 0, 300, 30000 );
2399*cdf0e10cSrcweir     _nTextStyle = TEXT_DRAW_CENTER | TEXT_DRAW_VCENTER | TEXT_DRAW_WORDBREAK | TEXT_DRAW_MULTILINE;
2400*cdf0e10cSrcweir     _aText = String( SfxResId( RID_CNT_STR_WAITING ) );
2401*cdf0e10cSrcweir     _aRect = GetTextRect( aRect, _aText, _nTextStyle );
2402*cdf0e10cSrcweir     aRect = _aRect;
2403*cdf0e10cSrcweir     aRect.Right() += 2*X_OFFSET;
2404*cdf0e10cSrcweir     aRect.Bottom() += 2*Y_OFFSET;
2405*cdf0e10cSrcweir     _aRect.SetPos( Point( X_OFFSET, Y_OFFSET ) );
2406*cdf0e10cSrcweir     SetOutputSizePixel( aRect.GetSize() );
2407*cdf0e10cSrcweir     Show();
2408*cdf0e10cSrcweir     Update();
2409*cdf0e10cSrcweir     Flush();
2410*cdf0e10cSrcweir }
2411*cdf0e10cSrcweir 
2412*cdf0e10cSrcweir //-----------------------------------------------------------------------------
2413*cdf0e10cSrcweir WaitWindow_Impl::~WaitWindow_Impl()
2414*cdf0e10cSrcweir {
2415*cdf0e10cSrcweir     Hide();
2416*cdf0e10cSrcweir }
2417*cdf0e10cSrcweir 
2418*cdf0e10cSrcweir //-----------------------------------------------------------------------------
2419*cdf0e10cSrcweir void WaitWindow_Impl::Paint( const Rectangle& /*rRect*/ )
2420*cdf0e10cSrcweir {
2421*cdf0e10cSrcweir     DrawText( _aRect, _aText, _nTextStyle );
2422*cdf0e10cSrcweir }
2423*cdf0e10cSrcweir 
2424*cdf0e10cSrcweir //-----------------------------------------------------------------------------
2425*cdf0e10cSrcweir //-----------------------------------------------------------------------------
2426*cdf0e10cSrcweir //-----------------------------------------------------------------------------
2427*cdf0e10cSrcweir void SfxDocTplService_Impl::addHierGroup( GroupList_Impl& rList,
2428*cdf0e10cSrcweir                                           const OUString& rTitle,
2429*cdf0e10cSrcweir                                           const OUString& rOwnURL )
2430*cdf0e10cSrcweir {
2431*cdf0e10cSrcweir     // now get the content of the Group
2432*cdf0e10cSrcweir     Content                 aContent;
2433*cdf0e10cSrcweir     uno::Reference< XResultSet > xResultSet;
2434*cdf0e10cSrcweir     Sequence< OUString >    aProps(3);
2435*cdf0e10cSrcweir 
2436*cdf0e10cSrcweir     aProps[0] = OUString::createFromAscii( TITLE );
2437*cdf0e10cSrcweir     aProps[1] = OUString::createFromAscii( TARGET_URL );
2438*cdf0e10cSrcweir     aProps[2] = OUString::createFromAscii( PROPERTY_TYPE );
2439*cdf0e10cSrcweir 
2440*cdf0e10cSrcweir     try
2441*cdf0e10cSrcweir     {
2442*cdf0e10cSrcweir         aContent = Content( rOwnURL, maCmdEnv );
2443*cdf0e10cSrcweir         ResultSetInclude eInclude = INCLUDE_DOCUMENTS_ONLY;
2444*cdf0e10cSrcweir         xResultSet = aContent.createCursor( aProps, eInclude );
2445*cdf0e10cSrcweir     }
2446*cdf0e10cSrcweir     catch ( ContentCreationException& )
2447*cdf0e10cSrcweir     {
2448*cdf0e10cSrcweir         DBG_ERRORFILE( "addHierGroup: ContentCreationException" );
2449*cdf0e10cSrcweir     }
2450*cdf0e10cSrcweir     catch ( Exception& ) {}
2451*cdf0e10cSrcweir 
2452*cdf0e10cSrcweir     if ( xResultSet.is() )
2453*cdf0e10cSrcweir     {
2454*cdf0e10cSrcweir         GroupData_Impl *pGroup = new GroupData_Impl( rTitle );
2455*cdf0e10cSrcweir         pGroup->setHierarchy( sal_True );
2456*cdf0e10cSrcweir         pGroup->setHierarchyURL( rOwnURL );
2457*cdf0e10cSrcweir         rList.Insert( pGroup );
2458*cdf0e10cSrcweir 
2459*cdf0e10cSrcweir         uno::Reference< XContentAccess > xContentAccess( xResultSet, UNO_QUERY );
2460*cdf0e10cSrcweir         uno::Reference< XRow > xRow( xResultSet, UNO_QUERY );
2461*cdf0e10cSrcweir 
2462*cdf0e10cSrcweir         try
2463*cdf0e10cSrcweir         {
2464*cdf0e10cSrcweir             while ( xResultSet->next() )
2465*cdf0e10cSrcweir             {
2466*cdf0e10cSrcweir                 sal_Bool             bUpdateType = sal_False;
2467*cdf0e10cSrcweir                 DocTemplates_EntryData_Impl  *pData;
2468*cdf0e10cSrcweir 
2469*cdf0e10cSrcweir                 OUString aTitle( xRow->getString( 1 ) );
2470*cdf0e10cSrcweir                 OUString aTargetDir( xRow->getString( 2 ) );
2471*cdf0e10cSrcweir                 OUString aType( xRow->getString( 3 ) );
2472*cdf0e10cSrcweir                 OUString aHierURL = xContentAccess->queryContentIdentifierString();
2473*cdf0e10cSrcweir 
2474*cdf0e10cSrcweir                 if ( !aType.getLength() )
2475*cdf0e10cSrcweir                 {
2476*cdf0e10cSrcweir                     OUString aTmpTitle;
2477*cdf0e10cSrcweir 
2478*cdf0e10cSrcweir 					sal_Bool bDocHasTitle = sal_False;
2479*cdf0e10cSrcweir 					if( !getTitleFromURL( aTargetDir, aTmpTitle, aType, bDocHasTitle ) )
2480*cdf0e10cSrcweir 					{
2481*cdf0e10cSrcweir             			DBG_ERRORFILE( "addHierGroup(): template of alien format" );
2482*cdf0e10cSrcweir 						continue;
2483*cdf0e10cSrcweir 					}
2484*cdf0e10cSrcweir 
2485*cdf0e10cSrcweir                     if ( aType.getLength() )
2486*cdf0e10cSrcweir                         bUpdateType = sal_True;
2487*cdf0e10cSrcweir                 }
2488*cdf0e10cSrcweir 
2489*cdf0e10cSrcweir                 pData = pGroup->addEntry( aTitle, aTargetDir, aType, aHierURL );
2490*cdf0e10cSrcweir                 pData->setUpdateType( bUpdateType );
2491*cdf0e10cSrcweir             }
2492*cdf0e10cSrcweir         }
2493*cdf0e10cSrcweir         catch ( Exception& ) {}
2494*cdf0e10cSrcweir     }
2495*cdf0e10cSrcweir }
2496*cdf0e10cSrcweir 
2497*cdf0e10cSrcweir //-----------------------------------------------------------------------------
2498*cdf0e10cSrcweir void SfxDocTplService_Impl::addFsysGroup( GroupList_Impl& rList,
2499*cdf0e10cSrcweir                                           const OUString& rTitle,
2500*cdf0e10cSrcweir 										  const OUString& rUITitle,
2501*cdf0e10cSrcweir                                           const OUString& rOwnURL,
2502*cdf0e10cSrcweir 										  sal_Bool bWriteableGroup )
2503*cdf0e10cSrcweir {
2504*cdf0e10cSrcweir 	::rtl::OUString aTitle;
2505*cdf0e10cSrcweir 
2506*cdf0e10cSrcweir 	if ( !rUITitle.getLength() )
2507*cdf0e10cSrcweir 	{
2508*cdf0e10cSrcweir 		// reserved FS names that should not be used
2509*cdf0e10cSrcweir     	if ( rTitle.compareToAscii( "wizard" ) == 0 )
2510*cdf0e10cSrcweir         	return;
2511*cdf0e10cSrcweir     	else if ( rTitle.compareToAscii( "internal" ) == 0 )
2512*cdf0e10cSrcweir         	return;
2513*cdf0e10cSrcweir 
2514*cdf0e10cSrcweir 		aTitle = getLongName( rTitle );
2515*cdf0e10cSrcweir 	}
2516*cdf0e10cSrcweir 	else
2517*cdf0e10cSrcweir 		aTitle = rUITitle;
2518*cdf0e10cSrcweir 
2519*cdf0e10cSrcweir 	if ( !aTitle.getLength() )
2520*cdf0e10cSrcweir 		return;
2521*cdf0e10cSrcweir 
2522*cdf0e10cSrcweir     GroupData_Impl *pGroup = rList.First();
2523*cdf0e10cSrcweir 
2524*cdf0e10cSrcweir     while ( pGroup && pGroup->getTitle() != aTitle )
2525*cdf0e10cSrcweir         pGroup = rList.Next();
2526*cdf0e10cSrcweir 
2527*cdf0e10cSrcweir     if ( !pGroup )
2528*cdf0e10cSrcweir     {
2529*cdf0e10cSrcweir         pGroup = new GroupData_Impl( aTitle );
2530*cdf0e10cSrcweir         rList.Insert( pGroup );
2531*cdf0e10cSrcweir     }
2532*cdf0e10cSrcweir 
2533*cdf0e10cSrcweir 	if ( bWriteableGroup )
2534*cdf0e10cSrcweir 		pGroup->setTargetURL( rOwnURL );
2535*cdf0e10cSrcweir 
2536*cdf0e10cSrcweir     pGroup->setInUse();
2537*cdf0e10cSrcweir 
2538*cdf0e10cSrcweir     // now get the content of the Group
2539*cdf0e10cSrcweir     Content                 aContent;
2540*cdf0e10cSrcweir     uno::Reference< XResultSet > xResultSet;
2541*cdf0e10cSrcweir     Sequence< OUString >    aProps(1);
2542*cdf0e10cSrcweir     aProps[0] = OUString::createFromAscii( TITLE );
2543*cdf0e10cSrcweir 
2544*cdf0e10cSrcweir     try
2545*cdf0e10cSrcweir     {
2546*cdf0e10cSrcweir         // this method is only used during checking of the available template-folders
2547*cdf0e10cSrcweir         // that should happen quietly
2548*cdf0e10cSrcweir         uno::Reference< XCommandEnvironment > aQuietEnv;
2549*cdf0e10cSrcweir         aContent = Content( rOwnURL, aQuietEnv );
2550*cdf0e10cSrcweir         ResultSetInclude eInclude = INCLUDE_DOCUMENTS_ONLY;
2551*cdf0e10cSrcweir         xResultSet = aContent.createCursor( aProps, eInclude );
2552*cdf0e10cSrcweir     }
2553*cdf0e10cSrcweir     catch ( Exception& ) {}
2554*cdf0e10cSrcweir 
2555*cdf0e10cSrcweir     if ( xResultSet.is() )
2556*cdf0e10cSrcweir     {
2557*cdf0e10cSrcweir         uno::Reference< XContentAccess > xContentAccess( xResultSet, UNO_QUERY );
2558*cdf0e10cSrcweir         uno::Reference< XRow > xRow( xResultSet, UNO_QUERY );
2559*cdf0e10cSrcweir 
2560*cdf0e10cSrcweir         try
2561*cdf0e10cSrcweir         {
2562*cdf0e10cSrcweir             while ( xResultSet->next() )
2563*cdf0e10cSrcweir             {
2564*cdf0e10cSrcweir                 OUString aChildTitle( xRow->getString( 1 ) );
2565*cdf0e10cSrcweir                 OUString aTargetURL = xContentAccess->queryContentIdentifierString();
2566*cdf0e10cSrcweir                 OUString aType;
2567*cdf0e10cSrcweir                 OUString aHierURL;
2568*cdf0e10cSrcweir 
2569*cdf0e10cSrcweir                 if ( aChildTitle.compareToAscii( "sfx.tlx" ) == 0
2570*cdf0e10cSrcweir 				  || aChildTitle.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "groupuinames.xml" ) ) )
2571*cdf0e10cSrcweir                     continue;
2572*cdf0e10cSrcweir 
2573*cdf0e10cSrcweir 				// only StarOffice templates are accepted
2574*cdf0e10cSrcweir 				sal_Bool bDocHasTitle = sal_False;
2575*cdf0e10cSrcweir                 if( !getTitleFromURL( aTargetURL, aChildTitle, aType, bDocHasTitle ) )
2576*cdf0e10cSrcweir 					continue;
2577*cdf0e10cSrcweir 
2578*cdf0e10cSrcweir                 pGroup->addEntry( aChildTitle, aTargetURL, aType, aHierURL );
2579*cdf0e10cSrcweir             }
2580*cdf0e10cSrcweir         }
2581*cdf0e10cSrcweir         catch ( Exception& ) {}
2582*cdf0e10cSrcweir     }
2583*cdf0e10cSrcweir }
2584*cdf0e10cSrcweir 
2585*cdf0e10cSrcweir // -----------------------------------------------------------------------
2586*cdf0e10cSrcweir void SfxDocTplService_Impl::createFromContent( GroupList_Impl& rList,
2587*cdf0e10cSrcweir                                                Content &rContent,
2588*cdf0e10cSrcweir                                                sal_Bool bHierarchy,
2589*cdf0e10cSrcweir 											   sal_Bool bWriteableContent )
2590*cdf0e10cSrcweir {
2591*cdf0e10cSrcweir     OUString aTargetURL = rContent.get()->getIdentifier()->getContentIdentifier();
2592*cdf0e10cSrcweir 
2593*cdf0e10cSrcweir     // when scanning the file system, we have to add the 'standard' group, too
2594*cdf0e10cSrcweir     if ( ! bHierarchy )
2595*cdf0e10cSrcweir     {
2596*cdf0e10cSrcweir 		OUString aUIStdTitle = getLongName( OUString( RTL_CONSTASCII_USTRINGPARAM( STANDARD_FOLDER ) ) );
2597*cdf0e10cSrcweir         addFsysGroup( rList, ::rtl::OUString(), aUIStdTitle, aTargetURL, bWriteableContent );
2598*cdf0e10cSrcweir     }
2599*cdf0e10cSrcweir 
2600*cdf0e10cSrcweir 	// search for predefined UI names
2601*cdf0e10cSrcweir     INetURLObject aLayerObj( aTargetURL );
2602*cdf0e10cSrcweir 
2603*cdf0e10cSrcweir 	// TODO/LATER: Use hashmap in future
2604*cdf0e10cSrcweir 	uno::Sequence< beans::StringPair > aUINames;
2605*cdf0e10cSrcweir 	if ( !bHierarchy )
2606*cdf0e10cSrcweir 		aUINames = ReadUINamesForTemplateDir_Impl( aLayerObj.GetMainURL( INetURLObject::NO_DECODE ) );
2607*cdf0e10cSrcweir 
2608*cdf0e10cSrcweir     uno::Reference< XResultSet > xResultSet;
2609*cdf0e10cSrcweir     Sequence< OUString > aProps(1);
2610*cdf0e10cSrcweir     aProps[0] = OUString::createFromAscii( TITLE );
2611*cdf0e10cSrcweir 
2612*cdf0e10cSrcweir     try
2613*cdf0e10cSrcweir     {
2614*cdf0e10cSrcweir         ResultSetInclude eInclude = INCLUDE_FOLDERS_ONLY;
2615*cdf0e10cSrcweir         xResultSet = rContent.createCursor( aProps, eInclude );
2616*cdf0e10cSrcweir     }
2617*cdf0e10cSrcweir     catch ( Exception& ) {}
2618*cdf0e10cSrcweir 
2619*cdf0e10cSrcweir     if ( xResultSet.is() )
2620*cdf0e10cSrcweir     {
2621*cdf0e10cSrcweir         uno::Reference< XContentAccess > xContentAccess( xResultSet, UNO_QUERY );
2622*cdf0e10cSrcweir         uno::Reference< XRow > xRow( xResultSet, UNO_QUERY );
2623*cdf0e10cSrcweir 
2624*cdf0e10cSrcweir         try
2625*cdf0e10cSrcweir         {
2626*cdf0e10cSrcweir             while ( xResultSet->next() )
2627*cdf0e10cSrcweir             {
2628*cdf0e10cSrcweir 				// TODO/LATER: clarify the encoding of the Title
2629*cdf0e10cSrcweir                 OUString aTitle( xRow->getString( 1 ) );
2630*cdf0e10cSrcweir                 OUString aTargetSubfolderURL( xContentAccess->queryContentIdentifierString() );
2631*cdf0e10cSrcweir 
2632*cdf0e10cSrcweir                 if ( bHierarchy )
2633*cdf0e10cSrcweir                     addHierGroup( rList, aTitle, aTargetSubfolderURL );
2634*cdf0e10cSrcweir                 else
2635*cdf0e10cSrcweir 				{
2636*cdf0e10cSrcweir 					::rtl::OUString aUITitle;
2637*cdf0e10cSrcweir 					for ( sal_Int32 nInd = 0; nInd < aUINames.getLength(); nInd++ )
2638*cdf0e10cSrcweir 						if ( aUINames[nInd].First.equals( aTitle ) )
2639*cdf0e10cSrcweir 						{
2640*cdf0e10cSrcweir 							aUITitle = aUINames[nInd].Second;
2641*cdf0e10cSrcweir 							break;
2642*cdf0e10cSrcweir 						}
2643*cdf0e10cSrcweir 
2644*cdf0e10cSrcweir                     addFsysGroup( rList, aTitle, aUITitle, aTargetSubfolderURL, bWriteableContent );
2645*cdf0e10cSrcweir 				}
2646*cdf0e10cSrcweir             }
2647*cdf0e10cSrcweir         }
2648*cdf0e10cSrcweir         catch ( Exception& ) {}
2649*cdf0e10cSrcweir     }
2650*cdf0e10cSrcweir }
2651*cdf0e10cSrcweir 
2652*cdf0e10cSrcweir //-----------------------------------------------------------------------------
2653*cdf0e10cSrcweir void SfxDocTplService_Impl::removeFromHierarchy( DocTemplates_EntryData_Impl *pData )
2654*cdf0e10cSrcweir {
2655*cdf0e10cSrcweir     Content aTemplate;
2656*cdf0e10cSrcweir 
2657*cdf0e10cSrcweir     if ( Content::create( pData->getHierarchyURL(), maCmdEnv, aTemplate ) )
2658*cdf0e10cSrcweir     {
2659*cdf0e10cSrcweir         removeContent( aTemplate );
2660*cdf0e10cSrcweir     }
2661*cdf0e10cSrcweir }
2662*cdf0e10cSrcweir 
2663*cdf0e10cSrcweir //-----------------------------------------------------------------------------
2664*cdf0e10cSrcweir void SfxDocTplService_Impl::addToHierarchy( GroupData_Impl *pGroup,
2665*cdf0e10cSrcweir                                             DocTemplates_EntryData_Impl *pData )
2666*cdf0e10cSrcweir {
2667*cdf0e10cSrcweir     Content aGroup, aTemplate;
2668*cdf0e10cSrcweir 
2669*cdf0e10cSrcweir     if ( ! Content::create( pGroup->getHierarchyURL(), maCmdEnv, aGroup ) )
2670*cdf0e10cSrcweir         return;
2671*cdf0e10cSrcweir 
2672*cdf0e10cSrcweir     // Check, if there's a template with the given name in this group
2673*cdf0e10cSrcweir     // Return if there is already a template
2674*cdf0e10cSrcweir     INetURLObject aGroupObj( pGroup->getHierarchyURL() );
2675*cdf0e10cSrcweir 
2676*cdf0e10cSrcweir     aGroupObj.insertName( pData->getTitle(), false,
2677*cdf0e10cSrcweir                       INetURLObject::LAST_SEGMENT, true,
2678*cdf0e10cSrcweir                       INetURLObject::ENCODE_ALL );
2679*cdf0e10cSrcweir 
2680*cdf0e10cSrcweir     OUString aTemplateURL = aGroupObj.GetMainURL( INetURLObject::NO_DECODE );
2681*cdf0e10cSrcweir 
2682*cdf0e10cSrcweir     if ( Content::create( aTemplateURL, maCmdEnv, aTemplate ) )
2683*cdf0e10cSrcweir         return;
2684*cdf0e10cSrcweir 
2685*cdf0e10cSrcweir     addEntry( aGroup, pData->getTitle(),
2686*cdf0e10cSrcweir               pData->getTargetURL(),
2687*cdf0e10cSrcweir               pData->getType() );
2688*cdf0e10cSrcweir }
2689*cdf0e10cSrcweir 
2690*cdf0e10cSrcweir //-----------------------------------------------------------------------------
2691*cdf0e10cSrcweir void SfxDocTplService_Impl::updateData( DocTemplates_EntryData_Impl *pData )
2692*cdf0e10cSrcweir {
2693*cdf0e10cSrcweir     Content aTemplate;
2694*cdf0e10cSrcweir 
2695*cdf0e10cSrcweir     if ( ! Content::create( pData->getHierarchyURL(), maCmdEnv, aTemplate ) )
2696*cdf0e10cSrcweir         return;
2697*cdf0e10cSrcweir 
2698*cdf0e10cSrcweir     OUString aPropName;
2699*cdf0e10cSrcweir 
2700*cdf0e10cSrcweir     if ( pData->getUpdateType() )
2701*cdf0e10cSrcweir     {
2702*cdf0e10cSrcweir         aPropName = OUString( RTL_CONSTASCII_USTRINGPARAM( PROPERTY_TYPE ) );
2703*cdf0e10cSrcweir         setProperty( aTemplate, aPropName, makeAny( pData->getType() ) );
2704*cdf0e10cSrcweir     }
2705*cdf0e10cSrcweir 
2706*cdf0e10cSrcweir     if ( pData->getUpdateLink() )
2707*cdf0e10cSrcweir     {
2708*cdf0e10cSrcweir         aPropName = OUString( RTL_CONSTASCII_USTRINGPARAM( TARGET_URL ) );
2709*cdf0e10cSrcweir         setProperty( aTemplate, aPropName, makeAny( pData->getTargetURL() ) );
2710*cdf0e10cSrcweir     }
2711*cdf0e10cSrcweir }
2712*cdf0e10cSrcweir 
2713*cdf0e10cSrcweir //-----------------------------------------------------------------------------
2714*cdf0e10cSrcweir void SfxDocTplService_Impl::addGroupToHierarchy( GroupData_Impl *pGroup )
2715*cdf0e10cSrcweir {
2716*cdf0e10cSrcweir     OUString aAdditionalProp( RTL_CONSTASCII_USTRINGPARAM( TARGET_DIR_URL ) );
2717*cdf0e10cSrcweir     Content aGroup;
2718*cdf0e10cSrcweir 
2719*cdf0e10cSrcweir     INetURLObject aNewGroupObj( maRootURL );
2720*cdf0e10cSrcweir     aNewGroupObj.insertName( pGroup->getTitle(), false,
2721*cdf0e10cSrcweir           INetURLObject::LAST_SEGMENT, true,
2722*cdf0e10cSrcweir           INetURLObject::ENCODE_ALL );
2723*cdf0e10cSrcweir 
2724*cdf0e10cSrcweir     OUString aNewGroupURL = aNewGroupObj.GetMainURL( INetURLObject::NO_DECODE );
2725*cdf0e10cSrcweir 
2726*cdf0e10cSrcweir     if ( createFolder( aNewGroupURL, sal_False, sal_False, aGroup ) )
2727*cdf0e10cSrcweir     {
2728*cdf0e10cSrcweir         setProperty( aGroup, aAdditionalProp, makeAny( pGroup->getTargetURL() ) );
2729*cdf0e10cSrcweir         pGroup->setHierarchyURL( aNewGroupURL );
2730*cdf0e10cSrcweir 
2731*cdf0e10cSrcweir         sal_uIntPtr nCount = pGroup->count();
2732*cdf0e10cSrcweir         for ( sal_uIntPtr i=0; i<nCount; i++ )
2733*cdf0e10cSrcweir         {
2734*cdf0e10cSrcweir             DocTemplates_EntryData_Impl *pData = pGroup->getEntry( i );
2735*cdf0e10cSrcweir             addToHierarchy( pGroup, pData ); // add entry to hierarchy
2736*cdf0e10cSrcweir         }
2737*cdf0e10cSrcweir     }
2738*cdf0e10cSrcweir }
2739*cdf0e10cSrcweir 
2740*cdf0e10cSrcweir //-----------------------------------------------------------------------------
2741*cdf0e10cSrcweir void SfxDocTplService_Impl::removeFromHierarchy( GroupData_Impl *pGroup )
2742*cdf0e10cSrcweir {
2743*cdf0e10cSrcweir     Content aGroup;
2744*cdf0e10cSrcweir 
2745*cdf0e10cSrcweir     if ( Content::create( pGroup->getHierarchyURL(), maCmdEnv, aGroup ) )
2746*cdf0e10cSrcweir     {
2747*cdf0e10cSrcweir         removeContent( aGroup );
2748*cdf0e10cSrcweir     }
2749*cdf0e10cSrcweir }
2750*cdf0e10cSrcweir 
2751*cdf0e10cSrcweir // -----------------------------------------------------------------------
2752*cdf0e10cSrcweir // -----------------------------------------------------------------------
2753*cdf0e10cSrcweir // -----------------------------------------------------------------------
2754*cdf0e10cSrcweir GroupData_Impl::GroupData_Impl( const OUString& rTitle )
2755*cdf0e10cSrcweir {
2756*cdf0e10cSrcweir     maTitle = rTitle;
2757*cdf0e10cSrcweir     mbInUse = sal_False;
2758*cdf0e10cSrcweir     mbInHierarchy = sal_False;
2759*cdf0e10cSrcweir }
2760*cdf0e10cSrcweir 
2761*cdf0e10cSrcweir // -----------------------------------------------------------------------
2762*cdf0e10cSrcweir GroupData_Impl::~GroupData_Impl()
2763*cdf0e10cSrcweir {
2764*cdf0e10cSrcweir     DocTemplates_EntryData_Impl *pData = maEntries.First();
2765*cdf0e10cSrcweir     while ( pData )
2766*cdf0e10cSrcweir     {
2767*cdf0e10cSrcweir         delete pData;
2768*cdf0e10cSrcweir         pData = maEntries.Next();
2769*cdf0e10cSrcweir     }
2770*cdf0e10cSrcweir }
2771*cdf0e10cSrcweir 
2772*cdf0e10cSrcweir // -----------------------------------------------------------------------
2773*cdf0e10cSrcweir DocTemplates_EntryData_Impl* GroupData_Impl::addEntry( const OUString& rTitle,
2774*cdf0e10cSrcweir                                           const OUString& rTargetURL,
2775*cdf0e10cSrcweir                                           const OUString& rType,
2776*cdf0e10cSrcweir                                           const OUString& rHierURL )
2777*cdf0e10cSrcweir {
2778*cdf0e10cSrcweir     DocTemplates_EntryData_Impl *pData = maEntries.First();
2779*cdf0e10cSrcweir 
2780*cdf0e10cSrcweir     while ( pData && pData->getTitle() != rTitle )
2781*cdf0e10cSrcweir         pData = maEntries.Next();
2782*cdf0e10cSrcweir 
2783*cdf0e10cSrcweir     if ( !pData )
2784*cdf0e10cSrcweir     {
2785*cdf0e10cSrcweir         pData = new DocTemplates_EntryData_Impl( rTitle );
2786*cdf0e10cSrcweir         pData->setTargetURL( rTargetURL );
2787*cdf0e10cSrcweir         pData->setType( rType );
2788*cdf0e10cSrcweir         if ( rHierURL.getLength() )
2789*cdf0e10cSrcweir         {
2790*cdf0e10cSrcweir             pData->setHierarchyURL( rHierURL );
2791*cdf0e10cSrcweir             pData->setHierarchy( sal_True );
2792*cdf0e10cSrcweir         }
2793*cdf0e10cSrcweir         maEntries.Insert( pData );
2794*cdf0e10cSrcweir     }
2795*cdf0e10cSrcweir     else
2796*cdf0e10cSrcweir     {
2797*cdf0e10cSrcweir         if ( rHierURL.getLength() )
2798*cdf0e10cSrcweir         {
2799*cdf0e10cSrcweir             pData->setHierarchyURL( rHierURL );
2800*cdf0e10cSrcweir             pData->setHierarchy( sal_True );
2801*cdf0e10cSrcweir         }
2802*cdf0e10cSrcweir 
2803*cdf0e10cSrcweir 		if ( pData->getInHierarchy() )
2804*cdf0e10cSrcweir 			pData->setInUse();
2805*cdf0e10cSrcweir 
2806*cdf0e10cSrcweir         if ( rTargetURL != pData->getTargetURL() )
2807*cdf0e10cSrcweir         {
2808*cdf0e10cSrcweir             pData->setTargetURL( rTargetURL );
2809*cdf0e10cSrcweir             pData->setUpdateLink( sal_True );
2810*cdf0e10cSrcweir         }
2811*cdf0e10cSrcweir     }
2812*cdf0e10cSrcweir 
2813*cdf0e10cSrcweir     return pData;
2814*cdf0e10cSrcweir }
2815*cdf0e10cSrcweir 
2816*cdf0e10cSrcweir // -----------------------------------------------------------------------
2817*cdf0e10cSrcweir // -----------------------------------------------------------------------
2818*cdf0e10cSrcweir // -----------------------------------------------------------------------
2819*cdf0e10cSrcweir DocTemplates_EntryData_Impl::DocTemplates_EntryData_Impl( const OUString& rTitle )
2820*cdf0e10cSrcweir {
2821*cdf0e10cSrcweir     maTitle         = rTitle;
2822*cdf0e10cSrcweir     mbInUse         = sal_False;
2823*cdf0e10cSrcweir     mbInHierarchy   = sal_False;
2824*cdf0e10cSrcweir     mbUpdateType    = sal_False;
2825*cdf0e10cSrcweir     mbUpdateLink    = sal_False;
2826*cdf0e10cSrcweir }
2827*cdf0e10cSrcweir 
2828*cdf0e10cSrcweir // -----------------------------------------------------------------------
2829*cdf0e10cSrcweir SfxURLRelocator_Impl::SfxURLRelocator_Impl( uno::Reference< XMultiServiceFactory > xFactory )
2830*cdf0e10cSrcweir : mxFactory( xFactory )
2831*cdf0e10cSrcweir {
2832*cdf0e10cSrcweir }
2833*cdf0e10cSrcweir 
2834*cdf0e10cSrcweir // -----------------------------------------------------------------------
2835*cdf0e10cSrcweir SfxURLRelocator_Impl::~SfxURLRelocator_Impl()
2836*cdf0e10cSrcweir {
2837*cdf0e10cSrcweir }
2838*cdf0e10cSrcweir 
2839*cdf0e10cSrcweir // -----------------------------------------------------------------------
2840*cdf0e10cSrcweir void SfxURLRelocator_Impl::initOfficeInstDirs()
2841*cdf0e10cSrcweir {
2842*cdf0e10cSrcweir     if ( !mxOfficeInstDirs.is() )
2843*cdf0e10cSrcweir     {
2844*cdf0e10cSrcweir         osl::MutexGuard aGuard( maMutex );
2845*cdf0e10cSrcweir         if ( !mxOfficeInstDirs.is() )
2846*cdf0e10cSrcweir         {
2847*cdf0e10cSrcweir             OSL_ENSURE( mxFactory.is(), "No service manager!" );
2848*cdf0e10cSrcweir 
2849*cdf0e10cSrcweir             uno::Reference< XComponentContext > xCtx;
2850*cdf0e10cSrcweir             uno::Reference< XPropertySet > xPropSet( mxFactory, UNO_QUERY );
2851*cdf0e10cSrcweir             if ( xPropSet.is() )
2852*cdf0e10cSrcweir             {
2853*cdf0e10cSrcweir                 xPropSet->getPropertyValue(
2854*cdf0e10cSrcweir                     rtl::OUString(
2855*cdf0e10cSrcweir                         RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ) ) )
2856*cdf0e10cSrcweir                 >>= xCtx;
2857*cdf0e10cSrcweir             }
2858*cdf0e10cSrcweir 
2859*cdf0e10cSrcweir             OSL_ENSURE( xCtx.is(),
2860*cdf0e10cSrcweir                         "Unable to obtain component context from "
2861*cdf0e10cSrcweir                         "service manager!" );
2862*cdf0e10cSrcweir 
2863*cdf0e10cSrcweir             if ( xCtx.is() )
2864*cdf0e10cSrcweir             {
2865*cdf0e10cSrcweir                 xCtx->getValueByName(
2866*cdf0e10cSrcweir                     rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
2867*cdf0e10cSrcweir                         "/singletons/"
2868*cdf0e10cSrcweir                         "com.sun.star.util.theOfficeInstallationDirectories" ) ) )
2869*cdf0e10cSrcweir                 >>= mxOfficeInstDirs;
2870*cdf0e10cSrcweir             }
2871*cdf0e10cSrcweir 
2872*cdf0e10cSrcweir             OSL_ENSURE( mxOfficeInstDirs.is(),
2873*cdf0e10cSrcweir                         "Unable to obtain office installation directory "
2874*cdf0e10cSrcweir                         "singleton!" );
2875*cdf0e10cSrcweir         }
2876*cdf0e10cSrcweir     }
2877*cdf0e10cSrcweir }
2878*cdf0e10cSrcweir 
2879*cdf0e10cSrcweir // -----------------------------------------------------------------------
2880*cdf0e10cSrcweir void SfxURLRelocator_Impl::implExpandURL( ::rtl::OUString& io_url )
2881*cdf0e10cSrcweir {
2882*cdf0e10cSrcweir     const INetURLObject aParser( io_url );
2883*cdf0e10cSrcweir     if ( aParser.GetProtocol() != INET_PROT_VND_SUN_STAR_EXPAND )
2884*cdf0e10cSrcweir         return;
2885*cdf0e10cSrcweir 
2886*cdf0e10cSrcweir     io_url = aParser.GetURLPath( INetURLObject::DECODE_WITH_CHARSET );
2887*cdf0e10cSrcweir     try
2888*cdf0e10cSrcweir     {
2889*cdf0e10cSrcweir         if ( !mxMacroExpander.is() )
2890*cdf0e10cSrcweir         {
2891*cdf0e10cSrcweir             ::comphelper::ComponentContext aContext( mxFactory );
2892*cdf0e10cSrcweir             mxMacroExpander.set( aContext.getSingleton( "com.sun.star.util.theMacroExpander" ), UNO_QUERY_THROW );
2893*cdf0e10cSrcweir         }
2894*cdf0e10cSrcweir         io_url = mxMacroExpander->expandMacros( io_url );
2895*cdf0e10cSrcweir     }
2896*cdf0e10cSrcweir     catch( const Exception& )
2897*cdf0e10cSrcweir     {
2898*cdf0e10cSrcweir     	DBG_UNHANDLED_EXCEPTION();
2899*cdf0e10cSrcweir     }
2900*cdf0e10cSrcweir }
2901*cdf0e10cSrcweir 
2902*cdf0e10cSrcweir // -----------------------------------------------------------------------
2903*cdf0e10cSrcweir void SfxURLRelocator_Impl::makeRelocatableURL( rtl::OUString & rURL )
2904*cdf0e10cSrcweir {
2905*cdf0e10cSrcweir     if ( rURL.getLength() > 0 )
2906*cdf0e10cSrcweir     {
2907*cdf0e10cSrcweir         initOfficeInstDirs();
2908*cdf0e10cSrcweir         implExpandURL( rURL );
2909*cdf0e10cSrcweir         rURL = mxOfficeInstDirs->makeRelocatableURL( rURL );
2910*cdf0e10cSrcweir     }
2911*cdf0e10cSrcweir }
2912*cdf0e10cSrcweir 
2913*cdf0e10cSrcweir // -----------------------------------------------------------------------
2914*cdf0e10cSrcweir void SfxURLRelocator_Impl::makeAbsoluteURL( rtl::OUString & rURL )
2915*cdf0e10cSrcweir {
2916*cdf0e10cSrcweir     if ( rURL.getLength() > 0 )
2917*cdf0e10cSrcweir     {
2918*cdf0e10cSrcweir         initOfficeInstDirs();
2919*cdf0e10cSrcweir         implExpandURL( rURL );
2920*cdf0e10cSrcweir         rURL = mxOfficeInstDirs->makeAbsoluteURL( rURL );
2921*cdf0e10cSrcweir     }
2922*cdf0e10cSrcweir }
2923*cdf0e10cSrcweir 
2924*cdf0e10cSrcweir 
2925