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