1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
31 #include <com/sun/star/uno/Any.h>
32 #include <osl/mutex.hxx>
33 #include <osl/thread.hxx>
35 #include <vcl/svapp.hxx>
36 #include <vcl/settings.hxx>
37 #include <unotools/localedatawrapper.hxx>
38 #include <unotools/pathoptions.hxx>
39 #include <tools/resary.hxx>
40 #include <tools/string.hxx>
41 #include <tools/urlobj.hxx>
42 #include <svtools/ehdl.hxx>
43 #include <svtools/sfxecode.hxx>
44 #include <comphelper/processfactory.hxx>
45 #include <ucbhelper/content.hxx>
46 #include <com/sun/star/beans/PropertyAttribute.hpp>
47 #include <com/sun/star/beans/PropertyValue.hpp>
48 #include <com/sun/star/beans/XPropertyContainer.hpp>
49 #include <com/sun/star/beans/XPropertySet.hpp>
50 #include <com/sun/star/beans/XPropertySetInfo.hpp>
51 #include <com/sun/star/document/XTypeDetection.hpp>
52 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
53 #include <com/sun/star/frame/XComponentLoader.hpp>
54 #include <com/sun/star/frame/DocumentTemplates.hpp>
55 #include <com/sun/star/frame/XDocumentTemplates.hpp>
56 #include <com/sun/star/io/XInputStream.hpp>
57 #include <com/sun/star/io/XPersist.hpp>
58 #include <com/sun/star/lang/XLocalizable.hpp>
59 #include <com/sun/star/sdbc/XResultSet.hpp>
60 #include <com/sun/star/sdbc/XRow.hpp>
61 #include <com/sun/star/ucb/ContentInfo.hpp>
62 #include <com/sun/star/ucb/InsertCommandArgument.hpp>
63 #include <com/sun/star/ucb/NameClash.hpp>
64 #include <com/sun/star/ucb/TransferInfo.hpp>
65 #include <com/sun/star/ucb/XCommandProcessor.hpp>
66 #include <com/sun/star/ucb/XContent.hpp>
67 #include <com/sun/star/ucb/XContentAccess.hpp>
68 #include <com/sun/star/ucb/XAnyCompareFactory.hpp>
69 #include <com/sun/star/ucb/XAnyCompare.hpp>
70 #include <com/sun/star/ucb/NumberedSortingInfo.hpp>
71 #include <com/sun/star/embed/ElementModes.hpp>
72 #include <com/sun/star/embed/XTransactedObject.hpp>
74 #include "sfxurlrelocator.hxx"
76 using namespace ::com::sun::star
;
77 using namespace ::com::sun::star::beans
;
78 using namespace ::com::sun::star::frame
;
79 using namespace ::com::sun::star::io
;
80 using namespace ::com::sun::star::lang
;
81 using namespace ::com::sun::star::sdbc
;
82 using namespace ::com::sun::star::uno
;
83 using namespace ::com::sun::star::ucb
;
84 using namespace ::com::sun::star::document
;
85 using namespace ::rtl
;
86 using namespace ::ucbhelper
;
89 #include <sfx2/doctempl.hxx>
90 #include <sfx2/docfac.hxx>
91 #include <sfx2/docfile.hxx>
92 #include <sfx2/objsh.hxx>
93 #include "sfxtypes.hxx"
94 #include <sfx2/app.hxx>
95 #include "sfx2/sfxresid.hxx"
96 #include <sfx2/templatelocnames.hrc>
98 #include <sfx2/fcontnr.hxx>
99 #include <svtools/templatefoldercache.hxx>
101 #include <comphelper/storagehelper.hxx>
102 #include <unotools/ucbhelper.hxx>
106 using ::std::advance
;
108 //========================================================================
110 #define TITLE "Title"
111 #define TARGET_URL "TargetURL"
113 #define TARGET_DIR_URL "TargetDirURL"
114 #define COMMAND_TRANSFER "transfer"
116 #define SERVICENAME_DOCINFO "com.sun.star.document.DocumentProperties"
117 #define SERVICENAME_DESKTOP "com.sun.star.frame.Desktop"
119 //========================================================================
121 class RegionData_Impl
;
125 class DocTempl_EntryData_Impl
127 RegionData_Impl
* mpParent
;
129 // the following member must be SfxObjectShellLock since it controlls that SfxObjectShell lifetime by design
130 // and users of this class expect it to be so.
131 SfxObjectShellLock mxObjShell
;
135 OUString maTargetURL
;
136 sal_Bool mbIsOwner
: 1;
137 sal_Bool mbDidConvert
: 1;
140 RegionData_Impl
* GetParent() const { return mpParent
; }
143 DocTempl_EntryData_Impl( RegionData_Impl
* pParent
,
144 const OUString
& rTitle
);
146 const OUString
& GetTitle() const { return maTitle
; }
147 const OUString
& GetTargetURL();
148 const OUString
& GetHierarchyURL();
150 void SetTitle( const OUString
& rTitle
) { maTitle
= rTitle
; }
151 void SetTargetURL( const OUString
& rURL
) { maTargetURL
= rURL
; }
152 void SetHierarchyURL( const OUString
& rURL
) { maOwnURL
= rURL
; }
154 int Compare( const OUString
& rTitle
) const;
156 SfxObjectShellRef
CreateObjectShell();
157 sal_Bool
DeleteObjectShell();
162 using namespace ::DocTempl
;
164 // ------------------------------------------------------------------------
166 class RegionData_Impl
168 const SfxDocTemplate_Impl
* mpParent
;
169 vector
< DocTempl_EntryData_Impl
* > maEntries
;
172 OUString maTargetURL
;
175 size_t GetEntryPos( const OUString
& rTitle
,
176 sal_Bool
& rFound
) const;
177 const SfxDocTemplate_Impl
* GetParent() const { return mpParent
; }
180 RegionData_Impl( const SfxDocTemplate_Impl
* pParent
,
181 const OUString
& rTitle
);
184 void SetTargetURL( const OUString
& rURL
) { maTargetURL
= rURL
; }
185 void SetHierarchyURL( const OUString
& rURL
) { maOwnURL
= rURL
; }
187 DocTempl_EntryData_Impl
* GetEntry( size_t nIndex
) const;
188 DocTempl_EntryData_Impl
* GetEntry( const OUString
& rName
) const;
190 const OUString
& GetTitle() const { return maTitle
; }
191 const OUString
& GetTargetURL();
192 const OUString
& GetHierarchyURL();
194 size_t GetCount() const;
196 void SetTitle( const OUString
& rTitle
) { maTitle
= rTitle
; }
198 void AddEntry( const OUString
& rTitle
,
199 const OUString
& rTargetURL
,
200 size_t *pPos
= NULL
);
201 void DeleteEntry( size_t nIndex
);
203 int Compare( const OUString
& rTitle
) const
204 { return maTitle
.compareTo( rTitle
); }
205 int Compare( RegionData_Impl
* pCompareWith
) const;
208 typedef vector
< RegionData_Impl
* > RegionList_Impl
;
210 // ------------------------------------------------------------------------
212 class SfxDocTemplate_Impl
: public SvRefBase
214 uno::Reference
< XPersist
> mxInfo
;
215 uno::Reference
< XDocumentTemplates
> mxTemplates
;
217 ::osl::Mutex maMutex
;
219 OUString maStandardGroup
;
220 RegionList_Impl maRegions
;
221 sal_Bool mbConstructed
;
223 uno::Reference
< XAnyCompareFactory
> m_rCompareFactory
;
225 // the following member is intended to prevent clearing of the global data when it is in use
226 // TODO/LATER: it still does not make the implementation complete thread-safe
227 sal_Int32 mnLockCounter
;
233 SfxDocTemplate_Impl();
234 ~SfxDocTemplate_Impl();
236 void IncrementLock();
237 void DecrementLock();
239 sal_Bool
Construct( );
240 void CreateFromHierarchy( Content
&rTemplRoot
);
241 void ReInitFromComponent();
242 void AddRegion( const OUString
& rTitle
,
247 void DeleteRegion( size_t nIndex
);
249 size_t GetRegionCount() const
250 { return maRegions
.size(); }
251 RegionData_Impl
* GetRegion( const OUString
& rName
) const;
252 RegionData_Impl
* GetRegion( size_t nIndex
) const;
254 sal_Bool
GetTitleFromURL( const OUString
& rURL
, OUString
& aTitle
);
255 sal_Bool
InsertRegion( RegionData_Impl
*pData
, size_t nPos
= size_t(-1) );
256 OUString
GetRootURL() const { return maRootURL
; }
258 uno::Reference
< XDocumentTemplates
> getDocTemplates() { return mxTemplates
; }
261 // ------------------------------------------------------------------------
263 class DocTemplLocker_Impl
265 SfxDocTemplate_Impl
& m_aDocTempl
;
267 DocTemplLocker_Impl( SfxDocTemplate_Impl
& aDocTempl
)
268 : m_aDocTempl( aDocTempl
)
270 m_aDocTempl
.IncrementLock();
273 ~DocTemplLocker_Impl()
275 m_aDocTempl
.DecrementLock();
279 // ------------------------------------------------------------------------
281 #ifndef SFX_DECL_DOCTEMPLATES_DEFINED
282 #define SFX_DECL_DOCTEMPLATES_DEFINED
283 SV_DECL_REF(SfxDocTemplate_Impl
)
286 SV_IMPL_REF(SfxDocTemplate_Impl
)
288 // ------------------------------------------------------------------------
290 SfxDocTemplate_Impl
*gpTemplateData
= 0;
292 // -----------------------------------------------------------------------
294 static sal_Bool
getTextProperty_Impl( Content
& rContent
,
295 const OUString
& rPropName
,
296 OUString
& rPropValue
);
298 //========================================================================
300 String
SfxDocumentTemplates::GetFullRegionName
302 sal_uInt16 nIdx
// Region Index
307 Returns the logical name of a region and its path
309 [Return value] Reference to the Region name
314 // First: find the RegionData for the index
317 DocTemplLocker_Impl
aLocker( *pImp
);
319 if ( pImp
->Construct() )
321 RegionData_Impl
*pData1
= pImp
->GetRegion( nIdx
);
324 aName
= pData1
->GetTitle();
326 // --**-- here was some code which appended the path to the
327 // group if there was more than one with the same name.
328 // this should not happen anymore
334 //------------------------------------------------------------------------
336 const String
& SfxDocumentTemplates::GetRegionName
338 sal_uInt16 nIdx
// Region Index
343 Returns the logical name of a region
347 const String& Reference to the Region name
351 static String maTmpString
;
353 DocTemplLocker_Impl
aLocker( *pImp
);
355 if ( pImp
->Construct() )
357 RegionData_Impl
*pData
= pImp
->GetRegion( nIdx
);
360 maTmpString
= pData
->GetTitle();
370 //------------------------------------------------------------------------
372 sal_uInt16
SfxDocumentTemplates::GetRegionCount() const
376 Returns the number of Regions
380 sal_uInt16 Number of Regions
383 DocTemplLocker_Impl
aLocker( *pImp
);
385 if ( !pImp
->Construct() )
388 sal_uIntPtr nCount
= pImp
->GetRegionCount();
390 return (sal_uInt16
) nCount
;
393 //------------------------------------------------------------------------
395 sal_Bool
SfxDocumentTemplates::IsRegionLoaded( sal_uInt16 nIdx
) const
397 DocTemplLocker_Impl
aLocker( *pImp
);
399 if ( !pImp
->Construct() )
402 RegionData_Impl
*pData
= pImp
->GetRegion( nIdx
);
410 //------------------------------------------------------------------------
412 sal_uInt16
SfxDocumentTemplates::GetCount
414 sal_uInt16 nRegion
/* Region index whose number is
421 Number of entries in Region
423 [Return value] Number of entries
427 DocTemplLocker_Impl
aLocker( *pImp
);
429 if ( !pImp
->Construct() )
432 RegionData_Impl
*pData
= pImp
->GetRegion( nRegion
);
433 sal_uIntPtr nCount
= 0;
436 nCount
= pData
->GetCount();
438 return (sal_uInt16
) nCount
;
441 //------------------------------------------------------------------------
443 const String
& SfxDocumentTemplates::GetName
445 sal_uInt16 nRegion
, // Region Index, in which the entry lies
446 sal_uInt16 nIdx
// Index of the entry
451 Returns the logical name of an entry in Region
455 const String& Entry Name
459 DocTemplLocker_Impl
aLocker( *pImp
);
461 static String maTmpString
;
463 if ( pImp
->Construct() )
465 DocTempl_EntryData_Impl
*pEntry
= NULL
;
466 RegionData_Impl
*pRegion
= pImp
->GetRegion( nRegion
);
469 pEntry
= pRegion
->GetEntry( nIdx
);
472 maTmpString
= pEntry
->GetTitle();
482 //------------------------------------------------------------------------
484 String
SfxDocumentTemplates::GetFileName
486 sal_uInt16 nRegion
, // Region Index, in which the entry lies
487 sal_uInt16 nIdx
// Index of the entry
492 Returns the file name of an entry in Region
494 [Return value] File name of the entry
497 DocTemplLocker_Impl
aLocker( *pImp
);
499 if ( !pImp
->Construct() )
502 DocTempl_EntryData_Impl
*pEntry
= NULL
;
503 RegionData_Impl
*pRegion
= pImp
->GetRegion( nRegion
);
506 pEntry
= pRegion
->GetEntry( nIdx
);
510 INetURLObject
aURLObj( pEntry
->GetTargetURL() );
511 return aURLObj
.getName( INetURLObject::LAST_SEGMENT
, true,
512 INetURLObject::DECODE_WITH_CHARSET
);
518 //------------------------------------------------------------------------
520 String
SfxDocumentTemplates::GetPath
522 sal_uInt16 nRegion
, // Region Index, in which the entry lies
523 sal_uInt16 nIdx
// Index of the entry
528 Returns the file name with full path to the file assigned to an entry
532 String File name with full path
535 DocTemplLocker_Impl
aLocker( *pImp
);
537 if ( !pImp
->Construct() )
540 DocTempl_EntryData_Impl
*pEntry
= NULL
;
541 RegionData_Impl
*pRegion
= pImp
->GetRegion( nRegion
);
544 pEntry
= pRegion
->GetEntry( nIdx
);
547 return pEntry
->GetTargetURL();
552 //------------------------------------------------------------------------
554 ::rtl::OUString
SfxDocumentTemplates::GetTemplateTargetURLFromComponent( const ::rtl::OUString
& aGroupName
,
555 const ::rtl::OUString
& aTitle
)
557 DocTemplLocker_Impl
aLocker( *pImp
);
559 INetURLObject
aTemplateObj( pImp
->GetRootURL() );
561 aTemplateObj
.insertName( aGroupName
, false,
562 INetURLObject::LAST_SEGMENT
, true,
563 INetURLObject::ENCODE_ALL
);
565 aTemplateObj
.insertName( aTitle
, false,
566 INetURLObject::LAST_SEGMENT
, true,
567 INetURLObject::ENCODE_ALL
);
570 ::rtl::OUString aResult
;
572 uno::Reference
< XCommandEnvironment
> aCmdEnv
;
573 if ( Content::create( aTemplateObj
.GetMainURL( INetURLObject::NO_DECODE
), aCmdEnv
, aTemplate
) )
575 OUString
aPropName( TARGET_URL
);
576 getTextProperty_Impl( aTemplate
, aPropName
, aResult
);
577 aResult
= SvtPathOptions().SubstituteVariable( aResult
);
583 //------------------------------------------------------------------------
585 /** Convert a resource string - a template name - to its localised pair if it exists.
587 Resource ID where the list of original en-US template names begin.
589 Resource ID where the list of localised template names begin.
591 The number of names that have been localised.
593 Name to be translated.
595 The localised pair of rString or rString if the former does not exist.
597 OUString
SfxDocumentTemplates::ConvertResourceString (
598 int nSourceResIds
, int nDestResIds
, int nCount
, const OUString
& rString
)
600 for( int i
= 0; i
< nCount
; ++i
)
602 if( rString
== SFX2_RESSTR(nSourceResIds
+ i
))
603 return SFX2_RESSTR(nDestResIds
+ i
);
608 //------------------------------------------------------------------------
610 sal_Bool
SfxDocumentTemplates::CopyOrMove
612 sal_uInt16 nTargetRegion
, // Target Region Index
613 sal_uInt16 nTargetIdx
, // Target position Index
614 sal_uInt16 nSourceRegion
, // Source Region Index
615 sal_uInt16 nSourceIdx
, /* Index to be copied / to moved template */
616 sal_Bool bMove
// Copy / Move
621 Copy or move a document template
625 sal_Bool sal_True, Action could be performed
626 sal_False, Action could not be performed
630 <SfxDocumentTemplates::Move(sal_uInt16,sal_uInt16,sal_uInt16,sal_uInt16)>
631 <SfxDocumentTemplates::Copy(sal_uInt16,sal_uInt16,sal_uInt16,sal_uInt16)>
635 /* to perform a copy or move, we need to send a transfer command to
636 the destination folder with the URL of the source as parameter.
637 ( If the destination content doesn't support the transfer command,
638 we could try a copy ( and delete ) instead. )
639 We need two transfers ( one for the real template and one for its
640 representation in the hierarchy )
644 DocTemplLocker_Impl
aLocker( *pImp
);
646 if ( !pImp
->Construct() )
649 // Don't copy or move any folders
650 if( nSourceIdx
== USHRT_MAX
)
653 if ( nSourceRegion
== nTargetRegion
)
655 SAL_WARN( "sfx2.doc", "Don't know, what to do!" );
659 RegionData_Impl
*pSourceRgn
= pImp
->GetRegion( nSourceRegion
);
663 DocTempl_EntryData_Impl
*pSource
= pSourceRgn
->GetEntry( nSourceIdx
);
667 RegionData_Impl
*pTargetRgn
= pImp
->GetRegion( nTargetRegion
);
671 OUString aTitle
= pSource
->GetTitle();
673 uno::Reference
< XDocumentTemplates
> xTemplates
= pImp
->getDocTemplates();
675 if ( xTemplates
->addTemplate( pTargetRgn
->GetTitle(),
677 pSource
->GetTargetURL() ) )
680 INetURLObject
aSourceObj( pSource
->GetTargetURL() );
682 ::rtl::OUString aNewTargetURL
= GetTemplateTargetURLFromComponent( pTargetRgn
->GetTitle(), aTitle
);
683 if ( aNewTargetURL
.isEmpty() )
688 // --**-- delete the original file
689 sal_Bool bDeleted
= xTemplates
->removeTemplate( pSourceRgn
->GetTitle(),
690 pSource
->GetTitle() );
692 pSourceRgn
->DeleteEntry( nSourceIdx
);
695 if ( xTemplates
->removeTemplate( pTargetRgn
->GetTitle(), aTitle
) )
696 return sal_False
; // will trigger tetry with copy instead of move
698 // if it is not possible to remove just created template ( must be possible! )
699 // it is better to report success here, since at least the copy has succeeded
700 // TODO/LATER: solve it more gracefully in future
704 // todo: fix SfxDocumentTemplates to handle size_t instead of sal_uInt16
705 size_t temp_nTargetIdx
= nTargetIdx
;
706 pTargetRgn
->AddEntry( aTitle
, aNewTargetURL
, &temp_nTargetIdx
);
711 // --**-- if the current file is opened,
712 // it must be re-opened afterwards.
717 //------------------------------------------------------------------------
719 sal_Bool
SfxDocumentTemplates::Move
721 sal_uInt16 nTargetRegion
, // Target Region Index
722 sal_uInt16 nTargetIdx
, // Target position Index
723 sal_uInt16 nSourceRegion
, // Source Region Index
724 sal_uInt16 nSourceIdx
/* Index to be copied / to moved template */
733 sal_Bool sal_True, Action could be performed
734 sal_False, Action could not be performed
738 <SfxDocumentTemplates::CopyOrMove(sal_uInt16,sal_uInt16,sal_uInt16,sal_uInt16,sal_Bool)>
741 DocTemplLocker_Impl
aLocker( *pImp
);
743 return CopyOrMove( nTargetRegion
, nTargetIdx
,
744 nSourceRegion
, nSourceIdx
, sal_True
);
747 //------------------------------------------------------------------------
749 sal_Bool
SfxDocumentTemplates::Copy
751 sal_uInt16 nTargetRegion
, // Target Region Index
752 sal_uInt16 nTargetIdx
, // Target position Index
753 sal_uInt16 nSourceRegion
, // Source Region Index
754 sal_uInt16 nSourceIdx
/* Index to be copied / to moved template */
763 sal_Bool sal_True, Action could be performed
764 sal_False, Action could not be performed
768 <SfxDocumentTemplates::CopyOrMove(sal_uInt16,sal_uInt16,sal_uInt16,sal_uInt16,sal_Bool)>
772 DocTemplLocker_Impl
aLocker( *pImp
);
774 return CopyOrMove( nTargetRegion
, nTargetIdx
,
775 nSourceRegion
, nSourceIdx
, sal_False
);
778 //------------------------------------------------------------------------
780 sal_Bool
SfxDocumentTemplates::CopyTo
782 sal_uInt16 nRegion
, // Region of the template to be exported
783 sal_uInt16 nIdx
, // Index of the template to be exported
784 const String
& rName
/* File name under which the template is to
790 Exporting a template into the file system
794 sal_Bool sal_True, Action could be performed
795 sal_False, Action could not be performed
799 <SfxDocumentTemplates::CopyFrom(sal_uInt16,sal_uInt16,String&)>
803 DocTemplLocker_Impl
aLocker( *pImp
);
805 if ( ! pImp
->Construct() )
808 RegionData_Impl
*pSourceRgn
= pImp
->GetRegion( nRegion
);
812 DocTempl_EntryData_Impl
*pSource
= pSourceRgn
->GetEntry( nIdx
);
816 INetURLObject
aTargetURL( rName
);
818 OUString
aTitle( aTargetURL
.getName( INetURLObject::LAST_SEGMENT
, true,
819 INetURLObject::DECODE_WITH_CHARSET
) );
820 aTargetURL
.removeSegment();
822 OUString aParentURL
= aTargetURL
.GetMainURL( INetURLObject::NO_DECODE
);
824 uno::Reference
< XCommandEnvironment
> aCmdEnv
;
829 aTarget
= Content( aParentURL
, aCmdEnv
);
831 TransferInfo aTransferInfo
;
832 aTransferInfo
.MoveData
= sal_False
;
833 aTransferInfo
.SourceURL
= pSource
->GetTargetURL();
834 aTransferInfo
.NewTitle
= aTitle
;
835 aTransferInfo
.NameClash
= NameClash::OVERWRITE
;
837 Any aArg
= makeAny( aTransferInfo
);
838 OUString
aCmd( COMMAND_TRANSFER
);
840 aTarget
.executeCommand( aCmd
, aArg
);
842 catch ( ContentCreationException
& )
843 { return sal_False
; }
845 { return sal_False
; }
850 //------------------------------------------------------------------------
852 sal_Bool
SfxDocumentTemplates::CopyFrom
854 sal_uInt16 nRegion
, /* Region in which the template is to be
856 sal_uInt16 nIdx
, // Index of the new template in this Region
857 String
& rName
/* File name of the template to be imported
858 as an out parameter of the (automatically
859 generated from the file name) logical name
865 Import a template from the file system
867 [Return value] Sucess (sal_True) or serfpTargetDirectory->GetContent());
869 sal_Bool sal_True, Action could be performed
870 sal_False, Action could not be performed
874 <SfxDocumentTemplates::CopyTo(sal_uInt16,sal_uInt16,const String&)>
878 DocTemplLocker_Impl
aLocker( *pImp
);
880 if ( ! pImp
->Construct() )
883 RegionData_Impl
*pTargetRgn
= pImp
->GetRegion( nRegion
);
888 uno::Reference
< XDocumentTemplates
> xTemplates
= pImp
->getDocTemplates();
889 if ( !xTemplates
.is() )
893 sal_Bool bTemplateAdded
= sal_False
;
895 if( pImp
->GetTitleFromURL( rName
, aTitle
) )
897 bTemplateAdded
= xTemplates
->addTemplate( pTargetRgn
->GetTitle(), aTitle
, rName
);
901 OUString
aService( SERVICENAME_DESKTOP
);
902 uno::Reference
< XComponentLoader
> xDesktop( ::comphelper::getProcessServiceFactory()->createInstance( aService
),
905 Sequence
< PropertyValue
> aArgs( 1 );
906 aArgs
[0].Name
= ::rtl::OUString("Hidden");
907 aArgs
[0].Value
<<= sal_True
;
909 INetURLObject
aTemplURL( rName
);
910 uno::Reference
< XDocumentPropertiesSupplier
> xDocPropsSupplier
;
911 uno::Reference
< XStorable
> xStorable
;
914 xStorable
= uno::Reference
< XStorable
>(
915 xDesktop
->loadComponentFromURL( aTemplURL
.GetMainURL(INetURLObject::NO_DECODE
),
921 xDocPropsSupplier
= uno::Reference
< XDocumentPropertiesSupplier
>(
922 xStorable
, UNO_QUERY
);
930 // get Title from XDocumentPropertiesSupplier
931 if( xDocPropsSupplier
.is() )
933 uno::Reference
< XDocumentProperties
> xDocProps
934 = xDocPropsSupplier
->getDocumentProperties();
935 if (xDocProps
.is() ) {
936 aTitle
= xDocProps
->getTitle();
940 if( aTitle
.isEmpty() )
942 INetURLObject
aURL( aTemplURL
);
944 aTitle
= aURL
.getName( INetURLObject::LAST_SEGMENT
, true,
945 INetURLObject::DECODE_WITH_CHARSET
);
948 // write a template using XStorable interface
949 bTemplateAdded
= xTemplates
->storeTemplate( pTargetRgn
->GetTitle(), aTitle
, xStorable
);
956 INetURLObject
aTemplObj( pTargetRgn
->GetHierarchyURL() );
957 aTemplObj
.insertName( aTitle
, false,
958 INetURLObject::LAST_SEGMENT
, true,
959 INetURLObject::ENCODE_ALL
);
960 OUString aTemplURL
= aTemplObj
.GetMainURL( INetURLObject::NO_DECODE
);
962 uno::Reference
< XCommandEnvironment
> aCmdEnv
;
965 if( Content::create( aTemplURL
, aCmdEnv
, aTemplCont
) )
968 OUString
aPropName( TARGET_URL
);
970 if( getTextProperty_Impl( aTemplCont
, aPropName
, aTemplName
) )
972 if ( nIdx
== USHRT_MAX
)
977 // todo: fix SfxDocumentTemplates to handle size_t instead of sal_uInt16
978 size_t temp_nIdx
= nIdx
;
979 pTargetRgn
->AddEntry( aTitle
, aTemplName
, &temp_nIdx
);
985 DBG_ASSERT( sal_False
, "CopyFrom(): The content should contain target URL!" );
990 DBG_ASSERT( sal_False
, "CopyFrom(): The content just was created!" );
997 //------------------------------------------------------------------------
999 sal_Bool
SfxDocumentTemplates::Delete
1001 sal_uInt16 nRegion
, // Region Index
1002 sal_uInt16 nIdx
/* Index of the entry or USHRT_MAX,
1003 if a directory is meant. */
1008 Deleting an entry or a directory
1012 sal_Bool sal_True, Action could be performed
1013 sal_False, Action could not be performed
1017 <SfxDocumentTemplates::InsertDir(const String&,sal_uInt16)>
1018 <SfxDocumentTemplates::KillDir(SfxTemplateDir&)>
1022 DocTemplLocker_Impl
aLocker( *pImp
);
1024 /* delete the template or folder in the hierarchy and in the
1025 template folder by sending a delete command to the content.
1026 Then remove the data from the lists
1028 if ( ! pImp
->Construct() )
1031 RegionData_Impl
*pRegion
= pImp
->GetRegion( nRegion
);
1037 uno::Reference
< XDocumentTemplates
> xTemplates
= pImp
->getDocTemplates();
1039 if ( nIdx
== USHRT_MAX
)
1041 bRet
= xTemplates
->removeGroup( pRegion
->GetTitle() );
1043 pImp
->DeleteRegion( nRegion
);
1047 DocTempl_EntryData_Impl
*pEntry
= pRegion
->GetEntry( nIdx
);
1052 bRet
= xTemplates
->removeTemplate( pRegion
->GetTitle(),
1053 pEntry
->GetTitle() );
1055 pRegion
->DeleteEntry( nIdx
);
1061 //------------------------------------------------------------------------
1063 sal_Bool
SfxDocumentTemplates::InsertDir
1065 const String
& rText
, // the logical name of the new Region
1066 sal_uInt16 nRegion
// Region Index
1075 sal_Bool sal_True, Action could be performed
1076 sal_False, Action could not be performed
1080 <SfxDocumentTemplates::KillDir(SfxTemplateDir&)>
1083 DocTemplLocker_Impl
aLocker( *pImp
);
1085 if ( ! pImp
->Construct() )
1088 RegionData_Impl
*pRegion
= pImp
->GetRegion( rText
);
1093 uno::Reference
< XDocumentTemplates
> xTemplates
= pImp
->getDocTemplates();
1095 if ( xTemplates
->addGroup( rText
) )
1097 RegionData_Impl
* pNewRegion
= new RegionData_Impl( pImp
, rText
);
1099 if ( ! pImp
->InsertRegion( pNewRegion
, nRegion
) )
1110 //------------------------------------------------------------------------
1112 sal_Bool
SfxDocumentTemplates::SetName
1114 const String
& rName
, // Der zu setzende Name
1115 sal_uInt16 nRegion
, // Region Index
1116 sal_uInt16 nIdx
/* Index of the entry oder USHRT_MAX,
1117 if a directory is meant. */
1122 Change the name of an entry or a directory
1126 sal_Bool sal_True, Action could be performed
1127 sal_False, Action could not be performed
1132 DocTemplLocker_Impl
aLocker( *pImp
);
1134 if ( ! pImp
->Construct() )
1137 RegionData_Impl
*pRegion
= pImp
->GetRegion( nRegion
);
1138 DocTempl_EntryData_Impl
*pEntry
= NULL
;
1143 uno::Reference
< XDocumentTemplates
> xTemplates
= pImp
->getDocTemplates();
1146 if ( nIdx
== USHRT_MAX
)
1148 if ( pRegion
->GetTitle() == OUString( rName
) )
1151 // we have to rename a region
1152 if ( xTemplates
->renameGroup( pRegion
->GetTitle(), rName
) )
1154 pRegion
->SetTitle( rName
);
1155 pRegion
->SetTargetURL( aEmpty
);
1156 pRegion
->SetHierarchyURL( aEmpty
);
1162 pEntry
= pRegion
->GetEntry( nIdx
);
1167 if ( pEntry
->GetTitle() == OUString( rName
) )
1170 if ( xTemplates
->renameTemplate( pRegion
->GetTitle(),
1174 pEntry
->SetTitle( rName
);
1175 pEntry
->SetTargetURL( aEmpty
);
1176 pEntry
->SetHierarchyURL( aEmpty
);
1184 //------------------------------------------------------------------------
1186 sal_Bool
SfxDocumentTemplates::Rescan()
1190 Comparison of administrative data with the current state on disk.
1191 The logical name for which no file exists, will be removed from the
1192 administrative structure. Files for which no record exists will be included.
1196 sal_Bool sal_True, Action could be performed
1197 sal_False, Action could not be performed
1201 <SfxTemplateDir::Scan(sal_Bool bDirectory, sal_Bool bSave)>
1202 <SfxTemplateDir::Freshen(const SfxTemplateDir &rNew)>
1205 if ( !pImp
->Construct() )
1213 //------------------------------------------------------------------------
1215 SfxObjectShellRef
SfxDocumentTemplates::CreateObjectShell
1217 sal_uInt16 nRegion
, // Region Index
1218 sal_uInt16 nIdx
// Index of the entry
1223 Access to the document shell of an entry
1227 SfxObjectShellRef Referece to the ObjectShell
1231 <SfxTemplateDirEntry::CreateObjectShell()>
1232 <SfxDocumentTemplates::DeleteObjectShell(sal_uInt16, sal_uInt16)>
1236 DocTemplLocker_Impl
aLocker( *pImp
);
1238 if ( !pImp
->Construct() )
1241 RegionData_Impl
*pRegion
= pImp
->GetRegion( nRegion
);
1242 DocTempl_EntryData_Impl
*pEntry
= NULL
;
1245 pEntry
= pRegion
->GetEntry( nIdx
);
1248 return pEntry
->CreateObjectShell();
1253 //------------------------------------------------------------------------
1255 sal_Bool
SfxDocumentTemplates::DeleteObjectShell
1257 sal_uInt16 nRegion
, // Region Index
1258 sal_uInt16 nIdx
// Index of the entry
1263 Releasing the ObjectShell of an entry
1267 sal_Bool sal_True, Action could be performed
1268 sal_False, Action could not be performed
1272 <SfxTemplateDirEntry::DeleteObjectShell()>
1273 <SfxDocumentTemplates::CreateObjectShell(sal_uInt16, sal_uInt16)>
1277 DocTemplLocker_Impl
aLocker( *pImp
);
1279 if ( ! pImp
->Construct() )
1282 RegionData_Impl
*pRegion
= pImp
->GetRegion( nRegion
);
1283 DocTempl_EntryData_Impl
*pEntry
= NULL
;
1286 pEntry
= pRegion
->GetEntry( nIdx
);
1289 return pEntry
->DeleteObjectShell();
1294 //------------------------------------------------------------------------
1296 sal_Bool
SfxDocumentTemplates::GetFull
1298 const String
&rRegion
, // Region Name
1299 const String
&rName
, // Template Name
1300 String
&rPath
// Out: Path + File name
1305 Returns Path + File name of the template specified by rRegion and rName.
1309 sal_Bool sal_True, Action could be performed
1310 sal_False, Action could not be performed
1314 <SfxDocumentTemplates::GetLogicNames(const String&,String&,String&)>
1318 DocTemplLocker_Impl
aLocker( *pImp
);
1320 // We don't search for empty names!
1321 if ( ! rName
.Len() )
1324 if ( ! pImp
->Construct() )
1327 DocTempl_EntryData_Impl
* pEntry
= NULL
;
1328 const sal_uInt16 nCount
= GetRegionCount();
1330 for ( sal_uInt16 i
= 0; i
< nCount
; ++i
)
1332 RegionData_Impl
*pRegion
= pImp
->GetRegion( i
);
1335 ( !rRegion
.Len() || ( rRegion
== String( pRegion
->GetTitle() ) ) ) )
1337 pEntry
= pRegion
->GetEntry( rName
);
1341 rPath
= pEntry
->GetTargetURL();
1347 return ( pEntry
!= NULL
);
1350 //------------------------------------------------------------------------
1352 sal_Bool
SfxDocumentTemplates::GetLogicNames
1354 const String
&rPath
, // Full Path to the template
1355 String
&rRegion
, // Out: Region name
1356 String
&rName
// Out: Template name
1361 Returns and logical path name to the template specified by rPath
1365 sal_Bool sal_True, Action could be performed
1366 sal_False, Action could not be performed
1370 <SfxDocumentTemplates::GetFull(const String&,const String&,DirEntry&)>
1374 DocTemplLocker_Impl
aLocker( *pImp
);
1376 if ( ! pImp
->Construct() )
1379 INetURLObject aFullPath
;
1381 aFullPath
.SetSmartProtocol( INET_PROT_FILE
);
1382 aFullPath
.SetURL( rPath
);
1383 OUString
aPath( aFullPath
.GetMainURL( INetURLObject::NO_DECODE
) );
1385 RegionData_Impl
*pData
= NULL
;
1386 DocTempl_EntryData_Impl
*pEntry
= NULL
;
1387 sal_Bool bFound
= sal_False
;
1389 sal_uIntPtr nCount
= GetRegionCount();
1391 for ( sal_uIntPtr i
=0; !bFound
&& (i
<nCount
); i
++ )
1393 pData
= pImp
->GetRegion( i
);
1396 sal_uIntPtr nChildCount
= pData
->GetCount();
1398 for ( sal_uIntPtr j
=0; !bFound
&& (j
<nChildCount
); j
++ )
1400 pEntry
= pData
->GetEntry( j
);
1401 if ( pEntry
->GetTargetURL() == aPath
)
1411 rRegion
= pData
->GetTitle();
1412 rName
= pEntry
->GetTitle();
1418 //------------------------------------------------------------------------
1420 SfxDocumentTemplates::SfxDocumentTemplates()
1427 if ( !gpTemplateData
)
1428 gpTemplateData
= new SfxDocTemplate_Impl
;
1430 pImp
= gpTemplateData
;
1433 //-------------------------------------------------------------------------
1435 void SfxDocumentTemplates::Construct()
1437 // Delayed build-up of administrative data
1442 //------------------------------------------------------------------------
1444 SfxDocumentTemplates::~SfxDocumentTemplates()
1449 Release of administrative data
1456 void SfxDocumentTemplates::Update( sal_Bool _bSmart
)
1458 if ( !_bSmart
// don't be smart
1459 || ::svt::TemplateFolderCache( sal_True
).needsUpdate() // update is really necessary
1462 if ( pImp
->Construct() )
1467 void SfxDocumentTemplates::ReInitFromComponent()
1469 pImp
->ReInitFromComponent();
1473 sal_Bool
SfxDocumentTemplates::HasUserContents( sal_uInt16 nRegion
, sal_uInt16 nIdx
) const
1475 DocTemplLocker_Impl
aLocker( *pImp
);
1477 sal_Bool bResult
= sal_False
;
1479 RegionData_Impl
* pRegion
= pImp
->GetRegion( nRegion
);
1483 ::rtl::OUString aRegionTargetURL
= pRegion
->GetTargetURL();
1484 if ( !aRegionTargetURL
.isEmpty() )
1486 sal_uInt16 nLen
= 0;
1487 sal_uInt16 nStartInd
= 0;
1489 if( nIdx
== USHRT_MAX
)
1492 // check whether there is at least one editable template
1493 nLen
= ( sal_uInt16
)pRegion
->GetCount();
1496 bResult
= sal_True
; // the writing part of empty folder with writing URL can be removed
1500 // this is a template
1501 // check whether the template is inserted by user
1506 for ( sal_uInt16 nInd
= nStartInd
; nInd
< nStartInd
+ nLen
; nInd
++ )
1508 DocTempl_EntryData_Impl
* pEntryData
= pRegion
->GetEntry( nInd
);
1511 ::rtl::OUString aEntryTargetURL
= pEntryData
->GetTargetURL();
1512 if ( !aEntryTargetURL
.isEmpty()
1513 && ::utl::UCBContentHelper::IsSubPath( aRegionTargetURL
, aEntryTargetURL
) )
1526 // -----------------------------------------------------------------------
1527 DocTempl_EntryData_Impl::DocTempl_EntryData_Impl( RegionData_Impl
* pParent
,
1528 const OUString
& rTitle
)
1531 maTitle
= SfxDocumentTemplates::ConvertResourceString(
1532 STR_TEMPLATE_NAME1_DEF
, STR_TEMPLATE_NAME1
, NUM_TEMPLATE_NAMES
, rTitle
);
1533 mbIsOwner
= sal_False
;
1534 mbDidConvert
= sal_False
;
1537 // -----------------------------------------------------------------------
1538 int DocTempl_EntryData_Impl::Compare( const OUString
& rTitle
) const
1540 return maTitle
.compareTo( rTitle
);
1543 // -----------------------------------------------------------------------
1544 SfxObjectShellRef
DocTempl_EntryData_Impl::CreateObjectShell()
1546 if( ! mxObjShell
.Is() )
1548 mbIsOwner
= sal_False
;
1549 sal_Bool bDum
= sal_False
;
1550 SfxApplication
*pSfxApp
= SFX_APP();
1551 String aTargetURL
= GetTargetURL();
1553 mxObjShell
= pSfxApp
->DocAlreadyLoaded( aTargetURL
, sal_True
, bDum
);
1555 if( ! mxObjShell
.Is() )
1557 mbIsOwner
= sal_True
;
1558 SfxMedium
*pMed
=new SfxMedium(
1559 aTargetURL
,(STREAM_STD_READWRITE
| STREAM_SHARE_DENYALL
), sal_False
, 0 );
1560 const SfxFilter
* pFilter
= NULL
;
1561 pMed
->UseInteractionHandler(sal_True
);
1562 if( pSfxApp
->GetFilterMatcher().GuessFilter(
1563 *pMed
, &pFilter
, SFX_FILTER_TEMPLATE
, 0 ) ||
1564 (pFilter
&& !pFilter
->IsOwnFormat()) ||
1565 (pFilter
&& !pFilter
->UsesStorage()) )
1567 SfxErrorContext
aEc( ERRCTX_SFX_LOADTEMPLATE
,
1570 mbDidConvert
=sal_True
;
1572 if ( mxObjShell
.Is() ) {
1573 lErr
= pSfxApp
->LoadTemplate( mxObjShell
,aTargetURL
);
1574 if( lErr
!= ERRCODE_NONE
)
1575 ErrorHandler::HandleError(lErr
);
1581 mbDidConvert
=sal_False
;
1582 mxObjShell
= SfxObjectShell::CreateObject( pFilter
->GetServiceName(), SFX_CREATE_MODE_ORGANIZER
);
1583 if ( mxObjShell
.Is() )
1585 mxObjShell
->DoInitNew(0);
1586 // TODO/LATER: make sure that we don't use binary templates!
1587 if( mxObjShell
->LoadFrom( *pMed
) )
1589 mxObjShell
->DoSaveCompleted( pMed
);
1598 return (SfxObjectShellRef
)(SfxObjectShell
*) mxObjShell
;
1601 //------------------------------------------------------------------------
1602 sal_Bool
DocTempl_EntryData_Impl::DeleteObjectShell()
1604 sal_Bool bRet
= sal_True
;
1606 if ( mxObjShell
.Is() )
1608 if( mxObjShell
->IsModified() )
1610 // Here we also save, if the Template is being processed ...
1617 bRet
=mxObjShell
->PreDoSaveAs_Impl(
1619 mxObjShell
->GetFactory().GetFilterContainer()->GetAnyFilter( SFX_FILTER_EXPORT
| SFX_FILTER_IMPORT
, SFX_FILTER_INTERNAL
)->GetFilterName(), 0 );
1623 if( mxObjShell
->Save() )
1625 uno::Reference
< embed::XTransactedObject
> xTransacted( mxObjShell
->GetStorage(), uno::UNO_QUERY
);
1626 DBG_ASSERT( xTransacted
.is(), "Storage must implement XTransactedObject!\n" );
1627 if ( xTransacted
.is() )
1631 xTransacted
->commit();
1634 catch( uno::Exception
& )
1651 // -----------------------------------------------------------------------
1652 const OUString
& DocTempl_EntryData_Impl::GetHierarchyURL()
1654 if ( maOwnURL
.isEmpty() )
1656 INetURLObject
aTemplateObj( GetParent()->GetHierarchyURL() );
1658 aTemplateObj
.insertName( GetTitle(), false,
1659 INetURLObject::LAST_SEGMENT
, true,
1660 INetURLObject::ENCODE_ALL
);
1662 maOwnURL
= aTemplateObj
.GetMainURL( INetURLObject::NO_DECODE
);
1663 DBG_ASSERT( !maOwnURL
.isEmpty(), "GetHierarchyURL(): Could not create URL!" );
1669 // -----------------------------------------------------------------------
1670 const OUString
& DocTempl_EntryData_Impl::GetTargetURL()
1672 if ( maTargetURL
.isEmpty() )
1674 uno::Reference
< XCommandEnvironment
> aCmdEnv
;
1677 if ( Content::create( GetHierarchyURL(), aCmdEnv
, aRegion
) )
1679 OUString
aPropName( TARGET_URL
);
1681 getTextProperty_Impl( aRegion
, aPropName
, maTargetURL
);
1685 SAL_WARN( "sfx2.doc", "GetTargetURL(): Could not create hierarchy content!" );
1692 // -----------------------------------------------------------------------
1693 RegionData_Impl::RegionData_Impl( const SfxDocTemplate_Impl
* pParent
,
1694 const OUString
& rTitle
)
1700 // -----------------------------------------------------------------------
1701 RegionData_Impl::~RegionData_Impl()
1703 for ( size_t i
= 0, n
= maEntries
.size(); i
< n
; ++i
)
1704 delete maEntries
[ i
];
1708 // -----------------------------------------------------------------------
1709 size_t RegionData_Impl::GetEntryPos( const OUString
& rTitle
, sal_Bool
& rFound
) const
1711 #if 1 // Don't use binary search today
1713 size_t nCount
= maEntries
.size();
1715 for ( i
=0; i
<nCount
; i
++ )
1717 DocTempl_EntryData_Impl
*pData
= maEntries
[ i
];
1719 if ( pData
->Compare( rTitle
) == 0 )
1730 // use binary search to find the correct position
1731 // in the maEntries list
1735 size_t nEnd
= maEntries
.size() - 1;
1738 DocTempl_EntryData_Impl
* pMid
;
1742 while ( nCompVal
&& ( nStart
<= nEnd
) )
1744 nMid
= ( nEnd
- nStart
) / 2 + nStart
;
1745 pMid
= maEntries
[ nMid
];
1747 nCompVal
= pMid
->Compare( rTitle
);
1749 if ( nCompVal
< 0 ) // pMid < pData
1755 if ( nCompVal
== 0 )
1761 if ( nCompVal
< 0 ) // pMid < pData
1769 // -----------------------------------------------------------------------
1770 void RegionData_Impl::AddEntry( const OUString
& rTitle
,
1771 const OUString
& rTargetURL
,
1774 INetURLObject
aLinkObj( GetHierarchyURL() );
1775 aLinkObj
.insertName( rTitle
, false,
1776 INetURLObject::LAST_SEGMENT
, true,
1777 INetURLObject::ENCODE_ALL
);
1778 OUString aLinkURL
= aLinkObj
.GetMainURL( INetURLObject::NO_DECODE
);
1780 DocTempl_EntryData_Impl
* pEntry
;
1781 sal_Bool bFound
= sal_False
;
1782 size_t nPos
= GetEntryPos( rTitle
, bFound
);
1786 pEntry
= maEntries
[ nPos
];
1793 pEntry
= new DocTempl_EntryData_Impl( this, rTitle
);
1794 pEntry
->SetTargetURL( rTargetURL
);
1795 pEntry
->SetHierarchyURL( aLinkURL
);
1796 if ( nPos
< maEntries
.size() ) {
1797 vector
< DocTempl_EntryData_Impl
* >::iterator it
= maEntries
.begin();
1798 advance( it
, nPos
);
1799 maEntries
.insert( it
, pEntry
);
1802 maEntries
.push_back( pEntry
);
1806 // -----------------------------------------------------------------------
1807 size_t RegionData_Impl::GetCount() const
1809 return maEntries
.size();
1812 // -----------------------------------------------------------------------
1813 const OUString
& RegionData_Impl::GetHierarchyURL()
1815 if ( maOwnURL
.isEmpty() )
1817 INetURLObject
aRegionObj( GetParent()->GetRootURL() );
1819 aRegionObj
.insertName( GetTitle(), false,
1820 INetURLObject::LAST_SEGMENT
, true,
1821 INetURLObject::ENCODE_ALL
);
1823 maOwnURL
= aRegionObj
.GetMainURL( INetURLObject::NO_DECODE
);
1824 DBG_ASSERT( !maOwnURL
.isEmpty(), "GetHierarchyURL(): Could not create URL!" );
1830 // -----------------------------------------------------------------------
1831 const OUString
& RegionData_Impl::GetTargetURL()
1833 if ( maTargetURL
.isEmpty() )
1835 uno::Reference
< XCommandEnvironment
> aCmdEnv
;
1838 if ( Content::create( GetHierarchyURL(), aCmdEnv
, aRegion
) )
1840 OUString
aPropName( TARGET_DIR_URL
);
1842 getTextProperty_Impl( aRegion
, aPropName
, maTargetURL
);
1843 // The targeturl must be substituted: $(baseinsturl) (#i32656#)
1844 maTargetURL
= SvtPathOptions().SubstituteVariable( maTargetURL
);
1848 SAL_WARN( "sfx2.doc", "GetTargetURL(): Could not create hierarchy content!" );
1855 // -----------------------------------------------------------------------
1856 DocTempl_EntryData_Impl
* RegionData_Impl::GetEntry( const OUString
& rName
) const
1858 sal_Bool bFound
= sal_False
;
1859 long nPos
= GetEntryPos( rName
, bFound
);
1862 return maEntries
[ nPos
];
1867 // -----------------------------------------------------------------------
1868 DocTempl_EntryData_Impl
* RegionData_Impl::GetEntry( size_t nIndex
) const
1870 if ( nIndex
< maEntries
.size() )
1871 return maEntries
[ nIndex
];
1875 // -----------------------------------------------------------------------
1876 void RegionData_Impl::DeleteEntry( size_t nIndex
)
1878 if ( nIndex
< maEntries
.size() )
1880 delete maEntries
[ nIndex
];
1881 vector
< DocTempl_EntryData_Impl
*>::iterator it
= maEntries
.begin();
1882 advance( it
, nIndex
);
1883 maEntries
.erase( it
);
1887 // -----------------------------------------------------------------------
1888 int RegionData_Impl::Compare( RegionData_Impl
* pCompare
) const
1890 int nCompare
= maTitle
.compareTo( pCompare
->maTitle
);
1895 // -----------------------------------------------------------------------
1897 SfxDocTemplate_Impl::SfxDocTemplate_Impl()
1898 : mbConstructed( sal_False
)
1899 , mnLockCounter( 0 )
1903 // -----------------------------------------------------------------------
1904 SfxDocTemplate_Impl::~SfxDocTemplate_Impl()
1908 gpTemplateData
= NULL
;
1911 // -----------------------------------------------------------------------
1912 void SfxDocTemplate_Impl::IncrementLock()
1914 ::osl::MutexGuard
aGuard( maMutex
);
1918 // -----------------------------------------------------------------------
1919 void SfxDocTemplate_Impl::DecrementLock()
1921 ::osl::MutexGuard
aGuard( maMutex
);
1922 if ( mnLockCounter
)
1926 // -----------------------------------------------------------------------
1927 RegionData_Impl
* SfxDocTemplate_Impl::GetRegion( size_t nIndex
) const
1929 if ( nIndex
< maRegions
.size() )
1930 return maRegions
[ nIndex
];
1934 // -----------------------------------------------------------------------
1935 RegionData_Impl
* SfxDocTemplate_Impl::GetRegion( const OUString
& rName
)
1938 for ( size_t i
= 0, n
= maRegions
.size(); i
< n
; ++i
)
1940 RegionData_Impl
* pData
= maRegions
[ i
];
1941 if( pData
->GetTitle() == rName
)
1947 // -----------------------------------------------------------------------
1948 void SfxDocTemplate_Impl::DeleteRegion( size_t nIndex
)
1950 if ( nIndex
< maRegions
.size() )
1952 delete maRegions
[ nIndex
];
1953 RegionList_Impl::iterator it
= maRegions
.begin();
1954 advance( it
, nIndex
);
1955 maRegions
.erase( it
);
1959 // -----------------------------------------------------------------------
1960 /* AddRegion adds a Region to the RegionList
1962 void SfxDocTemplate_Impl::AddRegion( const OUString
& rTitle
,
1965 RegionData_Impl
* pRegion
;
1966 pRegion
= new RegionData_Impl( this, rTitle
);
1968 if ( ! InsertRegion( pRegion
) )
1974 // now get the content of the region
1975 uno::Reference
< XResultSet
> xResultSet
;
1976 Sequence
< OUString
> aProps(2);
1977 aProps
[0] = OUString(TITLE
);
1978 aProps
[1] = OUString(TARGET_URL
);
1982 ResultSetInclude eInclude
= INCLUDE_DOCUMENTS_ONLY
;
1983 Sequence
< NumberedSortingInfo
> aSortingInfo(1);
1984 aSortingInfo
.getArray()->ColumnIndex
= 1;
1985 aSortingInfo
.getArray()->Ascending
= sal_True
;
1986 xResultSet
= rContent
.createSortedCursor( aProps
, aSortingInfo
, m_rCompareFactory
, eInclude
);
1988 catch ( Exception
& ) {}
1990 if ( xResultSet
.is() )
1992 uno::Reference
< XContentAccess
> xContentAccess( xResultSet
, UNO_QUERY
);
1993 uno::Reference
< XRow
> xRow( xResultSet
, UNO_QUERY
);
1997 while ( xResultSet
->next() )
1999 OUString
aTitle( xRow
->getString( 1 ) );
2000 OUString
aTargetDir( xRow
->getString( 2 ) );
2002 pRegion
->AddEntry( aTitle
, aTargetDir
);
2005 catch ( Exception
& ) {}
2009 // -----------------------------------------------------------------------
2010 void SfxDocTemplate_Impl::CreateFromHierarchy( Content
&rTemplRoot
)
2012 uno::Reference
< XResultSet
> xResultSet
;
2013 Sequence
< OUString
> aProps(1);
2014 aProps
[0] = OUString(TITLE
);
2018 ResultSetInclude eInclude
= INCLUDE_FOLDERS_ONLY
;
2019 Sequence
< NumberedSortingInfo
> aSortingInfo(1);
2020 aSortingInfo
.getArray()->ColumnIndex
= 1;
2021 aSortingInfo
.getArray()->Ascending
= sal_True
;
2022 xResultSet
= rTemplRoot
.createSortedCursor( aProps
, aSortingInfo
, m_rCompareFactory
, eInclude
);
2024 catch ( Exception
& ) {}
2026 if ( xResultSet
.is() )
2028 uno::Reference
< XCommandEnvironment
> aCmdEnv
;
2029 uno::Reference
< XContentAccess
> xContentAccess( xResultSet
, UNO_QUERY
);
2030 uno::Reference
< XRow
> xRow( xResultSet
, UNO_QUERY
);
2034 while ( xResultSet
->next() )
2036 OUString
aTitle( xRow
->getString( 1 ) );
2038 OUString aId
= xContentAccess
->queryContentIdentifierString();
2039 Content aContent
= Content( aId
, aCmdEnv
);
2041 AddRegion( aTitle
, aContent
);
2044 catch ( Exception
& ) {}
2048 // ------------------------------------------------------------------------
2049 sal_Bool
SfxDocTemplate_Impl::Construct( )
2051 ::osl::MutexGuard
aGuard( maMutex
);
2053 if ( mbConstructed
)
2056 uno::Reference
< XMultiServiceFactory
> xFactory
= ::comphelper::getProcessServiceFactory();
2057 uno::Reference
< XComponentContext
> xContext
= ::comphelper::getProcessComponentContext();
2059 OUString
aService( SERVICENAME_DOCINFO
);
2060 uno::Reference
< XPersist
> xInfo( xFactory
->createInstance( aService
), UNO_QUERY
);
2063 mxTemplates
= frame::DocumentTemplates::create(xContext
);
2065 uno::Reference
< XLocalizable
> xLocalizable( mxTemplates
, UNO_QUERY
);
2067 Sequence
< Any
> aCompareArg(1);
2068 *(aCompareArg
.getArray()) <<= xLocalizable
->getLocale();
2069 m_rCompareFactory
= uno::Reference
< XAnyCompareFactory
>(
2070 xFactory
->createInstanceWithArguments( OUString("com.sun.star.ucb.AnyCompareFactory"),
2074 uno::Reference
< XContent
> aRootContent
= mxTemplates
->getContent();
2075 uno::Reference
< XCommandEnvironment
> aCmdEnv
;
2077 if ( ! aRootContent
.is() )
2080 mbConstructed
= sal_True
;
2081 maRootURL
= aRootContent
->getIdentifier()->getContentIdentifier();
2083 ResStringArray
aLongNames( SfxResId( TEMPLATE_LONG_NAMES_ARY
) );
2085 if ( aLongNames
.Count() )
2086 maStandardGroup
= aLongNames
.GetString( 0 );
2088 Content
aTemplRoot( aRootContent
, aCmdEnv
);
2089 CreateFromHierarchy( aTemplRoot
);
2094 // -----------------------------------------------------------------------
2095 void SfxDocTemplate_Impl::ReInitFromComponent()
2097 uno::Reference
< XDocumentTemplates
> xTemplates
= getDocTemplates();
2098 if ( xTemplates
.is() )
2100 uno::Reference
< XContent
> aRootContent
= xTemplates
->getContent();
2101 uno::Reference
< XCommandEnvironment
> aCmdEnv
;
2102 Content
aTemplRoot( aRootContent
, aCmdEnv
);
2104 CreateFromHierarchy( aTemplRoot
);
2108 // -----------------------------------------------------------------------
2109 sal_Bool
SfxDocTemplate_Impl::InsertRegion( RegionData_Impl
*pNew
, size_t nPos
)
2111 ::osl::MutexGuard
aGuard( maMutex
);
2113 // return false (not inserted) if the entry already exists
2114 for ( size_t i
= 0, n
= maRegions
.size(); i
< n
; ++i
)
2115 if ( maRegions
[ i
]->Compare( pNew
) == 0 )
2118 size_t newPos
= nPos
;
2119 if ( pNew
->GetTitle() == maStandardGroup
)
2122 if ( newPos
< maRegions
.size() )
2124 RegionList_Impl::iterator it
= maRegions
.begin();
2125 advance( it
, newPos
);
2126 maRegions
.insert( it
, pNew
);
2129 maRegions
.push_back( pNew
);
2134 // -----------------------------------------------------------------------
2135 void SfxDocTemplate_Impl::Rescan()
2141 uno::Reference
< XDocumentTemplates
> xTemplates
= getDocTemplates();
2142 DBG_ASSERT( xTemplates
.is(), "SfxDocTemplate_Impl::Rescan:invalid template instance!" );
2143 if ( xTemplates
.is() )
2145 xTemplates
->update();
2147 uno::Reference
< XContent
> aRootContent
= xTemplates
->getContent();
2148 uno::Reference
< XCommandEnvironment
> aCmdEnv
;
2150 Content
aTemplRoot( aRootContent
, aCmdEnv
);
2151 CreateFromHierarchy( aTemplRoot
);
2154 catch( const Exception
& )
2156 SAL_WARN( "sfx2.doc", "SfxDocTemplate_Impl::Rescan: caught an exception while doing the update!" );
2160 // -----------------------------------------------------------------------
2161 sal_Bool
SfxDocTemplate_Impl::GetTitleFromURL( const OUString
& rURL
,
2168 mxInfo
->read( rURL
);
2170 catch ( Exception
& )
2172 // the document is not a StarOffice document
2179 uno::Reference
< XPropertySet
> aPropSet( mxInfo
, UNO_QUERY
);
2180 if ( aPropSet
.is() )
2182 OUString
aPropName( TITLE
);
2183 Any aValue
= aPropSet
->getPropertyValue( aPropName
);
2187 catch ( IOException
& ) {}
2188 catch ( UnknownPropertyException
& ) {}
2189 catch ( Exception
& ) {}
2192 if ( aTitle
.isEmpty() )
2194 INetURLObject
aURL( rURL
);
2195 aURL
.CutExtension();
2196 aTitle
= aURL
.getName( INetURLObject::LAST_SEGMENT
, true,
2197 INetURLObject::DECODE_WITH_CHARSET
);
2204 // -----------------------------------------------------------------------
2205 void SfxDocTemplate_Impl::Clear()
2207 ::osl::MutexGuard
aGuard( maMutex
);
2208 if ( mnLockCounter
)
2211 for ( size_t i
= 0, n
= maRegions
.size(); i
< n
; ++i
)
2212 delete maRegions
[ i
];
2216 // -----------------------------------------------------------------------
2217 sal_Bool
getTextProperty_Impl( Content
& rContent
,
2218 const OUString
& rPropName
,
2219 OUString
& rPropValue
)
2221 sal_Bool bGotProperty
= sal_False
;
2226 uno::Reference
< XPropertySetInfo
> aPropInfo
= rContent
.getProperties();
2228 // check, whether or not the property exists
2229 if ( !aPropInfo
.is() || !aPropInfo
->hasPropertyByName( rPropName
) )
2234 // now get the property
2237 aAnyValue
= rContent
.getPropertyValue( rPropName
);
2238 aAnyValue
>>= rPropValue
;
2240 if ( SfxURLRelocator_Impl::propertyCanContainOfficeDir( rPropName
) )
2242 SfxURLRelocator_Impl
aRelocImpl( ::comphelper::getProcessServiceFactory() );
2243 aRelocImpl
.makeAbsoluteURL( rPropValue
);
2246 bGotProperty
= sal_True
;
2248 catch ( RuntimeException
& ) {}
2249 catch ( Exception
& ) {}
2251 return bGotProperty
;
2254 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */