Bump version to 4.2-24
[LibreOffice.git] / sfx2 / source / doc / doctempl.cxx
blobdd8f8afe562f11f2cee4b3e09cf6c87f90829fe7
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/urlobj.hxx>
32 #include <svtools/ehdl.hxx>
33 #include <svtools/sfxecode.hxx>
34 #include <comphelper/processfactory.hxx>
35 #include <ucbhelper/content.hxx>
36 #include <com/sun/star/beans/PropertyAttribute.hpp>
37 #include <com/sun/star/beans/PropertyValue.hpp>
38 #include <com/sun/star/beans/XPropertyContainer.hpp>
39 #include <com/sun/star/beans/XPropertySet.hpp>
40 #include <com/sun/star/beans/XPropertySetInfo.hpp>
41 #include <com/sun/star/document/XTypeDetection.hpp>
42 #include <com/sun/star/document/DocumentProperties.hpp>
43 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
44 #include <com/sun/star/frame/Desktop.hpp>
45 #include <com/sun/star/frame/XComponentLoader.hpp>
46 #include <com/sun/star/frame/DocumentTemplates.hpp>
47 #include <com/sun/star/frame/XDocumentTemplates.hpp>
48 #include <com/sun/star/io/XInputStream.hpp>
49 #include <com/sun/star/io/XPersist.hpp>
50 #include <com/sun/star/lang/XLocalizable.hpp>
51 #include <com/sun/star/sdbc/XResultSet.hpp>
52 #include <com/sun/star/sdbc/XRow.hpp>
53 #include <com/sun/star/ucb/ContentInfo.hpp>
54 #include <com/sun/star/ucb/InsertCommandArgument.hpp>
55 #include <com/sun/star/ucb/NameClash.hpp>
56 #include <com/sun/star/ucb/TransferInfo.hpp>
57 #include <com/sun/star/ucb/XCommandProcessor.hpp>
58 #include <com/sun/star/ucb/XContent.hpp>
59 #include <com/sun/star/ucb/XContentAccess.hpp>
60 #include <com/sun/star/ucb/AnyCompareFactory.hpp>
61 #include <com/sun/star/ucb/XAnyCompare.hpp>
62 #include <com/sun/star/ucb/NumberedSortingInfo.hpp>
63 #include <com/sun/star/embed/ElementModes.hpp>
64 #include <com/sun/star/embed/XTransactedObject.hpp>
66 #include "sfxurlrelocator.hxx"
68 using namespace ::com::sun::star;
69 using namespace ::com::sun::star::beans;
70 using namespace ::com::sun::star::frame;
71 using namespace ::com::sun::star::io;
72 using namespace ::com::sun::star::lang;
73 using namespace ::com::sun::star::sdbc;
74 using namespace ::com::sun::star::uno;
75 using namespace ::com::sun::star::ucb;
76 using namespace ::com::sun::star::document;
77 using namespace ::rtl;
78 using namespace ::ucbhelper;
81 #include <sfx2/doctempl.hxx>
82 #include <sfx2/docfac.hxx>
83 #include <sfx2/docfile.hxx>
84 #include <sfx2/objsh.hxx>
85 #include "sfxtypes.hxx"
86 #include <sfx2/app.hxx>
87 #include <sfx2/sfxresid.hxx>
88 #include <sfx2/templatelocnames.hrc>
89 #include "doc.hrc"
90 #include <sfx2/fcontnr.hxx>
91 #include <svtools/templatefoldercache.hxx>
93 #include <comphelper/storagehelper.hxx>
94 #include <unotools/ucbhelper.hxx>
96 #include <vector>
97 using ::std::vector;
98 using ::std::advance;
100 //========================================================================
102 #define TITLE "Title"
103 #define TARGET_URL "TargetURL"
105 #define COMMAND_TRANSFER "transfer"
107 //========================================================================
109 class RegionData_Impl;
111 namespace DocTempl {
113 class DocTempl_EntryData_Impl
115 RegionData_Impl* mpParent;
117 // the following member must be SfxObjectShellLock since it controlls that SfxObjectShell lifetime by design
118 // and users of this class expect it to be so.
119 SfxObjectShellLock mxObjShell;
121 OUString maTitle;
122 OUString maOwnURL;
123 OUString maTargetURL;
124 sal_Bool mbIsOwner : 1;
125 sal_Bool mbDidConvert: 1;
127 private:
128 RegionData_Impl* GetParent() const { return mpParent; }
130 public:
131 DocTempl_EntryData_Impl( RegionData_Impl* pParent,
132 const OUString& rTitle );
134 const OUString& GetTitle() const { return maTitle; }
135 const OUString& GetTargetURL();
136 const OUString& GetHierarchyURL();
138 void SetTitle( const OUString& rTitle ) { maTitle = rTitle; }
139 void SetTargetURL( const OUString& rURL ) { maTargetURL = rURL; }
140 void SetHierarchyURL( const OUString& rURL) { maOwnURL = rURL; }
142 int Compare( const OUString& rTitle ) const;
147 using namespace ::DocTempl;
149 // ------------------------------------------------------------------------
151 class RegionData_Impl
153 const SfxDocTemplate_Impl* mpParent;
154 vector< DocTempl_EntryData_Impl* > maEntries;
155 OUString maTitle;
156 OUString maOwnURL;
157 OUString maTargetURL;
159 private:
160 size_t GetEntryPos( const OUString& rTitle,
161 sal_Bool& rFound ) const;
162 const SfxDocTemplate_Impl* GetParent() const { return mpParent; }
164 public:
165 RegionData_Impl( const SfxDocTemplate_Impl* pParent,
166 const OUString& rTitle );
167 ~RegionData_Impl();
169 void SetTargetURL( const OUString& rURL ) { maTargetURL = rURL; }
170 void SetHierarchyURL( const OUString& rURL) { maOwnURL = rURL; }
172 DocTempl_EntryData_Impl* GetEntry( size_t nIndex ) const;
173 DocTempl_EntryData_Impl* GetEntry( const OUString& rName ) const;
175 const OUString& GetTitle() const { return maTitle; }
176 const OUString& GetHierarchyURL();
178 size_t GetCount() const;
180 void SetTitle( const OUString& rTitle ) { maTitle = rTitle; }
182 void AddEntry( const OUString& rTitle,
183 const OUString& rTargetURL,
184 size_t *pPos = NULL );
185 void DeleteEntry( size_t nIndex );
187 int Compare( const OUString& rTitle ) const
188 { return maTitle.compareTo( rTitle ); }
189 int Compare( RegionData_Impl* pCompareWith ) const;
192 typedef vector< RegionData_Impl* > RegionList_Impl;
194 // ------------------------------------------------------------------------
196 class SfxDocTemplate_Impl : public SvRefBase
198 uno::Reference< XPersist > mxInfo;
199 uno::Reference< XDocumentTemplates > mxTemplates;
201 ::osl::Mutex maMutex;
202 OUString maRootURL;
203 OUString maStandardGroup;
204 RegionList_Impl maRegions;
205 sal_Bool mbConstructed;
207 uno::Reference< XAnyCompareFactory > m_rCompareFactory;
209 // the following member is intended to prevent clearing of the global data when it is in use
210 // TODO/LATER: it still does not make the implementation complete thread-safe
211 sal_Int32 mnLockCounter;
213 private:
214 void Clear();
216 public:
217 SfxDocTemplate_Impl();
218 ~SfxDocTemplate_Impl();
220 void IncrementLock();
221 void DecrementLock();
223 sal_Bool Construct( );
224 void CreateFromHierarchy( Content &rTemplRoot );
225 void ReInitFromComponent();
226 void AddRegion( const OUString& rTitle,
227 Content& rContent );
229 void Rescan();
231 void DeleteRegion( size_t nIndex );
233 size_t GetRegionCount() const
234 { return maRegions.size(); }
235 RegionData_Impl* GetRegion( const OUString& rName ) const;
236 RegionData_Impl* GetRegion( size_t nIndex ) const;
238 sal_Bool GetTitleFromURL( const OUString& rURL, OUString& aTitle );
239 sal_Bool InsertRegion( RegionData_Impl *pData, size_t nPos = size_t(-1) );
240 OUString GetRootURL() const { return maRootURL; }
242 uno::Reference< XDocumentTemplates > getDocTemplates() { return mxTemplates; }
245 // ------------------------------------------------------------------------
247 class DocTemplLocker_Impl
249 SfxDocTemplate_Impl& m_aDocTempl;
250 public:
251 DocTemplLocker_Impl( SfxDocTemplate_Impl& aDocTempl )
252 : m_aDocTempl( aDocTempl )
254 m_aDocTempl.IncrementLock();
257 ~DocTemplLocker_Impl()
259 m_aDocTempl.DecrementLock();
263 // ------------------------------------------------------------------------
265 #ifndef SFX_DECL_DOCTEMPLATES_DEFINED
266 #define SFX_DECL_DOCTEMPLATES_DEFINED
267 SV_DECL_REF(SfxDocTemplate_Impl)
268 #endif
270 SV_IMPL_REF(SfxDocTemplate_Impl)
272 // ------------------------------------------------------------------------
274 SfxDocTemplate_Impl *gpTemplateData = 0;
276 // -----------------------------------------------------------------------
278 static sal_Bool getTextProperty_Impl( Content& rContent,
279 const OUString& rPropName,
280 OUString& rPropValue );
282 //========================================================================
284 OUString SfxDocumentTemplates::GetFullRegionName
286 sal_uInt16 nIdx // Region Index
287 ) const
289 /* [Description]
291 Returns the logical name of a region and its path
293 [Return value] Reference to the Region name
298 // First: find the RegionData for the index
299 OUString aName;
301 DocTemplLocker_Impl aLocker( *pImp );
303 if ( pImp->Construct() )
305 RegionData_Impl *pData1 = pImp->GetRegion( nIdx );
307 if ( pData1 )
308 aName = pData1->GetTitle();
310 // --**-- here was some code which appended the path to the
311 // group if there was more than one with the same name.
312 // this should not happen anymore
315 return aName;
318 //------------------------------------------------------------------------
320 const OUString& SfxDocumentTemplates::GetRegionName
322 sal_uInt16 nIdx // Region Index
323 ) const
325 /* [Description]
327 Returns the logical name of a region
329 [Return value]
331 const String& Reference to the Region name
335 static OUString maTmpString;
337 DocTemplLocker_Impl aLocker( *pImp );
339 if ( pImp->Construct() )
341 RegionData_Impl *pData = pImp->GetRegion( nIdx );
343 if ( pData )
344 maTmpString = pData->GetTitle();
345 else
346 maTmpString = "";
348 else
349 maTmpString = "";
351 return maTmpString;
354 //------------------------------------------------------------------------
356 sal_uInt16 SfxDocumentTemplates::GetRegionCount() const
358 /* [Description]
360 Returns the number of Regions
362 [Return value]
364 sal_uInt16 Number of Regions
367 DocTemplLocker_Impl aLocker( *pImp );
369 if ( !pImp->Construct() )
370 return 0;
372 sal_uIntPtr nCount = pImp->GetRegionCount();
374 return (sal_uInt16) nCount;
377 //------------------------------------------------------------------------
379 sal_uInt16 SfxDocumentTemplates::GetCount
381 sal_uInt16 nRegion /* Region index whose number is
382 to be determined */
384 ) const
386 /* [Description]
388 Number of entries in Region
390 [Return value] Number of entries
394 DocTemplLocker_Impl aLocker( *pImp );
396 if ( !pImp->Construct() )
397 return 0;
399 RegionData_Impl *pData = pImp->GetRegion( nRegion );
400 sal_uIntPtr nCount = 0;
402 if ( pData )
403 nCount = pData->GetCount();
405 return (sal_uInt16) nCount;
408 //------------------------------------------------------------------------
410 const OUString& SfxDocumentTemplates::GetName
412 sal_uInt16 nRegion, // Region Index, in which the entry lies
413 sal_uInt16 nIdx // Index of the entry
414 ) const
416 /* [Description]
418 Returns the logical name of an entry in Region
420 [Return value]
422 const String& Entry Name
426 DocTemplLocker_Impl aLocker( *pImp );
428 static OUString maTmpString;
430 if ( pImp->Construct() )
432 DocTempl_EntryData_Impl *pEntry = NULL;
433 RegionData_Impl *pRegion = pImp->GetRegion( nRegion );
435 if ( pRegion )
436 pEntry = pRegion->GetEntry( nIdx );
438 if ( pEntry )
439 maTmpString = pEntry->GetTitle();
440 else
441 maTmpString = "";
443 else
444 maTmpString = "";
446 return maTmpString;
449 //------------------------------------------------------------------------
451 OUString SfxDocumentTemplates::GetPath
453 sal_uInt16 nRegion, // Region Index, in which the entry lies
454 sal_uInt16 nIdx // Index of the entry
455 ) const
457 /* [Description]
459 Returns the file name with full path to the file assigned to an entry
461 [Return value]
463 String File name with full path
466 DocTemplLocker_Impl aLocker( *pImp );
468 if ( !pImp->Construct() )
469 return OUString();
471 DocTempl_EntryData_Impl *pEntry = NULL;
472 RegionData_Impl *pRegion = pImp->GetRegion( nRegion );
474 if ( pRegion )
475 pEntry = pRegion->GetEntry( nIdx );
477 if ( pEntry )
478 return pEntry->GetTargetURL();
479 else
480 return OUString();
483 //------------------------------------------------------------------------
485 OUString SfxDocumentTemplates::GetTemplateTargetURLFromComponent( const OUString& aGroupName,
486 const OUString& aTitle )
488 DocTemplLocker_Impl aLocker( *pImp );
490 INetURLObject aTemplateObj( pImp->GetRootURL() );
492 aTemplateObj.insertName( aGroupName, false,
493 INetURLObject::LAST_SEGMENT, true,
494 INetURLObject::ENCODE_ALL );
496 aTemplateObj.insertName( aTitle, false,
497 INetURLObject::LAST_SEGMENT, true,
498 INetURLObject::ENCODE_ALL );
501 OUString aResult;
502 Content aTemplate;
503 uno::Reference< XCommandEnvironment > aCmdEnv;
504 if ( Content::create( aTemplateObj.GetMainURL( INetURLObject::NO_DECODE ), aCmdEnv, comphelper::getProcessComponentContext(), aTemplate ) )
506 OUString aPropName( TARGET_URL );
507 getTextProperty_Impl( aTemplate, aPropName, aResult );
508 aResult = SvtPathOptions().SubstituteVariable( aResult );
511 return aResult;
514 //------------------------------------------------------------------------
516 /** Convert a resource string - a template name - to its localised pair if it exists.
517 @param nSourceResIds
518 Resource ID where the list of original en-US template names begin.
519 @param nDestResIds
520 Resource ID where the list of localised template names begin.
521 @param nCount
522 The number of names that have been localised.
523 @param rString
524 Name to be translated.
525 @return
526 The localised pair of rString or rString if the former does not exist.
528 OUString SfxDocumentTemplates::ConvertResourceString (
529 int nSourceResIds, int nDestResIds, int nCount, const OUString& rString )
531 for( int i = 0; i < nCount; ++i )
533 if( rString == SFX2_RESSTR(nSourceResIds + i))
534 return SFX2_RESSTR(nDestResIds + i);
536 return rString;
539 //------------------------------------------------------------------------
541 sal_Bool SfxDocumentTemplates::CopyOrMove
543 sal_uInt16 nTargetRegion, // Target Region Index
544 sal_uInt16 nTargetIdx, // Target position Index
545 sal_uInt16 nSourceRegion, // Source Region Index
546 sal_uInt16 nSourceIdx, /* Index to be copied / to moved template */
547 sal_Bool bMove // Copy / Move
550 /* [Description]
552 Copy or move a document template
554 [Return value]
556 sal_Bool sal_True, Action could be performed
557 sal_False, Action could not be performed
559 [Cross-references]
561 <SfxDocumentTemplates::Move(sal_uInt16,sal_uInt16,sal_uInt16,sal_uInt16)>
562 <SfxDocumentTemplates::Copy(sal_uInt16,sal_uInt16,sal_uInt16,sal_uInt16)>
566 /* to perform a copy or move, we need to send a transfer command to
567 the destination folder with the URL of the source as parameter.
568 ( If the destination content doesn't support the transfer command,
569 we could try a copy ( and delete ) instead. )
570 We need two transfers ( one for the real template and one for its
571 representation in the hierarchy )
575 DocTemplLocker_Impl aLocker( *pImp );
577 if ( !pImp->Construct() )
578 return sal_False;
580 // Don't copy or move any folders
581 if( nSourceIdx == USHRT_MAX )
582 return sal_False ;
584 if ( nSourceRegion == nTargetRegion )
586 SAL_WARN( "sfx.doc", "Don't know, what to do!" );
587 return sal_False;
590 RegionData_Impl *pSourceRgn = pImp->GetRegion( nSourceRegion );
591 if ( !pSourceRgn )
592 return sal_False;
594 DocTempl_EntryData_Impl *pSource = pSourceRgn->GetEntry( nSourceIdx );
595 if ( !pSource )
596 return sal_False;
598 RegionData_Impl *pTargetRgn = pImp->GetRegion( nTargetRegion );
599 if ( !pTargetRgn )
600 return sal_False;
602 OUString aTitle = pSource->GetTitle();
604 uno::Reference< XDocumentTemplates > xTemplates = pImp->getDocTemplates();
606 if ( xTemplates->addTemplate( pTargetRgn->GetTitle(),
607 aTitle,
608 pSource->GetTargetURL() ) )
610 OUString aNewTargetURL = GetTemplateTargetURLFromComponent( pTargetRgn->GetTitle(), aTitle );
611 if ( aNewTargetURL.isEmpty() )
612 return sal_False;
614 if ( bMove )
616 // --**-- delete the original file
617 sal_Bool bDeleted = xTemplates->removeTemplate( pSourceRgn->GetTitle(),
618 pSource->GetTitle() );
619 if ( bDeleted )
620 pSourceRgn->DeleteEntry( nSourceIdx );
621 else
623 if ( xTemplates->removeTemplate( pTargetRgn->GetTitle(), aTitle ) )
624 return sal_False; // will trigger tetry with copy instead of move
626 // if it is not possible to remove just created template ( must be possible! )
627 // it is better to report success here, since at least the copy has succeeded
628 // TODO/LATER: solve it more gracefully in future
632 // todo: fix SfxDocumentTemplates to handle size_t instead of sal_uInt16
633 size_t temp_nTargetIdx = nTargetIdx;
634 pTargetRgn->AddEntry( aTitle, aNewTargetURL, &temp_nTargetIdx );
636 return sal_True;
639 // --**-- if the current file is opened,
640 // it must be re-opened afterwards.
642 return sal_False;
645 //------------------------------------------------------------------------
647 sal_Bool SfxDocumentTemplates::Move
649 sal_uInt16 nTargetRegion, // Target Region Index
650 sal_uInt16 nTargetIdx, // Target position Index
651 sal_uInt16 nSourceRegion, // Source Region Index
652 sal_uInt16 nSourceIdx /* Index to be copied / to moved template */
655 /* [Description]
657 Moving a template
659 [Return value]
661 sal_Bool sal_True, Action could be performed
662 sal_False, Action could not be performed
664 [Cross-references]
666 <SfxDocumentTemplates::CopyOrMove(sal_uInt16,sal_uInt16,sal_uInt16,sal_uInt16,sal_Bool)>
669 DocTemplLocker_Impl aLocker( *pImp );
671 return CopyOrMove( nTargetRegion, nTargetIdx,
672 nSourceRegion, nSourceIdx, sal_True );
675 //------------------------------------------------------------------------
677 sal_Bool SfxDocumentTemplates::Copy
679 sal_uInt16 nTargetRegion, // Target Region Index
680 sal_uInt16 nTargetIdx, // Target position Index
681 sal_uInt16 nSourceRegion, // Source Region Index
682 sal_uInt16 nSourceIdx /* Index to be copied / to moved template */
685 /* [Description]
687 Copying a template
689 [Return value]
691 sal_Bool sal_True, Action could be performed
692 sal_False, Action could not be performed
694 [Cross-references]
696 <SfxDocumentTemplates::CopyOrMove(sal_uInt16,sal_uInt16,sal_uInt16,sal_uInt16,sal_Bool)>
700 DocTemplLocker_Impl aLocker( *pImp );
702 return CopyOrMove( nTargetRegion, nTargetIdx,
703 nSourceRegion, nSourceIdx, sal_False );
706 //------------------------------------------------------------------------
708 sal_Bool SfxDocumentTemplates::CopyTo
710 sal_uInt16 nRegion, // Region of the template to be exported
711 sal_uInt16 nIdx, // Index of the template to be exported
712 const OUString& rName /* File name under which the template is to
713 be created */
714 ) const
716 /* [Description]
718 Exporting a template into the file system
720 [Return value]
722 sal_Bool sal_True, Action could be performed
723 sal_False, Action could not be performed
725 [Cross-references]
727 <SfxDocumentTemplates::CopyFrom(sal_uInt16,sal_uInt16,String&)>
731 DocTemplLocker_Impl aLocker( *pImp );
733 if ( ! pImp->Construct() )
734 return sal_False;
736 RegionData_Impl *pSourceRgn = pImp->GetRegion( nRegion );
737 if ( !pSourceRgn )
738 return sal_False;
740 DocTempl_EntryData_Impl *pSource = pSourceRgn->GetEntry( nIdx );
741 if ( !pSource )
742 return sal_False;
744 INetURLObject aTargetURL( rName );
746 OUString aTitle( aTargetURL.getName( INetURLObject::LAST_SEGMENT, true,
747 INetURLObject::DECODE_WITH_CHARSET ) );
748 aTargetURL.removeSegment();
750 OUString aParentURL = aTargetURL.GetMainURL( INetURLObject::NO_DECODE );
752 uno::Reference< XCommandEnvironment > aCmdEnv;
753 Content aTarget;
757 aTarget = Content( aParentURL, aCmdEnv, comphelper::getProcessComponentContext() );
759 TransferInfo aTransferInfo;
760 aTransferInfo.MoveData = sal_False;
761 aTransferInfo.SourceURL = pSource->GetTargetURL();
762 aTransferInfo.NewTitle = aTitle;
763 aTransferInfo.NameClash = NameClash::OVERWRITE;
765 Any aArg = makeAny( aTransferInfo );
766 OUString aCmd( COMMAND_TRANSFER );
768 aTarget.executeCommand( aCmd, aArg );
770 catch ( ContentCreationException& )
771 { return sal_False; }
772 catch ( Exception& )
773 { return sal_False; }
775 return sal_True;
778 //------------------------------------------------------------------------
780 sal_Bool SfxDocumentTemplates::CopyFrom
782 sal_uInt16 nRegion, /* Region in which the template is to be
783 imported */
784 sal_uInt16 nIdx, // Index of the new template in this Region
785 OUString& rName /* File name of the template to be imported
786 as an out parameter of the (automatically
787 generated from the file name) logical name
788 of the template */
791 /* [Description]
793 Import a template from the file system
795 [Return value] Sucess (sal_True) or serfpTargetDirectory->GetContent());
797 sal_Bool sal_True, Action could be performed
798 sal_False, Action could not be performed
800 [Cross-references]
802 <SfxDocumentTemplates::CopyTo(sal_uInt16,sal_uInt16,const String&)>
806 DocTemplLocker_Impl aLocker( *pImp );
808 if ( ! pImp->Construct() )
809 return sal_False;
811 RegionData_Impl *pTargetRgn = pImp->GetRegion( nRegion );
813 if ( !pTargetRgn )
814 return sal_False;
816 uno::Reference< XDocumentTemplates > xTemplates = pImp->getDocTemplates();
817 if ( !xTemplates.is() )
818 return sal_False;
820 OUString aTitle;
821 sal_Bool bTemplateAdded = sal_False;
823 if( pImp->GetTitleFromURL( rName, aTitle ) )
825 bTemplateAdded = xTemplates->addTemplate( pTargetRgn->GetTitle(), aTitle, rName );
827 else
829 uno::Reference< XDesktop2 > xDesktop = Desktop::create( ::comphelper::getProcessComponentContext() );;
831 Sequence< PropertyValue > aArgs( 1 );
832 aArgs[0].Name = "Hidden";
833 aArgs[0].Value <<= sal_True;
835 INetURLObject aTemplURL( rName );
836 uno::Reference< XDocumentPropertiesSupplier > xDocPropsSupplier;
837 uno::Reference< XStorable > xStorable;
840 xStorable = uno::Reference< XStorable >(
841 xDesktop->loadComponentFromURL( aTemplURL.GetMainURL(INetURLObject::NO_DECODE),
842 OUString("_blank"),
844 aArgs ),
845 UNO_QUERY );
847 xDocPropsSupplier = uno::Reference< XDocumentPropertiesSupplier >(
848 xStorable, UNO_QUERY );
850 catch( Exception& )
854 if( xStorable.is() )
856 // get Title from XDocumentPropertiesSupplier
857 if( xDocPropsSupplier.is() )
859 uno::Reference< XDocumentProperties > xDocProps
860 = xDocPropsSupplier->getDocumentProperties();
861 if (xDocProps.is() ) {
862 aTitle = xDocProps->getTitle();
866 if( aTitle.isEmpty() )
868 INetURLObject aURL( aTemplURL );
869 aURL.CutExtension();
870 aTitle = aURL.getName( INetURLObject::LAST_SEGMENT, true,
871 INetURLObject::DECODE_WITH_CHARSET );
874 // write a template using XStorable interface
875 bTemplateAdded = xTemplates->storeTemplate( pTargetRgn->GetTitle(), aTitle, xStorable );
880 if( bTemplateAdded )
882 INetURLObject aTemplObj( pTargetRgn->GetHierarchyURL() );
883 aTemplObj.insertName( aTitle, false,
884 INetURLObject::LAST_SEGMENT, true,
885 INetURLObject::ENCODE_ALL );
886 OUString aTemplURL = aTemplObj.GetMainURL( INetURLObject::NO_DECODE );
888 uno::Reference< XCommandEnvironment > aCmdEnv;
889 Content aTemplCont;
891 if( Content::create( aTemplURL, aCmdEnv, comphelper::getProcessComponentContext(), aTemplCont ) )
893 OUString aTemplName;
894 OUString aPropName( TARGET_URL );
896 if( getTextProperty_Impl( aTemplCont, aPropName, aTemplName ) )
898 if ( nIdx == USHRT_MAX )
899 nIdx = 0;
900 else
901 nIdx += 1;
903 // todo: fix SfxDocumentTemplates to handle size_t instead of sal_uInt16
904 size_t temp_nIdx = nIdx;
905 pTargetRgn->AddEntry( aTitle, aTemplName, &temp_nIdx );
906 rName = aTitle;
907 return sal_True;
909 else
911 DBG_ASSERT( sal_False, "CopyFrom(): The content should contain target URL!" );
914 else
916 DBG_ASSERT( sal_False, "CopyFrom(): The content just was created!" );
920 return sal_False;
923 //------------------------------------------------------------------------
925 sal_Bool SfxDocumentTemplates::Delete
927 sal_uInt16 nRegion, // Region Index
928 sal_uInt16 nIdx /* Index of the entry or USHRT_MAX,
929 if a directory is meant. */
932 /* [Description]
934 Deleting an entry or a directory
936 [Return value]
938 sal_Bool sal_True, Action could be performed
939 sal_False, Action could not be performed
941 [Cross-references]
943 <SfxDocumentTemplates::InsertDir(const String&,sal_uInt16)>
944 <SfxDocumentTemplates::KillDir(SfxTemplateDir&)>
948 DocTemplLocker_Impl aLocker( *pImp );
950 /* delete the template or folder in the hierarchy and in the
951 template folder by sending a delete command to the content.
952 Then remove the data from the lists
954 if ( ! pImp->Construct() )
955 return sal_False;
957 RegionData_Impl *pRegion = pImp->GetRegion( nRegion );
959 if ( !pRegion )
960 return sal_False;
962 sal_Bool bRet;
963 uno::Reference< XDocumentTemplates > xTemplates = pImp->getDocTemplates();
965 if ( nIdx == USHRT_MAX )
967 bRet = xTemplates->removeGroup( pRegion->GetTitle() );
968 if ( bRet )
969 pImp->DeleteRegion( nRegion );
971 else
973 DocTempl_EntryData_Impl *pEntry = pRegion->GetEntry( nIdx );
975 if ( !pEntry )
976 return sal_False;
978 bRet = xTemplates->removeTemplate( pRegion->GetTitle(),
979 pEntry->GetTitle() );
980 if( bRet )
981 pRegion->DeleteEntry( nIdx );
984 return bRet;
987 //------------------------------------------------------------------------
989 sal_Bool SfxDocumentTemplates::InsertDir
991 const OUString& rText, // the logical name of the new Region
992 sal_uInt16 nRegion // Region Index
995 /* [Description]
997 Insert an index
999 [Return value]
1001 sal_Bool sal_True, Action could be performed
1002 sal_False, Action could not be performed
1004 [Cross-references]
1006 <SfxDocumentTemplates::KillDir(SfxTemplateDir&)>
1009 DocTemplLocker_Impl aLocker( *pImp );
1011 if ( ! pImp->Construct() )
1012 return sal_False;
1014 RegionData_Impl *pRegion = pImp->GetRegion( rText );
1016 if ( pRegion )
1017 return sal_False;
1019 uno::Reference< XDocumentTemplates > xTemplates = pImp->getDocTemplates();
1021 if ( xTemplates->addGroup( rText ) )
1023 RegionData_Impl* pNewRegion = new RegionData_Impl( pImp, rText );
1025 if ( ! pImp->InsertRegion( pNewRegion, nRegion ) )
1027 delete pNewRegion;
1028 return sal_False;
1030 return sal_True;
1033 return sal_False;
1036 sal_Bool SfxDocumentTemplates::InsertTemplate(sal_uInt16 nSourceRegion, sal_uInt16 nIdx, const OUString &rName, const OUString &rPath)
1038 DocTemplLocker_Impl aLocker( *pImp );
1040 if ( ! pImp->Construct() )
1041 return sal_False;
1043 RegionData_Impl *pRegion = pImp->GetRegion( nSourceRegion );
1045 if ( !pRegion )
1046 return sal_False;
1048 size_t pos = nIdx;
1049 pRegion->AddEntry( rName, rPath, &pos );
1051 return sal_True;
1054 sal_Bool SfxDocumentTemplates::SetName( const OUString& rName, sal_uInt16 nRegion, sal_uInt16 nIdx )
1057 DocTemplLocker_Impl aLocker( *pImp );
1059 if ( ! pImp->Construct() )
1060 return sal_False;
1062 RegionData_Impl *pRegion = pImp->GetRegion( nRegion );
1064 if ( !pRegion )
1065 return sal_False;
1067 uno::Reference< XDocumentTemplates > xTemplates = pImp->getDocTemplates();
1068 OUString aEmpty;
1070 if ( nIdx == USHRT_MAX )
1072 if ( pRegion->GetTitle() == rName )
1073 return sal_True;
1075 // we have to rename a region
1076 if ( xTemplates->renameGroup( pRegion->GetTitle(), rName ) )
1078 pRegion->SetTitle( rName );
1079 pRegion->SetTargetURL( aEmpty );
1080 pRegion->SetHierarchyURL( aEmpty );
1081 return sal_True;
1084 else
1086 DocTempl_EntryData_Impl *pEntry = pRegion->GetEntry( nIdx );
1088 if ( !pEntry )
1089 return sal_False;
1091 if ( pEntry->GetTitle() == rName )
1092 return sal_True;
1094 if ( xTemplates->renameTemplate( pRegion->GetTitle(),
1095 pEntry->GetTitle(),
1096 rName ) )
1098 pEntry->SetTitle( rName );
1099 pEntry->SetTargetURL( aEmpty );
1100 pEntry->SetHierarchyURL( aEmpty );
1101 return sal_True;
1105 return sal_False;
1108 //------------------------------------------------------------------------
1110 sal_Bool SfxDocumentTemplates::GetFull
1112 const OUString &rRegion, // Region Name
1113 const OUString &rName, // Template Name
1114 OUString &rPath // Out: Path + File name
1117 /* [Description]
1119 Returns Path + File name of the template specified by rRegion and rName.
1121 [Return value]
1123 sal_Bool sal_True, Action could be performed
1124 sal_False, Action could not be performed
1126 [Cross-references]
1128 <SfxDocumentTemplates::GetLogicNames(const String&,String&,String&)>
1132 DocTemplLocker_Impl aLocker( *pImp );
1134 // We don't search for empty names!
1135 if ( rName.isEmpty() )
1136 return sal_False;
1138 if ( ! pImp->Construct() )
1139 return sal_False;
1141 DocTempl_EntryData_Impl* pEntry = NULL;
1142 const sal_uInt16 nCount = GetRegionCount();
1144 for ( sal_uInt16 i = 0; i < nCount; ++i )
1146 RegionData_Impl *pRegion = pImp->GetRegion( i );
1148 if( pRegion &&
1149 ( rRegion.isEmpty() || ( rRegion == pRegion->GetTitle() ) ) )
1151 pEntry = pRegion->GetEntry( rName );
1153 if ( pEntry )
1155 rPath = pEntry->GetTargetURL();
1156 break;
1161 return ( pEntry != NULL );
1164 //------------------------------------------------------------------------
1166 sal_Bool SfxDocumentTemplates::GetLogicNames
1168 const OUString &rPath, // Full Path to the template
1169 OUString &rRegion, // Out: Region name
1170 OUString &rName // Out: Template name
1171 ) const
1173 /* [Description]
1175 Returns and logical path name to the template specified by rPath
1177 [Return value]
1179 sal_Bool sal_True, Action could be performed
1180 sal_False, Action could not be performed
1182 [Cross-references]
1184 <SfxDocumentTemplates::GetFull(const String&,const String&,DirEntry&)>
1188 DocTemplLocker_Impl aLocker( *pImp );
1190 if ( ! pImp->Construct() )
1191 return sal_False;
1193 INetURLObject aFullPath;
1195 aFullPath.SetSmartProtocol( INET_PROT_FILE );
1196 aFullPath.SetURL( rPath );
1197 OUString aPath( aFullPath.GetMainURL( INetURLObject::NO_DECODE ) );
1199 RegionData_Impl *pData = NULL;
1200 DocTempl_EntryData_Impl *pEntry = NULL;
1201 sal_Bool bFound = sal_False;
1203 sal_uIntPtr nCount = GetRegionCount();
1205 for ( sal_uIntPtr i=0; !bFound && (i<nCount); i++ )
1207 pData = pImp->GetRegion( i );
1208 if ( pData )
1210 sal_uIntPtr nChildCount = pData->GetCount();
1212 for ( sal_uIntPtr j=0; !bFound && (j<nChildCount); j++ )
1214 pEntry = pData->GetEntry( j );
1215 if ( pEntry->GetTargetURL() == aPath )
1217 bFound = sal_True;
1223 if ( bFound )
1225 rRegion = pData->GetTitle();
1226 rName = pEntry->GetTitle();
1229 return bFound;
1232 //------------------------------------------------------------------------
1234 SfxDocumentTemplates::SfxDocumentTemplates()
1236 /* [Description]
1238 Constructor
1241 if ( !gpTemplateData )
1242 gpTemplateData = new SfxDocTemplate_Impl;
1244 pImp = gpTemplateData;
1247 //-------------------------------------------------------------------------
1249 void SfxDocumentTemplates::Construct()
1251 // Delayed build-up of administrative data
1256 //------------------------------------------------------------------------
1258 SfxDocumentTemplates::~SfxDocumentTemplates()
1260 /* [Description]
1262 Destructor
1263 Release of administrative data
1267 pImp = NULL;
1270 void SfxDocumentTemplates::Update( sal_Bool _bSmart )
1272 if ( !_bSmart // don't be smart
1273 || ::svt::TemplateFolderCache( sal_True ).needsUpdate() // update is really necessary
1276 if ( pImp->Construct() )
1277 pImp->Rescan();
1281 void SfxDocumentTemplates::ReInitFromComponent()
1283 pImp->ReInitFromComponent();
1286 // -----------------------------------------------------------------------
1287 DocTempl_EntryData_Impl::DocTempl_EntryData_Impl( RegionData_Impl* pParent,
1288 const OUString& rTitle )
1290 mpParent = pParent;
1291 maTitle = SfxDocumentTemplates::ConvertResourceString(
1292 STR_TEMPLATE_NAME1_DEF, STR_TEMPLATE_NAME1, NUM_TEMPLATE_NAMES, rTitle );
1293 mbIsOwner = sal_False;
1294 mbDidConvert= sal_False;
1297 // -----------------------------------------------------------------------
1298 int DocTempl_EntryData_Impl::Compare( const OUString& rTitle ) const
1300 return maTitle.compareTo( rTitle );
1303 // -----------------------------------------------------------------------
1304 const OUString& DocTempl_EntryData_Impl::GetHierarchyURL()
1306 if ( maOwnURL.isEmpty() )
1308 INetURLObject aTemplateObj( GetParent()->GetHierarchyURL() );
1310 aTemplateObj.insertName( GetTitle(), false,
1311 INetURLObject::LAST_SEGMENT, true,
1312 INetURLObject::ENCODE_ALL );
1314 maOwnURL = aTemplateObj.GetMainURL( INetURLObject::NO_DECODE );
1315 DBG_ASSERT( !maOwnURL.isEmpty(), "GetHierarchyURL(): Could not create URL!" );
1318 return maOwnURL;
1321 // -----------------------------------------------------------------------
1322 const OUString& DocTempl_EntryData_Impl::GetTargetURL()
1324 if ( maTargetURL.isEmpty() )
1326 uno::Reference< XCommandEnvironment > aCmdEnv;
1327 Content aRegion;
1329 if ( Content::create( GetHierarchyURL(), aCmdEnv, comphelper::getProcessComponentContext(), aRegion ) )
1331 OUString aPropName( TARGET_URL );
1333 getTextProperty_Impl( aRegion, aPropName, maTargetURL );
1335 else
1337 SAL_WARN( "sfx.doc", "GetTargetURL(): Could not create hierarchy content!" );
1341 return maTargetURL;
1344 // -----------------------------------------------------------------------
1345 RegionData_Impl::RegionData_Impl( const SfxDocTemplate_Impl* pParent,
1346 const OUString& rTitle )
1348 maTitle = rTitle;
1349 mpParent = pParent;
1352 // -----------------------------------------------------------------------
1353 RegionData_Impl::~RegionData_Impl()
1355 for ( size_t i = 0, n = maEntries.size(); i < n; ++i )
1356 delete maEntries[ i ];
1357 maEntries.clear();
1360 // -----------------------------------------------------------------------
1361 size_t RegionData_Impl::GetEntryPos( const OUString& rTitle, sal_Bool& rFound ) const
1363 #if 1 // Don't use binary search today
1364 size_t i;
1365 size_t nCount = maEntries.size();
1367 for ( i=0; i<nCount; i++ )
1369 DocTempl_EntryData_Impl *pData = maEntries[ i ];
1371 if ( pData->Compare( rTitle ) == 0 )
1373 rFound = sal_True;
1374 return i;
1378 rFound = sal_False;
1379 return i;
1381 #else
1382 // use binary search to find the correct position
1383 // in the maEntries list
1385 int nCompVal = 1;
1386 size_t nStart = 0;
1387 size_t nEnd = maEntries.size() - 1;
1388 size_t nMid;
1390 DocTempl_EntryData_Impl* pMid;
1392 rFound = sal_False;
1394 while ( nCompVal && ( nStart <= nEnd ) )
1396 nMid = ( nEnd - nStart ) / 2 + nStart;
1397 pMid = maEntries[ nMid ];
1399 nCompVal = pMid->Compare( rTitle );
1401 if ( nCompVal < 0 ) // pMid < pData
1402 nStart = nMid + 1;
1403 else
1404 nEnd = nMid - 1;
1407 if ( nCompVal == 0 )
1409 rFound = sal_True;
1411 else
1413 if ( nCompVal < 0 ) // pMid < pData
1414 nMid++;
1417 return nMid;
1418 #endif
1421 // -----------------------------------------------------------------------
1422 void RegionData_Impl::AddEntry( const OUString& rTitle,
1423 const OUString& rTargetURL,
1424 size_t *pPos )
1426 INetURLObject aLinkObj( GetHierarchyURL() );
1427 aLinkObj.insertName( rTitle, false,
1428 INetURLObject::LAST_SEGMENT, true,
1429 INetURLObject::ENCODE_ALL );
1430 OUString aLinkURL = aLinkObj.GetMainURL( INetURLObject::NO_DECODE );
1432 DocTempl_EntryData_Impl* pEntry;
1433 sal_Bool bFound = sal_False;
1434 size_t nPos = GetEntryPos( rTitle, bFound );
1436 if ( bFound )
1438 pEntry = maEntries[ nPos ];
1440 else
1442 if ( pPos )
1443 nPos = *pPos;
1445 pEntry = new DocTempl_EntryData_Impl( this, rTitle );
1446 pEntry->SetTargetURL( rTargetURL );
1447 pEntry->SetHierarchyURL( aLinkURL );
1448 if ( nPos < maEntries.size() ) {
1449 vector< DocTempl_EntryData_Impl* >::iterator it = maEntries.begin();
1450 advance( it, nPos );
1451 maEntries.insert( it, pEntry );
1453 else
1454 maEntries.push_back( pEntry );
1458 // -----------------------------------------------------------------------
1459 size_t RegionData_Impl::GetCount() const
1461 return maEntries.size();
1464 // -----------------------------------------------------------------------
1465 const OUString& RegionData_Impl::GetHierarchyURL()
1467 if ( maOwnURL.isEmpty() )
1469 INetURLObject aRegionObj( GetParent()->GetRootURL() );
1471 aRegionObj.insertName( GetTitle(), false,
1472 INetURLObject::LAST_SEGMENT, true,
1473 INetURLObject::ENCODE_ALL );
1475 maOwnURL = aRegionObj.GetMainURL( INetURLObject::NO_DECODE );
1476 DBG_ASSERT( !maOwnURL.isEmpty(), "GetHierarchyURL(): Could not create URL!" );
1479 return maOwnURL;
1482 // -----------------------------------------------------------------------
1483 DocTempl_EntryData_Impl* RegionData_Impl::GetEntry( const OUString& rName ) const
1485 sal_Bool bFound = sal_False;
1486 long nPos = GetEntryPos( rName, bFound );
1488 if ( bFound )
1489 return maEntries[ nPos ];
1490 else
1491 return NULL;
1494 // -----------------------------------------------------------------------
1495 DocTempl_EntryData_Impl* RegionData_Impl::GetEntry( size_t nIndex ) const
1497 if ( nIndex < maEntries.size() )
1498 return maEntries[ nIndex ];
1499 return NULL;
1502 // -----------------------------------------------------------------------
1503 void RegionData_Impl::DeleteEntry( size_t nIndex )
1505 if ( nIndex < maEntries.size() )
1507 delete maEntries[ nIndex ];
1508 vector< DocTempl_EntryData_Impl*>::iterator it = maEntries.begin();
1509 advance( it, nIndex );
1510 maEntries.erase( it );
1514 // -----------------------------------------------------------------------
1515 int RegionData_Impl::Compare( RegionData_Impl* pCompare ) const
1517 int nCompare = maTitle.compareTo( pCompare->maTitle );
1519 return nCompare;
1522 // -----------------------------------------------------------------------
1524 SfxDocTemplate_Impl::SfxDocTemplate_Impl()
1525 : mbConstructed( sal_False )
1526 , mnLockCounter( 0 )
1530 // -----------------------------------------------------------------------
1531 SfxDocTemplate_Impl::~SfxDocTemplate_Impl()
1533 Clear();
1535 gpTemplateData = NULL;
1538 // -----------------------------------------------------------------------
1539 void SfxDocTemplate_Impl::IncrementLock()
1541 ::osl::MutexGuard aGuard( maMutex );
1542 mnLockCounter++;
1545 // -----------------------------------------------------------------------
1546 void SfxDocTemplate_Impl::DecrementLock()
1548 ::osl::MutexGuard aGuard( maMutex );
1549 if ( mnLockCounter )
1550 mnLockCounter--;
1553 // -----------------------------------------------------------------------
1554 RegionData_Impl* SfxDocTemplate_Impl::GetRegion( size_t nIndex ) const
1556 if ( nIndex < maRegions.size() )
1557 return maRegions[ nIndex ];
1558 return NULL;
1561 // -----------------------------------------------------------------------
1562 RegionData_Impl* SfxDocTemplate_Impl::GetRegion( const OUString& rName )
1563 const
1565 for ( size_t i = 0, n = maRegions.size(); i < n; ++i )
1567 RegionData_Impl* pData = maRegions[ i ];
1568 if( pData->GetTitle() == rName )
1569 return pData;
1571 return NULL;
1574 // -----------------------------------------------------------------------
1575 void SfxDocTemplate_Impl::DeleteRegion( size_t nIndex )
1577 if ( nIndex < maRegions.size() )
1579 delete maRegions[ nIndex ];
1580 RegionList_Impl::iterator it = maRegions.begin();
1581 advance( it, nIndex );
1582 maRegions.erase( it );
1586 // -----------------------------------------------------------------------
1587 /* AddRegion adds a Region to the RegionList
1589 void SfxDocTemplate_Impl::AddRegion( const OUString& rTitle,
1590 Content& rContent )
1592 RegionData_Impl* pRegion;
1593 pRegion = new RegionData_Impl( this, rTitle );
1595 if ( ! InsertRegion( pRegion ) )
1597 delete pRegion;
1598 return;
1601 // now get the content of the region
1602 uno::Reference< XResultSet > xResultSet;
1603 Sequence< OUString > aProps(2);
1604 aProps[0] = TITLE;
1605 aProps[1] = TARGET_URL;
1609 ResultSetInclude eInclude = INCLUDE_DOCUMENTS_ONLY;
1610 Sequence< NumberedSortingInfo > aSortingInfo(1);
1611 aSortingInfo.getArray()->ColumnIndex = 1;
1612 aSortingInfo.getArray()->Ascending = sal_True;
1613 xResultSet = rContent.createSortedCursor( aProps, aSortingInfo, m_rCompareFactory, eInclude );
1615 catch ( Exception& ) {}
1617 if ( xResultSet.is() )
1619 uno::Reference< XContentAccess > xContentAccess( xResultSet, UNO_QUERY );
1620 uno::Reference< XRow > xRow( xResultSet, UNO_QUERY );
1624 while ( xResultSet->next() )
1626 OUString aTitle( xRow->getString( 1 ) );
1627 OUString aTargetDir( xRow->getString( 2 ) );
1629 pRegion->AddEntry( aTitle, aTargetDir );
1632 catch ( Exception& ) {}
1636 // -----------------------------------------------------------------------
1637 void SfxDocTemplate_Impl::CreateFromHierarchy( Content &rTemplRoot )
1639 uno::Reference< XResultSet > xResultSet;
1640 Sequence< OUString > aProps(1);
1641 aProps[0] = TITLE;
1645 ResultSetInclude eInclude = INCLUDE_FOLDERS_ONLY;
1646 Sequence< NumberedSortingInfo > aSortingInfo(1);
1647 aSortingInfo.getArray()->ColumnIndex = 1;
1648 aSortingInfo.getArray()->Ascending = sal_True;
1649 xResultSet = rTemplRoot.createSortedCursor( aProps, aSortingInfo, m_rCompareFactory, eInclude );
1651 catch ( Exception& ) {}
1653 if ( xResultSet.is() )
1655 uno::Reference< XCommandEnvironment > aCmdEnv;
1656 uno::Reference< XContentAccess > xContentAccess( xResultSet, UNO_QUERY );
1657 uno::Reference< XRow > xRow( xResultSet, UNO_QUERY );
1661 while ( xResultSet->next() )
1663 OUString aTitle( xRow->getString( 1 ) );
1665 OUString aId = xContentAccess->queryContentIdentifierString();
1666 Content aContent = Content( aId, aCmdEnv, comphelper::getProcessComponentContext() );
1668 AddRegion( aTitle, aContent );
1671 catch ( Exception& ) {}
1675 // ------------------------------------------------------------------------
1676 sal_Bool SfxDocTemplate_Impl::Construct( )
1678 ::osl::MutexGuard aGuard( maMutex );
1680 if ( mbConstructed )
1681 return sal_True;
1683 uno::Reference< XComponentContext > xContext = ::comphelper::getProcessComponentContext();
1685 uno::Reference< XPersist > xInfo( document::DocumentProperties::create(xContext), UNO_QUERY );
1686 mxInfo = xInfo;
1688 mxTemplates = frame::DocumentTemplates::create(xContext);
1690 uno::Reference< XLocalizable > xLocalizable( mxTemplates, UNO_QUERY );
1692 m_rCompareFactory = AnyCompareFactory::createWithLocale(xContext, xLocalizable->getLocale());
1694 uno::Reference < XContent > aRootContent = mxTemplates->getContent();
1695 uno::Reference < XCommandEnvironment > aCmdEnv;
1697 if ( ! aRootContent.is() )
1698 return sal_False;
1700 mbConstructed = sal_True;
1701 maRootURL = aRootContent->getIdentifier()->getContentIdentifier();
1703 ResStringArray aLongNames( SfxResId( TEMPLATE_LONG_NAMES_ARY ) );
1705 if ( aLongNames.Count() )
1706 maStandardGroup = aLongNames.GetString( 0 );
1708 Content aTemplRoot( aRootContent, aCmdEnv, xContext );
1709 CreateFromHierarchy( aTemplRoot );
1711 return sal_True;
1714 // -----------------------------------------------------------------------
1715 void SfxDocTemplate_Impl::ReInitFromComponent()
1717 uno::Reference< XDocumentTemplates > xTemplates = getDocTemplates();
1718 if ( xTemplates.is() )
1720 uno::Reference < XContent > aRootContent = xTemplates->getContent();
1721 uno::Reference < XCommandEnvironment > aCmdEnv;
1722 Content aTemplRoot( aRootContent, aCmdEnv, comphelper::getProcessComponentContext() );
1723 Clear();
1724 CreateFromHierarchy( aTemplRoot );
1728 // -----------------------------------------------------------------------
1729 sal_Bool SfxDocTemplate_Impl::InsertRegion( RegionData_Impl *pNew, size_t nPos )
1731 ::osl::MutexGuard aGuard( maMutex );
1733 // return false (not inserted) if the entry already exists
1734 for ( size_t i = 0, n = maRegions.size(); i < n; ++i )
1735 if ( maRegions[ i ]->Compare( pNew ) == 0 )
1736 return sal_False;
1738 size_t newPos = nPos;
1739 if ( pNew->GetTitle() == maStandardGroup )
1740 newPos = 0;
1742 if ( newPos < maRegions.size() )
1744 RegionList_Impl::iterator it = maRegions.begin();
1745 advance( it, newPos );
1746 maRegions.insert( it, pNew );
1748 else
1749 maRegions.push_back( pNew );
1751 return sal_True;
1754 // -----------------------------------------------------------------------
1755 void SfxDocTemplate_Impl::Rescan()
1757 Clear();
1761 uno::Reference< XDocumentTemplates > xTemplates = getDocTemplates();
1762 DBG_ASSERT( xTemplates.is(), "SfxDocTemplate_Impl::Rescan:invalid template instance!" );
1763 if ( xTemplates.is() )
1765 xTemplates->update();
1767 uno::Reference < XContent > aRootContent = xTemplates->getContent();
1768 uno::Reference < XCommandEnvironment > aCmdEnv;
1770 Content aTemplRoot( aRootContent, aCmdEnv, comphelper::getProcessComponentContext() );
1771 CreateFromHierarchy( aTemplRoot );
1774 catch( const Exception& )
1776 SAL_WARN( "sfx.doc", "SfxDocTemplate_Impl::Rescan: caught an exception while doing the update!" );
1780 // -----------------------------------------------------------------------
1781 sal_Bool SfxDocTemplate_Impl::GetTitleFromURL( const OUString& rURL,
1782 OUString& aTitle )
1784 if ( mxInfo.is() )
1788 mxInfo->read( rURL );
1790 catch ( Exception& )
1792 // the document is not a StarOffice document
1793 return sal_False;
1799 uno::Reference< XPropertySet > aPropSet( mxInfo, UNO_QUERY );
1800 if ( aPropSet.is() )
1802 OUString aPropName( TITLE );
1803 Any aValue = aPropSet->getPropertyValue( aPropName );
1804 aValue >>= aTitle;
1807 catch ( IOException& ) {}
1808 catch ( UnknownPropertyException& ) {}
1809 catch ( Exception& ) {}
1812 if ( aTitle.isEmpty() )
1814 INetURLObject aURL( rURL );
1815 aURL.CutExtension();
1816 aTitle = aURL.getName( INetURLObject::LAST_SEGMENT, true,
1817 INetURLObject::DECODE_WITH_CHARSET );
1820 return sal_True;
1824 // -----------------------------------------------------------------------
1825 void SfxDocTemplate_Impl::Clear()
1827 ::osl::MutexGuard aGuard( maMutex );
1828 if ( mnLockCounter )
1829 return;
1831 for ( size_t i = 0, n = maRegions.size(); i < n; ++i )
1832 delete maRegions[ i ];
1833 maRegions.clear();
1836 // -----------------------------------------------------------------------
1837 sal_Bool getTextProperty_Impl( Content& rContent,
1838 const OUString& rPropName,
1839 OUString& rPropValue )
1841 sal_Bool bGotProperty = sal_False;
1843 // Get the property
1846 uno::Reference< XPropertySetInfo > aPropInfo = rContent.getProperties();
1848 // check, whether or not the property exists
1849 if ( !aPropInfo.is() || !aPropInfo->hasPropertyByName( rPropName ) )
1851 return sal_False;
1854 // now get the property
1855 Any aAnyValue;
1857 aAnyValue = rContent.getPropertyValue( rPropName );
1858 aAnyValue >>= rPropValue;
1860 if ( SfxURLRelocator_Impl::propertyCanContainOfficeDir( rPropName ) )
1862 SfxURLRelocator_Impl aRelocImpl( ::comphelper::getProcessComponentContext() );
1863 aRelocImpl.makeAbsoluteURL( rPropValue );
1866 bGotProperty = sal_True;
1868 catch ( RuntimeException& ) {}
1869 catch ( Exception& ) {}
1871 return bGotProperty;
1874 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */