Bump version to 4.1-6
[LibreOffice.git] / sfx2 / source / doc / doctempl.cxx
blob802882fea206c5bb008a8fdf07f9762e07717af7
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <limits.h>
22 #include <com/sun/star/uno/Any.h>
23 #include <osl/mutex.hxx>
24 #include <osl/thread.hxx>
26 #include <vcl/svapp.hxx>
27 #include <vcl/settings.hxx>
28 #include <unotools/localedatawrapper.hxx>
29 #include <unotools/pathoptions.hxx>
30 #include <tools/resary.hxx>
31 #include <tools/string.hxx>
32 #include <tools/urlobj.hxx>
33 #include <svtools/ehdl.hxx>
34 #include <svtools/sfxecode.hxx>
35 #include <comphelper/processfactory.hxx>
36 #include <ucbhelper/content.hxx>
37 #include <com/sun/star/beans/PropertyAttribute.hpp>
38 #include <com/sun/star/beans/PropertyValue.hpp>
39 #include <com/sun/star/beans/XPropertyContainer.hpp>
40 #include <com/sun/star/beans/XPropertySet.hpp>
41 #include <com/sun/star/beans/XPropertySetInfo.hpp>
42 #include <com/sun/star/document/XTypeDetection.hpp>
43 #include <com/sun/star/document/DocumentProperties.hpp>
44 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
45 #include <com/sun/star/frame/Desktop.hpp>
46 #include <com/sun/star/frame/XComponentLoader.hpp>
47 #include <com/sun/star/frame/DocumentTemplates.hpp>
48 #include <com/sun/star/frame/XDocumentTemplates.hpp>
49 #include <com/sun/star/io/XInputStream.hpp>
50 #include <com/sun/star/io/XPersist.hpp>
51 #include <com/sun/star/lang/XLocalizable.hpp>
52 #include <com/sun/star/sdbc/XResultSet.hpp>
53 #include <com/sun/star/sdbc/XRow.hpp>
54 #include <com/sun/star/ucb/ContentInfo.hpp>
55 #include <com/sun/star/ucb/InsertCommandArgument.hpp>
56 #include <com/sun/star/ucb/NameClash.hpp>
57 #include <com/sun/star/ucb/TransferInfo.hpp>
58 #include <com/sun/star/ucb/XCommandProcessor.hpp>
59 #include <com/sun/star/ucb/XContent.hpp>
60 #include <com/sun/star/ucb/XContentAccess.hpp>
61 #include <com/sun/star/ucb/AnyCompareFactory.hpp>
62 #include <com/sun/star/ucb/XAnyCompare.hpp>
63 #include <com/sun/star/ucb/NumberedSortingInfo.hpp>
64 #include <com/sun/star/embed/ElementModes.hpp>
65 #include <com/sun/star/embed/XTransactedObject.hpp>
67 #include "sfxurlrelocator.hxx"
69 using namespace ::com::sun::star;
70 using namespace ::com::sun::star::beans;
71 using namespace ::com::sun::star::frame;
72 using namespace ::com::sun::star::io;
73 using namespace ::com::sun::star::lang;
74 using namespace ::com::sun::star::sdbc;
75 using namespace ::com::sun::star::uno;
76 using namespace ::com::sun::star::ucb;
77 using namespace ::com::sun::star::document;
78 using namespace ::rtl;
79 using namespace ::ucbhelper;
82 #include <sfx2/doctempl.hxx>
83 #include <sfx2/docfac.hxx>
84 #include <sfx2/docfile.hxx>
85 #include <sfx2/objsh.hxx>
86 #include "sfxtypes.hxx"
87 #include <sfx2/app.hxx>
88 #include "sfx2/sfxresid.hxx"
89 #include <sfx2/templatelocnames.hrc>
90 #include "doc.hrc"
91 #include <sfx2/fcontnr.hxx>
92 #include <svtools/templatefoldercache.hxx>
94 #include <comphelper/storagehelper.hxx>
95 #include <unotools/ucbhelper.hxx>
97 #include <vector>
98 using ::std::vector;
99 using ::std::advance;
101 //========================================================================
103 #define TITLE "Title"
104 #define TARGET_URL "TargetURL"
106 #define COMMAND_TRANSFER "transfer"
108 //========================================================================
110 class RegionData_Impl;
112 namespace DocTempl {
114 class DocTempl_EntryData_Impl
116 RegionData_Impl* mpParent;
118 // the following member must be SfxObjectShellLock since it controlls that SfxObjectShell lifetime by design
119 // and users of this class expect it to be so.
120 SfxObjectShellLock mxObjShell;
122 OUString maTitle;
123 OUString maOwnURL;
124 OUString maTargetURL;
125 sal_Bool mbIsOwner : 1;
126 sal_Bool mbDidConvert: 1;
128 private:
129 RegionData_Impl* GetParent() const { return mpParent; }
131 public:
132 DocTempl_EntryData_Impl( RegionData_Impl* pParent,
133 const OUString& rTitle );
135 const OUString& GetTitle() const { return maTitle; }
136 const OUString& GetTargetURL();
137 const OUString& GetHierarchyURL();
139 void SetTitle( const OUString& rTitle ) { maTitle = rTitle; }
140 void SetTargetURL( const OUString& rURL ) { maTargetURL = rURL; }
141 void SetHierarchyURL( const OUString& rURL) { maOwnURL = rURL; }
143 int Compare( const OUString& rTitle ) const;
148 using namespace ::DocTempl;
150 // ------------------------------------------------------------------------
152 class RegionData_Impl
154 const SfxDocTemplate_Impl* mpParent;
155 vector< DocTempl_EntryData_Impl* > maEntries;
156 OUString maTitle;
157 OUString maOwnURL;
158 OUString maTargetURL;
160 private:
161 size_t GetEntryPos( const OUString& rTitle,
162 sal_Bool& rFound ) const;
163 const SfxDocTemplate_Impl* GetParent() const { return mpParent; }
165 public:
166 RegionData_Impl( const SfxDocTemplate_Impl* pParent,
167 const OUString& rTitle );
168 ~RegionData_Impl();
170 void SetTargetURL( const OUString& rURL ) { maTargetURL = rURL; }
171 void SetHierarchyURL( const OUString& rURL) { maOwnURL = rURL; }
173 DocTempl_EntryData_Impl* GetEntry( size_t nIndex ) const;
174 DocTempl_EntryData_Impl* GetEntry( const OUString& rName ) const;
176 const OUString& GetTitle() const { return maTitle; }
177 const OUString& GetHierarchyURL();
179 size_t GetCount() const;
181 void SetTitle( const OUString& rTitle ) { maTitle = rTitle; }
183 void AddEntry( const OUString& rTitle,
184 const OUString& rTargetURL,
185 size_t *pPos = NULL );
186 void DeleteEntry( size_t nIndex );
188 int Compare( const OUString& rTitle ) const
189 { return maTitle.compareTo( rTitle ); }
190 int Compare( RegionData_Impl* pCompareWith ) const;
193 typedef vector< RegionData_Impl* > RegionList_Impl;
195 // ------------------------------------------------------------------------
197 class SfxDocTemplate_Impl : public SvRefBase
199 uno::Reference< XPersist > mxInfo;
200 uno::Reference< XDocumentTemplates > mxTemplates;
202 ::osl::Mutex maMutex;
203 OUString maRootURL;
204 OUString maStandardGroup;
205 RegionList_Impl maRegions;
206 sal_Bool mbConstructed;
208 uno::Reference< XAnyCompareFactory > m_rCompareFactory;
210 // the following member is intended to prevent clearing of the global data when it is in use
211 // TODO/LATER: it still does not make the implementation complete thread-safe
212 sal_Int32 mnLockCounter;
214 private:
215 void Clear();
217 public:
218 SfxDocTemplate_Impl();
219 ~SfxDocTemplate_Impl();
221 void IncrementLock();
222 void DecrementLock();
224 sal_Bool Construct( );
225 void CreateFromHierarchy( Content &rTemplRoot );
226 void ReInitFromComponent();
227 void AddRegion( const OUString& rTitle,
228 Content& rContent );
230 void Rescan();
232 void DeleteRegion( size_t nIndex );
234 size_t GetRegionCount() const
235 { return maRegions.size(); }
236 RegionData_Impl* GetRegion( const OUString& rName ) const;
237 RegionData_Impl* GetRegion( size_t nIndex ) const;
239 sal_Bool GetTitleFromURL( const OUString& rURL, OUString& aTitle );
240 sal_Bool InsertRegion( RegionData_Impl *pData, size_t nPos = size_t(-1) );
241 OUString GetRootURL() const { return maRootURL; }
243 uno::Reference< XDocumentTemplates > getDocTemplates() { return mxTemplates; }
246 // ------------------------------------------------------------------------
248 class DocTemplLocker_Impl
250 SfxDocTemplate_Impl& m_aDocTempl;
251 public:
252 DocTemplLocker_Impl( SfxDocTemplate_Impl& aDocTempl )
253 : m_aDocTempl( aDocTempl )
255 m_aDocTempl.IncrementLock();
258 ~DocTemplLocker_Impl()
260 m_aDocTempl.DecrementLock();
264 // ------------------------------------------------------------------------
266 #ifndef SFX_DECL_DOCTEMPLATES_DEFINED
267 #define SFX_DECL_DOCTEMPLATES_DEFINED
268 SV_DECL_REF(SfxDocTemplate_Impl)
269 #endif
271 SV_IMPL_REF(SfxDocTemplate_Impl)
273 // ------------------------------------------------------------------------
275 SfxDocTemplate_Impl *gpTemplateData = 0;
277 // -----------------------------------------------------------------------
279 static sal_Bool getTextProperty_Impl( Content& rContent,
280 const OUString& rPropName,
281 OUString& rPropValue );
283 //========================================================================
285 String SfxDocumentTemplates::GetFullRegionName
287 sal_uInt16 nIdx // Region Index
288 ) const
290 /* [Description]
292 Returns the logical name of a region and its path
294 [Return value] Reference to the Region name
299 // First: find the RegionData for the index
300 String aName;
302 DocTemplLocker_Impl aLocker( *pImp );
304 if ( pImp->Construct() )
306 RegionData_Impl *pData1 = pImp->GetRegion( nIdx );
308 if ( pData1 )
309 aName = pData1->GetTitle();
311 // --**-- here was some code which appended the path to the
312 // group if there was more than one with the same name.
313 // this should not happen anymore
316 return aName;
319 //------------------------------------------------------------------------
321 const String& SfxDocumentTemplates::GetRegionName
323 sal_uInt16 nIdx // Region Index
324 ) const
326 /* [Description]
328 Returns the logical name of a region
330 [Return value]
332 const String& Reference to the Region name
336 static String maTmpString;
338 DocTemplLocker_Impl aLocker( *pImp );
340 if ( pImp->Construct() )
342 RegionData_Impl *pData = pImp->GetRegion( nIdx );
344 if ( pData )
345 maTmpString = pData->GetTitle();
346 else
347 maTmpString.Erase();
349 else
350 maTmpString.Erase();
352 return maTmpString;
355 //------------------------------------------------------------------------
357 sal_uInt16 SfxDocumentTemplates::GetRegionCount() const
359 /* [Description]
361 Returns the number of Regions
363 [Return value]
365 sal_uInt16 Number of Regions
368 DocTemplLocker_Impl aLocker( *pImp );
370 if ( !pImp->Construct() )
371 return 0;
373 sal_uIntPtr nCount = pImp->GetRegionCount();
375 return (sal_uInt16) nCount;
378 //------------------------------------------------------------------------
380 sal_uInt16 SfxDocumentTemplates::GetCount
382 sal_uInt16 nRegion /* Region index whose number is
383 to be determined */
385 ) const
387 /* [Description]
389 Number of entries in Region
391 [Return value] Number of entries
395 DocTemplLocker_Impl aLocker( *pImp );
397 if ( !pImp->Construct() )
398 return 0;
400 RegionData_Impl *pData = pImp->GetRegion( nRegion );
401 sal_uIntPtr nCount = 0;
403 if ( pData )
404 nCount = pData->GetCount();
406 return (sal_uInt16) nCount;
409 //------------------------------------------------------------------------
411 const String& SfxDocumentTemplates::GetName
413 sal_uInt16 nRegion, // Region Index, in which the entry lies
414 sal_uInt16 nIdx // Index of the entry
415 ) const
417 /* [Description]
419 Returns the logical name of an entry in Region
421 [Return value]
423 const String& Entry Name
427 DocTemplLocker_Impl aLocker( *pImp );
429 static String maTmpString;
431 if ( pImp->Construct() )
433 DocTempl_EntryData_Impl *pEntry = NULL;
434 RegionData_Impl *pRegion = pImp->GetRegion( nRegion );
436 if ( pRegion )
437 pEntry = pRegion->GetEntry( nIdx );
439 if ( pEntry )
440 maTmpString = pEntry->GetTitle();
441 else
442 maTmpString.Erase();
444 else
445 maTmpString.Erase();
447 return maTmpString;
450 //------------------------------------------------------------------------
452 String SfxDocumentTemplates::GetPath
454 sal_uInt16 nRegion, // Region Index, in which the entry lies
455 sal_uInt16 nIdx // Index of the entry
456 ) const
458 /* [Description]
460 Returns the file name with full path to the file assigned to an entry
462 [Return value]
464 String File name with full path
467 DocTemplLocker_Impl aLocker( *pImp );
469 if ( !pImp->Construct() )
470 return String();
472 DocTempl_EntryData_Impl *pEntry = NULL;
473 RegionData_Impl *pRegion = pImp->GetRegion( nRegion );
475 if ( pRegion )
476 pEntry = pRegion->GetEntry( nIdx );
478 if ( pEntry )
479 return pEntry->GetTargetURL();
480 else
481 return String();
484 //------------------------------------------------------------------------
486 OUString SfxDocumentTemplates::GetTemplateTargetURLFromComponent( const OUString& aGroupName,
487 const OUString& aTitle )
489 DocTemplLocker_Impl aLocker( *pImp );
491 INetURLObject aTemplateObj( pImp->GetRootURL() );
493 aTemplateObj.insertName( aGroupName, false,
494 INetURLObject::LAST_SEGMENT, true,
495 INetURLObject::ENCODE_ALL );
497 aTemplateObj.insertName( aTitle, false,
498 INetURLObject::LAST_SEGMENT, true,
499 INetURLObject::ENCODE_ALL );
502 OUString aResult;
503 Content aTemplate;
504 uno::Reference< XCommandEnvironment > aCmdEnv;
505 if ( Content::create( aTemplateObj.GetMainURL( INetURLObject::NO_DECODE ), aCmdEnv, comphelper::getProcessComponentContext(), aTemplate ) )
507 OUString aPropName( TARGET_URL );
508 getTextProperty_Impl( aTemplate, aPropName, aResult );
509 aResult = SvtPathOptions().SubstituteVariable( aResult );
512 return aResult;
515 //------------------------------------------------------------------------
517 /** Convert a resource string - a template name - to its localised pair if it exists.
518 @param nSourceResIds
519 Resource ID where the list of original en-US template names begin.
520 @param nDestResIds
521 Resource ID where the list of localised template names begin.
522 @param nCount
523 The number of names that have been localised.
524 @param rString
525 Name to be translated.
526 @return
527 The localised pair of rString or rString if the former does not exist.
529 OUString SfxDocumentTemplates::ConvertResourceString (
530 int nSourceResIds, int nDestResIds, int nCount, const OUString& rString )
532 for( int i = 0; i < nCount; ++i )
534 if( rString == SFX2_RESSTR(nSourceResIds + i))
535 return SFX2_RESSTR(nDestResIds + i);
537 return rString;
540 //------------------------------------------------------------------------
542 sal_Bool SfxDocumentTemplates::CopyOrMove
544 sal_uInt16 nTargetRegion, // Target Region Index
545 sal_uInt16 nTargetIdx, // Target position Index
546 sal_uInt16 nSourceRegion, // Source Region Index
547 sal_uInt16 nSourceIdx, /* Index to be copied / to moved template */
548 sal_Bool bMove // Copy / Move
551 /* [Description]
553 Copy or move a document template
555 [Return value]
557 sal_Bool sal_True, Action could be performed
558 sal_False, Action could not be performed
560 [Cross-references]
562 <SfxDocumentTemplates::Move(sal_uInt16,sal_uInt16,sal_uInt16,sal_uInt16)>
563 <SfxDocumentTemplates::Copy(sal_uInt16,sal_uInt16,sal_uInt16,sal_uInt16)>
567 /* to perform a copy or move, we need to send a transfer command to
568 the destination folder with the URL of the source as parameter.
569 ( If the destination content doesn't support the transfer command,
570 we could try a copy ( and delete ) instead. )
571 We need two transfers ( one for the real template and one for its
572 representation in the hierarchy )
576 DocTemplLocker_Impl aLocker( *pImp );
578 if ( !pImp->Construct() )
579 return sal_False;
581 // Don't copy or move any folders
582 if( nSourceIdx == USHRT_MAX )
583 return sal_False ;
585 if ( nSourceRegion == nTargetRegion )
587 SAL_WARN( "sfx2.doc", "Don't know, what to do!" );
588 return sal_False;
591 RegionData_Impl *pSourceRgn = pImp->GetRegion( nSourceRegion );
592 if ( !pSourceRgn )
593 return sal_False;
595 DocTempl_EntryData_Impl *pSource = pSourceRgn->GetEntry( nSourceIdx );
596 if ( !pSource )
597 return sal_False;
599 RegionData_Impl *pTargetRgn = pImp->GetRegion( nTargetRegion );
600 if ( !pTargetRgn )
601 return sal_False;
603 OUString aTitle = pSource->GetTitle();
605 uno::Reference< XDocumentTemplates > xTemplates = pImp->getDocTemplates();
607 if ( xTemplates->addTemplate( pTargetRgn->GetTitle(),
608 aTitle,
609 pSource->GetTargetURL() ) )
612 INetURLObject aSourceObj( pSource->GetTargetURL() );
614 OUString aNewTargetURL = GetTemplateTargetURLFromComponent( pTargetRgn->GetTitle(), aTitle );
615 if ( aNewTargetURL.isEmpty() )
616 return sal_False;
618 if ( bMove )
620 // --**-- delete the original file
621 sal_Bool bDeleted = xTemplates->removeTemplate( pSourceRgn->GetTitle(),
622 pSource->GetTitle() );
623 if ( bDeleted )
624 pSourceRgn->DeleteEntry( nSourceIdx );
625 else
627 if ( xTemplates->removeTemplate( pTargetRgn->GetTitle(), aTitle ) )
628 return sal_False; // will trigger tetry with copy instead of move
630 // if it is not possible to remove just created template ( must be possible! )
631 // it is better to report success here, since at least the copy has succeeded
632 // TODO/LATER: solve it more gracefully in future
636 // todo: fix SfxDocumentTemplates to handle size_t instead of sal_uInt16
637 size_t temp_nTargetIdx = nTargetIdx;
638 pTargetRgn->AddEntry( aTitle, aNewTargetURL, &temp_nTargetIdx );
640 return sal_True;
643 // --**-- if the current file is opened,
644 // it must be re-opened afterwards.
646 return sal_False;
649 //------------------------------------------------------------------------
651 sal_Bool SfxDocumentTemplates::Move
653 sal_uInt16 nTargetRegion, // Target Region Index
654 sal_uInt16 nTargetIdx, // Target position Index
655 sal_uInt16 nSourceRegion, // Source Region Index
656 sal_uInt16 nSourceIdx /* Index to be copied / to moved template */
659 /* [Description]
661 Moving a template
663 [Return value]
665 sal_Bool sal_True, Action could be performed
666 sal_False, Action could not be performed
668 [Cross-references]
670 <SfxDocumentTemplates::CopyOrMove(sal_uInt16,sal_uInt16,sal_uInt16,sal_uInt16,sal_Bool)>
673 DocTemplLocker_Impl aLocker( *pImp );
675 return CopyOrMove( nTargetRegion, nTargetIdx,
676 nSourceRegion, nSourceIdx, sal_True );
679 //------------------------------------------------------------------------
681 sal_Bool SfxDocumentTemplates::Copy
683 sal_uInt16 nTargetRegion, // Target Region Index
684 sal_uInt16 nTargetIdx, // Target position Index
685 sal_uInt16 nSourceRegion, // Source Region Index
686 sal_uInt16 nSourceIdx /* Index to be copied / to moved template */
689 /* [Description]
691 Copying a template
693 [Return value]
695 sal_Bool sal_True, Action could be performed
696 sal_False, Action could not be performed
698 [Cross-references]
700 <SfxDocumentTemplates::CopyOrMove(sal_uInt16,sal_uInt16,sal_uInt16,sal_uInt16,sal_Bool)>
704 DocTemplLocker_Impl aLocker( *pImp );
706 return CopyOrMove( nTargetRegion, nTargetIdx,
707 nSourceRegion, nSourceIdx, sal_False );
710 //------------------------------------------------------------------------
712 sal_Bool SfxDocumentTemplates::CopyTo
714 sal_uInt16 nRegion, // Region of the template to be exported
715 sal_uInt16 nIdx, // Index of the template to be exported
716 const String& rName /* File name under which the template is to
717 be created */
718 ) const
720 /* [Description]
722 Exporting a template into the file system
724 [Return value]
726 sal_Bool sal_True, Action could be performed
727 sal_False, Action could not be performed
729 [Cross-references]
731 <SfxDocumentTemplates::CopyFrom(sal_uInt16,sal_uInt16,String&)>
735 DocTemplLocker_Impl aLocker( *pImp );
737 if ( ! pImp->Construct() )
738 return sal_False;
740 RegionData_Impl *pSourceRgn = pImp->GetRegion( nRegion );
741 if ( !pSourceRgn )
742 return sal_False;
744 DocTempl_EntryData_Impl *pSource = pSourceRgn->GetEntry( nIdx );
745 if ( !pSource )
746 return sal_False;
748 INetURLObject aTargetURL( rName );
750 OUString aTitle( aTargetURL.getName( INetURLObject::LAST_SEGMENT, true,
751 INetURLObject::DECODE_WITH_CHARSET ) );
752 aTargetURL.removeSegment();
754 OUString aParentURL = aTargetURL.GetMainURL( INetURLObject::NO_DECODE );
756 uno::Reference< XCommandEnvironment > aCmdEnv;
757 Content aTarget;
761 aTarget = Content( aParentURL, aCmdEnv, comphelper::getProcessComponentContext() );
763 TransferInfo aTransferInfo;
764 aTransferInfo.MoveData = sal_False;
765 aTransferInfo.SourceURL = pSource->GetTargetURL();
766 aTransferInfo.NewTitle = aTitle;
767 aTransferInfo.NameClash = NameClash::OVERWRITE;
769 Any aArg = makeAny( aTransferInfo );
770 OUString aCmd( COMMAND_TRANSFER );
772 aTarget.executeCommand( aCmd, aArg );
774 catch ( ContentCreationException& )
775 { return sal_False; }
776 catch ( Exception& )
777 { return sal_False; }
779 return sal_True;
782 //------------------------------------------------------------------------
784 sal_Bool SfxDocumentTemplates::CopyFrom
786 sal_uInt16 nRegion, /* Region in which the template is to be
787 imported */
788 sal_uInt16 nIdx, // Index of the new template in this Region
789 String& rName /* File name of the template to be imported
790 as an out parameter of the (automatically
791 generated from the file name) logical name
792 of the template */
795 /* [Description]
797 Import a template from the file system
799 [Return value] Sucess (sal_True) or serfpTargetDirectory->GetContent());
801 sal_Bool sal_True, Action could be performed
802 sal_False, Action could not be performed
804 [Cross-references]
806 <SfxDocumentTemplates::CopyTo(sal_uInt16,sal_uInt16,const String&)>
810 DocTemplLocker_Impl aLocker( *pImp );
812 if ( ! pImp->Construct() )
813 return sal_False;
815 RegionData_Impl *pTargetRgn = pImp->GetRegion( nRegion );
817 if ( !pTargetRgn )
818 return sal_False;
820 uno::Reference< XDocumentTemplates > xTemplates = pImp->getDocTemplates();
821 if ( !xTemplates.is() )
822 return sal_False;
824 OUString aTitle;
825 sal_Bool bTemplateAdded = sal_False;
827 if( pImp->GetTitleFromURL( rName, aTitle ) )
829 bTemplateAdded = xTemplates->addTemplate( pTargetRgn->GetTitle(), aTitle, rName );
831 else
833 uno::Reference< XDesktop2 > xDesktop = Desktop::create( ::comphelper::getProcessComponentContext() );;
835 Sequence< PropertyValue > aArgs( 1 );
836 aArgs[0].Name = OUString("Hidden");
837 aArgs[0].Value <<= sal_True;
839 INetURLObject aTemplURL( rName );
840 uno::Reference< XDocumentPropertiesSupplier > xDocPropsSupplier;
841 uno::Reference< XStorable > xStorable;
844 xStorable = uno::Reference< XStorable >(
845 xDesktop->loadComponentFromURL( aTemplURL.GetMainURL(INetURLObject::NO_DECODE),
846 OUString("_blank"),
848 aArgs ),
849 UNO_QUERY );
851 xDocPropsSupplier = uno::Reference< XDocumentPropertiesSupplier >(
852 xStorable, UNO_QUERY );
854 catch( Exception& )
858 if( xStorable.is() )
860 // get Title from XDocumentPropertiesSupplier
861 if( xDocPropsSupplier.is() )
863 uno::Reference< XDocumentProperties > xDocProps
864 = xDocPropsSupplier->getDocumentProperties();
865 if (xDocProps.is() ) {
866 aTitle = xDocProps->getTitle();
870 if( aTitle.isEmpty() )
872 INetURLObject aURL( aTemplURL );
873 aURL.CutExtension();
874 aTitle = aURL.getName( INetURLObject::LAST_SEGMENT, true,
875 INetURLObject::DECODE_WITH_CHARSET );
878 // write a template using XStorable interface
879 bTemplateAdded = xTemplates->storeTemplate( pTargetRgn->GetTitle(), aTitle, xStorable );
884 if( bTemplateAdded )
886 INetURLObject aTemplObj( pTargetRgn->GetHierarchyURL() );
887 aTemplObj.insertName( aTitle, false,
888 INetURLObject::LAST_SEGMENT, true,
889 INetURLObject::ENCODE_ALL );
890 OUString aTemplURL = aTemplObj.GetMainURL( INetURLObject::NO_DECODE );
892 uno::Reference< XCommandEnvironment > aCmdEnv;
893 Content aTemplCont;
895 if( Content::create( aTemplURL, aCmdEnv, comphelper::getProcessComponentContext(), aTemplCont ) )
897 OUString aTemplName;
898 OUString aPropName( TARGET_URL );
900 if( getTextProperty_Impl( aTemplCont, aPropName, aTemplName ) )
902 if ( nIdx == USHRT_MAX )
903 nIdx = 0;
904 else
905 nIdx += 1;
907 // todo: fix SfxDocumentTemplates to handle size_t instead of sal_uInt16
908 size_t temp_nIdx = nIdx;
909 pTargetRgn->AddEntry( aTitle, aTemplName, &temp_nIdx );
910 rName = aTitle;
911 return sal_True;
913 else
915 DBG_ASSERT( sal_False, "CopyFrom(): The content should contain target URL!" );
918 else
920 DBG_ASSERT( sal_False, "CopyFrom(): The content just was created!" );
924 return sal_False;
927 //------------------------------------------------------------------------
929 sal_Bool SfxDocumentTemplates::Delete
931 sal_uInt16 nRegion, // Region Index
932 sal_uInt16 nIdx /* Index of the entry or USHRT_MAX,
933 if a directory is meant. */
936 /* [Description]
938 Deleting an entry or a directory
940 [Return value]
942 sal_Bool sal_True, Action could be performed
943 sal_False, Action could not be performed
945 [Cross-references]
947 <SfxDocumentTemplates::InsertDir(const String&,sal_uInt16)>
948 <SfxDocumentTemplates::KillDir(SfxTemplateDir&)>
952 DocTemplLocker_Impl aLocker( *pImp );
954 /* delete the template or folder in the hierarchy and in the
955 template folder by sending a delete command to the content.
956 Then remove the data from the lists
958 if ( ! pImp->Construct() )
959 return sal_False;
961 RegionData_Impl *pRegion = pImp->GetRegion( nRegion );
963 if ( !pRegion )
964 return sal_False;
966 sal_Bool bRet;
967 uno::Reference< XDocumentTemplates > xTemplates = pImp->getDocTemplates();
969 if ( nIdx == USHRT_MAX )
971 bRet = xTemplates->removeGroup( pRegion->GetTitle() );
972 if ( bRet )
973 pImp->DeleteRegion( nRegion );
975 else
977 DocTempl_EntryData_Impl *pEntry = pRegion->GetEntry( nIdx );
979 if ( !pEntry )
980 return sal_False;
982 bRet = xTemplates->removeTemplate( pRegion->GetTitle(),
983 pEntry->GetTitle() );
984 if( bRet )
985 pRegion->DeleteEntry( nIdx );
988 return bRet;
991 //------------------------------------------------------------------------
993 sal_Bool SfxDocumentTemplates::InsertDir
995 const String& rText, // the logical name of the new Region
996 sal_uInt16 nRegion // Region Index
999 /* [Description]
1001 Insert an index
1003 [Return value]
1005 sal_Bool sal_True, Action could be performed
1006 sal_False, Action could not be performed
1008 [Cross-references]
1010 <SfxDocumentTemplates::KillDir(SfxTemplateDir&)>
1013 DocTemplLocker_Impl aLocker( *pImp );
1015 if ( ! pImp->Construct() )
1016 return sal_False;
1018 RegionData_Impl *pRegion = pImp->GetRegion( rText );
1020 if ( pRegion )
1021 return sal_False;
1023 uno::Reference< XDocumentTemplates > xTemplates = pImp->getDocTemplates();
1025 if ( xTemplates->addGroup( rText ) )
1027 RegionData_Impl* pNewRegion = new RegionData_Impl( pImp, rText );
1029 if ( ! pImp->InsertRegion( pNewRegion, nRegion ) )
1031 delete pNewRegion;
1032 return sal_False;
1034 return sal_True;
1037 return sal_False;
1040 sal_Bool SfxDocumentTemplates::InsertTemplate(sal_uInt16 nSourceRegion, sal_uInt16 nIdx, const OUString &rName, const OUString &rPath)
1042 DocTemplLocker_Impl aLocker( *pImp );
1044 if ( ! pImp->Construct() )
1045 return sal_False;
1047 RegionData_Impl *pRegion = pImp->GetRegion( nSourceRegion );
1049 if ( !pRegion )
1050 return sal_False;
1052 size_t pos = nIdx;
1053 pRegion->AddEntry( rName, rPath, &pos );
1055 return sal_True;
1058 sal_Bool SfxDocumentTemplates::SetName( const OUString& rName, sal_uInt16 nRegion, sal_uInt16 nIdx )
1061 DocTemplLocker_Impl aLocker( *pImp );
1063 if ( ! pImp->Construct() )
1064 return sal_False;
1066 RegionData_Impl *pRegion = pImp->GetRegion( nRegion );
1068 if ( !pRegion )
1069 return sal_False;
1071 uno::Reference< XDocumentTemplates > xTemplates = pImp->getDocTemplates();
1072 OUString aEmpty;
1074 if ( nIdx == USHRT_MAX )
1076 if ( pRegion->GetTitle() == rName )
1077 return sal_True;
1079 // we have to rename a region
1080 if ( xTemplates->renameGroup( pRegion->GetTitle(), rName ) )
1082 pRegion->SetTitle( rName );
1083 pRegion->SetTargetURL( aEmpty );
1084 pRegion->SetHierarchyURL( aEmpty );
1085 return sal_True;
1088 else
1090 DocTempl_EntryData_Impl *pEntry = pRegion->GetEntry( nIdx );
1092 if ( !pEntry )
1093 return sal_False;
1095 if ( pEntry->GetTitle() == rName )
1096 return sal_True;
1098 if ( xTemplates->renameTemplate( pRegion->GetTitle(),
1099 pEntry->GetTitle(),
1100 rName ) )
1102 pEntry->SetTitle( rName );
1103 pEntry->SetTargetURL( aEmpty );
1104 pEntry->SetHierarchyURL( aEmpty );
1105 return sal_True;
1109 return sal_False;
1112 //------------------------------------------------------------------------
1114 sal_Bool SfxDocumentTemplates::GetFull
1116 const String &rRegion, // Region Name
1117 const String &rName, // Template Name
1118 String &rPath // Out: Path + File name
1121 /* [Description]
1123 Returns Path + File name of the template specified by rRegion and rName.
1125 [Return value]
1127 sal_Bool sal_True, Action could be performed
1128 sal_False, Action could not be performed
1130 [Cross-references]
1132 <SfxDocumentTemplates::GetLogicNames(const String&,String&,String&)>
1136 DocTemplLocker_Impl aLocker( *pImp );
1138 // We don't search for empty names!
1139 if ( ! rName.Len() )
1140 return sal_False;
1142 if ( ! pImp->Construct() )
1143 return sal_False;
1145 DocTempl_EntryData_Impl* pEntry = NULL;
1146 const sal_uInt16 nCount = GetRegionCount();
1148 for ( sal_uInt16 i = 0; i < nCount; ++i )
1150 RegionData_Impl *pRegion = pImp->GetRegion( i );
1152 if( pRegion &&
1153 ( !rRegion.Len() || ( rRegion == String( pRegion->GetTitle() ) ) ) )
1155 pEntry = pRegion->GetEntry( rName );
1157 if ( pEntry )
1159 rPath = pEntry->GetTargetURL();
1160 break;
1165 return ( pEntry != NULL );
1168 //------------------------------------------------------------------------
1170 sal_Bool SfxDocumentTemplates::GetLogicNames
1172 const String &rPath, // Full Path to the template
1173 String &rRegion, // Out: Region name
1174 String &rName // Out: Template name
1175 ) const
1177 /* [Description]
1179 Returns and logical path name to the template specified by rPath
1181 [Return value]
1183 sal_Bool sal_True, Action could be performed
1184 sal_False, Action could not be performed
1186 [Cross-references]
1188 <SfxDocumentTemplates::GetFull(const String&,const String&,DirEntry&)>
1192 DocTemplLocker_Impl aLocker( *pImp );
1194 if ( ! pImp->Construct() )
1195 return sal_False;
1197 INetURLObject aFullPath;
1199 aFullPath.SetSmartProtocol( INET_PROT_FILE );
1200 aFullPath.SetURL( rPath );
1201 OUString aPath( aFullPath.GetMainURL( INetURLObject::NO_DECODE ) );
1203 RegionData_Impl *pData = NULL;
1204 DocTempl_EntryData_Impl *pEntry = NULL;
1205 sal_Bool bFound = sal_False;
1207 sal_uIntPtr nCount = GetRegionCount();
1209 for ( sal_uIntPtr i=0; !bFound && (i<nCount); i++ )
1211 pData = pImp->GetRegion( i );
1212 if ( pData )
1214 sal_uIntPtr nChildCount = pData->GetCount();
1216 for ( sal_uIntPtr j=0; !bFound && (j<nChildCount); j++ )
1218 pEntry = pData->GetEntry( j );
1219 if ( pEntry->GetTargetURL() == aPath )
1221 bFound = sal_True;
1227 if ( bFound )
1229 rRegion = pData->GetTitle();
1230 rName = pEntry->GetTitle();
1233 return bFound;
1236 //------------------------------------------------------------------------
1238 SfxDocumentTemplates::SfxDocumentTemplates()
1240 /* [Description]
1242 Constructor
1245 if ( !gpTemplateData )
1246 gpTemplateData = new SfxDocTemplate_Impl;
1248 pImp = gpTemplateData;
1251 //-------------------------------------------------------------------------
1253 void SfxDocumentTemplates::Construct()
1255 // Delayed build-up of administrative data
1260 //------------------------------------------------------------------------
1262 SfxDocumentTemplates::~SfxDocumentTemplates()
1264 /* [Description]
1266 Destructor
1267 Release of administrative data
1271 pImp = NULL;
1274 void SfxDocumentTemplates::Update( sal_Bool _bSmart )
1276 if ( !_bSmart // don't be smart
1277 || ::svt::TemplateFolderCache( sal_True ).needsUpdate() // update is really necessary
1280 if ( pImp->Construct() )
1281 pImp->Rescan();
1285 void SfxDocumentTemplates::ReInitFromComponent()
1287 pImp->ReInitFromComponent();
1290 // -----------------------------------------------------------------------
1291 DocTempl_EntryData_Impl::DocTempl_EntryData_Impl( RegionData_Impl* pParent,
1292 const OUString& rTitle )
1294 mpParent = pParent;
1295 maTitle = SfxDocumentTemplates::ConvertResourceString(
1296 STR_TEMPLATE_NAME1_DEF, STR_TEMPLATE_NAME1, NUM_TEMPLATE_NAMES, rTitle );
1297 mbIsOwner = sal_False;
1298 mbDidConvert= sal_False;
1301 // -----------------------------------------------------------------------
1302 int DocTempl_EntryData_Impl::Compare( const OUString& rTitle ) const
1304 return maTitle.compareTo( rTitle );
1307 // -----------------------------------------------------------------------
1308 const OUString& DocTempl_EntryData_Impl::GetHierarchyURL()
1310 if ( maOwnURL.isEmpty() )
1312 INetURLObject aTemplateObj( GetParent()->GetHierarchyURL() );
1314 aTemplateObj.insertName( GetTitle(), false,
1315 INetURLObject::LAST_SEGMENT, true,
1316 INetURLObject::ENCODE_ALL );
1318 maOwnURL = aTemplateObj.GetMainURL( INetURLObject::NO_DECODE );
1319 DBG_ASSERT( !maOwnURL.isEmpty(), "GetHierarchyURL(): Could not create URL!" );
1322 return maOwnURL;
1325 // -----------------------------------------------------------------------
1326 const OUString& DocTempl_EntryData_Impl::GetTargetURL()
1328 if ( maTargetURL.isEmpty() )
1330 uno::Reference< XCommandEnvironment > aCmdEnv;
1331 Content aRegion;
1333 if ( Content::create( GetHierarchyURL(), aCmdEnv, comphelper::getProcessComponentContext(), aRegion ) )
1335 OUString aPropName( TARGET_URL );
1337 getTextProperty_Impl( aRegion, aPropName, maTargetURL );
1339 else
1341 SAL_WARN( "sfx2.doc", "GetTargetURL(): Could not create hierarchy content!" );
1345 return maTargetURL;
1348 // -----------------------------------------------------------------------
1349 RegionData_Impl::RegionData_Impl( const SfxDocTemplate_Impl* pParent,
1350 const OUString& rTitle )
1352 maTitle = rTitle;
1353 mpParent = pParent;
1356 // -----------------------------------------------------------------------
1357 RegionData_Impl::~RegionData_Impl()
1359 for ( size_t i = 0, n = maEntries.size(); i < n; ++i )
1360 delete maEntries[ i ];
1361 maEntries.clear();
1364 // -----------------------------------------------------------------------
1365 size_t RegionData_Impl::GetEntryPos( const OUString& rTitle, sal_Bool& rFound ) const
1367 #if 1 // Don't use binary search today
1368 size_t i;
1369 size_t nCount = maEntries.size();
1371 for ( i=0; i<nCount; i++ )
1373 DocTempl_EntryData_Impl *pData = maEntries[ i ];
1375 if ( pData->Compare( rTitle ) == 0 )
1377 rFound = sal_True;
1378 return i;
1382 rFound = sal_False;
1383 return i;
1385 #else
1386 // use binary search to find the correct position
1387 // in the maEntries list
1389 int nCompVal = 1;
1390 size_t nStart = 0;
1391 size_t nEnd = maEntries.size() - 1;
1392 size_t nMid;
1394 DocTempl_EntryData_Impl* pMid;
1396 rFound = sal_False;
1398 while ( nCompVal && ( nStart <= nEnd ) )
1400 nMid = ( nEnd - nStart ) / 2 + nStart;
1401 pMid = maEntries[ nMid ];
1403 nCompVal = pMid->Compare( rTitle );
1405 if ( nCompVal < 0 ) // pMid < pData
1406 nStart = nMid + 1;
1407 else
1408 nEnd = nMid - 1;
1411 if ( nCompVal == 0 )
1413 rFound = sal_True;
1415 else
1417 if ( nCompVal < 0 ) // pMid < pData
1418 nMid++;
1421 return nMid;
1422 #endif
1425 // -----------------------------------------------------------------------
1426 void RegionData_Impl::AddEntry( const OUString& rTitle,
1427 const OUString& rTargetURL,
1428 size_t *pPos )
1430 INetURLObject aLinkObj( GetHierarchyURL() );
1431 aLinkObj.insertName( rTitle, false,
1432 INetURLObject::LAST_SEGMENT, true,
1433 INetURLObject::ENCODE_ALL );
1434 OUString aLinkURL = aLinkObj.GetMainURL( INetURLObject::NO_DECODE );
1436 DocTempl_EntryData_Impl* pEntry;
1437 sal_Bool bFound = sal_False;
1438 size_t nPos = GetEntryPos( rTitle, bFound );
1440 if ( bFound )
1442 pEntry = maEntries[ nPos ];
1444 else
1446 if ( pPos )
1447 nPos = *pPos;
1449 pEntry = new DocTempl_EntryData_Impl( this, rTitle );
1450 pEntry->SetTargetURL( rTargetURL );
1451 pEntry->SetHierarchyURL( aLinkURL );
1452 if ( nPos < maEntries.size() ) {
1453 vector< DocTempl_EntryData_Impl* >::iterator it = maEntries.begin();
1454 advance( it, nPos );
1455 maEntries.insert( it, pEntry );
1457 else
1458 maEntries.push_back( pEntry );
1462 // -----------------------------------------------------------------------
1463 size_t RegionData_Impl::GetCount() const
1465 return maEntries.size();
1468 // -----------------------------------------------------------------------
1469 const OUString& RegionData_Impl::GetHierarchyURL()
1471 if ( maOwnURL.isEmpty() )
1473 INetURLObject aRegionObj( GetParent()->GetRootURL() );
1475 aRegionObj.insertName( GetTitle(), false,
1476 INetURLObject::LAST_SEGMENT, true,
1477 INetURLObject::ENCODE_ALL );
1479 maOwnURL = aRegionObj.GetMainURL( INetURLObject::NO_DECODE );
1480 DBG_ASSERT( !maOwnURL.isEmpty(), "GetHierarchyURL(): Could not create URL!" );
1483 return maOwnURL;
1486 // -----------------------------------------------------------------------
1487 DocTempl_EntryData_Impl* RegionData_Impl::GetEntry( const OUString& rName ) const
1489 sal_Bool bFound = sal_False;
1490 long nPos = GetEntryPos( rName, bFound );
1492 if ( bFound )
1493 return maEntries[ nPos ];
1494 else
1495 return NULL;
1498 // -----------------------------------------------------------------------
1499 DocTempl_EntryData_Impl* RegionData_Impl::GetEntry( size_t nIndex ) const
1501 if ( nIndex < maEntries.size() )
1502 return maEntries[ nIndex ];
1503 return NULL;
1506 // -----------------------------------------------------------------------
1507 void RegionData_Impl::DeleteEntry( size_t nIndex )
1509 if ( nIndex < maEntries.size() )
1511 delete maEntries[ nIndex ];
1512 vector< DocTempl_EntryData_Impl*>::iterator it = maEntries.begin();
1513 advance( it, nIndex );
1514 maEntries.erase( it );
1518 // -----------------------------------------------------------------------
1519 int RegionData_Impl::Compare( RegionData_Impl* pCompare ) const
1521 int nCompare = maTitle.compareTo( pCompare->maTitle );
1523 return nCompare;
1526 // -----------------------------------------------------------------------
1528 SfxDocTemplate_Impl::SfxDocTemplate_Impl()
1529 : mbConstructed( sal_False )
1530 , mnLockCounter( 0 )
1534 // -----------------------------------------------------------------------
1535 SfxDocTemplate_Impl::~SfxDocTemplate_Impl()
1537 Clear();
1539 gpTemplateData = NULL;
1542 // -----------------------------------------------------------------------
1543 void SfxDocTemplate_Impl::IncrementLock()
1545 ::osl::MutexGuard aGuard( maMutex );
1546 mnLockCounter++;
1549 // -----------------------------------------------------------------------
1550 void SfxDocTemplate_Impl::DecrementLock()
1552 ::osl::MutexGuard aGuard( maMutex );
1553 if ( mnLockCounter )
1554 mnLockCounter--;
1557 // -----------------------------------------------------------------------
1558 RegionData_Impl* SfxDocTemplate_Impl::GetRegion( size_t nIndex ) const
1560 if ( nIndex < maRegions.size() )
1561 return maRegions[ nIndex ];
1562 return NULL;
1565 // -----------------------------------------------------------------------
1566 RegionData_Impl* SfxDocTemplate_Impl::GetRegion( const OUString& rName )
1567 const
1569 for ( size_t i = 0, n = maRegions.size(); i < n; ++i )
1571 RegionData_Impl* pData = maRegions[ i ];
1572 if( pData->GetTitle() == rName )
1573 return pData;
1575 return NULL;
1578 // -----------------------------------------------------------------------
1579 void SfxDocTemplate_Impl::DeleteRegion( size_t nIndex )
1581 if ( nIndex < maRegions.size() )
1583 delete maRegions[ nIndex ];
1584 RegionList_Impl::iterator it = maRegions.begin();
1585 advance( it, nIndex );
1586 maRegions.erase( it );
1590 // -----------------------------------------------------------------------
1591 /* AddRegion adds a Region to the RegionList
1593 void SfxDocTemplate_Impl::AddRegion( const OUString& rTitle,
1594 Content& rContent )
1596 RegionData_Impl* pRegion;
1597 pRegion = new RegionData_Impl( this, rTitle );
1599 if ( ! InsertRegion( pRegion ) )
1601 delete pRegion;
1602 return;
1605 // now get the content of the region
1606 uno::Reference< XResultSet > xResultSet;
1607 Sequence< OUString > aProps(2);
1608 aProps[0] = OUString(TITLE );
1609 aProps[1] = OUString(TARGET_URL );
1613 ResultSetInclude eInclude = INCLUDE_DOCUMENTS_ONLY;
1614 Sequence< NumberedSortingInfo > aSortingInfo(1);
1615 aSortingInfo.getArray()->ColumnIndex = 1;
1616 aSortingInfo.getArray()->Ascending = sal_True;
1617 xResultSet = rContent.createSortedCursor( aProps, aSortingInfo, m_rCompareFactory, eInclude );
1619 catch ( Exception& ) {}
1621 if ( xResultSet.is() )
1623 uno::Reference< XContentAccess > xContentAccess( xResultSet, UNO_QUERY );
1624 uno::Reference< XRow > xRow( xResultSet, UNO_QUERY );
1628 while ( xResultSet->next() )
1630 OUString aTitle( xRow->getString( 1 ) );
1631 OUString aTargetDir( xRow->getString( 2 ) );
1633 pRegion->AddEntry( aTitle, aTargetDir );
1636 catch ( Exception& ) {}
1640 // -----------------------------------------------------------------------
1641 void SfxDocTemplate_Impl::CreateFromHierarchy( Content &rTemplRoot )
1643 uno::Reference< XResultSet > xResultSet;
1644 Sequence< OUString > aProps(1);
1645 aProps[0] = OUString(TITLE );
1649 ResultSetInclude eInclude = INCLUDE_FOLDERS_ONLY;
1650 Sequence< NumberedSortingInfo > aSortingInfo(1);
1651 aSortingInfo.getArray()->ColumnIndex = 1;
1652 aSortingInfo.getArray()->Ascending = sal_True;
1653 xResultSet = rTemplRoot.createSortedCursor( aProps, aSortingInfo, m_rCompareFactory, eInclude );
1655 catch ( Exception& ) {}
1657 if ( xResultSet.is() )
1659 uno::Reference< XCommandEnvironment > aCmdEnv;
1660 uno::Reference< XContentAccess > xContentAccess( xResultSet, UNO_QUERY );
1661 uno::Reference< XRow > xRow( xResultSet, UNO_QUERY );
1665 while ( xResultSet->next() )
1667 OUString aTitle( xRow->getString( 1 ) );
1669 OUString aId = xContentAccess->queryContentIdentifierString();
1670 Content aContent = Content( aId, aCmdEnv, comphelper::getProcessComponentContext() );
1672 AddRegion( aTitle, aContent );
1675 catch ( Exception& ) {}
1679 // ------------------------------------------------------------------------
1680 sal_Bool SfxDocTemplate_Impl::Construct( )
1682 ::osl::MutexGuard aGuard( maMutex );
1684 if ( mbConstructed )
1685 return sal_True;
1687 uno::Reference< XComponentContext > xContext = ::comphelper::getProcessComponentContext();
1689 uno::Reference< XPersist > xInfo( document::DocumentProperties::create(xContext), UNO_QUERY );
1690 mxInfo = xInfo;
1692 mxTemplates = frame::DocumentTemplates::create(xContext);
1694 uno::Reference< XLocalizable > xLocalizable( mxTemplates, UNO_QUERY );
1696 m_rCompareFactory = AnyCompareFactory::createWithLocale(xContext, xLocalizable->getLocale());
1698 uno::Reference < XContent > aRootContent = mxTemplates->getContent();
1699 uno::Reference < XCommandEnvironment > aCmdEnv;
1701 if ( ! aRootContent.is() )
1702 return sal_False;
1704 mbConstructed = sal_True;
1705 maRootURL = aRootContent->getIdentifier()->getContentIdentifier();
1707 ResStringArray aLongNames( SfxResId( TEMPLATE_LONG_NAMES_ARY ) );
1709 if ( aLongNames.Count() )
1710 maStandardGroup = aLongNames.GetString( 0 );
1712 Content aTemplRoot( aRootContent, aCmdEnv, xContext );
1713 CreateFromHierarchy( aTemplRoot );
1715 return sal_True;
1718 // -----------------------------------------------------------------------
1719 void SfxDocTemplate_Impl::ReInitFromComponent()
1721 uno::Reference< XDocumentTemplates > xTemplates = getDocTemplates();
1722 if ( xTemplates.is() )
1724 uno::Reference < XContent > aRootContent = xTemplates->getContent();
1725 uno::Reference < XCommandEnvironment > aCmdEnv;
1726 Content aTemplRoot( aRootContent, aCmdEnv, comphelper::getProcessComponentContext() );
1727 Clear();
1728 CreateFromHierarchy( aTemplRoot );
1732 // -----------------------------------------------------------------------
1733 sal_Bool SfxDocTemplate_Impl::InsertRegion( RegionData_Impl *pNew, size_t nPos )
1735 ::osl::MutexGuard aGuard( maMutex );
1737 // return false (not inserted) if the entry already exists
1738 for ( size_t i = 0, n = maRegions.size(); i < n; ++i )
1739 if ( maRegions[ i ]->Compare( pNew ) == 0 )
1740 return sal_False;
1742 size_t newPos = nPos;
1743 if ( pNew->GetTitle() == maStandardGroup )
1744 newPos = 0;
1746 if ( newPos < maRegions.size() )
1748 RegionList_Impl::iterator it = maRegions.begin();
1749 advance( it, newPos );
1750 maRegions.insert( it, pNew );
1752 else
1753 maRegions.push_back( pNew );
1755 return sal_True;
1758 // -----------------------------------------------------------------------
1759 void SfxDocTemplate_Impl::Rescan()
1761 Clear();
1765 uno::Reference< XDocumentTemplates > xTemplates = getDocTemplates();
1766 DBG_ASSERT( xTemplates.is(), "SfxDocTemplate_Impl::Rescan:invalid template instance!" );
1767 if ( xTemplates.is() )
1769 xTemplates->update();
1771 uno::Reference < XContent > aRootContent = xTemplates->getContent();
1772 uno::Reference < XCommandEnvironment > aCmdEnv;
1774 Content aTemplRoot( aRootContent, aCmdEnv, comphelper::getProcessComponentContext() );
1775 CreateFromHierarchy( aTemplRoot );
1778 catch( const Exception& )
1780 SAL_WARN( "sfx2.doc", "SfxDocTemplate_Impl::Rescan: caught an exception while doing the update!" );
1784 // -----------------------------------------------------------------------
1785 sal_Bool SfxDocTemplate_Impl::GetTitleFromURL( const OUString& rURL,
1786 OUString& aTitle )
1788 if ( mxInfo.is() )
1792 mxInfo->read( rURL );
1794 catch ( Exception& )
1796 // the document is not a StarOffice document
1797 return sal_False;
1803 uno::Reference< XPropertySet > aPropSet( mxInfo, UNO_QUERY );
1804 if ( aPropSet.is() )
1806 OUString aPropName( TITLE );
1807 Any aValue = aPropSet->getPropertyValue( aPropName );
1808 aValue >>= aTitle;
1811 catch ( IOException& ) {}
1812 catch ( UnknownPropertyException& ) {}
1813 catch ( Exception& ) {}
1816 if ( aTitle.isEmpty() )
1818 INetURLObject aURL( rURL );
1819 aURL.CutExtension();
1820 aTitle = aURL.getName( INetURLObject::LAST_SEGMENT, true,
1821 INetURLObject::DECODE_WITH_CHARSET );
1824 return sal_True;
1828 // -----------------------------------------------------------------------
1829 void SfxDocTemplate_Impl::Clear()
1831 ::osl::MutexGuard aGuard( maMutex );
1832 if ( mnLockCounter )
1833 return;
1835 for ( size_t i = 0, n = maRegions.size(); i < n; ++i )
1836 delete maRegions[ i ];
1837 maRegions.clear();
1840 // -----------------------------------------------------------------------
1841 sal_Bool getTextProperty_Impl( Content& rContent,
1842 const OUString& rPropName,
1843 OUString& rPropValue )
1845 sal_Bool bGotProperty = sal_False;
1847 // Get the property
1850 uno::Reference< XPropertySetInfo > aPropInfo = rContent.getProperties();
1852 // check, whether or not the property exists
1853 if ( !aPropInfo.is() || !aPropInfo->hasPropertyByName( rPropName ) )
1855 return sal_False;
1858 // now get the property
1859 Any aAnyValue;
1861 aAnyValue = rContent.getPropertyValue( rPropName );
1862 aAnyValue >>= rPropValue;
1864 if ( SfxURLRelocator_Impl::propertyCanContainOfficeDir( rPropName ) )
1866 SfxURLRelocator_Impl aRelocImpl( ::comphelper::getProcessComponentContext() );
1867 aRelocImpl.makeAbsoluteURL( rPropValue );
1870 bGotProperty = sal_True;
1872 catch ( RuntimeException& ) {}
1873 catch ( Exception& ) {}
1875 return bGotProperty;
1878 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */