Update ooo320-m1
[ooovba.git] / sfx2 / source / doc / doctempl.cxx
blobd0ee1aacc8d4dae32c7aa367e5363bff9a46259f
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: doctempl.cxx,v $
10 * $Revision: 1.76 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sfx2.hxx"
34 #include <limits.h>
35 #include <com/sun/star/uno/Any.h>
36 #include <vos/mutex.hxx>
37 #include <vos/thread.hxx>
39 #ifndef _SV_RESARY_HXX
40 #include <tools/resary.hxx>
41 #endif
42 #include <vcl/svapp.hxx>
43 #include <vcl/settings.hxx>
44 #include <unotools/localedatawrapper.hxx>
45 #include <svtools/pathoptions.hxx>
46 #include <tools/string.hxx>
47 #include <tools/urlobj.hxx>
48 #include <svtools/ehdl.hxx>
49 #include <svtools/sfxecode.hxx>
50 #include <comphelper/processfactory.hxx>
51 #include <ucbhelper/content.hxx>
52 #include <com/sun/star/beans/PropertyAttribute.hpp>
53 #include <com/sun/star/beans/PropertyValue.hpp>
54 #include <com/sun/star/beans/XPropertyContainer.hpp>
55 #include <com/sun/star/beans/XPropertySet.hpp>
56 #include <com/sun/star/beans/XPropertySetInfo.hpp>
57 #include <com/sun/star/document/XTypeDetection.hpp>
58 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
59 #include <com/sun/star/frame/XComponentLoader.hpp>
60 #include <com/sun/star/frame/XDocumentTemplates.hpp>
61 #include <com/sun/star/io/XInputStream.hpp>
62 #include <com/sun/star/io/XPersist.hpp>
63 #include <com/sun/star/lang/XLocalizable.hpp>
64 #include <com/sun/star/sdbc/XResultSet.hpp>
65 #include <com/sun/star/sdbc/XRow.hpp>
66 #include <com/sun/star/ucb/ContentInfo.hpp>
67 #include <com/sun/star/ucb/InsertCommandArgument.hpp>
68 #include <com/sun/star/ucb/NameClash.hpp>
69 #include <com/sun/star/ucb/TransferInfo.hpp>
70 #include <com/sun/star/ucb/XCommandProcessor.hpp>
71 #include <com/sun/star/ucb/XContent.hpp>
72 #include <com/sun/star/ucb/XContentCreator.hpp>
73 #include <com/sun/star/ucb/XContentAccess.hpp>
74 #include <com/sun/star/ucb/XAnyCompareFactory.hpp>
75 #include <com/sun/star/ucb/XAnyCompare.hpp>
76 #include <com/sun/star/ucb/NumberedSortingInfo.hpp>
77 #include <com/sun/star/embed/ElementModes.hpp>
78 #include <com/sun/star/embed/XTransactedObject.hpp>
80 #include "sfxurlrelocator.hxx"
82 using namespace ::com::sun::star;
83 using namespace ::com::sun::star::beans;
84 using namespace ::com::sun::star::frame;
85 using namespace ::com::sun::star::io;
86 using namespace ::com::sun::star::lang;
87 using namespace ::com::sun::star::sdbc;
88 using namespace ::com::sun::star::uno;
89 using namespace ::com::sun::star::ucb;
90 using namespace ::com::sun::star::document;
91 using namespace ::rtl;
92 using namespace ::ucbhelper;
95 #include <sfx2/doctempl.hxx>
96 #include <sfx2/docfac.hxx>
97 #include <sfx2/docfile.hxx>
98 #include <sfx2/objsh.hxx>
99 #include "sfxtypes.hxx"
100 #include <sfx2/app.hxx>
101 #include "sfxresid.hxx"
102 #include "doc.hrc"
103 #include <sfx2/fcontnr.hxx>
104 #include <svtools/templatefoldercache.hxx>
106 #include <comphelper/storagehelper.hxx>
107 #include <unotools/ucbhelper.hxx>
109 //========================================================================
111 // #define DONT_USE_HIERARCHY
113 #define TITLE "Title"
114 #define IS_FOLDER "IsFolder"
115 #define PROPERTY_TYPE "TypeDescription"
116 #define TARGET_URL "TargetURL"
117 #define TYPE_FOLDER "application/vnd.sun.star.hier-folder"
118 #define TYPE_LINK "application/vnd.sun.star.hier-link"
119 #define TYPE_FSYS_FOLDER "application/vnd.sun.staroffice.fsys-folder"
121 #define TARGET_DIR_URL "TargetDirURL"
122 #define COMMAND_DELETE "delete"
123 #define COMMAND_TRANSFER "transfer"
125 #define STANDARD_FOLDER "standard"
127 #define SERVICENAME_TYPEDETECTION "com.sun.star.document.TypeDetection"
128 #define TYPEDETECTION_PARAMETER "FileName"
129 //#define SERVICENAME_OLD_TYPEDETECTION "com.sun.star.frame.FrameLoaderFactory"
130 //#define PARAMETER_OLD_TYPEDETECTION "DeepDetection"
131 #define SERVICENAME_DOCINFO "com.sun.star.document.DocumentProperties"
132 #define SERVICENAME_DOCTEMPLATES "com.sun.star.frame.DocumentTemplates"
133 #define SERVICENAME_DESKTOP "com.sun.star.frame.Desktop"
135 //========================================================================
137 class RegionData_Impl;
139 namespace DocTempl {
141 class DocTempl_EntryData_Impl
143 RegionData_Impl* mpParent;
144 SfxObjectShellLock mxObjShell;
145 OUString maTitle;
146 OUString maOwnURL;
147 OUString maTargetURL;
148 sal_Bool mbIsOwner : 1;
149 sal_Bool mbDidConvert: 1;
151 private:
152 RegionData_Impl* GetParent() const { return mpParent; }
154 public:
155 DocTempl_EntryData_Impl( RegionData_Impl* pParent,
156 const OUString& rTitle );
158 const OUString& GetTitle() const { return maTitle; }
159 const OUString& GetTargetURL();
160 const OUString& GetHierarchyURL();
162 void SetTitle( const OUString& rTitle ) { maTitle = rTitle; }
163 void SetTargetURL( const OUString& rURL ) { maTargetURL = rURL; }
164 void SetHierarchyURL( const OUString& rURL) { maOwnURL = rURL; }
166 int Compare( const OUString& rTitle ) const;
168 SfxObjectShellRef CreateObjectShell();
169 sal_Bool DeleteObjectShell();
174 using namespace ::DocTempl;
176 // ------------------------------------------------------------------------
178 class RegionData_Impl
180 DECLARE_LIST( EntryList_Impl, DocTempl_EntryData_Impl* )
181 const SfxDocTemplate_Impl* mpParent;
182 EntryList_Impl maEntries;
183 OUString maTitle;
184 OUString maOwnURL;
185 OUString maTargetURL;
187 private:
188 long GetEntryPos( const OUString& rTitle,
189 sal_Bool& rFound ) const;
190 const SfxDocTemplate_Impl* GetParent() const { return mpParent; }
192 public:
193 RegionData_Impl( const SfxDocTemplate_Impl* pParent,
194 const OUString& rTitle );
195 ~RegionData_Impl();
197 void SetTargetURL( const OUString& rURL ) { maTargetURL = rURL; }
198 void SetHierarchyURL( const OUString& rURL) { maOwnURL = rURL; }
200 DocTempl_EntryData_Impl* GetEntry( ULONG nIndex ) const;
201 DocTempl_EntryData_Impl* GetEntry( const OUString& rName ) const;
202 DocTempl_EntryData_Impl* GetByTargetURL( const OUString& rName ) const;
204 const OUString& GetTitle() const { return maTitle; }
205 const OUString& GetTargetURL();
206 const OUString& GetHierarchyURL();
208 ULONG GetCount() const;
210 void SetTitle( const OUString& rTitle ) { maTitle = rTitle; }
212 void AddEntry( const OUString& rTitle,
213 const OUString& rTargetURL,
214 USHORT *pPos = NULL );
215 void DeleteEntry( ULONG nIndex );
217 int Compare( const OUString& rTitle ) const
218 { return maTitle.compareTo( rTitle ); }
219 int Compare( RegionData_Impl* pCompareWith ) const;
222 DECLARE_LIST( RegionList_Impl, RegionData_Impl* )
224 // ------------------------------------------------------------------------
226 class SfxDocTemplate_Impl : public SvRefBase
228 uno::Reference< XPersist > mxInfo;
229 uno::Reference< XDocumentTemplates > mxTemplates;
231 ::osl::Mutex maMutex;
232 OUString maRootURL;
233 OUString maStandardGroup;
234 RegionList_Impl maRegions;
235 sal_Bool mbConstructed;
237 uno::Reference< XAnyCompareFactory > m_rCompareFactory;
239 // the following member is intended to prevent clearing of the global data when it is in use
240 // TODO/LATER: it still does not make the implementation complete thread-safe
241 sal_Int32 mnLockCounter;
243 private:
244 void Clear();
246 public:
247 SfxDocTemplate_Impl();
248 ~SfxDocTemplate_Impl();
250 void IncrementLock();
251 void DecrementLock();
253 sal_Bool Construct( );
254 void CreateFromHierarchy( Content &rTemplRoot );
255 void ReInitFromComponent();
256 void AddRegion( const OUString& rTitle,
257 Content& rContent );
259 void Rescan();
261 void DeleteRegion( ULONG nIndex );
263 ULONG GetRegionCount() const
264 { return maRegions.Count(); }
265 RegionData_Impl* GetRegion( const OUString& rName ) const;
266 RegionData_Impl* GetRegion( ULONG nIndex ) const;
267 void GetTemplates( Content& rTargetFolder,
268 Content& rParentFolder,
269 RegionData_Impl* pRegion );
271 long GetRegionPos( const OUString& rTitle,
272 sal_Bool& rFound ) const;
274 sal_Bool GetTitleFromURL( const OUString& rURL, OUString& aTitle );
275 sal_Bool InsertRegion( RegionData_Impl *pData, ULONG nPos = LIST_APPEND );
276 OUString GetRootURL() const { return maRootURL; }
278 uno::Reference< XDocumentTemplates > getDocTemplates() { return mxTemplates; }
281 // ------------------------------------------------------------------------
283 class DocTemplLocker_Impl
285 SfxDocTemplate_Impl& m_aDocTempl;
286 public:
287 DocTemplLocker_Impl( SfxDocTemplate_Impl& aDocTempl )
288 : m_aDocTempl( aDocTempl )
290 m_aDocTempl.IncrementLock();
293 ~DocTemplLocker_Impl()
295 m_aDocTempl.DecrementLock();
299 // ------------------------------------------------------------------------
301 #ifndef SFX_DECL_DOCTEMPLATES_DEFINED
302 #define SFX_DECL_DOCTEMPLATES_DEFINED
303 SV_DECL_REF(SfxDocTemplate_Impl)
304 #endif
306 SV_IMPL_REF(SfxDocTemplate_Impl)
308 // ------------------------------------------------------------------------
310 SfxDocTemplate_Impl *gpTemplateData = 0;
312 // -----------------------------------------------------------------------
314 static sal_Bool getTextProperty_Impl( Content& rContent,
315 const OUString& rPropName,
316 OUString& rPropValue );
318 //========================================================================
319 //========================================================================
320 //========================================================================
322 String SfxDocumentTemplates::GetFullRegionName
324 USHORT nIdx // Index des Bereiches
325 ) const
327 /* [Beschreibung]
329 Liefert den logischen Namen eines Bereiches Plus seinem Pfad
332 [R"uckgabewert] Referenz auf diesen Namen
337 // First: find the RegionData for the index
338 String aName;
340 DocTemplLocker_Impl aLocker( *pImp );
342 if ( pImp->Construct() )
344 RegionData_Impl *pData1 = pImp->GetRegion( nIdx );
346 if ( pData1 )
347 aName = pData1->GetTitle();
349 // --**-- here was some code which appended the path to the
350 // group if there was more than one with the same name.
351 // this should not happen anymore
354 return aName;
357 //------------------------------------------------------------------------
359 const String& SfxDocumentTemplates::GetRegionName
361 USHORT nIdx // Index des Bereiches
362 ) const
364 /* [Beschreibung]
366 Liefert den logischen Namen eines Bereiches
369 [R"uckgabewert]
371 const String& Referenz auf diesen Namen
375 static String maTmpString;
377 DocTemplLocker_Impl aLocker( *pImp );
379 if ( pImp->Construct() )
381 RegionData_Impl *pData = pImp->GetRegion( nIdx );
383 if ( pData )
384 maTmpString = pData->GetTitle();
385 else
386 maTmpString.Erase();
388 else
389 maTmpString.Erase();
391 return maTmpString;
395 //------------------------------------------------------------------------
397 USHORT SfxDocumentTemplates::GetRegionNo
399 const String &rRegion // Name der Region
400 ) const
402 /* [Beschreibung]
404 Liefert den Index f"ur einen logischen Namen eines Bereiches.
407 [R"uckgabewert]
409 USHORT Index von 'rRegion' oder USHRT_MAX falls unbekannt
413 DocTemplLocker_Impl aLocker( *pImp );
415 if ( !pImp->Construct() )
416 return USHRT_MAX;
418 sal_Bool bFound;
419 ULONG nIndex = pImp->GetRegionPos( rRegion, bFound );
421 if ( bFound )
422 return (USHORT) nIndex;
423 else
424 return USHRT_MAX;
428 //------------------------------------------------------------------------
430 USHORT SfxDocumentTemplates::GetRegionCount() const
432 /* [Beschreibung]
434 Liefert die Anzahl der Bereiche
437 [R"uckgabewert]
439 USHORT Anzahl der Bereiche
443 DocTemplLocker_Impl aLocker( *pImp );
445 if ( !pImp->Construct() )
446 return 0;
448 ULONG nCount = pImp->GetRegionCount();
450 return (USHORT) nCount;
453 //------------------------------------------------------------------------
455 sal_Bool SfxDocumentTemplates::IsRegionLoaded( USHORT nIdx ) const
457 DocTemplLocker_Impl aLocker( *pImp );
459 if ( !pImp->Construct() )
460 return sal_False;
462 RegionData_Impl *pData = pImp->GetRegion( nIdx );
464 if ( pData )
465 return sal_True;
466 else
467 return sal_False;
470 //------------------------------------------------------------------------
472 USHORT SfxDocumentTemplates::GetCount
474 const String& rName /* Name des Bereiches, dessen Eintrags-
475 anzahl ermittelt werden soll */
477 ) const
479 /* [Beschreibung]
481 Liefert die Anzahl der Eintr"age eines Bereiches
484 [R"uckgabewert]
486 USHORT Anzahl der Eintr"age
491 DocTemplLocker_Impl aLocker( *pImp );
493 if ( !pImp->Construct() )
494 return 0;
496 RegionData_Impl *pData = pImp->GetRegion( rName );
497 ULONG nCount = 0;
499 if ( pData )
500 nCount = pData->GetCount();
502 return (USHORT) nCount;
505 //------------------------------------------------------------------------
507 USHORT SfxDocumentTemplates::GetCount
509 USHORT nRegion /* Index des Bereiches, dessen Eintrags-
510 anzahl ermittelt werden soll */
512 ) const
514 /* [Beschreibung]
516 Liefert die Anzahl der Eintr"age eines Bereiches
519 [R"uckgabewert] Anzahl der Eintr"age
524 DocTemplLocker_Impl aLocker( *pImp );
526 if ( !pImp->Construct() )
527 return 0;
529 RegionData_Impl *pData = pImp->GetRegion( nRegion );
530 ULONG nCount = 0;
532 if ( pData )
533 nCount = pData->GetCount();
535 return (USHORT) nCount;
538 //------------------------------------------------------------------------
540 const String& SfxDocumentTemplates::GetName
542 USHORT nRegion, // Index des Bereiches, in dem der Eintrag liegt
543 USHORT nIdx // Index des Eintrags
544 ) const
546 /* [Beschreibung]
548 Liefert den logischen Namen eines Eintrags eines Bereiches
551 [R"uckgabewert]
553 const String& Name des Eintrags
558 DocTemplLocker_Impl aLocker( *pImp );
560 static String maTmpString;
562 if ( pImp->Construct() )
564 DocTempl_EntryData_Impl *pEntry = NULL;
565 RegionData_Impl *pRegion = pImp->GetRegion( nRegion );
567 if ( pRegion )
568 pEntry = pRegion->GetEntry( nIdx );
570 if ( pEntry )
571 maTmpString = pEntry->GetTitle();
572 else
573 maTmpString.Erase();
575 else
576 maTmpString.Erase();
578 return maTmpString;
581 //------------------------------------------------------------------------
583 String SfxDocumentTemplates::GetFileName
585 USHORT nRegion, // Index des Bereiches, in dem der Eintrag liegt
586 USHORT nIdx // Index des Eintrags
587 ) const
589 /* [Beschreibung]
591 Liefert den Dateinamen eines Eintrags eines Bereiches
593 [R"uckgabewert] Dateiname des Eintrags
597 DocTemplLocker_Impl aLocker( *pImp );
599 if ( !pImp->Construct() )
600 return String();
602 DocTempl_EntryData_Impl *pEntry = NULL;
603 RegionData_Impl *pRegion = pImp->GetRegion( nRegion );
605 if ( pRegion )
606 pEntry = pRegion->GetEntry( nIdx );
608 if ( pEntry )
610 INetURLObject aURLObj( pEntry->GetTargetURL() );
611 return aURLObj.getName( INetURLObject::LAST_SEGMENT, true,
612 INetURLObject::DECODE_WITH_CHARSET );
614 else
615 return String();
618 //------------------------------------------------------------------------
620 String SfxDocumentTemplates::GetPath
622 USHORT nRegion, // Index des Bereiches, in dem der Eintrag liegt
623 USHORT nIdx // Index des Eintrags
624 ) const
626 /* [Beschreibung]
628 Liefert den Dateinamen mit vollst"andigem Pfad zu der einem
629 Eintrag zugeordneten Datei
632 [R"uckgabewert]
634 String Dateiname mit vollst"andigem Pfad
638 DocTemplLocker_Impl aLocker( *pImp );
640 if ( !pImp->Construct() )
641 return String();
643 DocTempl_EntryData_Impl *pEntry = NULL;
644 RegionData_Impl *pRegion = pImp->GetRegion( nRegion );
646 if ( pRegion )
647 pEntry = pRegion->GetEntry( nIdx );
649 if ( pEntry )
650 return pEntry->GetTargetURL();
651 else
652 return String();
655 //------------------------------------------------------------------------
657 String SfxDocumentTemplates::GetTemplatePath
659 USHORT nRegion, // Index des Bereiches, in dem der Eintrag liegt
660 const String& rLongName // logischer Name des Eintrags
661 ) const
663 /* [Beschreibung]
665 Liefert den Dateinamen mit vollst"andigem Pfad zu der einem
666 Eintrag zugeordneten Datei
669 [R"uckgabewert]
671 String Dateiname mit vollst"andigem Pfad
675 DocTemplLocker_Impl aLocker( *pImp );
677 if ( !pImp->Construct() )
678 return String();
680 DocTempl_EntryData_Impl *pEntry = NULL;
681 RegionData_Impl *pRegion = pImp->GetRegion( nRegion );
683 if ( pRegion )
684 pEntry = pRegion->GetEntry( rLongName );
686 if ( pEntry )
687 return pEntry->GetTargetURL();
688 else if ( pRegion )
690 // a new template is going to be inserted, generate a new URL
691 // TODO/LATER: if the title is localized, use minimized URL in future
693 // --**-- extension handling will become more complicated, because
694 // every new document type will have it's own extension
695 // e.g.: .stw or .stc instead of .vor
696 INetURLObject aURLObj( pRegion->GetTargetURL() );
697 aURLObj.insertName( rLongName, false,
698 INetURLObject::LAST_SEGMENT, true,
699 INetURLObject::ENCODE_ALL );
701 OUString aExtension = aURLObj.getExtension();
703 if ( ! aExtension.getLength() )
704 aURLObj.setExtension( OUString( RTL_CONSTASCII_USTRINGPARAM( "vor" ) ) );
706 return aURLObj.GetMainURL( INetURLObject::NO_DECODE );
708 else
709 return String();
712 //------------------------------------------------------------------------
714 String SfxDocumentTemplates::GetDefaultTemplatePath
716 const String& rLongName
719 /* [Beschreibung]
721 Liefert den Standardpfad zu Dokumentvorlagen
724 [R"uckgabewert]
726 String Standardpfad zu Dokumentvorlagen
730 DocTemplLocker_Impl aLocker( *pImp );
732 if ( ! pImp->Construct() )
733 return String();
735 // the first region in the list should always be the standard
736 // group
737 // --**-- perhaps we have to create it ???
738 RegionData_Impl *pRegion = pImp->GetRegion( 0L );
739 DocTempl_EntryData_Impl *pEntry = NULL;
741 if ( pRegion )
742 pEntry = pRegion->GetEntry( rLongName );
744 if ( pEntry )
745 return pEntry->GetTargetURL();
746 else if ( pRegion )
748 // a new template is going to be inserted, generate a new URL
749 // TODO/LATER: if the title is localized, use minimized URL in future
751 INetURLObject aURLObj( pRegion->GetTargetURL() );
752 aURLObj.insertName( rLongName, false,
753 INetURLObject::LAST_SEGMENT, true,
754 INetURLObject::ENCODE_ALL );
756 OUString aExtension = aURLObj.getExtension();
758 if ( ! aExtension.getLength() )
759 aURLObj.setExtension( OUString( RTL_CONSTASCII_USTRINGPARAM( "vor" ) ) );
761 return aURLObj.GetMainURL( INetURLObject::NO_DECODE );
763 else
764 return String();
766 /* dv! missing: create the directory, if it doesn't exists
769 DBG_ASSERT(aDirs.GetTokenCount(cDelim), "Keine Bereiche");
770 DirEntry aPath(aDirs.GetToken(0, cDelim));
772 // Verzeichnis anlegen
773 if(!aPath.MakeDir())
774 return String();
776 MakeFileName_Impl(aPath, rLongName, sal_True);
777 SfxTemplateDir *pEntry = new SfxTemplateDir;
778 SfxTemplateDirEntryPtr pDirEntry =
779 new SfxTemplateDirEntry( String( '.' ), aPath.GetPath() );
780 pDirEntry->SetContent(new SfxTemplateDir(aPath.GetPath()));
781 pEntry->Insert(pDirEntry, pEntry->Count());
782 pDirs->Insert(pEntry, pDirs->Count());
783 return aPath.GetFull();
787 //------------------------------------------------------------------------
789 ::rtl::OUString SfxDocumentTemplates::GetTemplateTargetURLFromComponent( const ::rtl::OUString& aGroupName,
790 const ::rtl::OUString& aTitle )
792 DocTemplLocker_Impl aLocker( *pImp );
794 INetURLObject aTemplateObj( pImp->GetRootURL() );
796 aTemplateObj.insertName( aGroupName, false,
797 INetURLObject::LAST_SEGMENT, true,
798 INetURLObject::ENCODE_ALL );
800 aTemplateObj.insertName( aTitle, false,
801 INetURLObject::LAST_SEGMENT, true,
802 INetURLObject::ENCODE_ALL );
805 ::rtl::OUString aResult;
806 Content aTemplate;
807 uno::Reference< XCommandEnvironment > aCmdEnv;
808 if ( Content::create( aTemplateObj.GetMainURL( INetURLObject::NO_DECODE ), aCmdEnv, aTemplate ) )
810 OUString aPropName( RTL_CONSTASCII_USTRINGPARAM( TARGET_URL ) );
811 getTextProperty_Impl( aTemplate, aPropName, aResult );
812 aResult = SvtPathOptions().SubstituteVariable( aResult );
815 return aResult;
818 //------------------------------------------------------------------------
820 sal_Bool SfxDocumentTemplates::SaveDir
822 // SfxTemplateDir& rDir // das zu speichernde Directory
825 /* [Beschreibung]
827 Speichert das Directory rDir
830 [R"uckgabewert]
832 sal_Bool sal_False,
833 Schreibfehler
835 sal_True
836 gespeichert
841 return sal_True;
844 //------------------------------------------------------------------------
846 void SfxDocumentTemplates::NewTemplate
848 USHORT nRegion, /* Index des Bereiches, in dem die Vorlage
849 angelegt werden soll */
851 const String& rLongName, // logischer Name der neuen Vorlage
852 const String& rFileName // Dateiname der neuen Vorlage
855 /* [Beschreibung]
857 Eintragen einer neuen Dokumentvorlage in die Verwaltungsstrukturen
858 Das "Uberschreiben einer Vorlage gleichen Namens wird
859 verhindert (!! Fehlermeldung)
864 DocTemplLocker_Impl aLocker( *pImp );
866 if ( ! pImp->Construct() )
867 return;
869 DocTempl_EntryData_Impl *pEntry;
870 RegionData_Impl *pRegion = pImp->GetRegion( nRegion );
872 // do nothing if there is no region with that index
873 if ( !pRegion )
874 return;
876 pEntry = pRegion->GetEntry( rLongName );
878 // do nothing if there is already an entry with that name
879 if ( pEntry )
880 return;
882 uno::Reference< XDocumentTemplates > xTemplates = pImp->getDocTemplates();
884 if ( xTemplates->addTemplate( pRegion->GetTitle(), rLongName, rFileName ) )
885 pRegion->AddEntry( rLongName, rFileName );
888 //------------------------------------------------------------------------
890 sal_Bool SfxDocumentTemplates::CopyOrMove
892 USHORT nTargetRegion, // Index des Zielbereiches
893 USHORT nTargetIdx, // Index Zielposition
894 USHORT nSourceRegion, // Index des Quellbereiches
895 USHORT nSourceIdx, /* Index der zu kopierenden / zu verschiebenden
896 Dokumentvorlage */
897 sal_Bool bMove // kopieren / verschieben
900 /* [Beschreibung]
902 Kopieren oder Verschieben einer Dokumentvorlage
904 [R"uckgabewert]
906 sal_Bool sal_True
907 Aktion konnte ausgef"uhrt werden
909 sal_False
910 Aktion konnte nicht ausgef2uhrt werden
911 [Querverweise]
913 <SfxDocumentTemplates::Move(USHORT,USHORT,USHORT,USHORT)>
914 <SfxDocumentTemplates::Copy(USHORT,USHORT,USHORT,USHORT)>
918 /* to perform a copy or move, we need to send a transfer command to
919 the destination folder with the URL of the source as parameter.
920 ( If the destination content doesn't support the transfer command,
921 we could try a copy ( and delete ) instead. )
922 We need two transfers ( one for the real template and one for its
923 representation in the hierarchy )
927 DocTemplLocker_Impl aLocker( *pImp );
929 if ( !pImp->Construct() )
930 return sal_False;
932 // Don't copy or move any folders
933 if( nSourceIdx == USHRT_MAX )
934 return sal_False ;
936 if ( nSourceRegion == nTargetRegion )
938 DBG_ERRORFILE( "Don't know, what to do!" );
939 return sal_False;
940 #if 0
941 // Verschieben einer Vorlage innerhalb eines Bereiches
942 // --> nur Verwaltungsdaten aktualisieren
943 if ( bMove && nTargetRegion == nSourceRegion )
945 if(nTargetIdx == USHRT_MAX)
946 nTargetIdx = 0;
947 const SfxTemplateDirEntryPtr pEntry = rTargetDir[nSourceIdx];
948 rTargetDir.Insert(pEntry, nTargetIdx);
949 if(nTargetIdx < nSourceIdx)
950 ++nSourceIdx;
951 rTargetDir.Remove(nSourceIdx);
952 return SaveDir(rTargetDir);
954 #endif
957 RegionData_Impl *pSourceRgn = pImp->GetRegion( nSourceRegion );
958 if ( !pSourceRgn )
959 return sal_False;
961 DocTempl_EntryData_Impl *pSource = pSourceRgn->GetEntry( nSourceIdx );
962 if ( !pSource )
963 return sal_False;
965 RegionData_Impl *pTargetRgn = pImp->GetRegion( nTargetRegion );
966 if ( !pTargetRgn )
967 return sal_False;
969 OUString aTitle = pSource->GetTitle();
971 uno::Reference< XDocumentTemplates > xTemplates = pImp->getDocTemplates();
973 if ( xTemplates->addTemplate( pTargetRgn->GetTitle(),
974 aTitle,
975 pSource->GetTargetURL() ) )
978 INetURLObject aSourceObj( pSource->GetTargetURL() );
980 ::rtl::OUString aNewTargetURL = GetTemplateTargetURLFromComponent( pTargetRgn->GetTitle(), aTitle );
981 if ( !aNewTargetURL.getLength() )
982 return sal_False;
984 if ( bMove )
986 // --**-- delete the original file
987 sal_Bool bDeleted = xTemplates->removeTemplate( pSourceRgn->GetTitle(),
988 pSource->GetTitle() );
989 if ( bDeleted )
990 pSourceRgn->DeleteEntry( nSourceIdx );
991 else
993 if ( xTemplates->removeTemplate( pTargetRgn->GetTitle(), aTitle ) )
994 return sal_False; // will trigger tetry with copy instead of move
996 // if it is not possible to remove just created template ( must be possible! )
997 // it is better to report success here, since at least the copy has succeeded
998 // TODO/LATER: solve it more gracefully in future
1002 pTargetRgn->AddEntry( aTitle, aNewTargetURL, &nTargetIdx );
1004 return sal_True;
1007 // --**-- wenn aktuell das File geoeffnet ist,
1008 // muss es hinterher wieder geoeffnet werden
1010 return sal_False;
1013 //------------------------------------------------------------------------
1015 sal_Bool SfxDocumentTemplates::Move
1017 USHORT nTargetRegion, // Index des Zielbereiches
1018 USHORT nTargetIdx, // Index Zielposition
1019 USHORT nSourceRegion, // Index des Quellbereiches
1020 USHORT nSourceIdx /* Index der zu kopierenden / zu verschiebenden
1021 Dokumentvorlage */
1024 /* [Beschreibung]
1026 Verschieben einer Dokumentvorlage
1029 [R"uckgabewert]
1031 sal_Bool sal_True
1032 Aktion konnte ausgef"uhrt werden
1034 sal_False
1035 Aktion konnte nicht ausgef2uhrt werden
1037 [Querverweise]
1039 <SfxDocumentTemplates::CopyOrMove(USHORT,USHORT,USHORT,USHORT,sal_Bool)>
1042 DocTemplLocker_Impl aLocker( *pImp );
1044 return CopyOrMove( nTargetRegion, nTargetIdx,
1045 nSourceRegion, nSourceIdx, sal_True );
1048 //------------------------------------------------------------------------
1050 sal_Bool SfxDocumentTemplates::Copy
1052 USHORT nTargetRegion, // Index des Zielbereiches
1053 USHORT nTargetIdx, // Index Zielposition
1054 USHORT nSourceRegion, // Index des Quellbereiches
1055 USHORT nSourceIdx /* Index der zu kopierenden / zu verschiebenden
1056 Dokumentvorlage */
1059 /* [Beschreibung]
1061 Kopieren einer Dokumentvorlage
1064 [R"uckgabewert]
1066 sal_Bool sal_True
1067 Aktion konnte ausgef"uhrt werden
1069 sal_False
1070 Aktion konnte nicht ausgef"uhrt werden
1072 [Querverweise]
1074 <SfxDocumentTemplates::CopyOrMove(USHORT,USHORT,USHORT,USHORT,sal_Bool)>
1078 DocTemplLocker_Impl aLocker( *pImp );
1080 return CopyOrMove( nTargetRegion, nTargetIdx,
1081 nSourceRegion, nSourceIdx, sal_False );
1084 //------------------------------------------------------------------------
1086 sal_Bool SfxDocumentTemplates::CopyTo
1088 USHORT nRegion, /* Bereich der Vorlage, die exportiert werden
1089 soll */
1090 USHORT nIdx, /* Index der Vorlage, die exportiert werden
1091 soll */
1092 const String& rName /* Dateiname, unter dem die Vorlage angelegt
1093 werden soll */
1094 ) const
1096 /* [Beschreibung]
1098 Exportieren einer Dokumentvorlage in das Dateisystem
1101 [R"uckgabewert]
1103 sal_Bool sal_True
1104 Aktion konnte ausgef"uhrt werden
1106 sal_False
1107 Aktion konnte nicht ausgef"uhrt werden
1110 [Querverweise]
1112 <SfxDocumentTemplates::CopyFrom(USHORT,USHORT,String&)>
1116 DocTemplLocker_Impl aLocker( *pImp );
1118 if ( ! pImp->Construct() )
1119 return sal_False;
1121 RegionData_Impl *pSourceRgn = pImp->GetRegion( nRegion );
1122 if ( !pSourceRgn )
1123 return sal_False;
1125 DocTempl_EntryData_Impl *pSource = pSourceRgn->GetEntry( nIdx );
1126 if ( !pSource )
1127 return sal_False;
1129 INetURLObject aTargetURL( rName );
1131 OUString aTitle( aTargetURL.getName( INetURLObject::LAST_SEGMENT, true,
1132 INetURLObject::DECODE_WITH_CHARSET ) );
1133 aTargetURL.removeSegment();
1135 OUString aParentURL = aTargetURL.GetMainURL( INetURLObject::NO_DECODE );
1137 uno::Reference< XCommandEnvironment > aCmdEnv;
1138 Content aTarget;
1142 aTarget = Content( aParentURL, aCmdEnv );
1144 TransferInfo aTransferInfo;
1145 aTransferInfo.MoveData = sal_False;
1146 aTransferInfo.SourceURL = pSource->GetTargetURL();
1147 aTransferInfo.NewTitle = aTitle;
1148 aTransferInfo.NameClash = NameClash::OVERWRITE;
1150 Any aArg = makeAny( aTransferInfo );
1151 OUString aCmd( RTL_CONSTASCII_USTRINGPARAM( COMMAND_TRANSFER ) );
1153 aTarget.executeCommand( aCmd, aArg );
1155 catch ( ContentCreationException& )
1156 { return sal_False; }
1157 catch ( Exception& )
1158 { return sal_False; }
1160 return sal_True;
1163 //------------------------------------------------------------------------
1165 sal_Bool SfxDocumentTemplates::CopyFrom
1167 USHORT nRegion, /* Bereich, in den die Vorlage importiert
1168 werden soll */
1169 USHORT nIdx, // Index der neuen Vorlage in diesem Bereich
1170 String& rName /* Dateiname der Vorlage, die importiert
1171 werden soll, als out-Parameter der (auto-
1172 matisch aus dem Dateinamen generierte)
1173 logische Name der Vorlage */
1176 /* [Beschreibung]
1178 Importieren einer Dokumentvorlage aus dem Dateisystem
1181 [R"uckgabewert] Erfolg (sal_True) oder Mi"serfpTargetDirectory->GetContent());
1183 sal_Bool sal_True
1184 Aktion konnte ausgef"uhrt werden
1186 sal_False
1187 Aktion konnte nicht ausgef"uhrt werden
1189 [Querverweise]
1191 <SfxDocumentTemplates::CopyTo(USHORT,USHORT,const String&)>
1195 DocTemplLocker_Impl aLocker( *pImp );
1197 if ( ! pImp->Construct() )
1198 return sal_False;
1200 RegionData_Impl *pTargetRgn = pImp->GetRegion( nRegion );
1202 if ( !pTargetRgn )
1203 return sal_False;
1205 uno::Reference< XDocumentTemplates > xTemplates = pImp->getDocTemplates();
1206 if ( !xTemplates.is() )
1207 return sal_False;
1209 OUString aTitle;
1210 sal_Bool bTemplateAdded = sal_False;
1212 if( pImp->GetTitleFromURL( rName, aTitle ) )
1214 bTemplateAdded = xTemplates->addTemplate( pTargetRgn->GetTitle(), aTitle, rName );
1216 else
1218 OUString aService( RTL_CONSTASCII_USTRINGPARAM( SERVICENAME_DESKTOP ) );
1219 uno::Reference< XComponentLoader > xDesktop( ::comphelper::getProcessServiceFactory()->createInstance( aService ),
1220 UNO_QUERY );
1222 Sequence< PropertyValue > aArgs( 1 );
1223 aArgs[0].Name = ::rtl::OUString::createFromAscii("Hidden");
1224 aArgs[0].Value <<= sal_True;
1226 INetURLObject aTemplURL( rName );
1227 uno::Reference< XDocumentPropertiesSupplier > xDocPropsSupplier;
1228 uno::Reference< XStorable > xStorable;
1231 xStorable = uno::Reference< XStorable >(
1232 xDesktop->loadComponentFromURL( aTemplURL.GetMainURL(INetURLObject::NO_DECODE),
1233 OUString::createFromAscii( "_blank" ),
1235 aArgs ),
1236 UNO_QUERY );
1238 xDocPropsSupplier = uno::Reference< XDocumentPropertiesSupplier >(
1239 xStorable, UNO_QUERY );
1241 catch( Exception& )
1245 if( xStorable.is() )
1247 // get Title from XDocumentPropertiesSupplier
1248 if( xDocPropsSupplier.is() )
1250 uno::Reference< XDocumentProperties > xDocProps
1251 = xDocPropsSupplier->getDocumentProperties();
1252 if (xDocProps.is() ) {
1253 aTitle = xDocProps->getTitle();
1257 if( ! aTitle.getLength() )
1259 INetURLObject aURL( aTemplURL );
1260 aURL.CutExtension();
1261 aTitle = aURL.getName( INetURLObject::LAST_SEGMENT, true,
1262 INetURLObject::DECODE_WITH_CHARSET );
1265 // write a template using XStorable interface
1266 bTemplateAdded = xTemplates->storeTemplate( pTargetRgn->GetTitle(), aTitle, xStorable );
1271 if( bTemplateAdded )
1273 INetURLObject aTemplObj( pTargetRgn->GetHierarchyURL() );
1274 aTemplObj.insertName( aTitle, false,
1275 INetURLObject::LAST_SEGMENT, true,
1276 INetURLObject::ENCODE_ALL );
1277 OUString aTemplURL = aTemplObj.GetMainURL( INetURLObject::NO_DECODE );
1279 uno::Reference< XCommandEnvironment > aCmdEnv;
1280 Content aTemplCont;
1282 if( Content::create( aTemplURL, aCmdEnv, aTemplCont ) )
1284 OUString aTemplName;
1285 OUString aPropName( RTL_CONSTASCII_USTRINGPARAM( TARGET_URL ) );
1287 if( getTextProperty_Impl( aTemplCont, aPropName, aTemplName ) )
1289 if ( nIdx == USHRT_MAX )
1290 nIdx = 0;
1291 else
1292 nIdx += 1;
1294 pTargetRgn->AddEntry( aTitle, aTemplName, &nIdx );
1295 rName = aTitle;
1296 return sal_True;
1298 else
1300 DBG_ASSERT( sal_False, "CopyFrom(): The content should contain target URL!" );
1303 else
1305 DBG_ASSERT( sal_False, "CopyFrom(): The content just was created!" );
1309 return sal_False;
1312 //------------------------------------------------------------------------
1314 sal_Bool SfxDocumentTemplates::Delete
1316 USHORT nRegion, // Index des Bereiches
1317 USHORT nIdx /* Index des Eintrags oder USHRT_MAX,
1318 wenn ein Verzeichnis gemeint ist. */
1321 /* [Beschreibung]
1323 "oschen eines Eintrags oder eines Verzeichnisses
1326 [R"uckgabewert]
1328 sal_Bool sal_True
1329 Aktion konnte ausgef"uhrt werden
1331 sal_False
1332 Aktion konnte nicht ausgef"uhrt werden
1335 [Querverweise]
1337 <SfxDocumentTemplates::InsertDir(const String&,USHORT)>
1338 <SfxDocumentTemplates::KillDir(SfxTemplateDir&)>
1339 <SfxDocumentTemplates::SaveDir(SfxTemplateDir&)>
1343 DocTemplLocker_Impl aLocker( *pImp );
1345 /* delete the template or folder in the hierarchy and in the
1346 template folder by sending a delete command to the content.
1347 Then remove the data from the lists
1349 if ( ! pImp->Construct() )
1350 return sal_False;
1352 RegionData_Impl *pRegion = pImp->GetRegion( nRegion );
1354 if ( !pRegion )
1355 return sal_False;
1357 sal_Bool bRet;
1358 uno::Reference< XDocumentTemplates > xTemplates = pImp->getDocTemplates();
1360 if ( nIdx == USHRT_MAX )
1362 bRet = xTemplates->removeGroup( pRegion->GetTitle() );
1363 if ( bRet )
1364 pImp->DeleteRegion( nRegion );
1366 else
1368 DocTempl_EntryData_Impl *pEntry = pRegion->GetEntry( nIdx );
1370 if ( !pEntry )
1371 return sal_False;
1373 bRet = xTemplates->removeTemplate( pRegion->GetTitle(),
1374 pEntry->GetTitle() );
1375 if( bRet )
1376 pRegion->DeleteEntry( nIdx );
1379 return bRet;
1382 //------------------------------------------------------------------------
1384 sal_Bool SfxDocumentTemplates::InsertDir
1386 const String& rText, // der logische Name des neuen Bereiches
1387 USHORT nRegion // Index des Bereiches
1390 /* [Beschreibung]
1392 Einf"ugen eines Verzeichnisses
1395 [R"uckgabewert]
1397 sal_Bool sal_True
1398 Aktion konnte ausgef"uhrt werden
1400 sal_False
1401 Aktion konnte nicht ausgef"uhrt werden
1403 [Querverweise]
1405 <SfxDocumentTemplates::KillDir(SfxTemplateDir&)>
1406 <SfxDocumentTemplates::SaveDir(SfxTemplateDir&)>
1409 DocTemplLocker_Impl aLocker( *pImp );
1411 if ( ! pImp->Construct() )
1412 return sal_False;
1414 RegionData_Impl *pRegion = pImp->GetRegion( rText );
1416 if ( pRegion )
1417 return sal_False;
1419 uno::Reference< XDocumentTemplates > xTemplates = pImp->getDocTemplates();
1421 if ( xTemplates->addGroup( rText ) )
1423 RegionData_Impl* pNewRegion = new RegionData_Impl( pImp, rText );
1425 if ( ! pImp->InsertRegion( pNewRegion, nRegion ) )
1427 delete pNewRegion;
1428 return sal_False;
1430 return sal_True;
1433 return sal_False;
1436 //------------------------------------------------------------------------
1438 sal_Bool SfxDocumentTemplates::SetName
1440 const String& rName, // Der zu setzende Name
1441 USHORT nRegion, // Index des Bereiches
1442 USHORT nIdx /* Index des Eintrags oder USHRT_MAX,
1443 wenn ein Verzeichnis gemeint ist. */
1446 /* [Beschreibung]
1448 "Andern des Namens eines Eintrags oder eines Verzeichnisses
1451 [R"uckgabewert]
1453 sal_Bool sal_True
1454 Aktion konnte ausgef"uhrt werden
1456 sal_False
1457 Aktion konnte nicht ausgef"uhrt werden
1462 DocTemplLocker_Impl aLocker( *pImp );
1464 if ( ! pImp->Construct() )
1465 return sal_False;
1467 RegionData_Impl *pRegion = pImp->GetRegion( nRegion );
1468 DocTempl_EntryData_Impl *pEntry = NULL;
1470 if ( !pRegion )
1471 return sal_False;
1473 uno::Reference< XDocumentTemplates > xTemplates = pImp->getDocTemplates();
1474 OUString aEmpty;
1476 if ( nIdx == USHRT_MAX )
1478 if ( pRegion->GetTitle() == OUString( rName ) )
1479 return sal_True;
1481 // we have to rename a region
1482 if ( xTemplates->renameGroup( pRegion->GetTitle(), rName ) )
1484 pRegion->SetTitle( rName );
1485 pRegion->SetTargetURL( aEmpty );
1486 pRegion->SetHierarchyURL( aEmpty );
1487 return sal_True;
1490 else
1492 pEntry = pRegion->GetEntry( nIdx );
1494 if ( !pEntry )
1495 return sal_False;
1497 if ( pEntry->GetTitle() == OUString( rName ) )
1498 return sal_True;
1500 if ( xTemplates->renameTemplate( pRegion->GetTitle(),
1501 pEntry->GetTitle(),
1502 rName ) )
1504 pEntry->SetTitle( rName );
1505 pEntry->SetTargetURL( aEmpty );
1506 pEntry->SetHierarchyURL( aEmpty );
1507 return sal_True;
1511 return sal_False;
1514 //------------------------------------------------------------------------
1516 sal_Bool SfxDocumentTemplates::Rescan()
1518 /* [Beschreibung]
1520 Abgleich des Verwaltungsdaten mit dem aktuellen Zustand auf der Platte.
1521 Die logischen Namen, zu denen keine Datei mit existiert, werden aus
1522 der Verwaltungsstruktur entfernt; Dateien, zu denen kein Eintrag
1523 existiert, werden aufgenommen.
1526 [R"uckgabewert]
1528 sal_Bool sal_True
1529 Aktion konnte ausgef"uhrt werden
1531 sal_False
1532 Aktion konnte nicht ausgef"uhrt werden
1535 [Querverweise]
1537 <SfxTemplateDir::Scan(sal_Bool bDirectory, sal_Bool bSave)>
1538 <SfxTemplateDir::Freshen(const SfxTemplateDir &rNew)>
1541 if ( !pImp->Construct() )
1542 return sal_False;
1544 pImp->Rescan();
1546 return sal_True;
1549 //------------------------------------------------------------------------
1551 SfxObjectShellRef SfxDocumentTemplates::CreateObjectShell
1553 USHORT nRegion, // Index des Bereiches
1554 USHORT nIdx // Index des Eintrags
1557 /* [Beschreibung]
1559 Zugriff auf die DokumentShell eines Eintrags
1562 [R"uckgabewert]
1564 SfxObjectShellRef Referenz auf die ObjectShell
1567 [Querverweise]
1569 <SfxTemplateDirEntry::CreateObjectShell()>
1570 <SfxDocumentTemplates::DeleteObjectShell(USHORT, USHORT)>
1574 DocTemplLocker_Impl aLocker( *pImp );
1576 if ( !pImp->Construct() )
1577 return NULL;
1579 RegionData_Impl *pRegion = pImp->GetRegion( nRegion );
1580 DocTempl_EntryData_Impl *pEntry = NULL;
1582 if ( pRegion )
1583 pEntry = pRegion->GetEntry( nIdx );
1585 if ( pEntry )
1586 return pEntry->CreateObjectShell();
1587 else
1588 return NULL;
1591 //------------------------------------------------------------------------
1593 sal_Bool SfxDocumentTemplates::DeleteObjectShell
1595 USHORT nRegion, // Index des Bereiches
1596 USHORT nIdx // Index des Eintrags
1599 /* [Beschreibung]
1601 Freigeben der ObjectShell eines Eintrags
1604 [R"uckgabewert]
1606 sal_Bool sal_True
1607 Aktion konnte ausgef"uhrt werden
1609 sal_False
1610 Aktion konnte nicht ausgef"uhrt werden
1612 [Querverweise]
1614 <SfxTemplateDirEntry::DeleteObjectShell()>
1615 <SfxDocumentTemplates::CreateObjectShell(USHORT, USHORT)>
1619 DocTemplLocker_Impl aLocker( *pImp );
1621 if ( ! pImp->Construct() )
1622 return sal_True;
1624 RegionData_Impl *pRegion = pImp->GetRegion( nRegion );
1625 DocTempl_EntryData_Impl *pEntry = NULL;
1627 if ( pRegion )
1628 pEntry = pRegion->GetEntry( nIdx );
1630 if ( pEntry )
1631 return pEntry->DeleteObjectShell();
1632 else
1633 return sal_True;
1636 //------------------------------------------------------------------------
1638 sal_Bool SfxDocumentTemplates::GetFull
1640 const String &rRegion, // Der Name des Bereiches
1641 const String &rName, // Der Name der Vorlage
1642 String &rPath // Out: Pfad + Dateiname
1645 /* [Beschreibung]
1647 Liefert Pfad + Dateiname zu der durch rRegion und rName bezeichneten
1648 Vorlage
1651 [R"uckgabewert]
1653 sal_Bool sal_True
1654 Aktion konnte ausgef"uhrt werden
1656 sal_False
1657 Aktion konnte nicht ausgef"uhrt werden
1660 [Querverweise]
1662 <SfxDocumentTemplates::GetLogicNames(const String&,String&,String&)>
1666 DocTemplLocker_Impl aLocker( *pImp );
1668 // We don't search for empty names!
1669 if ( ! rName.Len() )
1670 return sal_False;
1672 if ( ! pImp->Construct() )
1673 return sal_False;
1675 DocTempl_EntryData_Impl* pEntry = NULL;
1676 const USHORT nCount = GetRegionCount();
1678 for ( USHORT i = 0; i < nCount; ++i )
1680 RegionData_Impl *pRegion = pImp->GetRegion( i );
1682 if( pRegion &&
1683 ( !rRegion.Len() || ( rRegion == String( pRegion->GetTitle() ) ) ) )
1685 pEntry = pRegion->GetEntry( rName );
1687 if ( pEntry )
1689 rPath = pEntry->GetTargetURL();
1690 break;
1695 return ( pEntry != NULL );
1698 //------------------------------------------------------------------------
1700 sal_Bool SfxDocumentTemplates::GetLogicNames
1702 const String &rPath, // vollst"andiger Pfad zu der Vorlage
1703 String &rRegion, // Out: der Bereichsname
1704 String &rName // Out: der Vorlagenname
1705 ) const
1707 /* [Beschreibung]
1709 Liefert Pfad und logischen Namen zu der durch rPath bezeichneten
1710 Vorlage
1712 [R"uckgabewert]
1714 sal_Bool sal_True
1715 Aktion konnte ausgef"uhrt werden
1717 sal_False
1718 Aktion konnte nicht ausgef"uhrt werden
1721 [Querverweise]
1723 <SfxDocumentTemplates::GetFull(const String&,const String&,DirEntry&)>
1727 DocTemplLocker_Impl aLocker( *pImp );
1729 if ( ! pImp->Construct() )
1730 return sal_False;
1732 INetURLObject aFullPath;
1734 aFullPath.SetSmartProtocol( INET_PROT_FILE );
1735 aFullPath.SetURL( rPath );
1736 OUString aPath( aFullPath.GetMainURL( INetURLObject::NO_DECODE ) );
1738 RegionData_Impl *pData = NULL;
1739 DocTempl_EntryData_Impl *pEntry = NULL;
1740 sal_Bool bFound = sal_False;
1742 ULONG nCount = GetRegionCount();
1744 for ( ULONG i=0; !bFound && (i<nCount); i++ )
1746 pData = pImp->GetRegion( i );
1747 if ( pData )
1749 ULONG nChildCount = pData->GetCount();
1751 for ( ULONG j=0; !bFound && (j<nChildCount); j++ )
1753 pEntry = pData->GetEntry( j );
1754 if ( pEntry->GetTargetURL() == aPath )
1756 bFound = sal_True;
1762 if ( bFound )
1764 rRegion = pData->GetTitle();
1765 rName = pEntry->GetTitle();
1768 return bFound;
1771 //------------------------------------------------------------------------
1773 SfxDocumentTemplates::SfxDocumentTemplates()
1775 /* [Beschreibung]
1777 Konstruktor
1780 if ( !gpTemplateData )
1781 gpTemplateData = new SfxDocTemplate_Impl;
1783 pImp = gpTemplateData;
1786 //-------------------------------------------------------------------------
1788 void SfxDocumentTemplates::Construct()
1790 // verz"ogerter Aufbau der Verwaltungsdaten
1793 // pImp->Construct();
1796 //------------------------------------------------------------------------
1798 SfxDocumentTemplates::~SfxDocumentTemplates()
1800 /* [Beschreibung]
1802 Destruktor
1803 Freigeben der Verwaltungsdaten
1807 pImp = NULL;
1810 void SfxDocumentTemplates::Update( sal_Bool _bSmart )
1812 if ( !_bSmart // don't be smart
1813 || ::svt::TemplateFolderCache( sal_True ).needsUpdate() // update is really necessary
1816 if ( pImp->Construct() )
1817 pImp->Rescan();
1821 void SfxDocumentTemplates::ReInitFromComponent()
1823 pImp->ReInitFromComponent();
1827 sal_Bool SfxDocumentTemplates::HasUserContents( sal_uInt16 nRegion, sal_uInt16 nIdx ) const
1829 DocTemplLocker_Impl aLocker( *pImp );
1831 sal_Bool bResult = sal_False;
1833 RegionData_Impl* pRegion = pImp->GetRegion( nRegion );
1835 if ( pRegion )
1837 ::rtl::OUString aRegionTargetURL = pRegion->GetTargetURL();
1838 if ( aRegionTargetURL.getLength() )
1840 sal_uInt16 nLen = 0;
1841 sal_uInt16 nStartInd = 0;
1843 if( nIdx == USHRT_MAX )
1845 // this is a folder
1846 // check whether there is at least one editable template
1847 nLen = ( sal_uInt16 )pRegion->GetCount();
1848 nStartInd = 0;
1849 if ( nLen == 0 )
1850 bResult = sal_True; // the writing part of empty folder with writing URL can be removed
1852 else
1854 // this is a template
1855 // check whether the template is inserted by user
1856 nLen = 1;
1857 nStartInd = nIdx;
1860 for ( sal_uInt16 nInd = nStartInd; nInd < nStartInd + nLen; nInd++ )
1862 DocTempl_EntryData_Impl* pEntryData = pRegion->GetEntry( nInd );
1863 if ( pEntryData )
1865 ::rtl::OUString aEntryTargetURL = pEntryData->GetTargetURL();
1866 if ( aEntryTargetURL.getLength()
1867 && ::utl::UCBContentHelper::IsSubPath( aRegionTargetURL, aEntryTargetURL ) )
1869 bResult = sal_True;
1870 break;
1877 return bResult;
1880 // -----------------------------------------------------------------------
1881 // -----------------------------------------------------------------------
1882 // -----------------------------------------------------------------------
1883 DocTempl_EntryData_Impl::DocTempl_EntryData_Impl( RegionData_Impl* pParent,
1884 const OUString& rTitle )
1886 mpParent = pParent;
1887 maTitle = rTitle;
1888 mbIsOwner = sal_False;
1889 mbDidConvert= sal_False;
1892 // -----------------------------------------------------------------------
1893 int DocTempl_EntryData_Impl::Compare( const OUString& rTitle ) const
1895 return maTitle.compareTo( rTitle );
1898 //------------------------------------------------------------------------
1899 SfxObjectShellRef DocTempl_EntryData_Impl::CreateObjectShell()
1901 if( ! mxObjShell.Is() )
1903 mbIsOwner = sal_False;
1904 sal_Bool bDum = sal_False;
1905 SfxApplication *pSfxApp = SFX_APP();
1906 String aTargetURL = GetTargetURL();
1908 mxObjShell = pSfxApp->DocAlreadyLoaded( aTargetURL, sal_True, bDum );
1910 if( ! mxObjShell.Is() )
1912 mbIsOwner = sal_True;
1913 SfxMedium *pMed=new SfxMedium(
1914 aTargetURL,(STREAM_STD_READWRITE | STREAM_SHARE_DENYALL), sal_False, 0 );
1915 const SfxFilter* pFilter = NULL;
1916 pMed->UseInteractionHandler(TRUE);
1917 if( pSfxApp->GetFilterMatcher().GuessFilter(
1918 *pMed, &pFilter, SFX_FILTER_TEMPLATE, 0 ) ||
1919 (pFilter && !pFilter->IsOwnFormat()) ||
1920 (pFilter && !pFilter->UsesStorage()) )
1922 SfxErrorContext aEc( ERRCTX_SFX_LOADTEMPLATE,
1923 aTargetURL );
1924 delete pMed;
1925 mbDidConvert=sal_True;
1926 ULONG lErr;
1927 if ( mxObjShell.Is() ) {
1928 lErr = pSfxApp->LoadTemplate( mxObjShell,aTargetURL);
1929 if( lErr != ERRCODE_NONE )
1930 ErrorHandler::HandleError(lErr);
1934 else if (pFilter)
1936 mbDidConvert=sal_False;
1937 mxObjShell = SfxObjectShell::CreateObject( pFilter->GetServiceName(), SFX_CREATE_MODE_ORGANIZER );
1938 if ( mxObjShell.Is() )
1940 mxObjShell->DoInitNew(0);
1941 // TODO/LATER: make sure that we don't use binary templates!
1942 if( mxObjShell->LoadFrom( *pMed ) )
1944 mxObjShell->DoSaveCompleted( pMed );
1946 else
1947 mxObjShell.Clear();
1953 return (SfxObjectShellRef)(SfxObjectShell*) mxObjShell;
1956 //------------------------------------------------------------------------
1957 BOOL DocTempl_EntryData_Impl::DeleteObjectShell()
1959 sal_Bool bRet = sal_True;
1961 if ( mxObjShell.Is() )
1963 if( mxObjShell->IsModified() )
1965 //Hier speichern wir auch, falls die Vorlage in Bearbeitung ist...
1966 bRet = sal_False;
1968 if ( mbIsOwner )
1970 if( mbDidConvert )
1972 bRet=mxObjShell->PreDoSaveAs_Impl(
1973 GetTargetURL(),
1974 mxObjShell->GetFactory().GetFilterContainer()->GetAnyFilter( SFX_FILTER_EXPORT | SFX_FILTER_IMPORT, SFX_FILTER_INTERNAL )->GetFilterName(), 0 );
1976 else
1978 if( mxObjShell->Save() )
1980 uno::Reference< embed::XTransactedObject > xTransacted( mxObjShell->GetStorage(), uno::UNO_QUERY );
1981 DBG_ASSERT( xTransacted.is(), "Storage must implement XTransactedObject!\n" );
1982 if ( xTransacted.is() )
1986 xTransacted->commit();
1987 bRet = sal_True;
1989 catch( uno::Exception& )
1998 if( bRet )
2000 mxObjShell.Clear();
2003 return bRet;
2006 // -----------------------------------------------------------------------
2007 const OUString& DocTempl_EntryData_Impl::GetHierarchyURL()
2009 if ( !maOwnURL.getLength() )
2011 INetURLObject aTemplateObj( GetParent()->GetHierarchyURL() );
2013 aTemplateObj.insertName( GetTitle(), false,
2014 INetURLObject::LAST_SEGMENT, true,
2015 INetURLObject::ENCODE_ALL );
2017 maOwnURL = aTemplateObj.GetMainURL( INetURLObject::NO_DECODE );
2018 DBG_ASSERT( maOwnURL.getLength(), "GetHierarchyURL(): Could not create URL!" );
2021 return maOwnURL;
2024 // -----------------------------------------------------------------------
2025 const OUString& DocTempl_EntryData_Impl::GetTargetURL()
2027 if ( !maTargetURL.getLength() )
2029 uno::Reference< XCommandEnvironment > aCmdEnv;
2030 Content aRegion;
2032 if ( Content::create( GetHierarchyURL(), aCmdEnv, aRegion ) )
2034 OUString aPropName( RTL_CONSTASCII_USTRINGPARAM( TARGET_URL ) );
2036 getTextProperty_Impl( aRegion, aPropName, maTargetURL );
2038 else
2040 DBG_ERRORFILE( "GetTargetURL(): Could not create hierarchy content!" );
2044 return maTargetURL;
2047 // -----------------------------------------------------------------------
2048 // -----------------------------------------------------------------------
2049 // -----------------------------------------------------------------------
2050 // -----------------------------------------------------------------------
2051 RegionData_Impl::RegionData_Impl( const SfxDocTemplate_Impl* pParent,
2052 const OUString& rTitle )
2054 maTitle = rTitle;
2055 mpParent = pParent;
2058 // -----------------------------------------------------------------------
2059 RegionData_Impl::~RegionData_Impl()
2061 DocTempl_EntryData_Impl *pData = maEntries.First();
2063 while ( pData )
2065 delete pData;
2066 pData = maEntries.Next();
2070 // -----------------------------------------------------------------------
2071 long RegionData_Impl::GetEntryPos( const OUString& rTitle,
2072 sal_Bool& rFound ) const
2074 #if 1 // Don't use binary search today
2075 ULONG i;
2076 ULONG nCount = maEntries.Count();
2078 for ( i=0; i<nCount; i++ )
2080 DocTempl_EntryData_Impl *pData = maEntries.GetObject( i );
2082 if ( pData->Compare( rTitle ) == 0 )
2084 rFound = sal_True;
2085 return i;
2089 rFound = sal_False;
2090 return i;
2092 #else
2093 // use binary search to find the correct position
2094 // in the maEntries list
2096 int nCompVal = 1;
2097 long nStart = 0;
2098 long nEnd = maEntries.Count() - 1;
2099 long nMid;
2101 DocTempl_EntryData_Impl* pMid;
2103 rFound = sal_False;
2105 while ( nCompVal && ( nStart <= nEnd ) )
2107 nMid = ( nEnd - nStart ) / 2 + nStart;
2108 pMid = maEntries.GetObject( nMid );
2110 nCompVal = pMid->Compare( rTitle );
2112 if ( nCompVal < 0 ) // pMid < pData
2113 nStart = nMid + 1;
2114 else
2115 nEnd = nMid - 1;
2118 if ( nCompVal == 0 )
2120 rFound = sal_True;
2122 else
2124 if ( nCompVal < 0 ) // pMid < pData
2125 nMid++;
2128 return nMid;
2129 #endif
2132 // -----------------------------------------------------------------------
2133 void RegionData_Impl::AddEntry( const OUString& rTitle,
2134 const OUString& rTargetURL,
2135 USHORT *pPos )
2137 INetURLObject aLinkObj( GetHierarchyURL() );
2138 aLinkObj.insertName( rTitle, false,
2139 INetURLObject::LAST_SEGMENT, true,
2140 INetURLObject::ENCODE_ALL );
2141 OUString aLinkURL = aLinkObj.GetMainURL( INetURLObject::NO_DECODE );
2143 DocTempl_EntryData_Impl *pEntry;
2144 sal_Bool bFound = sal_False;
2145 long nPos = GetEntryPos( rTitle, bFound );
2147 if ( bFound )
2149 pEntry = maEntries.GetObject( nPos );
2151 else
2153 if ( pPos )
2154 nPos = *pPos;
2156 pEntry = new DocTempl_EntryData_Impl( this, rTitle );
2157 pEntry->SetTargetURL( rTargetURL );
2158 pEntry->SetHierarchyURL( aLinkURL );
2159 maEntries.Insert( pEntry, nPos );
2163 // -----------------------------------------------------------------------
2164 ULONG RegionData_Impl::GetCount() const
2166 return maEntries.Count();
2169 // -----------------------------------------------------------------------
2170 const OUString& RegionData_Impl::GetHierarchyURL()
2172 if ( !maOwnURL.getLength() )
2174 INetURLObject aRegionObj( GetParent()->GetRootURL() );
2176 aRegionObj.insertName( GetTitle(), false,
2177 INetURLObject::LAST_SEGMENT, true,
2178 INetURLObject::ENCODE_ALL );
2180 maOwnURL = aRegionObj.GetMainURL( INetURLObject::NO_DECODE );
2181 DBG_ASSERT( maOwnURL.getLength(), "GetHierarchyURL(): Could not create URL!" );
2184 return maOwnURL;
2187 // -----------------------------------------------------------------------
2188 const OUString& RegionData_Impl::GetTargetURL()
2190 if ( !maTargetURL.getLength() )
2192 uno::Reference< XCommandEnvironment > aCmdEnv;
2193 Content aRegion;
2195 if ( Content::create( GetHierarchyURL(), aCmdEnv, aRegion ) )
2197 OUString aPropName( RTL_CONSTASCII_USTRINGPARAM( TARGET_DIR_URL ) );
2199 getTextProperty_Impl( aRegion, aPropName, maTargetURL );
2200 // --> PB 2004-10-27 #i32656# - the targeturl must be substituted: $(baseinsturl)
2201 maTargetURL = SvtPathOptions().SubstituteVariable( maTargetURL );
2202 // <--
2204 else
2206 DBG_ERRORFILE( "GetTargetURL(): Could not create hierarchy content!" );
2210 return maTargetURL;
2213 // -----------------------------------------------------------------------
2214 DocTempl_EntryData_Impl* RegionData_Impl::GetEntry( const OUString& rName ) const
2216 sal_Bool bFound = sal_False;
2217 long nPos = GetEntryPos( rName, bFound );
2219 if ( bFound )
2220 return maEntries.GetObject( nPos );
2221 else
2222 return NULL;
2225 // -----------------------------------------------------------------------
2226 DocTempl_EntryData_Impl* RegionData_Impl::GetByTargetURL( const OUString& rName ) const
2228 DocTempl_EntryData_Impl *pEntry;
2230 ULONG nCount = maEntries.Count();
2232 for ( ULONG i=0; i<nCount; i++ )
2234 pEntry = maEntries.GetObject( i );
2235 if ( pEntry && ( pEntry->GetTargetURL() == rName ) )
2236 return pEntry;
2239 return NULL;
2242 // -----------------------------------------------------------------------
2243 DocTempl_EntryData_Impl* RegionData_Impl::GetEntry( ULONG nIndex ) const
2245 return maEntries.GetObject( nIndex );
2248 // -----------------------------------------------------------------------
2249 void RegionData_Impl::DeleteEntry( ULONG nIndex )
2251 DocTempl_EntryData_Impl *pEntry = maEntries.GetObject( nIndex );
2253 if ( pEntry )
2255 delete pEntry;
2256 maEntries.Remove( (ULONG) nIndex );
2260 // -----------------------------------------------------------------------
2261 int RegionData_Impl::Compare( RegionData_Impl* pCompare ) const
2263 int nCompare = maTitle.compareTo( pCompare->maTitle );
2265 return nCompare;
2268 // -----------------------------------------------------------------------
2269 // -----------------------------------------------------------------------
2270 // -----------------------------------------------------------------------
2272 SfxDocTemplate_Impl::SfxDocTemplate_Impl()
2273 : mbConstructed( sal_False )
2274 , mnLockCounter( 0 )
2278 // -----------------------------------------------------------------------
2279 SfxDocTemplate_Impl::~SfxDocTemplate_Impl()
2281 Clear();
2283 gpTemplateData = NULL;
2286 // -----------------------------------------------------------------------
2287 void SfxDocTemplate_Impl::IncrementLock()
2289 ::osl::MutexGuard aGuard( maMutex );
2290 mnLockCounter++;
2293 // -----------------------------------------------------------------------
2294 void SfxDocTemplate_Impl::DecrementLock()
2296 ::osl::MutexGuard aGuard( maMutex );
2297 if ( mnLockCounter )
2298 mnLockCounter--;
2301 // -----------------------------------------------------------------------
2302 RegionData_Impl* SfxDocTemplate_Impl::GetRegion( ULONG nIndex ) const
2304 return maRegions.GetObject( nIndex );
2307 // -----------------------------------------------------------------------
2308 RegionData_Impl* SfxDocTemplate_Impl::GetRegion( const OUString& rName )
2309 const
2311 ULONG nCount = maRegions.Count();
2312 RegionData_Impl *pData;
2314 for ( ULONG i=0; i<nCount; i++ )
2316 pData = maRegions.GetObject( i );
2318 if ( pData->GetTitle() == rName )
2319 return pData;
2322 return NULL;
2325 // -----------------------------------------------------------------------
2326 void SfxDocTemplate_Impl::DeleteRegion( ULONG nIndex )
2328 RegionData_Impl* pRegion = maRegions.GetObject( nIndex );
2330 if ( pRegion )
2332 delete pRegion;
2333 maRegions.Remove( (ULONG) nIndex );
2337 // -----------------------------------------------------------------------
2338 /* AddRegion adds a Region to the RegionList
2340 void SfxDocTemplate_Impl::AddRegion( const OUString& rTitle,
2341 Content& rContent )
2343 RegionData_Impl* pRegion;
2344 pRegion = new RegionData_Impl( this, rTitle );
2346 if ( ! InsertRegion( pRegion ) )
2348 delete pRegion;
2349 return;
2352 // now get the content of the region
2353 uno::Reference< XResultSet > xResultSet;
2354 Sequence< OUString > aProps(2);
2355 aProps[0] = OUString::createFromAscii( TITLE );
2356 aProps[1] = OUString::createFromAscii( TARGET_URL );
2360 ResultSetInclude eInclude = INCLUDE_DOCUMENTS_ONLY;
2361 Sequence< NumberedSortingInfo > aSortingInfo(1);
2362 aSortingInfo.getArray()->ColumnIndex = 1;
2363 aSortingInfo.getArray()->Ascending = sal_True;
2364 xResultSet = rContent.createSortedCursor( aProps, aSortingInfo, m_rCompareFactory, eInclude );
2366 catch ( Exception& ) {}
2368 if ( xResultSet.is() )
2370 uno::Reference< XContentAccess > xContentAccess( xResultSet, UNO_QUERY );
2371 uno::Reference< XRow > xRow( xResultSet, UNO_QUERY );
2375 while ( xResultSet->next() )
2377 OUString aTitle( xRow->getString( 1 ) );
2378 OUString aTargetDir( xRow->getString( 2 ) );
2380 pRegion->AddEntry( aTitle, aTargetDir );
2383 catch ( Exception& ) {}
2387 // -----------------------------------------------------------------------
2388 void SfxDocTemplate_Impl::CreateFromHierarchy( Content &rTemplRoot )
2390 uno::Reference< XResultSet > xResultSet;
2391 Sequence< OUString > aProps(1);
2392 aProps[0] = OUString::createFromAscii( TITLE );
2396 ResultSetInclude eInclude = INCLUDE_FOLDERS_ONLY;
2397 Sequence< NumberedSortingInfo > aSortingInfo(1);
2398 aSortingInfo.getArray()->ColumnIndex = 1;
2399 aSortingInfo.getArray()->Ascending = sal_True;
2400 xResultSet = rTemplRoot.createSortedCursor( aProps, aSortingInfo, m_rCompareFactory, eInclude );
2402 catch ( Exception& ) {}
2404 if ( xResultSet.is() )
2406 uno::Reference< XCommandEnvironment > aCmdEnv;
2407 uno::Reference< XContentAccess > xContentAccess( xResultSet, UNO_QUERY );
2408 uno::Reference< XRow > xRow( xResultSet, UNO_QUERY );
2412 while ( xResultSet->next() )
2414 OUString aTitle( xRow->getString( 1 ) );
2416 OUString aId = xContentAccess->queryContentIdentifierString();
2417 Content aContent = Content( aId, aCmdEnv );
2419 AddRegion( aTitle, aContent );
2422 catch ( Exception& ) {}
2426 // ------------------------------------------------------------------------
2427 sal_Bool SfxDocTemplate_Impl::Construct( )
2429 ::osl::MutexGuard aGuard( maMutex );
2431 if ( mbConstructed )
2432 return sal_True;
2434 uno::Reference< XMultiServiceFactory > xFactory;
2435 xFactory = ::comphelper::getProcessServiceFactory();
2437 OUString aService( RTL_CONSTASCII_USTRINGPARAM( SERVICENAME_DOCINFO ) );
2438 uno::Reference< XPersist > xInfo( xFactory->createInstance( aService ), UNO_QUERY );
2439 mxInfo = xInfo;
2441 aService = OUString( RTL_CONSTASCII_USTRINGPARAM( SERVICENAME_DOCTEMPLATES ) );
2442 uno::Reference< XDocumentTemplates > xTemplates( xFactory->createInstance( aService ), UNO_QUERY );
2444 if ( xTemplates.is() )
2445 mxTemplates = xTemplates;
2446 else
2447 return sal_False;
2449 uno::Reference< XLocalizable > xLocalizable( xTemplates, UNO_QUERY );
2451 Sequence< Any > aCompareArg(1);
2452 *(aCompareArg.getArray()) <<= xLocalizable->getLocale();;
2453 m_rCompareFactory = uno::Reference< XAnyCompareFactory >(
2454 xFactory->createInstanceWithArguments( OUString::createFromAscii( "com.sun.star.ucb.AnyCompareFactory" ),
2455 aCompareArg ),
2456 UNO_QUERY );
2458 uno::Reference < XContent > aRootContent = xTemplates->getContent();
2459 uno::Reference < XCommandEnvironment > aCmdEnv;
2461 if ( ! aRootContent.is() )
2462 return sal_False;
2464 mbConstructed = sal_True;
2465 maRootURL = aRootContent->getIdentifier()->getContentIdentifier();
2467 ResStringArray aLongNames( SfxResId( TEMPLATE_LONG_NAMES_ARY ) );
2469 if ( aLongNames.Count() )
2470 maStandardGroup = aLongNames.GetString( 0 );
2472 Content aTemplRoot( aRootContent, aCmdEnv );
2473 CreateFromHierarchy( aTemplRoot );
2475 return sal_True;
2478 // -----------------------------------------------------------------------
2479 void SfxDocTemplate_Impl::ReInitFromComponent()
2481 uno::Reference< XDocumentTemplates > xTemplates = getDocTemplates();
2482 if ( xTemplates.is() )
2484 uno::Reference < XContent > aRootContent = xTemplates->getContent();
2485 uno::Reference < XCommandEnvironment > aCmdEnv;
2486 Content aTemplRoot( aRootContent, aCmdEnv );
2487 Clear();
2488 CreateFromHierarchy( aTemplRoot );
2492 // -----------------------------------------------------------------------
2493 void SfxDocTemplate_Impl::GetTemplates( Content& rTargetFolder,
2494 Content& /*rParentFolder*/,
2495 RegionData_Impl* pRegion )
2497 uno::Reference< XResultSet > xResultSet;
2498 Sequence< OUString > aProps(1);
2500 aProps[0] = OUString::createFromAscii( TITLE );
2504 ResultSetInclude eInclude = INCLUDE_DOCUMENTS_ONLY;
2505 Sequence< NumberedSortingInfo > aSortingInfo(1);
2506 aSortingInfo.getArray()->ColumnIndex = 1;
2507 aSortingInfo.getArray()->Ascending = sal_True;
2508 xResultSet = rTargetFolder.createSortedCursor( aProps, aSortingInfo, m_rCompareFactory, eInclude );
2510 catch ( Exception& ) {}
2512 if ( xResultSet.is() )
2514 uno::Reference< XContentAccess > xContentAccess( xResultSet, UNO_QUERY );
2515 uno::Reference< XRow > xRow( xResultSet, UNO_QUERY );
2519 while ( xResultSet->next() )
2521 OUString aTitle( xRow->getString(1) );
2523 if ( aTitle.compareToAscii( "sfx.tlx" ) == 0 )
2524 continue;
2526 OUString aId = xContentAccess->queryContentIdentifierString();
2528 DocTempl_EntryData_Impl* pEntry = pRegion->GetByTargetURL( aId );
2530 if ( ! pEntry )
2532 OUString aFullTitle;
2533 if( !GetTitleFromURL( aId, aFullTitle ) )
2535 DBG_ERRORFILE( "GetTemplates(): template of alien format" );
2536 continue;
2539 if ( aFullTitle.getLength() )
2540 aTitle = aFullTitle;
2542 pRegion->AddEntry( aTitle, aId );
2546 catch ( Exception& ) {}
2551 // -----------------------------------------------------------------------
2552 long SfxDocTemplate_Impl::GetRegionPos( const OUString& rTitle,
2553 sal_Bool& rFound ) const
2555 int nCompVal = 1;
2556 long nStart = 0;
2557 long nEnd = maRegions.Count() - 1;
2558 long nMid = 0;
2560 RegionData_Impl* pMid;
2562 while ( nCompVal && ( nStart <= nEnd ) )
2564 nMid = ( nEnd - nStart ) / 2 + nStart;
2565 pMid = maRegions.GetObject( nMid );
2567 nCompVal = pMid->Compare( rTitle );
2569 if ( nCompVal < 0 ) // pMid < pData
2570 nStart = nMid + 1;
2571 else
2572 nEnd = nMid - 1;
2575 if ( nCompVal == 0 )
2576 rFound = sal_True;
2577 else
2579 if ( nCompVal < 0 ) // pMid < pData
2580 nMid++;
2582 rFound = sal_False;
2585 return nMid;
2588 // -----------------------------------------------------------------------
2589 sal_Bool SfxDocTemplate_Impl::InsertRegion( RegionData_Impl *pNew,
2590 ULONG nPos )
2592 ::osl::MutexGuard aGuard( maMutex );
2593 RegionData_Impl *pData = maRegions.First();
2595 while ( pData && ( pData->Compare( pNew ) != 0 ) )
2596 pData = maRegions.Next();
2598 if ( ! pData )
2600 // compare with the name of the standard group here to insert it
2601 // first
2603 if ( pNew->GetTitle() == maStandardGroup )
2604 maRegions.Insert( pNew, (ULONG) 0 );
2605 else
2606 maRegions.Insert( pNew, nPos );
2609 return ( pData == NULL );
2612 // -----------------------------------------------------------------------
2613 void SfxDocTemplate_Impl::Rescan()
2615 Clear();
2619 uno::Reference< XDocumentTemplates > xTemplates = getDocTemplates();
2620 DBG_ASSERT( xTemplates.is(), "SfxDocTemplate_Impl::Rescan:invalid template instance!" );
2621 if ( xTemplates.is() )
2623 xTemplates->update();
2625 uno::Reference < XContent > aRootContent = xTemplates->getContent();
2626 uno::Reference < XCommandEnvironment > aCmdEnv;
2628 Content aTemplRoot( aRootContent, aCmdEnv );
2629 CreateFromHierarchy( aTemplRoot );
2632 catch( const Exception& )
2634 DBG_ERRORFILE( "SfxDocTemplate_Impl::Rescan: caught an exception while doing the update!" );
2638 // -----------------------------------------------------------------------
2639 sal_Bool SfxDocTemplate_Impl::GetTitleFromURL( const OUString& rURL,
2640 OUString& aTitle )
2642 if ( mxInfo.is() )
2646 mxInfo->read( rURL );
2648 catch ( Exception& )
2650 // the document is not a StarOffice document
2651 return sal_False;
2657 uno::Reference< XPropertySet > aPropSet( mxInfo, UNO_QUERY );
2658 if ( aPropSet.is() )
2660 OUString aPropName( RTL_CONSTASCII_USTRINGPARAM( TITLE ) );
2661 Any aValue = aPropSet->getPropertyValue( aPropName );
2662 aValue >>= aTitle;
2665 catch ( IOException& ) {}
2666 catch ( UnknownPropertyException& ) {}
2667 catch ( Exception& ) {}
2670 if ( ! aTitle.getLength() )
2672 INetURLObject aURL( rURL );
2673 aURL.CutExtension();
2674 aTitle = aURL.getName( INetURLObject::LAST_SEGMENT, true,
2675 INetURLObject::DECODE_WITH_CHARSET );
2678 return sal_True;
2682 // -----------------------------------------------------------------------
2683 void SfxDocTemplate_Impl::Clear()
2685 ::osl::MutexGuard aGuard( maMutex );
2686 if ( mnLockCounter )
2687 return;
2689 RegionData_Impl *pRegData = maRegions.First();
2691 while ( pRegData )
2693 delete pRegData;
2694 pRegData = maRegions.Next();
2697 maRegions.Clear();
2700 // -----------------------------------------------------------------------
2701 // -----------------------------------------------------------------------
2702 // -----------------------------------------------------------------------
2703 sal_Bool getTextProperty_Impl( Content& rContent,
2704 const OUString& rPropName,
2705 OUString& rPropValue )
2707 sal_Bool bGotProperty = sal_False;
2709 // Get the property
2712 uno::Reference< XPropertySetInfo > aPropInfo = rContent.getProperties();
2714 // check, wether or not the property exists
2715 if ( !aPropInfo.is() || !aPropInfo->hasPropertyByName( rPropName ) )
2717 return sal_False;
2720 // now get the property
2721 Any aAnyValue;
2723 aAnyValue = rContent.getPropertyValue( rPropName );
2724 aAnyValue >>= rPropValue;
2726 if ( SfxURLRelocator_Impl::propertyCanContainOfficeDir( rPropName ) )
2728 SfxURLRelocator_Impl aRelocImpl( ::comphelper::getProcessServiceFactory() );
2729 aRelocImpl.makeAbsoluteURL( rPropValue );
2732 bGotProperty = sal_True;
2734 catch ( RuntimeException& ) {}
2735 catch ( Exception& ) {}
2737 return bGotProperty;