Branch libreoffice-5-0-4
[LibreOffice.git] / sfx2 / source / doc / doctempl.cxx
blob140e62cd044ca77c00cc5eee0448d2a271b2759f
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;
102 #define TITLE "Title"
103 #define TARGET_URL "TargetURL"
105 #define COMMAND_TRANSFER "transfer"
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 controls 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 bool mbIsOwner : 1;
125 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;
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 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( RegionData_Impl* pCompareWith ) const;
190 typedef vector< RegionData_Impl* > RegionList_Impl;
194 class SfxDocTemplate_Impl : public SvRefBase
196 uno::Reference< XPersist > mxInfo;
197 uno::Reference< XDocumentTemplates > mxTemplates;
199 ::osl::Mutex maMutex;
200 OUString maRootURL;
201 OUString maStandardGroup;
202 RegionList_Impl maRegions;
203 bool mbConstructed;
205 uno::Reference< XAnyCompareFactory > m_rCompareFactory;
207 // the following member is intended to prevent clearing of the global data when it is in use
208 // TODO/LATER: it still does not make the implementation complete thread-safe
209 sal_Int32 mnLockCounter;
211 private:
212 void Clear();
214 public:
215 SfxDocTemplate_Impl();
216 virtual ~SfxDocTemplate_Impl();
218 void IncrementLock();
219 void DecrementLock();
221 bool Construct( );
222 void CreateFromHierarchy( Content &rTemplRoot );
223 void ReInitFromComponent();
224 void AddRegion( const OUString& rTitle,
225 Content& rContent );
227 void Rescan();
229 void DeleteRegion( size_t nIndex );
231 size_t GetRegionCount() const
232 { return maRegions.size(); }
233 RegionData_Impl* GetRegion( const OUString& rName ) const;
234 RegionData_Impl* GetRegion( size_t nIndex ) const;
236 bool GetTitleFromURL( const OUString& rURL, OUString& aTitle );
237 bool InsertRegion( RegionData_Impl *pData, size_t nPos = size_t(-1) );
238 OUString GetRootURL() const { return maRootURL; }
240 uno::Reference< XDocumentTemplates > getDocTemplates() { return mxTemplates; }
245 class DocTemplLocker_Impl
247 SfxDocTemplate_Impl& m_aDocTempl;
248 public:
249 DocTemplLocker_Impl( SfxDocTemplate_Impl& aDocTempl )
250 : m_aDocTempl( aDocTempl )
252 m_aDocTempl.IncrementLock();
255 ~DocTemplLocker_Impl()
257 m_aDocTempl.DecrementLock();
263 #ifndef SFX_DECL_DOCTEMPLATES_DEFINED
264 #define SFX_DECL_DOCTEMPLATES_DEFINED
265 typedef tools::SvRef<SfxDocTemplate_Impl> SfxDocTemplate_ImplRef;
266 #endif
268 SfxDocTemplate_Impl *gpTemplateData = 0;
272 static bool getTextProperty_Impl( Content& rContent,
273 const OUString& rPropName,
274 OUString& rPropValue );
278 OUString SfxDocumentTemplates::GetFullRegionName
280 sal_uInt16 nIdx // vcl::Region Index
281 ) const
283 /* [Description]
285 Returns the logical name of a region and its path
287 [Return value] Reference to the vcl::Region name
292 // First: find the RegionData for the index
293 OUString aName;
295 DocTemplLocker_Impl aLocker( *pImp );
297 if ( pImp->Construct() )
299 RegionData_Impl *pData1 = pImp->GetRegion( nIdx );
301 if ( pData1 )
302 aName = pData1->GetTitle();
304 // --**-- here was some code which appended the path to the
305 // group if there was more than one with the same name.
306 // this should not happen anymore
309 return aName;
314 const OUString& SfxDocumentTemplates::GetRegionName
316 sal_uInt16 nIdx // vcl::Region Index
317 ) const
319 /* [Description]
321 Returns the logical name of a region
323 [Return value]
325 const String& Reference to the vcl::Region name
329 static OUString maTmpString;
331 DocTemplLocker_Impl aLocker( *pImp );
333 if ( pImp->Construct() )
335 RegionData_Impl *pData = pImp->GetRegion( nIdx );
337 if ( pData )
338 maTmpString = pData->GetTitle();
339 else
340 maTmpString.clear();
342 else
343 maTmpString.clear();
345 return maTmpString;
350 sal_uInt16 SfxDocumentTemplates::GetRegionCount() const
352 /* [Description]
354 Returns the number of Regions
356 [Return value]
358 sal_uInt16 Number of Regions
361 DocTemplLocker_Impl aLocker( *pImp );
363 if ( !pImp->Construct() )
364 return 0;
366 sal_uIntPtr nCount = pImp->GetRegionCount();
368 return (sal_uInt16) nCount;
373 sal_uInt16 SfxDocumentTemplates::GetCount
375 sal_uInt16 nRegion /* vcl::Region index whose number is
376 to be determined */
378 ) const
380 /* [Description]
382 Number of entries in Region
384 [Return value] Number of entries
388 DocTemplLocker_Impl aLocker( *pImp );
390 if ( !pImp->Construct() )
391 return 0;
393 RegionData_Impl *pData = pImp->GetRegion( nRegion );
394 sal_uIntPtr nCount = 0;
396 if ( pData )
397 nCount = pData->GetCount();
399 return (sal_uInt16) nCount;
404 const OUString& SfxDocumentTemplates::GetName
406 sal_uInt16 nRegion, // vcl::Region Index, in which the entry lies
407 sal_uInt16 nIdx // Index of the entry
408 ) const
410 /* [Description]
412 Returns the logical name of an entry in Region
414 [Return value]
416 const String& Entry Name
420 DocTemplLocker_Impl aLocker( *pImp );
422 static OUString maTmpString;
424 if ( pImp->Construct() )
426 DocTempl_EntryData_Impl *pEntry = NULL;
427 RegionData_Impl *pRegion = pImp->GetRegion( nRegion );
429 if ( pRegion )
430 pEntry = pRegion->GetEntry( nIdx );
432 if ( pEntry )
433 maTmpString = pEntry->GetTitle();
434 else
435 maTmpString.clear();
437 else
438 maTmpString.clear();
440 return maTmpString;
445 OUString SfxDocumentTemplates::GetPath
447 sal_uInt16 nRegion, // vcl::Region Index, in which the entry lies
448 sal_uInt16 nIdx // Index of the entry
449 ) const
451 /* [Description]
453 Returns the file name with full path to the file assigned to an entry
455 [Return value]
457 String File name with full path
460 DocTemplLocker_Impl aLocker( *pImp );
462 if ( !pImp->Construct() )
463 return OUString();
465 DocTempl_EntryData_Impl *pEntry = NULL;
466 RegionData_Impl *pRegion = pImp->GetRegion( nRegion );
468 if ( pRegion )
469 pEntry = pRegion->GetEntry( nIdx );
471 if ( pEntry )
472 return pEntry->GetTargetURL();
473 else
474 return OUString();
479 OUString SfxDocumentTemplates::GetTemplateTargetURLFromComponent( const OUString& aGroupName,
480 const OUString& aTitle )
482 DocTemplLocker_Impl aLocker( *pImp );
484 INetURLObject aTemplateObj( pImp->GetRootURL() );
486 aTemplateObj.insertName( aGroupName, false,
487 INetURLObject::LAST_SEGMENT, true,
488 INetURLObject::ENCODE_ALL );
490 aTemplateObj.insertName( aTitle, false,
491 INetURLObject::LAST_SEGMENT, true,
492 INetURLObject::ENCODE_ALL );
495 OUString aResult;
496 Content aTemplate;
497 uno::Reference< XCommandEnvironment > aCmdEnv;
498 if ( Content::create( aTemplateObj.GetMainURL( INetURLObject::NO_DECODE ), aCmdEnv, comphelper::getProcessComponentContext(), aTemplate ) )
500 OUString aPropName( TARGET_URL );
501 getTextProperty_Impl( aTemplate, aPropName, aResult );
502 aResult = SvtPathOptions().SubstituteVariable( aResult );
505 return aResult;
510 /** Convert a resource string - a template name - to its localised pair if it exists.
511 @param nSourceResIds
512 Resource ID where the list of original en-US template names begin.
513 @param nDestResIds
514 Resource ID where the list of localised template names begin.
515 @param nCount
516 The number of names that have been localised.
517 @param rString
518 Name to be translated.
519 @return
520 The localised pair of rString or rString if the former does not exist.
522 OUString SfxDocumentTemplates::ConvertResourceString (
523 int nSourceResIds, int nDestResIds, int nCount, const OUString& rString )
525 for( int i = 0; i < nCount; ++i )
527 if( rString == SFX2_RESSTR(nSourceResIds + i))
528 return SFX2_RESSTR(nDestResIds + i);
530 return rString;
535 bool SfxDocumentTemplates::CopyOrMove
537 sal_uInt16 nTargetRegion, // Target vcl::Region Index
538 sal_uInt16 nTargetIdx, // Target position Index
539 sal_uInt16 nSourceRegion, // Source vcl::Region Index
540 sal_uInt16 nSourceIdx, /* Index to be copied / to moved template */
541 bool bMove // Copy / Move
544 /* [Description]
546 Copy or move a document template
548 [Return value]
550 sal_Bool sal_True, Action could be performed
551 sal_False, Action could not be performed
553 [Cross-references]
555 <SfxDocumentTemplates::Move(sal_uInt16,sal_uInt16,sal_uInt16,sal_uInt16)>
556 <SfxDocumentTemplates::Copy(sal_uInt16,sal_uInt16,sal_uInt16,sal_uInt16)>
560 /* to perform a copy or move, we need to send a transfer command to
561 the destination folder with the URL of the source as parameter.
562 ( If the destination content doesn't support the transfer command,
563 we could try a copy ( and delete ) instead. )
564 We need two transfers ( one for the real template and one for its
565 representation in the hierarchy )
569 DocTemplLocker_Impl aLocker( *pImp );
571 if ( !pImp->Construct() )
572 return false;
574 // Don't copy or move any folders
575 if( nSourceIdx == USHRT_MAX )
576 return false ;
578 if ( nSourceRegion == nTargetRegion )
580 SAL_WARN( "sfx.doc", "Don't know, what to do!" );
581 return false;
584 RegionData_Impl *pSourceRgn = pImp->GetRegion( nSourceRegion );
585 if ( !pSourceRgn )
586 return false;
588 DocTempl_EntryData_Impl *pSource = pSourceRgn->GetEntry( nSourceIdx );
589 if ( !pSource )
590 return false;
592 RegionData_Impl *pTargetRgn = pImp->GetRegion( nTargetRegion );
593 if ( !pTargetRgn )
594 return false;
596 OUString aTitle = pSource->GetTitle();
598 uno::Reference< XDocumentTemplates > xTemplates = pImp->getDocTemplates();
600 if ( xTemplates->addTemplate( pTargetRgn->GetTitle(),
601 aTitle,
602 pSource->GetTargetURL() ) )
604 OUString aNewTargetURL = GetTemplateTargetURLFromComponent( pTargetRgn->GetTitle(), aTitle );
605 if ( aNewTargetURL.isEmpty() )
606 return false;
608 if ( bMove )
610 // --**-- delete the original file
611 bool bDeleted = xTemplates->removeTemplate( pSourceRgn->GetTitle(),
612 pSource->GetTitle() );
613 if ( bDeleted )
614 pSourceRgn->DeleteEntry( nSourceIdx );
615 else
617 if ( xTemplates->removeTemplate( pTargetRgn->GetTitle(), aTitle ) )
618 return false; // will trigger tetry with copy instead of move
620 // if it is not possible to remove just created template ( must be possible! )
621 // it is better to report success here, since at least the copy has succeeded
622 // TODO/LATER: solve it more gracefully in future
626 // todo: fix SfxDocumentTemplates to handle size_t instead of sal_uInt16
627 size_t temp_nTargetIdx = nTargetIdx;
628 pTargetRgn->AddEntry( aTitle, aNewTargetURL, &temp_nTargetIdx );
630 return true;
633 // --**-- if the current file is opened,
634 // it must be re-opened afterwards.
636 return false;
641 bool SfxDocumentTemplates::Move
643 sal_uInt16 nTargetRegion, // Target vcl::Region Index
644 sal_uInt16 nTargetIdx, // Target position Index
645 sal_uInt16 nSourceRegion, // Source vcl::Region Index
646 sal_uInt16 nSourceIdx /* Index to be copied / to moved template */
649 /* [Description]
651 Moving a template
653 [Return value]
655 sal_Bool sal_True, Action could be performed
656 sal_False, Action could not be performed
658 [Cross-references]
660 <SfxDocumentTemplates::CopyOrMove(sal_uInt16,sal_uInt16,sal_uInt16,sal_uInt16,sal_Bool)>
663 DocTemplLocker_Impl aLocker( *pImp );
665 return CopyOrMove( nTargetRegion, nTargetIdx,
666 nSourceRegion, nSourceIdx, true );
671 bool SfxDocumentTemplates::Copy
673 sal_uInt16 nTargetRegion, // Target vcl::Region Index
674 sal_uInt16 nTargetIdx, // Target position Index
675 sal_uInt16 nSourceRegion, // Source vcl::Region Index
676 sal_uInt16 nSourceIdx /* Index to be copied / to moved template */
679 /* [Description]
681 Copying a template
683 [Return value]
685 sal_Bool sal_True, Action could be performed
686 sal_False, Action could not be performed
688 [Cross-references]
690 <SfxDocumentTemplates::CopyOrMove(sal_uInt16,sal_uInt16,sal_uInt16,sal_uInt16,sal_Bool)>
694 DocTemplLocker_Impl aLocker( *pImp );
696 return CopyOrMove( nTargetRegion, nTargetIdx,
697 nSourceRegion, nSourceIdx, false );
702 bool SfxDocumentTemplates::CopyTo
704 sal_uInt16 nRegion, // vcl::Region of the template to be exported
705 sal_uInt16 nIdx, // Index of the template to be exported
706 const OUString& rName /* File name under which the template is to
707 be created */
708 ) const
710 /* [Description]
712 Exporting a template into the file system
714 [Return value]
716 sal_Bool sal_True, Action could be performed
717 sal_False, Action could not be performed
719 [Cross-references]
721 <SfxDocumentTemplates::CopyFrom(sal_uInt16,sal_uInt16,String&)>
725 DocTemplLocker_Impl aLocker( *pImp );
727 if ( ! pImp->Construct() )
728 return false;
730 RegionData_Impl *pSourceRgn = pImp->GetRegion( nRegion );
731 if ( !pSourceRgn )
732 return false;
734 DocTempl_EntryData_Impl *pSource = pSourceRgn->GetEntry( nIdx );
735 if ( !pSource )
736 return false;
738 INetURLObject aTargetURL( rName );
740 OUString aTitle( aTargetURL.getName( INetURLObject::LAST_SEGMENT, true,
741 INetURLObject::DECODE_WITH_CHARSET ) );
742 aTargetURL.removeSegment();
744 OUString aParentURL = aTargetURL.GetMainURL( INetURLObject::NO_DECODE );
746 uno::Reference< XCommandEnvironment > aCmdEnv;
747 Content aTarget;
751 aTarget = Content( aParentURL, aCmdEnv, comphelper::getProcessComponentContext() );
753 TransferInfo aTransferInfo;
754 aTransferInfo.MoveData = sal_False;
755 aTransferInfo.SourceURL = pSource->GetTargetURL();
756 aTransferInfo.NewTitle = aTitle;
757 aTransferInfo.NameClash = NameClash::OVERWRITE;
759 Any aArg = makeAny( aTransferInfo );
760 OUString aCmd( COMMAND_TRANSFER );
762 aTarget.executeCommand( aCmd, aArg );
764 catch ( ContentCreationException& )
765 { return false; }
766 catch ( Exception& )
767 { return false; }
769 return true;
774 bool SfxDocumentTemplates::CopyFrom
776 sal_uInt16 nRegion, /* vcl::Region in which the template is to be
777 imported */
778 sal_uInt16 nIdx, // Index of the new template in this Region
779 OUString& rName /* File name of the template to be imported
780 as an out parameter of the (automatically
781 generated from the file name) logical name
782 of the template */
785 /* [Description]
787 Import a template from the file system
789 [Return value] Success (sal_True) or serfpTargetDirectory->GetContent());
791 sal_Bool sal_True, Action could be performed
792 sal_False, Action could not be performed
794 [Cross-references]
796 <SfxDocumentTemplates::CopyTo(sal_uInt16,sal_uInt16,const String&)>
800 DocTemplLocker_Impl aLocker( *pImp );
802 if ( ! pImp->Construct() )
803 return false;
805 RegionData_Impl *pTargetRgn = pImp->GetRegion( nRegion );
807 if ( !pTargetRgn )
808 return false;
810 uno::Reference< XDocumentTemplates > xTemplates = pImp->getDocTemplates();
811 if ( !xTemplates.is() )
812 return false;
814 OUString aTitle;
815 bool bTemplateAdded = false;
817 if( pImp->GetTitleFromURL( rName, aTitle ) )
819 bTemplateAdded = xTemplates->addTemplate( pTargetRgn->GetTitle(), aTitle, rName );
821 else
823 uno::Reference< XDesktop2 > xDesktop = Desktop::create( ::comphelper::getProcessComponentContext() );;
825 Sequence< PropertyValue > aArgs( 1 );
826 aArgs[0].Name = "Hidden";
827 aArgs[0].Value <<= sal_True;
829 INetURLObject aTemplURL( rName );
830 uno::Reference< XDocumentPropertiesSupplier > xDocPropsSupplier;
831 uno::Reference< XStorable > xStorable;
834 xStorable = uno::Reference< XStorable >(
835 xDesktop->loadComponentFromURL( aTemplURL.GetMainURL(INetURLObject::NO_DECODE),
836 OUString("_blank"),
838 aArgs ),
839 UNO_QUERY );
841 xDocPropsSupplier = uno::Reference< XDocumentPropertiesSupplier >(
842 xStorable, UNO_QUERY );
844 catch( Exception& )
848 if( xStorable.is() )
850 // get Title from XDocumentPropertiesSupplier
851 if( xDocPropsSupplier.is() )
853 uno::Reference< XDocumentProperties > xDocProps
854 = xDocPropsSupplier->getDocumentProperties();
855 if (xDocProps.is() ) {
856 aTitle = xDocProps->getTitle();
860 if( aTitle.isEmpty() )
862 INetURLObject aURL( aTemplURL );
863 aURL.CutExtension();
864 aTitle = aURL.getName( INetURLObject::LAST_SEGMENT, true,
865 INetURLObject::DECODE_WITH_CHARSET );
868 // write a template using XStorable interface
869 bTemplateAdded = xTemplates->storeTemplate( pTargetRgn->GetTitle(), aTitle, xStorable );
874 if( bTemplateAdded )
876 INetURLObject aTemplObj( pTargetRgn->GetHierarchyURL() );
877 aTemplObj.insertName( aTitle, false,
878 INetURLObject::LAST_SEGMENT, true,
879 INetURLObject::ENCODE_ALL );
880 OUString aTemplURL = aTemplObj.GetMainURL( INetURLObject::NO_DECODE );
882 uno::Reference< XCommandEnvironment > aCmdEnv;
883 Content aTemplCont;
885 if( Content::create( aTemplURL, aCmdEnv, comphelper::getProcessComponentContext(), aTemplCont ) )
887 OUString aTemplName;
888 OUString aPropName( TARGET_URL );
890 if( getTextProperty_Impl( aTemplCont, aPropName, aTemplName ) )
892 if ( nIdx == USHRT_MAX )
893 nIdx = 0;
894 else
895 nIdx += 1;
897 // todo: fix SfxDocumentTemplates to handle size_t instead of sal_uInt16
898 size_t temp_nIdx = nIdx;
899 pTargetRgn->AddEntry( aTitle, aTemplName, &temp_nIdx );
900 rName = aTitle;
901 return true;
903 else
905 DBG_ASSERT( false, "CopyFrom(): The content should contain target URL!" );
908 else
910 DBG_ASSERT( false, "CopyFrom(): The content just was created!" );
914 return false;
919 bool SfxDocumentTemplates::Delete
921 sal_uInt16 nRegion, // vcl::Region Index
922 sal_uInt16 nIdx /* Index of the entry or USHRT_MAX,
923 if a directory is meant. */
926 /* [Description]
928 Deleting an entry or a directory
930 [Return value]
932 sal_Bool sal_True, Action could be performed
933 sal_False, Action could not be performed
935 [Cross-references]
937 <SfxDocumentTemplates::InsertDir(const String&,sal_uInt16)>
938 <SfxDocumentTemplates::KillDir(SfxTemplateDir&)>
942 DocTemplLocker_Impl aLocker( *pImp );
944 /* delete the template or folder in the hierarchy and in the
945 template folder by sending a delete command to the content.
946 Then remove the data from the lists
948 if ( ! pImp->Construct() )
949 return false;
951 RegionData_Impl *pRegion = pImp->GetRegion( nRegion );
953 if ( !pRegion )
954 return false;
956 bool bRet;
957 uno::Reference< XDocumentTemplates > xTemplates = pImp->getDocTemplates();
959 if ( nIdx == USHRT_MAX )
961 bRet = xTemplates->removeGroup( pRegion->GetTitle() );
962 if ( bRet )
963 pImp->DeleteRegion( nRegion );
965 else
967 DocTempl_EntryData_Impl *pEntry = pRegion->GetEntry( nIdx );
969 if ( !pEntry )
970 return false;
972 bRet = xTemplates->removeTemplate( pRegion->GetTitle(),
973 pEntry->GetTitle() );
974 if( bRet )
975 pRegion->DeleteEntry( nIdx );
978 return bRet;
983 bool SfxDocumentTemplates::InsertDir
985 const OUString& rText, // the logical name of the new Region
986 sal_uInt16 nRegion // vcl::Region Index
989 /* [Description]
991 Insert an index
993 [Return value]
995 sal_Bool sal_True, Action could be performed
996 sal_False, Action could not be performed
998 [Cross-references]
1000 <SfxDocumentTemplates::KillDir(SfxTemplateDir&)>
1003 DocTemplLocker_Impl aLocker( *pImp );
1005 if ( ! pImp->Construct() )
1006 return false;
1008 RegionData_Impl *pRegion = pImp->GetRegion( rText );
1010 if ( pRegion )
1011 return false;
1013 uno::Reference< XDocumentTemplates > xTemplates = pImp->getDocTemplates();
1015 if ( xTemplates->addGroup( rText ) )
1017 RegionData_Impl* pNewRegion = new RegionData_Impl( pImp, rText );
1019 if ( ! pImp->InsertRegion( pNewRegion, nRegion ) )
1021 delete pNewRegion;
1022 return false;
1024 return true;
1027 return false;
1030 bool SfxDocumentTemplates::InsertTemplate(sal_uInt16 nSourceRegion, sal_uInt16 nIdx, const OUString &rName, const OUString &rPath)
1032 DocTemplLocker_Impl aLocker( *pImp );
1034 if ( ! pImp->Construct() )
1035 return false;
1037 RegionData_Impl *pRegion = pImp->GetRegion( nSourceRegion );
1039 if ( !pRegion )
1040 return false;
1042 size_t pos = nIdx;
1043 pRegion->AddEntry( rName, rPath, &pos );
1045 return true;
1048 bool SfxDocumentTemplates::SetName( const OUString& rName, sal_uInt16 nRegion, sal_uInt16 nIdx )
1051 DocTemplLocker_Impl aLocker( *pImp );
1053 if ( ! pImp->Construct() )
1054 return false;
1056 RegionData_Impl *pRegion = pImp->GetRegion( nRegion );
1058 if ( !pRegion )
1059 return false;
1061 uno::Reference< XDocumentTemplates > xTemplates = pImp->getDocTemplates();
1062 OUString aEmpty;
1064 if ( nIdx == USHRT_MAX )
1066 if ( pRegion->GetTitle() == rName )
1067 return true;
1069 // we have to rename a region
1070 if ( xTemplates->renameGroup( pRegion->GetTitle(), rName ) )
1072 pRegion->SetTitle( rName );
1073 pRegion->SetTargetURL( aEmpty );
1074 pRegion->SetHierarchyURL( aEmpty );
1075 return true;
1078 else
1080 DocTempl_EntryData_Impl *pEntry = pRegion->GetEntry( nIdx );
1082 if ( !pEntry )
1083 return false;
1085 if ( pEntry->GetTitle() == rName )
1086 return true;
1088 if ( xTemplates->renameTemplate( pRegion->GetTitle(),
1089 pEntry->GetTitle(),
1090 rName ) )
1092 pEntry->SetTitle( rName );
1093 pEntry->SetTargetURL( aEmpty );
1094 pEntry->SetHierarchyURL( aEmpty );
1095 return true;
1099 return false;
1104 bool SfxDocumentTemplates::GetFull
1106 const OUString &rRegion, // vcl::Region Name
1107 const OUString &rName, // Template Name
1108 OUString &rPath // Out: Path + File name
1111 /* [Description]
1113 Returns Path + File name of the template specified by rRegion and rName.
1115 [Return value]
1117 sal_Bool sal_True, Action could be performed
1118 sal_False, Action could not be performed
1120 [Cross-references]
1122 <SfxDocumentTemplates::GetLogicNames(const String&,String&,String&)>
1126 DocTemplLocker_Impl aLocker( *pImp );
1128 // We don't search for empty names!
1129 if ( rName.isEmpty() )
1130 return false;
1132 if ( ! pImp->Construct() )
1133 return false;
1135 DocTempl_EntryData_Impl* pEntry = NULL;
1136 const sal_uInt16 nCount = GetRegionCount();
1138 for ( sal_uInt16 i = 0; i < nCount; ++i )
1140 RegionData_Impl *pRegion = pImp->GetRegion( i );
1142 if( pRegion &&
1143 ( rRegion.isEmpty() || ( rRegion == pRegion->GetTitle() ) ) )
1145 pEntry = pRegion->GetEntry( rName );
1147 if ( pEntry )
1149 rPath = pEntry->GetTargetURL();
1150 break;
1155 return ( pEntry != NULL );
1160 bool SfxDocumentTemplates::GetLogicNames
1162 const OUString &rPath, // Full Path to the template
1163 OUString &rRegion, // Out: vcl::Region name
1164 OUString &rName // Out: Template name
1165 ) const
1167 /* [Description]
1169 Returns and logical path name to the template specified by rPath
1171 [Return value]
1173 sal_Bool sal_True, Action could be performed
1174 sal_False, Action could not be performed
1176 [Cross-references]
1178 <SfxDocumentTemplates::GetFull(const String&,const String&,DirEntry&)>
1182 DocTemplLocker_Impl aLocker( *pImp );
1184 if ( ! pImp->Construct() )
1185 return false;
1187 INetURLObject aFullPath;
1189 aFullPath.SetSmartProtocol( INetProtocol::File );
1190 aFullPath.SetURL( rPath );
1191 OUString aPath( aFullPath.GetMainURL( INetURLObject::NO_DECODE ) );
1193 RegionData_Impl *pData = NULL;
1194 DocTempl_EntryData_Impl *pEntry = NULL;
1195 bool bFound = false;
1197 sal_uIntPtr nCount = GetRegionCount();
1199 for ( sal_uIntPtr i=0; !bFound && (i<nCount); i++ )
1201 pData = pImp->GetRegion( i );
1202 if ( pData )
1204 sal_uIntPtr nChildCount = pData->GetCount();
1206 for ( sal_uIntPtr j=0; !bFound && (j<nChildCount); j++ )
1208 pEntry = pData->GetEntry( j );
1209 if ( pEntry && pEntry->GetTargetURL() == aPath )
1211 bFound = true;
1217 if ( bFound )
1219 rRegion = pData->GetTitle();
1220 rName = pEntry->GetTitle();
1223 return bFound;
1228 SfxDocumentTemplates::SfxDocumentTemplates()
1230 /* [Description]
1232 Constructor
1235 if ( !gpTemplateData )
1236 gpTemplateData = new SfxDocTemplate_Impl;
1238 pImp = gpTemplateData;
1243 SfxDocumentTemplates::~SfxDocumentTemplates()
1245 /* [Description]
1247 Destructor
1248 Release of administrative data
1252 pImp = NULL;
1255 void SfxDocumentTemplates::Update( bool _bSmart )
1257 if ( !_bSmart // don't be smart
1258 || ::svt::TemplateFolderCache( true ).needsUpdate() // update is really necessary
1261 if ( pImp->Construct() )
1262 pImp->Rescan();
1266 void SfxDocumentTemplates::ReInitFromComponent()
1268 pImp->ReInitFromComponent();
1272 DocTempl_EntryData_Impl::DocTempl_EntryData_Impl( RegionData_Impl* pParent,
1273 const OUString& rTitle )
1275 mpParent = pParent;
1276 maTitle = SfxDocumentTemplates::ConvertResourceString(
1277 STR_TEMPLATE_NAME1_DEF, STR_TEMPLATE_NAME1, NUM_TEMPLATE_NAMES, rTitle );
1278 mbIsOwner = false;
1279 mbDidConvert= false;
1283 int DocTempl_EntryData_Impl::Compare( const OUString& rTitle ) const
1285 return maTitle.compareTo( rTitle );
1289 const OUString& DocTempl_EntryData_Impl::GetHierarchyURL()
1291 if ( maOwnURL.isEmpty() )
1293 INetURLObject aTemplateObj( GetParent()->GetHierarchyURL() );
1295 aTemplateObj.insertName( GetTitle(), false,
1296 INetURLObject::LAST_SEGMENT, true,
1297 INetURLObject::ENCODE_ALL );
1299 maOwnURL = aTemplateObj.GetMainURL( INetURLObject::NO_DECODE );
1300 DBG_ASSERT( !maOwnURL.isEmpty(), "GetHierarchyURL(): Could not create URL!" );
1303 return maOwnURL;
1307 const OUString& DocTempl_EntryData_Impl::GetTargetURL()
1309 if ( maTargetURL.isEmpty() )
1311 uno::Reference< XCommandEnvironment > aCmdEnv;
1312 Content aRegion;
1314 if ( Content::create( GetHierarchyURL(), aCmdEnv, comphelper::getProcessComponentContext(), aRegion ) )
1316 OUString aPropName( TARGET_URL );
1318 getTextProperty_Impl( aRegion, aPropName, maTargetURL );
1320 else
1322 SAL_WARN( "sfx.doc", "GetTargetURL(): Could not create hierarchy content!" );
1326 return maTargetURL;
1330 RegionData_Impl::RegionData_Impl( const SfxDocTemplate_Impl* pParent,
1331 const OUString& rTitle )
1333 maTitle = rTitle;
1334 mpParent = pParent;
1338 RegionData_Impl::~RegionData_Impl()
1340 for ( size_t i = 0, n = maEntries.size(); i < n; ++i )
1341 delete maEntries[ i ];
1342 maEntries.clear();
1346 size_t RegionData_Impl::GetEntryPos( const OUString& rTitle, bool& rFound ) const
1348 #if 1 // Don't use binary search today
1349 size_t i;
1350 size_t nCount = maEntries.size();
1352 for ( i=0; i<nCount; i++ )
1354 DocTempl_EntryData_Impl *pData = maEntries[ i ];
1356 if ( pData->Compare( rTitle ) == 0 )
1358 rFound = true;
1359 return i;
1363 rFound = false;
1364 return i;
1366 #else
1367 // use binary search to find the correct position
1368 // in the maEntries list
1370 int nCompVal = 1;
1371 size_t nStart = 0;
1372 size_t nEnd = maEntries.size() - 1;
1373 size_t nMid;
1375 DocTempl_EntryData_Impl* pMid;
1377 rFound = sal_False;
1379 while ( nCompVal && ( nStart <= nEnd ) )
1381 nMid = ( nEnd - nStart ) / 2 + nStart;
1382 pMid = maEntries[ nMid ];
1384 nCompVal = pMid->Compare( rTitle );
1386 if ( nCompVal < 0 ) // pMid < pData
1387 nStart = nMid + 1;
1388 else
1389 nEnd = nMid - 1;
1392 if ( nCompVal == 0 )
1394 rFound = sal_True;
1396 else
1398 if ( nCompVal < 0 ) // pMid < pData
1399 nMid++;
1402 return nMid;
1403 #endif
1407 void RegionData_Impl::AddEntry( const OUString& rTitle,
1408 const OUString& rTargetURL,
1409 size_t *pPos )
1411 INetURLObject aLinkObj( GetHierarchyURL() );
1412 aLinkObj.insertName( rTitle, false,
1413 INetURLObject::LAST_SEGMENT, true,
1414 INetURLObject::ENCODE_ALL );
1415 OUString aLinkURL = aLinkObj.GetMainURL( INetURLObject::NO_DECODE );
1417 DocTempl_EntryData_Impl* pEntry;
1418 bool bFound = false;
1419 size_t nPos = GetEntryPos( rTitle, bFound );
1421 if ( bFound )
1423 pEntry = maEntries[ nPos ];
1425 else
1427 if ( pPos )
1428 nPos = *pPos;
1430 pEntry = new DocTempl_EntryData_Impl( this, rTitle );
1431 pEntry->SetTargetURL( rTargetURL );
1432 pEntry->SetHierarchyURL( aLinkURL );
1433 if ( nPos < maEntries.size() ) {
1434 vector< DocTempl_EntryData_Impl* >::iterator it = maEntries.begin();
1435 advance( it, nPos );
1436 maEntries.insert( it, pEntry );
1438 else
1439 maEntries.push_back( pEntry );
1444 size_t RegionData_Impl::GetCount() const
1446 return maEntries.size();
1450 const OUString& RegionData_Impl::GetHierarchyURL()
1452 if ( maOwnURL.isEmpty() )
1454 INetURLObject aRegionObj( GetParent()->GetRootURL() );
1456 aRegionObj.insertName( GetTitle(), false,
1457 INetURLObject::LAST_SEGMENT, true,
1458 INetURLObject::ENCODE_ALL );
1460 maOwnURL = aRegionObj.GetMainURL( INetURLObject::NO_DECODE );
1461 DBG_ASSERT( !maOwnURL.isEmpty(), "GetHierarchyURL(): Could not create URL!" );
1464 return maOwnURL;
1468 DocTempl_EntryData_Impl* RegionData_Impl::GetEntry( const OUString& rName ) const
1470 bool bFound = false;
1471 long nPos = GetEntryPos( rName, bFound );
1473 if ( bFound )
1474 return maEntries[ nPos ];
1475 else
1476 return NULL;
1480 DocTempl_EntryData_Impl* RegionData_Impl::GetEntry( size_t nIndex ) const
1482 if ( nIndex < maEntries.size() )
1483 return maEntries[ nIndex ];
1484 return NULL;
1488 void RegionData_Impl::DeleteEntry( size_t nIndex )
1490 if ( nIndex < maEntries.size() )
1492 delete maEntries[ nIndex ];
1493 vector< DocTempl_EntryData_Impl*>::iterator it = maEntries.begin();
1494 advance( it, nIndex );
1495 maEntries.erase( it );
1500 int RegionData_Impl::Compare( RegionData_Impl* pCompare ) const
1502 int nCompare = maTitle.compareTo( pCompare->maTitle );
1504 return nCompare;
1509 SfxDocTemplate_Impl::SfxDocTemplate_Impl()
1510 : mbConstructed( false )
1511 , mnLockCounter( 0 )
1516 SfxDocTemplate_Impl::~SfxDocTemplate_Impl()
1518 Clear();
1520 gpTemplateData = NULL;
1524 void SfxDocTemplate_Impl::IncrementLock()
1526 ::osl::MutexGuard aGuard( maMutex );
1527 mnLockCounter++;
1531 void SfxDocTemplate_Impl::DecrementLock()
1533 ::osl::MutexGuard aGuard( maMutex );
1534 if ( mnLockCounter )
1535 mnLockCounter--;
1539 RegionData_Impl* SfxDocTemplate_Impl::GetRegion( size_t nIndex ) const
1541 if ( nIndex < maRegions.size() )
1542 return maRegions[ nIndex ];
1543 return NULL;
1547 RegionData_Impl* SfxDocTemplate_Impl::GetRegion( const OUString& rName )
1548 const
1550 for ( size_t i = 0, n = maRegions.size(); i < n; ++i )
1552 RegionData_Impl* pData = maRegions[ i ];
1553 if( pData->GetTitle() == rName )
1554 return pData;
1556 return NULL;
1560 void SfxDocTemplate_Impl::DeleteRegion( size_t nIndex )
1562 if ( nIndex < maRegions.size() )
1564 delete maRegions[ nIndex ];
1565 RegionList_Impl::iterator it = maRegions.begin();
1566 advance( it, nIndex );
1567 maRegions.erase( it );
1572 /* AddRegion adds a vcl::Region to the RegionList
1574 void SfxDocTemplate_Impl::AddRegion( const OUString& rTitle,
1575 Content& rContent )
1577 RegionData_Impl* pRegion;
1578 pRegion = new RegionData_Impl( this, rTitle );
1580 if ( ! InsertRegion( pRegion ) )
1582 delete pRegion;
1583 return;
1586 // now get the content of the region
1587 uno::Reference< XResultSet > xResultSet;
1588 Sequence< OUString > aProps(2);
1589 aProps[0] = TITLE;
1590 aProps[1] = TARGET_URL;
1594 ResultSetInclude eInclude = INCLUDE_DOCUMENTS_ONLY;
1595 Sequence< NumberedSortingInfo > aSortingInfo(1);
1596 aSortingInfo.getArray()->ColumnIndex = 1;
1597 aSortingInfo.getArray()->Ascending = sal_True;
1598 xResultSet = rContent.createSortedCursor( aProps, aSortingInfo, m_rCompareFactory, eInclude );
1600 catch ( Exception& ) {}
1602 if ( xResultSet.is() )
1604 uno::Reference< XContentAccess > xContentAccess( xResultSet, UNO_QUERY );
1605 uno::Reference< XRow > xRow( xResultSet, UNO_QUERY );
1609 while ( xResultSet->next() )
1611 OUString aTitle( xRow->getString( 1 ) );
1612 OUString aTargetDir( xRow->getString( 2 ) );
1614 pRegion->AddEntry( aTitle, aTargetDir );
1617 catch ( Exception& ) {}
1622 void SfxDocTemplate_Impl::CreateFromHierarchy( Content &rTemplRoot )
1624 uno::Reference< XResultSet > xResultSet;
1625 Sequence< OUString > aProps(1);
1626 aProps[0] = TITLE;
1630 ResultSetInclude eInclude = INCLUDE_FOLDERS_ONLY;
1631 Sequence< NumberedSortingInfo > aSortingInfo(1);
1632 aSortingInfo.getArray()->ColumnIndex = 1;
1633 aSortingInfo.getArray()->Ascending = sal_True;
1634 xResultSet = rTemplRoot.createSortedCursor( aProps, aSortingInfo, m_rCompareFactory, eInclude );
1636 catch ( Exception& ) {}
1638 if ( xResultSet.is() )
1640 uno::Reference< XCommandEnvironment > aCmdEnv;
1641 uno::Reference< XContentAccess > xContentAccess( xResultSet, UNO_QUERY );
1642 uno::Reference< XRow > xRow( xResultSet, UNO_QUERY );
1646 while ( xResultSet->next() )
1648 OUString aTitle( xRow->getString( 1 ) );
1650 OUString aId = xContentAccess->queryContentIdentifierString();
1651 Content aContent = Content( aId, aCmdEnv, comphelper::getProcessComponentContext() );
1653 AddRegion( aTitle, aContent );
1656 catch ( Exception& ) {}
1661 bool SfxDocTemplate_Impl::Construct( )
1663 ::osl::MutexGuard aGuard( maMutex );
1665 if ( mbConstructed )
1666 return true;
1668 uno::Reference< XComponentContext > xContext = ::comphelper::getProcessComponentContext();
1670 uno::Reference< XPersist > xInfo( document::DocumentProperties::create(xContext), UNO_QUERY );
1671 mxInfo = xInfo;
1673 mxTemplates = frame::DocumentTemplates::create(xContext);
1675 uno::Reference< XLocalizable > xLocalizable( mxTemplates, UNO_QUERY );
1677 m_rCompareFactory = AnyCompareFactory::createWithLocale(xContext, xLocalizable->getLocale());
1679 uno::Reference < XContent > aRootContent = mxTemplates->getContent();
1680 uno::Reference < XCommandEnvironment > aCmdEnv;
1682 if ( ! aRootContent.is() )
1683 return false;
1685 mbConstructed = true;
1686 maRootURL = aRootContent->getIdentifier()->getContentIdentifier();
1688 ResStringArray aLongNames( SfxResId( TEMPLATE_LONG_NAMES_ARY ) );
1690 if ( aLongNames.Count() )
1691 maStandardGroup = aLongNames.GetString( 0 );
1693 Content aTemplRoot( aRootContent, aCmdEnv, xContext );
1694 CreateFromHierarchy( aTemplRoot );
1696 return true;
1700 void SfxDocTemplate_Impl::ReInitFromComponent()
1702 uno::Reference< XDocumentTemplates > xTemplates = getDocTemplates();
1703 if ( xTemplates.is() )
1705 uno::Reference < XContent > aRootContent = xTemplates->getContent();
1706 uno::Reference < XCommandEnvironment > aCmdEnv;
1707 Content aTemplRoot( aRootContent, aCmdEnv, comphelper::getProcessComponentContext() );
1708 Clear();
1709 CreateFromHierarchy( aTemplRoot );
1714 bool SfxDocTemplate_Impl::InsertRegion( RegionData_Impl *pNew, size_t nPos )
1716 ::osl::MutexGuard aGuard( maMutex );
1718 // return false (not inserted) if the entry already exists
1719 for ( size_t i = 0, n = maRegions.size(); i < n; ++i )
1720 if ( maRegions[ i ]->Compare( pNew ) == 0 )
1721 return false;
1723 size_t newPos = nPos;
1724 if ( pNew->GetTitle() == maStandardGroup )
1725 newPos = 0;
1727 if ( newPos < maRegions.size() )
1729 RegionList_Impl::iterator it = maRegions.begin();
1730 advance( it, newPos );
1731 maRegions.insert( it, pNew );
1733 else
1734 maRegions.push_back( pNew );
1736 return true;
1740 void SfxDocTemplate_Impl::Rescan()
1742 Clear();
1746 uno::Reference< XDocumentTemplates > xTemplates = getDocTemplates();
1747 DBG_ASSERT( xTemplates.is(), "SfxDocTemplate_Impl::Rescan:invalid template instance!" );
1748 if ( xTemplates.is() )
1750 xTemplates->update();
1752 uno::Reference < XContent > aRootContent = xTemplates->getContent();
1753 uno::Reference < XCommandEnvironment > aCmdEnv;
1755 Content aTemplRoot( aRootContent, aCmdEnv, comphelper::getProcessComponentContext() );
1756 CreateFromHierarchy( aTemplRoot );
1759 catch( const Exception& )
1761 SAL_WARN( "sfx.doc", "SfxDocTemplate_Impl::Rescan: caught an exception while doing the update!" );
1766 bool SfxDocTemplate_Impl::GetTitleFromURL( const OUString& rURL,
1767 OUString& aTitle )
1769 if ( mxInfo.is() )
1773 mxInfo->read( rURL );
1775 catch ( Exception& )
1777 // the document is not a StarOffice document
1778 return false;
1784 uno::Reference< XPropertySet > aPropSet( mxInfo, UNO_QUERY );
1785 if ( aPropSet.is() )
1787 OUString aPropName( TITLE );
1788 Any aValue = aPropSet->getPropertyValue( aPropName );
1789 aValue >>= aTitle;
1792 catch ( IOException& ) {}
1793 catch ( UnknownPropertyException& ) {}
1794 catch ( Exception& ) {}
1797 if ( aTitle.isEmpty() )
1799 INetURLObject aURL( rURL );
1800 aURL.CutExtension();
1801 aTitle = aURL.getName( INetURLObject::LAST_SEGMENT, true,
1802 INetURLObject::DECODE_WITH_CHARSET );
1805 return true;
1810 void SfxDocTemplate_Impl::Clear()
1812 ::osl::MutexGuard aGuard( maMutex );
1813 if ( mnLockCounter )
1814 return;
1816 for ( size_t i = 0, n = maRegions.size(); i < n; ++i )
1817 delete maRegions[ i ];
1818 maRegions.clear();
1822 bool getTextProperty_Impl( Content& rContent,
1823 const OUString& rPropName,
1824 OUString& rPropValue )
1826 bool bGotProperty = false;
1828 // Get the property
1831 uno::Reference< XPropertySetInfo > aPropInfo = rContent.getProperties();
1833 // check, whether or not the property exists
1834 if ( !aPropInfo.is() || !aPropInfo->hasPropertyByName( rPropName ) )
1836 return false;
1839 // now get the property
1840 Any aAnyValue;
1842 aAnyValue = rContent.getPropertyValue( rPropName );
1843 aAnyValue >>= rPropValue;
1845 if ( SfxURLRelocator_Impl::propertyCanContainOfficeDir( rPropName ) )
1847 SfxURLRelocator_Impl aRelocImpl( ::comphelper::getProcessComponentContext() );
1848 aRelocImpl.makeAbsoluteURL( rPropValue );
1851 bGotProperty = true;
1853 catch ( RuntimeException& ) {}
1854 catch ( Exception& ) {}
1856 return bGotProperty;
1859 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */