summaryrefslogtreecommitdiff
path: root/sfx2/source/doc/doctempl.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sfx2/source/doc/doctempl.cxx')
-rw-r--r--sfx2/source/doc/doctempl.cxx2735
1 files changed, 2735 insertions, 0 deletions
diff --git a/sfx2/source/doc/doctempl.cxx b/sfx2/source/doc/doctempl.cxx
new file mode 100644
index 000000000000..db6f2a2d133f
--- /dev/null
+++ b/sfx2/source/doc/doctempl.cxx
@@ -0,0 +1,2735 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sfx2.hxx"
+
+#include <limits.h>
+#include <com/sun/star/uno/Any.h>
+#include <vos/mutex.hxx>
+#include <vos/thread.hxx>
+
+#ifndef _SV_RESARY_HXX
+#include <tools/resary.hxx>
+#endif
+#include <vcl/svapp.hxx>
+#include <vcl/settings.hxx>
+#include <unotools/localedatawrapper.hxx>
+#include <unotools/pathoptions.hxx>
+#include <tools/string.hxx>
+#include <tools/urlobj.hxx>
+#include <svtools/ehdl.hxx>
+#include <svtools/sfxecode.hxx>
+#include <comphelper/processfactory.hxx>
+#include <ucbhelper/content.hxx>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/beans/XPropertyContainer.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/XPropertySetInfo.hpp>
+#include <com/sun/star/document/XTypeDetection.hpp>
+#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
+#include <com/sun/star/frame/XComponentLoader.hpp>
+#include <com/sun/star/frame/XDocumentTemplates.hpp>
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/io/XPersist.hpp>
+#include <com/sun/star/lang/XLocalizable.hpp>
+#include <com/sun/star/sdbc/XResultSet.hpp>
+#include <com/sun/star/sdbc/XRow.hpp>
+#include <com/sun/star/ucb/ContentInfo.hpp>
+#include <com/sun/star/ucb/InsertCommandArgument.hpp>
+#include <com/sun/star/ucb/NameClash.hpp>
+#include <com/sun/star/ucb/TransferInfo.hpp>
+#include <com/sun/star/ucb/XCommandProcessor.hpp>
+#include <com/sun/star/ucb/XContent.hpp>
+#include <com/sun/star/ucb/XContentAccess.hpp>
+#include <com/sun/star/ucb/XAnyCompareFactory.hpp>
+#include <com/sun/star/ucb/XAnyCompare.hpp>
+#include <com/sun/star/ucb/NumberedSortingInfo.hpp>
+#include <com/sun/star/embed/ElementModes.hpp>
+#include <com/sun/star/embed/XTransactedObject.hpp>
+
+#include "sfxurlrelocator.hxx"
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::ucb;
+using namespace ::com::sun::star::document;
+using namespace ::rtl;
+using namespace ::ucbhelper;
+
+
+#include <sfx2/doctempl.hxx>
+#include <sfx2/docfac.hxx>
+#include <sfx2/docfile.hxx>
+#include <sfx2/objsh.hxx>
+#include "sfxtypes.hxx"
+#include <sfx2/app.hxx>
+#include "sfxresid.hxx"
+#include "doc.hrc"
+#include <sfx2/fcontnr.hxx>
+#include <svtools/templatefoldercache.hxx>
+
+#include <comphelper/storagehelper.hxx>
+#include <unotools/ucbhelper.hxx>
+
+//========================================================================
+
+// #define DONT_USE_HIERARCHY
+
+#define TITLE "Title"
+#define IS_FOLDER "IsFolder"
+#define PROPERTY_TYPE "TypeDescription"
+#define TARGET_URL "TargetURL"
+#define TYPE_FOLDER "application/vnd.sun.star.hier-folder"
+#define TYPE_LINK "application/vnd.sun.star.hier-link"
+#define TYPE_FSYS_FOLDER "application/vnd.sun.staroffice.fsys-folder"
+
+#define TARGET_DIR_URL "TargetDirURL"
+#define COMMAND_DELETE "delete"
+#define COMMAND_TRANSFER "transfer"
+
+#define STANDARD_FOLDER "standard"
+
+#define SERVICENAME_TYPEDETECTION "com.sun.star.document.TypeDetection"
+#define TYPEDETECTION_PARAMETER "FileName"
+//#define SERVICENAME_OLD_TYPEDETECTION "com.sun.star.frame.FrameLoaderFactory"
+//#define PARAMETER_OLD_TYPEDETECTION "DeepDetection"
+#define SERVICENAME_DOCINFO "com.sun.star.document.DocumentProperties"
+#define SERVICENAME_DOCTEMPLATES "com.sun.star.frame.DocumentTemplates"
+#define SERVICENAME_DESKTOP "com.sun.star.frame.Desktop"
+
+//========================================================================
+
+class RegionData_Impl;
+
+namespace DocTempl {
+
+class DocTempl_EntryData_Impl
+{
+ RegionData_Impl* mpParent;
+ SfxObjectShellLock mxObjShell;
+ OUString maTitle;
+ OUString maOwnURL;
+ OUString maTargetURL;
+ sal_Bool mbIsOwner : 1;
+ sal_Bool mbDidConvert: 1;
+
+private:
+ RegionData_Impl* GetParent() const { return mpParent; }
+
+public:
+ DocTempl_EntryData_Impl( RegionData_Impl* pParent,
+ const OUString& rTitle );
+
+ const OUString& GetTitle() const { return maTitle; }
+ const OUString& GetTargetURL();
+ const OUString& GetHierarchyURL();
+
+ void SetTitle( const OUString& rTitle ) { maTitle = rTitle; }
+ void SetTargetURL( const OUString& rURL ) { maTargetURL = rURL; }
+ void SetHierarchyURL( const OUString& rURL) { maOwnURL = rURL; }
+
+ int Compare( const OUString& rTitle ) const;
+
+ SfxObjectShellRef CreateObjectShell();
+ sal_Bool DeleteObjectShell();
+};
+
+}
+
+using namespace ::DocTempl;
+
+// ------------------------------------------------------------------------
+
+class RegionData_Impl
+{
+ DECLARE_LIST( EntryList_Impl, DocTempl_EntryData_Impl* )
+ const SfxDocTemplate_Impl* mpParent;
+ EntryList_Impl maEntries;
+ OUString maTitle;
+ OUString maOwnURL;
+ OUString maTargetURL;
+
+private:
+ long GetEntryPos( const OUString& rTitle,
+ sal_Bool& rFound ) const;
+ const SfxDocTemplate_Impl* GetParent() const { return mpParent; }
+
+public:
+ RegionData_Impl( const SfxDocTemplate_Impl* pParent,
+ const OUString& rTitle );
+ ~RegionData_Impl();
+
+ void SetTargetURL( const OUString& rURL ) { maTargetURL = rURL; }
+ void SetHierarchyURL( const OUString& rURL) { maOwnURL = rURL; }
+
+ DocTempl_EntryData_Impl* GetEntry( ULONG nIndex ) const;
+ DocTempl_EntryData_Impl* GetEntry( const OUString& rName ) const;
+ DocTempl_EntryData_Impl* GetByTargetURL( const OUString& rName ) const;
+
+ const OUString& GetTitle() const { return maTitle; }
+ const OUString& GetTargetURL();
+ const OUString& GetHierarchyURL();
+
+ ULONG GetCount() const;
+
+ void SetTitle( const OUString& rTitle ) { maTitle = rTitle; }
+
+ void AddEntry( const OUString& rTitle,
+ const OUString& rTargetURL,
+ USHORT *pPos = NULL );
+ void DeleteEntry( ULONG nIndex );
+
+ int Compare( const OUString& rTitle ) const
+ { return maTitle.compareTo( rTitle ); }
+ int Compare( RegionData_Impl* pCompareWith ) const;
+};
+
+DECLARE_LIST( RegionList_Impl, RegionData_Impl* )
+
+// ------------------------------------------------------------------------
+
+class SfxDocTemplate_Impl : public SvRefBase
+{
+ uno::Reference< XPersist > mxInfo;
+ uno::Reference< XDocumentTemplates > mxTemplates;
+
+ ::osl::Mutex maMutex;
+ OUString maRootURL;
+ OUString maStandardGroup;
+ RegionList_Impl maRegions;
+ sal_Bool mbConstructed;
+
+ uno::Reference< XAnyCompareFactory > m_rCompareFactory;
+
+ // the following member is intended to prevent clearing of the global data when it is in use
+ // TODO/LATER: it still does not make the implementation complete thread-safe
+ sal_Int32 mnLockCounter;
+
+private:
+ void Clear();
+
+public:
+ SfxDocTemplate_Impl();
+ ~SfxDocTemplate_Impl();
+
+ void IncrementLock();
+ void DecrementLock();
+
+ sal_Bool Construct( );
+ void CreateFromHierarchy( Content &rTemplRoot );
+ void ReInitFromComponent();
+ void AddRegion( const OUString& rTitle,
+ Content& rContent );
+
+ void Rescan();
+
+ void DeleteRegion( ULONG nIndex );
+
+ ULONG GetRegionCount() const
+ { return maRegions.Count(); }
+ RegionData_Impl* GetRegion( const OUString& rName ) const;
+ RegionData_Impl* GetRegion( ULONG nIndex ) const;
+ void GetTemplates( Content& rTargetFolder,
+ Content& rParentFolder,
+ RegionData_Impl* pRegion );
+
+ long GetRegionPos( const OUString& rTitle,
+ sal_Bool& rFound ) const;
+
+ sal_Bool GetTitleFromURL( const OUString& rURL, OUString& aTitle );
+ sal_Bool InsertRegion( RegionData_Impl *pData, ULONG nPos = LIST_APPEND );
+ OUString GetRootURL() const { return maRootURL; }
+
+ uno::Reference< XDocumentTemplates > getDocTemplates() { return mxTemplates; }
+};
+
+// ------------------------------------------------------------------------
+
+class DocTemplLocker_Impl
+{
+ SfxDocTemplate_Impl& m_aDocTempl;
+public:
+ DocTemplLocker_Impl( SfxDocTemplate_Impl& aDocTempl )
+ : m_aDocTempl( aDocTempl )
+ {
+ m_aDocTempl.IncrementLock();
+ }
+
+ ~DocTemplLocker_Impl()
+ {
+ m_aDocTempl.DecrementLock();
+ }
+};
+
+// ------------------------------------------------------------------------
+
+#ifndef SFX_DECL_DOCTEMPLATES_DEFINED
+#define SFX_DECL_DOCTEMPLATES_DEFINED
+SV_DECL_REF(SfxDocTemplate_Impl)
+#endif
+
+SV_IMPL_REF(SfxDocTemplate_Impl)
+
+// ------------------------------------------------------------------------
+
+SfxDocTemplate_Impl *gpTemplateData = 0;
+
+// -----------------------------------------------------------------------
+
+static sal_Bool getTextProperty_Impl( Content& rContent,
+ const OUString& rPropName,
+ OUString& rPropValue );
+
+//========================================================================
+//========================================================================
+//========================================================================
+
+String SfxDocumentTemplates::GetFullRegionName
+(
+ USHORT nIdx // Index des Bereiches
+) const
+
+/* [Beschreibung]
+
+ Liefert den logischen Namen eines Bereiches Plus seinem Pfad
+
+
+ [R"uckgabewert] Referenz auf diesen Namen
+
+*/
+
+{
+ // First: find the RegionData for the index
+ String aName;
+
+ DocTemplLocker_Impl aLocker( *pImp );
+
+ if ( pImp->Construct() )
+ {
+ RegionData_Impl *pData1 = pImp->GetRegion( nIdx );
+
+ if ( pData1 )
+ aName = pData1->GetTitle();
+
+ // --**-- here was some code which appended the path to the
+ // group if there was more than one with the same name.
+ // this should not happen anymore
+ }
+
+ return aName;
+}
+
+//------------------------------------------------------------------------
+
+const String& SfxDocumentTemplates::GetRegionName
+(
+ USHORT nIdx // Index des Bereiches
+) const
+
+/* [Beschreibung]
+
+ Liefert den logischen Namen eines Bereiches
+
+
+ [R"uckgabewert]
+
+ const String& Referenz auf diesen Namen
+
+*/
+{
+ static String maTmpString;
+
+ DocTemplLocker_Impl aLocker( *pImp );
+
+ if ( pImp->Construct() )
+ {
+ RegionData_Impl *pData = pImp->GetRegion( nIdx );
+
+ if ( pData )
+ maTmpString = pData->GetTitle();
+ else
+ maTmpString.Erase();
+ }
+ else
+ maTmpString.Erase();
+
+ return maTmpString;
+}
+
+
+//------------------------------------------------------------------------
+
+USHORT SfxDocumentTemplates::GetRegionNo
+(
+ const String &rRegion // Name der Region
+) const
+
+/* [Beschreibung]
+
+ Liefert den Index f"ur einen logischen Namen eines Bereiches.
+
+
+ [R"uckgabewert]
+
+ USHORT Index von 'rRegion' oder USHRT_MAX falls unbekannt
+
+*/
+{
+ DocTemplLocker_Impl aLocker( *pImp );
+
+ if ( !pImp->Construct() )
+ return USHRT_MAX;
+
+ sal_Bool bFound;
+ ULONG nIndex = pImp->GetRegionPos( rRegion, bFound );
+
+ if ( bFound )
+ return (USHORT) nIndex;
+ else
+ return USHRT_MAX;
+}
+
+
+//------------------------------------------------------------------------
+
+USHORT SfxDocumentTemplates::GetRegionCount() const
+
+/* [Beschreibung]
+
+ Liefert die Anzahl der Bereiche
+
+
+ [R"uckgabewert]
+
+ USHORT Anzahl der Bereiche
+
+*/
+{
+ DocTemplLocker_Impl aLocker( *pImp );
+
+ if ( !pImp->Construct() )
+ return 0;
+
+ ULONG nCount = pImp->GetRegionCount();
+
+ return (USHORT) nCount;
+}
+
+//------------------------------------------------------------------------
+
+sal_Bool SfxDocumentTemplates::IsRegionLoaded( USHORT nIdx ) const
+{
+ DocTemplLocker_Impl aLocker( *pImp );
+
+ if ( !pImp->Construct() )
+ return sal_False;
+
+ RegionData_Impl *pData = pImp->GetRegion( nIdx );
+
+ if ( pData )
+ return sal_True;
+ else
+ return sal_False;
+}
+
+//------------------------------------------------------------------------
+
+USHORT SfxDocumentTemplates::GetCount
+(
+ const String& rName /* Name des Bereiches, dessen Eintrags-
+ anzahl ermittelt werden soll */
+
+) const
+
+/* [Beschreibung]
+
+ Liefert die Anzahl der Eintr"age eines Bereiches
+
+
+ [R"uckgabewert]
+
+ USHORT Anzahl der Eintr"age
+
+*/
+
+{
+ DocTemplLocker_Impl aLocker( *pImp );
+
+ if ( !pImp->Construct() )
+ return 0;
+
+ RegionData_Impl *pData = pImp->GetRegion( rName );
+ ULONG nCount = 0;
+
+ if ( pData )
+ nCount = pData->GetCount();
+
+ return (USHORT) nCount;
+}
+
+//------------------------------------------------------------------------
+
+USHORT SfxDocumentTemplates::GetCount
+(
+ USHORT nRegion /* Index des Bereiches, dessen Eintrags-
+ anzahl ermittelt werden soll */
+
+) const
+
+/* [Beschreibung]
+
+ Liefert die Anzahl der Eintr"age eines Bereiches
+
+
+ [R"uckgabewert] Anzahl der Eintr"age
+
+*/
+
+{
+ DocTemplLocker_Impl aLocker( *pImp );
+
+ if ( !pImp->Construct() )
+ return 0;
+
+ RegionData_Impl *pData = pImp->GetRegion( nRegion );
+ ULONG nCount = 0;
+
+ if ( pData )
+ nCount = pData->GetCount();
+
+ return (USHORT) nCount;
+}
+
+//------------------------------------------------------------------------
+
+const String& SfxDocumentTemplates::GetName
+(
+ USHORT nRegion, // Index des Bereiches, in dem der Eintrag liegt
+ USHORT nIdx // Index des Eintrags
+) const
+
+/* [Beschreibung]
+
+ Liefert den logischen Namen eines Eintrags eines Bereiches
+
+
+ [R"uckgabewert]
+
+ const String& Name des Eintrags
+
+*/
+
+{
+ DocTemplLocker_Impl aLocker( *pImp );
+
+ static String maTmpString;
+
+ if ( pImp->Construct() )
+ {
+ DocTempl_EntryData_Impl *pEntry = NULL;
+ RegionData_Impl *pRegion = pImp->GetRegion( nRegion );
+
+ if ( pRegion )
+ pEntry = pRegion->GetEntry( nIdx );
+
+ if ( pEntry )
+ maTmpString = pEntry->GetTitle();
+ else
+ maTmpString.Erase();
+ }
+ else
+ maTmpString.Erase();
+
+ return maTmpString;
+}
+
+//------------------------------------------------------------------------
+
+String SfxDocumentTemplates::GetFileName
+(
+ USHORT nRegion, // Index des Bereiches, in dem der Eintrag liegt
+ USHORT nIdx // Index des Eintrags
+) const
+
+/* [Beschreibung]
+
+ Liefert den Dateinamen eines Eintrags eines Bereiches
+
+ [R"uckgabewert] Dateiname des Eintrags
+
+*/
+{
+ DocTemplLocker_Impl aLocker( *pImp );
+
+ if ( !pImp->Construct() )
+ return String();
+
+ DocTempl_EntryData_Impl *pEntry = NULL;
+ RegionData_Impl *pRegion = pImp->GetRegion( nRegion );
+
+ if ( pRegion )
+ pEntry = pRegion->GetEntry( nIdx );
+
+ if ( pEntry )
+ {
+ INetURLObject aURLObj( pEntry->GetTargetURL() );
+ return aURLObj.getName( INetURLObject::LAST_SEGMENT, true,
+ INetURLObject::DECODE_WITH_CHARSET );
+ }
+ else
+ return String();
+}
+
+//------------------------------------------------------------------------
+
+String SfxDocumentTemplates::GetPath
+(
+ USHORT nRegion, // Index des Bereiches, in dem der Eintrag liegt
+ USHORT nIdx // Index des Eintrags
+) const
+
+/* [Beschreibung]
+
+ Liefert den Dateinamen mit vollst"andigem Pfad zu der einem
+ Eintrag zugeordneten Datei
+
+
+ [R"uckgabewert]
+
+ String Dateiname mit vollst"andigem Pfad
+
+*/
+{
+ DocTemplLocker_Impl aLocker( *pImp );
+
+ if ( !pImp->Construct() )
+ return String();
+
+ DocTempl_EntryData_Impl *pEntry = NULL;
+ RegionData_Impl *pRegion = pImp->GetRegion( nRegion );
+
+ if ( pRegion )
+ pEntry = pRegion->GetEntry( nIdx );
+
+ if ( pEntry )
+ return pEntry->GetTargetURL();
+ else
+ return String();
+}
+
+//------------------------------------------------------------------------
+
+String SfxDocumentTemplates::GetTemplatePath
+(
+ USHORT nRegion, // Index des Bereiches, in dem der Eintrag liegt
+ const String& rLongName // logischer Name des Eintrags
+) const
+
+/* [Beschreibung]
+
+ Liefert den Dateinamen mit vollst"andigem Pfad zu der einem
+ Eintrag zugeordneten Datei
+
+
+ [R"uckgabewert]
+
+ String Dateiname mit vollst"andigem Pfad
+
+*/
+{
+ DocTemplLocker_Impl aLocker( *pImp );
+
+ if ( !pImp->Construct() )
+ return String();
+
+ DocTempl_EntryData_Impl *pEntry = NULL;
+ RegionData_Impl *pRegion = pImp->GetRegion( nRegion );
+
+ if ( pRegion )
+ pEntry = pRegion->GetEntry( rLongName );
+
+ if ( pEntry )
+ return pEntry->GetTargetURL();
+ else if ( pRegion )
+ {
+ // a new template is going to be inserted, generate a new URL
+ // TODO/LATER: if the title is localized, use minimized URL in future
+
+ // --**-- extension handling will become more complicated, because
+ // every new document type will have it's own extension
+ // e.g.: .stw or .stc instead of .vor
+ INetURLObject aURLObj( pRegion->GetTargetURL() );
+ aURLObj.insertName( rLongName, false,
+ INetURLObject::LAST_SEGMENT, true,
+ INetURLObject::ENCODE_ALL );
+
+ OUString aExtension = aURLObj.getExtension();
+
+ if ( ! aExtension.getLength() )
+ aURLObj.setExtension( OUString( RTL_CONSTASCII_USTRINGPARAM( "vor" ) ) );
+
+ return aURLObj.GetMainURL( INetURLObject::NO_DECODE );
+ }
+ else
+ return String();
+}
+
+//------------------------------------------------------------------------
+
+String SfxDocumentTemplates::GetDefaultTemplatePath
+(
+ const String& rLongName
+)
+
+/* [Beschreibung]
+
+ Liefert den Standardpfad zu Dokumentvorlagen
+
+
+ [R"uckgabewert]
+
+ String Standardpfad zu Dokumentvorlagen
+
+*/
+{
+ DocTemplLocker_Impl aLocker( *pImp );
+
+ if ( ! pImp->Construct() )
+ return String();
+
+ // the first region in the list should always be the standard
+ // group
+ // --**-- perhaps we have to create it ???
+ RegionData_Impl *pRegion = pImp->GetRegion( 0L );
+ DocTempl_EntryData_Impl *pEntry = NULL;
+
+ if ( pRegion )
+ pEntry = pRegion->GetEntry( rLongName );
+
+ if ( pEntry )
+ return pEntry->GetTargetURL();
+ else if ( pRegion )
+ {
+ // a new template is going to be inserted, generate a new URL
+ // TODO/LATER: if the title is localized, use minimized URL in future
+
+ INetURLObject aURLObj( pRegion->GetTargetURL() );
+ aURLObj.insertName( rLongName, false,
+ INetURLObject::LAST_SEGMENT, true,
+ INetURLObject::ENCODE_ALL );
+
+ OUString aExtension = aURLObj.getExtension();
+
+ if ( ! aExtension.getLength() )
+ aURLObj.setExtension( OUString( RTL_CONSTASCII_USTRINGPARAM( "vor" ) ) );
+
+ return aURLObj.GetMainURL( INetURLObject::NO_DECODE );
+ }
+ else
+ return String();
+
+/* dv! missing: create the directory, if it doesn't exists
+
+
+ DBG_ASSERT(aDirs.GetTokenCount(cDelim), "Keine Bereiche");
+ DirEntry aPath(aDirs.GetToken(0, cDelim));
+
+ // Verzeichnis anlegen
+ if(!aPath.MakeDir())
+ return String();
+
+ MakeFileName_Impl(aPath, rLongName, sal_True);
+ SfxTemplateDir *pEntry = new SfxTemplateDir;
+ SfxTemplateDirEntryPtr pDirEntry =
+ new SfxTemplateDirEntry( String( '.' ), aPath.GetPath() );
+ pDirEntry->SetContent(new SfxTemplateDir(aPath.GetPath()));
+ pEntry->Insert(pDirEntry, pEntry->Count());
+ pDirs->Insert(pEntry, pDirs->Count());
+ return aPath.GetFull();
+*/
+}
+
+//------------------------------------------------------------------------
+
+::rtl::OUString SfxDocumentTemplates::GetTemplateTargetURLFromComponent( const ::rtl::OUString& aGroupName,
+ const ::rtl::OUString& aTitle )
+{
+ DocTemplLocker_Impl aLocker( *pImp );
+
+ INetURLObject aTemplateObj( pImp->GetRootURL() );
+
+ aTemplateObj.insertName( aGroupName, false,
+ INetURLObject::LAST_SEGMENT, true,
+ INetURLObject::ENCODE_ALL );
+
+ aTemplateObj.insertName( aTitle, false,
+ INetURLObject::LAST_SEGMENT, true,
+ INetURLObject::ENCODE_ALL );
+
+
+ ::rtl::OUString aResult;
+ Content aTemplate;
+ uno::Reference< XCommandEnvironment > aCmdEnv;
+ if ( Content::create( aTemplateObj.GetMainURL( INetURLObject::NO_DECODE ), aCmdEnv, aTemplate ) )
+ {
+ OUString aPropName( RTL_CONSTASCII_USTRINGPARAM( TARGET_URL ) );
+ getTextProperty_Impl( aTemplate, aPropName, aResult );
+ aResult = SvtPathOptions().SubstituteVariable( aResult );
+ }
+
+ return aResult;
+}
+
+//------------------------------------------------------------------------
+
+sal_Bool SfxDocumentTemplates::SaveDir
+(
+// SfxTemplateDir& rDir // das zu speichernde Directory
+)
+
+/* [Beschreibung]
+
+ Speichert das Directory rDir
+
+
+ [R"uckgabewert]
+
+ sal_Bool sal_False,
+ Schreibfehler
+
+ sal_True
+ gespeichert
+
+*/
+
+{
+ return sal_True;
+}
+
+//------------------------------------------------------------------------
+
+void SfxDocumentTemplates::NewTemplate
+(
+ USHORT nRegion, /* Index des Bereiches, in dem die Vorlage
+ angelegt werden soll */
+
+ const String& rLongName, // logischer Name der neuen Vorlage
+ const String& rFileName // Dateiname der neuen Vorlage
+)
+
+/* [Beschreibung]
+
+ Eintragen einer neuen Dokumentvorlage in die Verwaltungsstrukturen
+ Das "Uberschreiben einer Vorlage gleichen Namens wird
+ verhindert (!! Fehlermeldung)
+
+*/
+
+{
+ DocTemplLocker_Impl aLocker( *pImp );
+
+ if ( ! pImp->Construct() )
+ return;
+
+ DocTempl_EntryData_Impl *pEntry;
+ RegionData_Impl *pRegion = pImp->GetRegion( nRegion );
+
+ // do nothing if there is no region with that index
+ if ( !pRegion )
+ return;
+
+ pEntry = pRegion->GetEntry( rLongName );
+
+ // do nothing if there is already an entry with that name
+ if ( pEntry )
+ return;
+
+ uno::Reference< XDocumentTemplates > xTemplates = pImp->getDocTemplates();
+
+ if ( xTemplates->addTemplate( pRegion->GetTitle(), rLongName, rFileName ) )
+ pRegion->AddEntry( rLongName, rFileName );
+}
+
+//------------------------------------------------------------------------
+
+sal_Bool SfxDocumentTemplates::CopyOrMove
+(
+ USHORT nTargetRegion, // Index des Zielbereiches
+ USHORT nTargetIdx, // Index Zielposition
+ USHORT nSourceRegion, // Index des Quellbereiches
+ USHORT nSourceIdx, /* Index der zu kopierenden / zu verschiebenden
+ Dokumentvorlage */
+ sal_Bool bMove // kopieren / verschieben
+)
+
+/* [Beschreibung]
+
+ Kopieren oder Verschieben einer Dokumentvorlage
+
+ [R"uckgabewert]
+
+ sal_Bool sal_True
+ Aktion konnte ausgef"uhrt werden
+
+ sal_False
+ Aktion konnte nicht ausgef2uhrt werden
+ [Querverweise]
+
+ <SfxDocumentTemplates::Move(USHORT,USHORT,USHORT,USHORT)>
+ <SfxDocumentTemplates::Copy(USHORT,USHORT,USHORT,USHORT)>
+*/
+
+{
+ /* to perform a copy or move, we need to send a transfer command to
+ the destination folder with the URL of the source as parameter.
+ ( If the destination content doesn't support the transfer command,
+ we could try a copy ( and delete ) instead. )
+ We need two transfers ( one for the real template and one for its
+ representation in the hierarchy )
+ ...
+ */
+
+ DocTemplLocker_Impl aLocker( *pImp );
+
+ if ( !pImp->Construct() )
+ return sal_False;
+
+ // Don't copy or move any folders
+ if( nSourceIdx == USHRT_MAX )
+ return sal_False ;
+
+ if ( nSourceRegion == nTargetRegion )
+ {
+ DBG_ERRORFILE( "Don't know, what to do!" );
+ return sal_False;
+#if 0
+ // Verschieben einer Vorlage innerhalb eines Bereiches
+ // --> nur Verwaltungsdaten aktualisieren
+ if ( bMove && nTargetRegion == nSourceRegion )
+ {
+ if(nTargetIdx == USHRT_MAX)
+ nTargetIdx = 0;
+ const SfxTemplateDirEntryPtr pEntry = rTargetDir[nSourceIdx];
+ rTargetDir.Insert(pEntry, nTargetIdx);
+ if(nTargetIdx < nSourceIdx)
+ ++nSourceIdx;
+ rTargetDir.Remove(nSourceIdx);
+ return SaveDir(rTargetDir);
+ }
+#endif
+ }
+
+ RegionData_Impl *pSourceRgn = pImp->GetRegion( nSourceRegion );
+ if ( !pSourceRgn )
+ return sal_False;
+
+ DocTempl_EntryData_Impl *pSource = pSourceRgn->GetEntry( nSourceIdx );
+ if ( !pSource )
+ return sal_False;
+
+ RegionData_Impl *pTargetRgn = pImp->GetRegion( nTargetRegion );
+ if ( !pTargetRgn )
+ return sal_False;
+
+ OUString aTitle = pSource->GetTitle();
+
+ uno::Reference< XDocumentTemplates > xTemplates = pImp->getDocTemplates();
+
+ if ( xTemplates->addTemplate( pTargetRgn->GetTitle(),
+ aTitle,
+ pSource->GetTargetURL() ) )
+ {
+
+ INetURLObject aSourceObj( pSource->GetTargetURL() );
+
+ ::rtl::OUString aNewTargetURL = GetTemplateTargetURLFromComponent( pTargetRgn->GetTitle(), aTitle );
+ if ( !aNewTargetURL.getLength() )
+ return sal_False;
+
+ if ( bMove )
+ {
+ // --**-- delete the original file
+ sal_Bool bDeleted = xTemplates->removeTemplate( pSourceRgn->GetTitle(),
+ pSource->GetTitle() );
+ if ( bDeleted )
+ pSourceRgn->DeleteEntry( nSourceIdx );
+ else
+ {
+ if ( xTemplates->removeTemplate( pTargetRgn->GetTitle(), aTitle ) )
+ return sal_False; // will trigger tetry with copy instead of move
+
+ // if it is not possible to remove just created template ( must be possible! )
+ // it is better to report success here, since at least the copy has succeeded
+ // TODO/LATER: solve it more gracefully in future
+ }
+ }
+
+ pTargetRgn->AddEntry( aTitle, aNewTargetURL, &nTargetIdx );
+
+ return sal_True;
+ }
+
+ // --**-- wenn aktuell das File geoeffnet ist,
+ // muss es hinterher wieder geoeffnet werden
+
+ return sal_False;
+}
+
+//------------------------------------------------------------------------
+
+sal_Bool SfxDocumentTemplates::Move
+(
+ USHORT nTargetRegion, // Index des Zielbereiches
+ USHORT nTargetIdx, // Index Zielposition
+ USHORT nSourceRegion, // Index des Quellbereiches
+ USHORT nSourceIdx /* Index der zu kopierenden / zu verschiebenden
+ Dokumentvorlage */
+)
+
+/* [Beschreibung]
+
+ Verschieben einer Dokumentvorlage
+
+
+ [R"uckgabewert]
+
+ sal_Bool sal_True
+ Aktion konnte ausgef"uhrt werden
+
+ sal_False
+ Aktion konnte nicht ausgef2uhrt werden
+
+ [Querverweise]
+
+ <SfxDocumentTemplates::CopyOrMove(USHORT,USHORT,USHORT,USHORT,sal_Bool)>
+*/
+{
+ DocTemplLocker_Impl aLocker( *pImp );
+
+ return CopyOrMove( nTargetRegion, nTargetIdx,
+ nSourceRegion, nSourceIdx, sal_True );
+}
+
+//------------------------------------------------------------------------
+
+sal_Bool SfxDocumentTemplates::Copy
+(
+ USHORT nTargetRegion, // Index des Zielbereiches
+ USHORT nTargetIdx, // Index Zielposition
+ USHORT nSourceRegion, // Index des Quellbereiches
+ USHORT nSourceIdx /* Index der zu kopierenden / zu verschiebenden
+ Dokumentvorlage */
+)
+
+/* [Beschreibung]
+
+ Kopieren einer Dokumentvorlage
+
+
+ [R"uckgabewert]
+
+ sal_Bool sal_True
+ Aktion konnte ausgef"uhrt werden
+
+ sal_False
+ Aktion konnte nicht ausgef"uhrt werden
+
+ [Querverweise]
+
+ <SfxDocumentTemplates::CopyOrMove(USHORT,USHORT,USHORT,USHORT,sal_Bool)>
+*/
+
+{
+ DocTemplLocker_Impl aLocker( *pImp );
+
+ return CopyOrMove( nTargetRegion, nTargetIdx,
+ nSourceRegion, nSourceIdx, sal_False );
+}
+
+//------------------------------------------------------------------------
+
+sal_Bool SfxDocumentTemplates::CopyTo
+(
+ USHORT nRegion, /* Bereich der Vorlage, die exportiert werden
+ soll */
+ USHORT nIdx, /* Index der Vorlage, die exportiert werden
+ soll */
+ const String& rName /* Dateiname, unter dem die Vorlage angelegt
+ werden soll */
+) const
+
+/* [Beschreibung]
+
+ Exportieren einer Dokumentvorlage in das Dateisystem
+
+
+ [R"uckgabewert]
+
+ sal_Bool sal_True
+ Aktion konnte ausgef"uhrt werden
+
+ sal_False
+ Aktion konnte nicht ausgef"uhrt werden
+
+
+ [Querverweise]
+
+ <SfxDocumentTemplates::CopyFrom(USHORT,USHORT,String&)>
+*/
+
+{
+ DocTemplLocker_Impl aLocker( *pImp );
+
+ if ( ! pImp->Construct() )
+ return sal_False;
+
+ RegionData_Impl *pSourceRgn = pImp->GetRegion( nRegion );
+ if ( !pSourceRgn )
+ return sal_False;
+
+ DocTempl_EntryData_Impl *pSource = pSourceRgn->GetEntry( nIdx );
+ if ( !pSource )
+ return sal_False;
+
+ INetURLObject aTargetURL( rName );
+
+ OUString aTitle( aTargetURL.getName( INetURLObject::LAST_SEGMENT, true,
+ INetURLObject::DECODE_WITH_CHARSET ) );
+ aTargetURL.removeSegment();
+
+ OUString aParentURL = aTargetURL.GetMainURL( INetURLObject::NO_DECODE );
+
+ uno::Reference< XCommandEnvironment > aCmdEnv;
+ Content aTarget;
+
+ try
+ {
+ aTarget = Content( aParentURL, aCmdEnv );
+
+ TransferInfo aTransferInfo;
+ aTransferInfo.MoveData = sal_False;
+ aTransferInfo.SourceURL = pSource->GetTargetURL();
+ aTransferInfo.NewTitle = aTitle;
+ aTransferInfo.NameClash = NameClash::OVERWRITE;
+
+ Any aArg = makeAny( aTransferInfo );
+ OUString aCmd( RTL_CONSTASCII_USTRINGPARAM( COMMAND_TRANSFER ) );
+
+ aTarget.executeCommand( aCmd, aArg );
+ }
+ catch ( ContentCreationException& )
+ { return sal_False; }
+ catch ( Exception& )
+ { return sal_False; }
+
+ return sal_True;
+}
+
+//------------------------------------------------------------------------
+
+sal_Bool SfxDocumentTemplates::CopyFrom
+(
+ USHORT nRegion, /* Bereich, in den die Vorlage importiert
+ werden soll */
+ USHORT nIdx, // Index der neuen Vorlage in diesem Bereich
+ String& rName /* Dateiname der Vorlage, die importiert
+ werden soll, als out-Parameter der (auto-
+ matisch aus dem Dateinamen generierte)
+ logische Name der Vorlage */
+)
+
+/* [Beschreibung]
+
+ Importieren einer Dokumentvorlage aus dem Dateisystem
+
+
+ [R"uckgabewert] Erfolg (sal_True) oder Mi"serfpTargetDirectory->GetContent());
+
+ sal_Bool sal_True
+ Aktion konnte ausgef"uhrt werden
+
+ sal_False
+ Aktion konnte nicht ausgef"uhrt werden
+
+ [Querverweise]
+
+ <SfxDocumentTemplates::CopyTo(USHORT,USHORT,const String&)>
+*/
+
+{
+ DocTemplLocker_Impl aLocker( *pImp );
+
+ if ( ! pImp->Construct() )
+ return sal_False;
+
+ RegionData_Impl *pTargetRgn = pImp->GetRegion( nRegion );
+
+ if ( !pTargetRgn )
+ return sal_False;
+
+ uno::Reference< XDocumentTemplates > xTemplates = pImp->getDocTemplates();
+ if ( !xTemplates.is() )
+ return sal_False;
+
+ OUString aTitle;
+ sal_Bool bTemplateAdded = sal_False;
+
+ if( pImp->GetTitleFromURL( rName, aTitle ) )
+ {
+ bTemplateAdded = xTemplates->addTemplate( pTargetRgn->GetTitle(), aTitle, rName );
+ }
+ else
+ {
+ OUString aService( RTL_CONSTASCII_USTRINGPARAM( SERVICENAME_DESKTOP ) );
+ uno::Reference< XComponentLoader > xDesktop( ::comphelper::getProcessServiceFactory()->createInstance( aService ),
+ UNO_QUERY );
+
+ Sequence< PropertyValue > aArgs( 1 );
+ aArgs[0].Name = ::rtl::OUString::createFromAscii("Hidden");
+ aArgs[0].Value <<= sal_True;
+
+ INetURLObject aTemplURL( rName );
+ uno::Reference< XDocumentPropertiesSupplier > xDocPropsSupplier;
+ uno::Reference< XStorable > xStorable;
+ try
+ {
+ xStorable = uno::Reference< XStorable >(
+ xDesktop->loadComponentFromURL( aTemplURL.GetMainURL(INetURLObject::NO_DECODE),
+ OUString::createFromAscii( "_blank" ),
+ 0,
+ aArgs ),
+ UNO_QUERY );
+
+ xDocPropsSupplier = uno::Reference< XDocumentPropertiesSupplier >(
+ xStorable, UNO_QUERY );
+ }
+ catch( Exception& )
+ {
+ }
+
+ if( xStorable.is() )
+ {
+ // get Title from XDocumentPropertiesSupplier
+ if( xDocPropsSupplier.is() )
+ {
+ uno::Reference< XDocumentProperties > xDocProps
+ = xDocPropsSupplier->getDocumentProperties();
+ if (xDocProps.is() ) {
+ aTitle = xDocProps->getTitle();
+ }
+ }
+
+ if( ! aTitle.getLength() )
+ {
+ INetURLObject aURL( aTemplURL );
+ aURL.CutExtension();
+ aTitle = aURL.getName( INetURLObject::LAST_SEGMENT, true,
+ INetURLObject::DECODE_WITH_CHARSET );
+ }
+
+ // write a template using XStorable interface
+ bTemplateAdded = xTemplates->storeTemplate( pTargetRgn->GetTitle(), aTitle, xStorable );
+ }
+ }
+
+
+ if( bTemplateAdded )
+ {
+ INetURLObject aTemplObj( pTargetRgn->GetHierarchyURL() );
+ aTemplObj.insertName( aTitle, false,
+ INetURLObject::LAST_SEGMENT, true,
+ INetURLObject::ENCODE_ALL );
+ OUString aTemplURL = aTemplObj.GetMainURL( INetURLObject::NO_DECODE );
+
+ uno::Reference< XCommandEnvironment > aCmdEnv;
+ Content aTemplCont;
+
+ if( Content::create( aTemplURL, aCmdEnv, aTemplCont ) )
+ {
+ OUString aTemplName;
+ OUString aPropName( RTL_CONSTASCII_USTRINGPARAM( TARGET_URL ) );
+
+ if( getTextProperty_Impl( aTemplCont, aPropName, aTemplName ) )
+ {
+ if ( nIdx == USHRT_MAX )
+ nIdx = 0;
+ else
+ nIdx += 1;
+
+ pTargetRgn->AddEntry( aTitle, aTemplName, &nIdx );
+ rName = aTitle;
+ return sal_True;
+ }
+ else
+ {
+ DBG_ASSERT( sal_False, "CopyFrom(): The content should contain target URL!" );
+ }
+ }
+ else
+ {
+ DBG_ASSERT( sal_False, "CopyFrom(): The content just was created!" );
+ }
+ }
+
+ return sal_False;
+}
+
+//------------------------------------------------------------------------
+
+sal_Bool SfxDocumentTemplates::Delete
+(
+ USHORT nRegion, // Index des Bereiches
+ USHORT nIdx /* Index des Eintrags oder USHRT_MAX,
+ wenn ein Verzeichnis gemeint ist. */
+)
+
+/* [Beschreibung]
+
+ "oschen eines Eintrags oder eines Verzeichnisses
+
+
+ [R"uckgabewert]
+
+ sal_Bool sal_True
+ Aktion konnte ausgef"uhrt werden
+
+ sal_False
+ Aktion konnte nicht ausgef"uhrt werden
+
+
+ [Querverweise]
+
+ <SfxDocumentTemplates::InsertDir(const String&,USHORT)>
+ <SfxDocumentTemplates::KillDir(SfxTemplateDir&)>
+ <SfxDocumentTemplates::SaveDir(SfxTemplateDir&)>
+*/
+
+{
+ DocTemplLocker_Impl aLocker( *pImp );
+
+ /* delete the template or folder in the hierarchy and in the
+ template folder by sending a delete command to the content.
+ Then remove the data from the lists
+ */
+ if ( ! pImp->Construct() )
+ return sal_False;
+
+ RegionData_Impl *pRegion = pImp->GetRegion( nRegion );
+
+ if ( !pRegion )
+ return sal_False;
+
+ sal_Bool bRet;
+ uno::Reference< XDocumentTemplates > xTemplates = pImp->getDocTemplates();
+
+ if ( nIdx == USHRT_MAX )
+ {
+ bRet = xTemplates->removeGroup( pRegion->GetTitle() );
+ if ( bRet )
+ pImp->DeleteRegion( nRegion );
+ }
+ else
+ {
+ DocTempl_EntryData_Impl *pEntry = pRegion->GetEntry( nIdx );
+
+ if ( !pEntry )
+ return sal_False;
+
+ bRet = xTemplates->removeTemplate( pRegion->GetTitle(),
+ pEntry->GetTitle() );
+ if( bRet )
+ pRegion->DeleteEntry( nIdx );
+ }
+
+ return bRet;
+}
+
+//------------------------------------------------------------------------
+
+sal_Bool SfxDocumentTemplates::InsertDir
+(
+ const String& rText, // der logische Name des neuen Bereiches
+ USHORT nRegion // Index des Bereiches
+)
+
+/* [Beschreibung]
+
+ Einf"ugen eines Verzeichnisses
+
+
+ [R"uckgabewert]
+
+ sal_Bool sal_True
+ Aktion konnte ausgef"uhrt werden
+
+ sal_False
+ Aktion konnte nicht ausgef"uhrt werden
+
+ [Querverweise]
+
+ <SfxDocumentTemplates::KillDir(SfxTemplateDir&)>
+ <SfxDocumentTemplates::SaveDir(SfxTemplateDir&)>
+*/
+{
+ DocTemplLocker_Impl aLocker( *pImp );
+
+ if ( ! pImp->Construct() )
+ return sal_False;
+
+ RegionData_Impl *pRegion = pImp->GetRegion( rText );
+
+ if ( pRegion )
+ return sal_False;
+
+ uno::Reference< XDocumentTemplates > xTemplates = pImp->getDocTemplates();
+
+ if ( xTemplates->addGroup( rText ) )
+ {
+ RegionData_Impl* pNewRegion = new RegionData_Impl( pImp, rText );
+
+ if ( ! pImp->InsertRegion( pNewRegion, nRegion ) )
+ {
+ delete pNewRegion;
+ return sal_False;
+ }
+ return sal_True;
+ }
+
+ return sal_False;
+}
+
+//------------------------------------------------------------------------
+
+sal_Bool SfxDocumentTemplates::SetName
+(
+ const String& rName, // Der zu setzende Name
+ USHORT nRegion, // Index des Bereiches
+ USHORT nIdx /* Index des Eintrags oder USHRT_MAX,
+ wenn ein Verzeichnis gemeint ist. */
+)
+
+/* [Beschreibung]
+
+ "Andern des Namens eines Eintrags oder eines Verzeichnisses
+
+
+ [R"uckgabewert]
+
+ sal_Bool sal_True
+ Aktion konnte ausgef"uhrt werden
+
+ sal_False
+ Aktion konnte nicht ausgef"uhrt werden
+
+*/
+
+{
+ DocTemplLocker_Impl aLocker( *pImp );
+
+ if ( ! pImp->Construct() )
+ return sal_False;
+
+ RegionData_Impl *pRegion = pImp->GetRegion( nRegion );
+ DocTempl_EntryData_Impl *pEntry = NULL;
+
+ if ( !pRegion )
+ return sal_False;
+
+ uno::Reference< XDocumentTemplates > xTemplates = pImp->getDocTemplates();
+ OUString aEmpty;
+
+ if ( nIdx == USHRT_MAX )
+ {
+ if ( pRegion->GetTitle() == OUString( rName ) )
+ return sal_True;
+
+ // we have to rename a region
+ if ( xTemplates->renameGroup( pRegion->GetTitle(), rName ) )
+ {
+ pRegion->SetTitle( rName );
+ pRegion->SetTargetURL( aEmpty );
+ pRegion->SetHierarchyURL( aEmpty );
+ return sal_True;
+ }
+ }
+ else
+ {
+ pEntry = pRegion->GetEntry( nIdx );
+
+ if ( !pEntry )
+ return sal_False;
+
+ if ( pEntry->GetTitle() == OUString( rName ) )
+ return sal_True;
+
+ if ( xTemplates->renameTemplate( pRegion->GetTitle(),
+ pEntry->GetTitle(),
+ rName ) )
+ {
+ pEntry->SetTitle( rName );
+ pEntry->SetTargetURL( aEmpty );
+ pEntry->SetHierarchyURL( aEmpty );
+ return sal_True;
+ }
+ }
+
+ return sal_False;
+}
+
+//------------------------------------------------------------------------
+
+sal_Bool SfxDocumentTemplates::Rescan()
+
+/* [Beschreibung]
+
+ Abgleich des Verwaltungsdaten mit dem aktuellen Zustand auf der Platte.
+ Die logischen Namen, zu denen keine Datei mit existiert, werden aus
+ der Verwaltungsstruktur entfernt; Dateien, zu denen kein Eintrag
+ existiert, werden aufgenommen.
+
+
+ [R"uckgabewert]
+
+ sal_Bool sal_True
+ Aktion konnte ausgef"uhrt werden
+
+ sal_False
+ Aktion konnte nicht ausgef"uhrt werden
+
+
+ [Querverweise]
+
+ <SfxTemplateDir::Scan(sal_Bool bDirectory, sal_Bool bSave)>
+ <SfxTemplateDir::Freshen(const SfxTemplateDir &rNew)>
+*/
+{
+ if ( !pImp->Construct() )
+ return sal_False;
+
+ pImp->Rescan();
+
+ return sal_True;
+}
+
+//------------------------------------------------------------------------
+
+SfxObjectShellRef SfxDocumentTemplates::CreateObjectShell
+(
+ USHORT nRegion, // Index des Bereiches
+ USHORT nIdx // Index des Eintrags
+)
+
+/* [Beschreibung]
+
+ Zugriff auf die DokumentShell eines Eintrags
+
+
+ [R"uckgabewert]
+
+ SfxObjectShellRef Referenz auf die ObjectShell
+
+
+ [Querverweise]
+
+ <SfxTemplateDirEntry::CreateObjectShell()>
+ <SfxDocumentTemplates::DeleteObjectShell(USHORT, USHORT)>
+*/
+
+{
+ DocTemplLocker_Impl aLocker( *pImp );
+
+ if ( !pImp->Construct() )
+ return NULL;
+
+ RegionData_Impl *pRegion = pImp->GetRegion( nRegion );
+ DocTempl_EntryData_Impl *pEntry = NULL;
+
+ if ( pRegion )
+ pEntry = pRegion->GetEntry( nIdx );
+
+ if ( pEntry )
+ return pEntry->CreateObjectShell();
+ else
+ return NULL;
+}
+
+//------------------------------------------------------------------------
+
+sal_Bool SfxDocumentTemplates::DeleteObjectShell
+(
+ USHORT nRegion, // Index des Bereiches
+ USHORT nIdx // Index des Eintrags
+)
+
+/* [Beschreibung]
+
+ Freigeben der ObjectShell eines Eintrags
+
+
+ [R"uckgabewert]
+
+ sal_Bool sal_True
+ Aktion konnte ausgef"uhrt werden
+
+ sal_False
+ Aktion konnte nicht ausgef"uhrt werden
+
+ [Querverweise]
+
+ <SfxTemplateDirEntry::DeleteObjectShell()>
+ <SfxDocumentTemplates::CreateObjectShell(USHORT, USHORT)>
+*/
+
+{
+ DocTemplLocker_Impl aLocker( *pImp );
+
+ if ( ! pImp->Construct() )
+ return sal_True;
+
+ RegionData_Impl *pRegion = pImp->GetRegion( nRegion );
+ DocTempl_EntryData_Impl *pEntry = NULL;
+
+ if ( pRegion )
+ pEntry = pRegion->GetEntry( nIdx );
+
+ if ( pEntry )
+ return pEntry->DeleteObjectShell();
+ else
+ return sal_True;
+}
+
+//------------------------------------------------------------------------
+
+sal_Bool SfxDocumentTemplates::GetFull
+(
+ const String &rRegion, // Der Name des Bereiches
+ const String &rName, // Der Name der Vorlage
+ String &rPath // Out: Pfad + Dateiname
+)
+
+/* [Beschreibung]
+
+ Liefert Pfad + Dateiname zu der durch rRegion und rName bezeichneten
+ Vorlage
+
+
+ [R"uckgabewert]
+
+ sal_Bool sal_True
+ Aktion konnte ausgef"uhrt werden
+
+ sal_False
+ Aktion konnte nicht ausgef"uhrt werden
+
+
+ [Querverweise]
+
+ <SfxDocumentTemplates::GetLogicNames(const String&,String&,String&)>
+*/
+
+{
+ DocTemplLocker_Impl aLocker( *pImp );
+
+ // We don't search for empty names!
+ if ( ! rName.Len() )
+ return sal_False;
+
+ if ( ! pImp->Construct() )
+ return sal_False;
+
+ DocTempl_EntryData_Impl* pEntry = NULL;
+ const USHORT nCount = GetRegionCount();
+
+ for ( USHORT i = 0; i < nCount; ++i )
+ {
+ RegionData_Impl *pRegion = pImp->GetRegion( i );
+
+ if( pRegion &&
+ ( !rRegion.Len() || ( rRegion == String( pRegion->GetTitle() ) ) ) )
+ {
+ pEntry = pRegion->GetEntry( rName );
+
+ if ( pEntry )
+ {
+ rPath = pEntry->GetTargetURL();
+ break;
+ }
+ }
+ }
+
+ return ( pEntry != NULL );
+}
+
+//------------------------------------------------------------------------
+
+sal_Bool SfxDocumentTemplates::GetLogicNames
+(
+ const String &rPath, // vollst"andiger Pfad zu der Vorlage
+ String &rRegion, // Out: der Bereichsname
+ String &rName // Out: der Vorlagenname
+) const
+
+/* [Beschreibung]
+
+ Liefert Pfad und logischen Namen zu der durch rPath bezeichneten
+ Vorlage
+
+ [R"uckgabewert]
+
+ sal_Bool sal_True
+ Aktion konnte ausgef"uhrt werden
+
+ sal_False
+ Aktion konnte nicht ausgef"uhrt werden
+
+
+ [Querverweise]
+
+ <SfxDocumentTemplates::GetFull(const String&,const String&,DirEntry&)>
+*/
+
+{
+ DocTemplLocker_Impl aLocker( *pImp );
+
+ if ( ! pImp->Construct() )
+ return sal_False;
+
+ INetURLObject aFullPath;
+
+ aFullPath.SetSmartProtocol( INET_PROT_FILE );
+ aFullPath.SetURL( rPath );
+ OUString aPath( aFullPath.GetMainURL( INetURLObject::NO_DECODE ) );
+
+ RegionData_Impl *pData = NULL;
+ DocTempl_EntryData_Impl *pEntry = NULL;
+ sal_Bool bFound = sal_False;
+
+ ULONG nCount = GetRegionCount();
+
+ for ( ULONG i=0; !bFound && (i<nCount); i++ )
+ {
+ pData = pImp->GetRegion( i );
+ if ( pData )
+ {
+ ULONG nChildCount = pData->GetCount();
+
+ for ( ULONG j=0; !bFound && (j<nChildCount); j++ )
+ {
+ pEntry = pData->GetEntry( j );
+ if ( pEntry->GetTargetURL() == aPath )
+ {
+ bFound = sal_True;
+ }
+ }
+ }
+ }
+
+ if ( bFound )
+ {
+ rRegion = pData->GetTitle();
+ rName = pEntry->GetTitle();
+ }
+
+ return bFound;
+}
+
+//------------------------------------------------------------------------
+
+SfxDocumentTemplates::SfxDocumentTemplates()
+
+/* [Beschreibung]
+
+ Konstruktor
+*/
+{
+ if ( !gpTemplateData )
+ gpTemplateData = new SfxDocTemplate_Impl;
+
+ pImp = gpTemplateData;
+}
+
+//-------------------------------------------------------------------------
+
+void SfxDocumentTemplates::Construct()
+
+// verz"ogerter Aufbau der Verwaltungsdaten
+
+{
+// pImp->Construct();
+}
+
+//------------------------------------------------------------------------
+
+SfxDocumentTemplates::~SfxDocumentTemplates()
+
+/* [Beschreibung]
+
+ Destruktor
+ Freigeben der Verwaltungsdaten
+*/
+
+{
+ pImp = NULL;
+}
+
+void SfxDocumentTemplates::Update( sal_Bool _bSmart )
+{
+ if ( !_bSmart // don't be smart
+ || ::svt::TemplateFolderCache( sal_True ).needsUpdate() // update is really necessary
+ )
+ {
+ if ( pImp->Construct() )
+ pImp->Rescan();
+ }
+}
+
+void SfxDocumentTemplates::ReInitFromComponent()
+{
+ pImp->ReInitFromComponent();
+}
+
+
+sal_Bool SfxDocumentTemplates::HasUserContents( sal_uInt16 nRegion, sal_uInt16 nIdx ) const
+{
+ DocTemplLocker_Impl aLocker( *pImp );
+
+ sal_Bool bResult = sal_False;
+
+ RegionData_Impl* pRegion = pImp->GetRegion( nRegion );
+
+ if ( pRegion )
+ {
+ ::rtl::OUString aRegionTargetURL = pRegion->GetTargetURL();
+ if ( aRegionTargetURL.getLength() )
+ {
+ sal_uInt16 nLen = 0;
+ sal_uInt16 nStartInd = 0;
+
+ if( nIdx == USHRT_MAX )
+ {
+ // this is a folder
+ // check whether there is at least one editable template
+ nLen = ( sal_uInt16 )pRegion->GetCount();
+ nStartInd = 0;
+ if ( nLen == 0 )
+ bResult = sal_True; // the writing part of empty folder with writing URL can be removed
+ }
+ else
+ {
+ // this is a template
+ // check whether the template is inserted by user
+ nLen = 1;
+ nStartInd = nIdx;
+ }
+
+ for ( sal_uInt16 nInd = nStartInd; nInd < nStartInd + nLen; nInd++ )
+ {
+ DocTempl_EntryData_Impl* pEntryData = pRegion->GetEntry( nInd );
+ if ( pEntryData )
+ {
+ ::rtl::OUString aEntryTargetURL = pEntryData->GetTargetURL();
+ if ( aEntryTargetURL.getLength()
+ && ::utl::UCBContentHelper::IsSubPath( aRegionTargetURL, aEntryTargetURL ) )
+ {
+ bResult = sal_True;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ return bResult;
+}
+
+// -----------------------------------------------------------------------
+// -----------------------------------------------------------------------
+// -----------------------------------------------------------------------
+DocTempl_EntryData_Impl::DocTempl_EntryData_Impl( RegionData_Impl* pParent,
+ const OUString& rTitle )
+{
+ mpParent = pParent;
+ maTitle = rTitle;
+ mbIsOwner = sal_False;
+ mbDidConvert= sal_False;
+}
+
+// -----------------------------------------------------------------------
+int DocTempl_EntryData_Impl::Compare( const OUString& rTitle ) const
+{
+ return maTitle.compareTo( rTitle );
+}
+
+//------------------------------------------------------------------------
+SfxObjectShellRef DocTempl_EntryData_Impl::CreateObjectShell()
+{
+ if( ! mxObjShell.Is() )
+ {
+ mbIsOwner = sal_False;
+ sal_Bool bDum = sal_False;
+ SfxApplication *pSfxApp = SFX_APP();
+ String aTargetURL = GetTargetURL();
+
+ mxObjShell = pSfxApp->DocAlreadyLoaded( aTargetURL, sal_True, bDum );
+
+ if( ! mxObjShell.Is() )
+ {
+ mbIsOwner = sal_True;
+ SfxMedium *pMed=new SfxMedium(
+ aTargetURL,(STREAM_STD_READWRITE | STREAM_SHARE_DENYALL), sal_False, 0 );
+ const SfxFilter* pFilter = NULL;
+ pMed->UseInteractionHandler(TRUE);
+ if( pSfxApp->GetFilterMatcher().GuessFilter(
+ *pMed, &pFilter, SFX_FILTER_TEMPLATE, 0 ) ||
+ (pFilter && !pFilter->IsOwnFormat()) ||
+ (pFilter && !pFilter->UsesStorage()) )
+ {
+ SfxErrorContext aEc( ERRCTX_SFX_LOADTEMPLATE,
+ aTargetURL );
+ delete pMed;
+ mbDidConvert=sal_True;
+ ULONG lErr;
+ if ( mxObjShell.Is() ) {
+ lErr = pSfxApp->LoadTemplate( mxObjShell,aTargetURL);
+ if( lErr != ERRCODE_NONE )
+ ErrorHandler::HandleError(lErr);
+ }
+
+ }
+ else if (pFilter)
+ {
+ mbDidConvert=sal_False;
+ mxObjShell = SfxObjectShell::CreateObject( pFilter->GetServiceName(), SFX_CREATE_MODE_ORGANIZER );
+ if ( mxObjShell.Is() )
+ {
+ mxObjShell->DoInitNew(0);
+ // TODO/LATER: make sure that we don't use binary templates!
+ if( mxObjShell->LoadFrom( *pMed ) )
+ {
+ mxObjShell->DoSaveCompleted( pMed );
+ }
+ else
+ mxObjShell.Clear();
+ }
+ }
+ }
+ }
+
+ return (SfxObjectShellRef)(SfxObjectShell*) mxObjShell;
+}
+
+//------------------------------------------------------------------------
+BOOL DocTempl_EntryData_Impl::DeleteObjectShell()
+{
+ sal_Bool bRet = sal_True;
+
+ if ( mxObjShell.Is() )
+ {
+ if( mxObjShell->IsModified() )
+ {
+ //Hier speichern wir auch, falls die Vorlage in Bearbeitung ist...
+ bRet = sal_False;
+
+ if ( mbIsOwner )
+ {
+ if( mbDidConvert )
+ {
+ bRet=mxObjShell->PreDoSaveAs_Impl(
+ GetTargetURL(),
+ mxObjShell->GetFactory().GetFilterContainer()->GetAnyFilter( SFX_FILTER_EXPORT | SFX_FILTER_IMPORT, SFX_FILTER_INTERNAL )->GetFilterName(), 0 );
+ }
+ else
+ {
+ if( mxObjShell->Save() )
+ {
+ uno::Reference< embed::XTransactedObject > xTransacted( mxObjShell->GetStorage(), uno::UNO_QUERY );
+ DBG_ASSERT( xTransacted.is(), "Storage must implement XTransactedObject!\n" );
+ if ( xTransacted.is() )
+ {
+ try
+ {
+ xTransacted->commit();
+ bRet = sal_True;
+ }
+ catch( uno::Exception& )
+ {
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if( bRet )
+ {
+ mxObjShell.Clear();
+ }
+ }
+ return bRet;
+}
+
+// -----------------------------------------------------------------------
+const OUString& DocTempl_EntryData_Impl::GetHierarchyURL()
+{
+ if ( !maOwnURL.getLength() )
+ {
+ INetURLObject aTemplateObj( GetParent()->GetHierarchyURL() );
+
+ aTemplateObj.insertName( GetTitle(), false,
+ INetURLObject::LAST_SEGMENT, true,
+ INetURLObject::ENCODE_ALL );
+
+ maOwnURL = aTemplateObj.GetMainURL( INetURLObject::NO_DECODE );
+ DBG_ASSERT( maOwnURL.getLength(), "GetHierarchyURL(): Could not create URL!" );
+ }
+
+ return maOwnURL;
+}
+
+// -----------------------------------------------------------------------
+const OUString& DocTempl_EntryData_Impl::GetTargetURL()
+{
+ if ( !maTargetURL.getLength() )
+ {
+ uno::Reference< XCommandEnvironment > aCmdEnv;
+ Content aRegion;
+
+ if ( Content::create( GetHierarchyURL(), aCmdEnv, aRegion ) )
+ {
+ OUString aPropName( RTL_CONSTASCII_USTRINGPARAM( TARGET_URL ) );
+
+ getTextProperty_Impl( aRegion, aPropName, maTargetURL );
+ }
+ else
+ {
+ DBG_ERRORFILE( "GetTargetURL(): Could not create hierarchy content!" );
+ }
+ }
+
+ return maTargetURL;
+}
+
+// -----------------------------------------------------------------------
+// -----------------------------------------------------------------------
+// -----------------------------------------------------------------------
+// -----------------------------------------------------------------------
+RegionData_Impl::RegionData_Impl( const SfxDocTemplate_Impl* pParent,
+ const OUString& rTitle )
+{
+ maTitle = rTitle;
+ mpParent = pParent;
+}
+
+// -----------------------------------------------------------------------
+RegionData_Impl::~RegionData_Impl()
+{
+ DocTempl_EntryData_Impl *pData = maEntries.First();
+
+ while ( pData )
+ {
+ delete pData;
+ pData = maEntries.Next();
+ }
+}
+
+// -----------------------------------------------------------------------
+long RegionData_Impl::GetEntryPos( const OUString& rTitle,
+ sal_Bool& rFound ) const
+{
+#if 1 // Don't use binary search today
+ ULONG i;
+ ULONG nCount = maEntries.Count();
+
+ for ( i=0; i<nCount; i++ )
+ {
+ DocTempl_EntryData_Impl *pData = maEntries.GetObject( i );
+
+ if ( pData->Compare( rTitle ) == 0 )
+ {
+ rFound = sal_True;
+ return i;
+ }
+ }
+
+ rFound = sal_False;
+ return i;
+
+#else
+ // use binary search to find the correct position
+ // in the maEntries list
+
+ int nCompVal = 1;
+ long nStart = 0;
+ long nEnd = maEntries.Count() - 1;
+ long nMid;
+
+ DocTempl_EntryData_Impl* pMid;
+
+ rFound = sal_False;
+
+ while ( nCompVal && ( nStart <= nEnd ) )
+ {
+ nMid = ( nEnd - nStart ) / 2 + nStart;
+ pMid = maEntries.GetObject( nMid );
+
+ nCompVal = pMid->Compare( rTitle );
+
+ if ( nCompVal < 0 ) // pMid < pData
+ nStart = nMid + 1;
+ else
+ nEnd = nMid - 1;
+ }
+
+ if ( nCompVal == 0 )
+ {
+ rFound = sal_True;
+ }
+ else
+ {
+ if ( nCompVal < 0 ) // pMid < pData
+ nMid++;
+ }
+
+ return nMid;
+#endif
+}
+
+// -----------------------------------------------------------------------
+void RegionData_Impl::AddEntry( const OUString& rTitle,
+ const OUString& rTargetURL,
+ USHORT *pPos )
+{
+ INetURLObject aLinkObj( GetHierarchyURL() );
+ aLinkObj.insertName( rTitle, false,
+ INetURLObject::LAST_SEGMENT, true,
+ INetURLObject::ENCODE_ALL );
+ OUString aLinkURL = aLinkObj.GetMainURL( INetURLObject::NO_DECODE );
+
+ DocTempl_EntryData_Impl *pEntry;
+ sal_Bool bFound = sal_False;
+ long nPos = GetEntryPos( rTitle, bFound );
+
+ if ( bFound )
+ {
+ pEntry = maEntries.GetObject( nPos );
+ }
+ else
+ {
+ if ( pPos )
+ nPos = *pPos;
+
+ pEntry = new DocTempl_EntryData_Impl( this, rTitle );
+ pEntry->SetTargetURL( rTargetURL );
+ pEntry->SetHierarchyURL( aLinkURL );
+ maEntries.Insert( pEntry, nPos );
+ }
+}
+
+// -----------------------------------------------------------------------
+ULONG RegionData_Impl::GetCount() const
+{
+ return maEntries.Count();
+}
+
+// -----------------------------------------------------------------------
+const OUString& RegionData_Impl::GetHierarchyURL()
+{
+ if ( !maOwnURL.getLength() )
+ {
+ INetURLObject aRegionObj( GetParent()->GetRootURL() );
+
+ aRegionObj.insertName( GetTitle(), false,
+ INetURLObject::LAST_SEGMENT, true,
+ INetURLObject::ENCODE_ALL );
+
+ maOwnURL = aRegionObj.GetMainURL( INetURLObject::NO_DECODE );
+ DBG_ASSERT( maOwnURL.getLength(), "GetHierarchyURL(): Could not create URL!" );
+ }
+
+ return maOwnURL;
+}
+
+// -----------------------------------------------------------------------
+const OUString& RegionData_Impl::GetTargetURL()
+{
+ if ( !maTargetURL.getLength() )
+ {
+ uno::Reference< XCommandEnvironment > aCmdEnv;
+ Content aRegion;
+
+ if ( Content::create( GetHierarchyURL(), aCmdEnv, aRegion ) )
+ {
+ OUString aPropName( RTL_CONSTASCII_USTRINGPARAM( TARGET_DIR_URL ) );
+
+ getTextProperty_Impl( aRegion, aPropName, maTargetURL );
+ // --> PB 2004-10-27 #i32656# - the targeturl must be substituted: $(baseinsturl)
+ maTargetURL = SvtPathOptions().SubstituteVariable( maTargetURL );
+ // <--
+ }
+ else
+ {
+ DBG_ERRORFILE( "GetTargetURL(): Could not create hierarchy content!" );
+ }
+ }
+
+ return maTargetURL;
+}
+
+// -----------------------------------------------------------------------
+DocTempl_EntryData_Impl* RegionData_Impl::GetEntry( const OUString& rName ) const
+{
+ sal_Bool bFound = sal_False;
+ long nPos = GetEntryPos( rName, bFound );
+
+ if ( bFound )
+ return maEntries.GetObject( nPos );
+ else
+ return NULL;
+}
+
+// -----------------------------------------------------------------------
+DocTempl_EntryData_Impl* RegionData_Impl::GetByTargetURL( const OUString& rName ) const
+{
+ DocTempl_EntryData_Impl *pEntry;
+
+ ULONG nCount = maEntries.Count();
+
+ for ( ULONG i=0; i<nCount; i++ )
+ {
+ pEntry = maEntries.GetObject( i );
+ if ( pEntry && ( pEntry->GetTargetURL() == rName ) )
+ return pEntry;
+ }
+
+ return NULL;
+}
+
+// -----------------------------------------------------------------------
+DocTempl_EntryData_Impl* RegionData_Impl::GetEntry( ULONG nIndex ) const
+{
+ return maEntries.GetObject( nIndex );
+}
+
+// -----------------------------------------------------------------------
+void RegionData_Impl::DeleteEntry( ULONG nIndex )
+{
+ DocTempl_EntryData_Impl *pEntry = maEntries.GetObject( nIndex );
+
+ if ( pEntry )
+ {
+ delete pEntry;
+ maEntries.Remove( (ULONG) nIndex );
+ }
+}
+
+// -----------------------------------------------------------------------
+int RegionData_Impl::Compare( RegionData_Impl* pCompare ) const
+{
+ int nCompare = maTitle.compareTo( pCompare->maTitle );
+
+ return nCompare;
+}
+
+// -----------------------------------------------------------------------
+// -----------------------------------------------------------------------
+// -----------------------------------------------------------------------
+
+SfxDocTemplate_Impl::SfxDocTemplate_Impl()
+: mbConstructed( sal_False )
+, mnLockCounter( 0 )
+{
+}
+
+// -----------------------------------------------------------------------
+SfxDocTemplate_Impl::~SfxDocTemplate_Impl()
+{
+ Clear();
+
+ gpTemplateData = NULL;
+}
+
+// -----------------------------------------------------------------------
+void SfxDocTemplate_Impl::IncrementLock()
+{
+ ::osl::MutexGuard aGuard( maMutex );
+ mnLockCounter++;
+}
+
+// -----------------------------------------------------------------------
+void SfxDocTemplate_Impl::DecrementLock()
+{
+ ::osl::MutexGuard aGuard( maMutex );
+ if ( mnLockCounter )
+ mnLockCounter--;
+}
+
+// -----------------------------------------------------------------------
+RegionData_Impl* SfxDocTemplate_Impl::GetRegion( ULONG nIndex ) const
+{
+ return maRegions.GetObject( nIndex );
+}
+
+// -----------------------------------------------------------------------
+RegionData_Impl* SfxDocTemplate_Impl::GetRegion( const OUString& rName )
+ const
+{
+ ULONG nCount = maRegions.Count();
+ RegionData_Impl *pData;
+
+ for ( ULONG i=0; i<nCount; i++ )
+ {
+ pData = maRegions.GetObject( i );
+
+ if ( pData->GetTitle() == rName )
+ return pData;
+ }
+
+ return NULL;
+}
+
+// -----------------------------------------------------------------------
+void SfxDocTemplate_Impl::DeleteRegion( ULONG nIndex )
+{
+ RegionData_Impl* pRegion = maRegions.GetObject( nIndex );
+
+ if ( pRegion )
+ {
+ delete pRegion;
+ maRegions.Remove( (ULONG) nIndex );
+ }
+}
+
+// -----------------------------------------------------------------------
+/* AddRegion adds a Region to the RegionList
+*/
+void SfxDocTemplate_Impl::AddRegion( const OUString& rTitle,
+ Content& rContent )
+{
+ RegionData_Impl* pRegion;
+ pRegion = new RegionData_Impl( this, rTitle );
+
+ if ( ! InsertRegion( pRegion ) )
+ {
+ delete pRegion;
+ return;
+ }
+
+ // now get the content of the region
+ uno::Reference< XResultSet > xResultSet;
+ Sequence< OUString > aProps(2);
+ aProps[0] = OUString::createFromAscii( TITLE );
+ aProps[1] = OUString::createFromAscii( TARGET_URL );
+
+ try
+ {
+ ResultSetInclude eInclude = INCLUDE_DOCUMENTS_ONLY;
+ Sequence< NumberedSortingInfo > aSortingInfo(1);
+ aSortingInfo.getArray()->ColumnIndex = 1;
+ aSortingInfo.getArray()->Ascending = sal_True;
+ xResultSet = rContent.createSortedCursor( aProps, aSortingInfo, m_rCompareFactory, eInclude );
+ }
+ catch ( Exception& ) {}
+
+ if ( xResultSet.is() )
+ {
+ uno::Reference< XContentAccess > xContentAccess( xResultSet, UNO_QUERY );
+ uno::Reference< XRow > xRow( xResultSet, UNO_QUERY );
+
+ try
+ {
+ while ( xResultSet->next() )
+ {
+ OUString aTitle( xRow->getString( 1 ) );
+ OUString aTargetDir( xRow->getString( 2 ) );
+
+ pRegion->AddEntry( aTitle, aTargetDir );
+ }
+ }
+ catch ( Exception& ) {}
+ }
+}
+
+// -----------------------------------------------------------------------
+void SfxDocTemplate_Impl::CreateFromHierarchy( Content &rTemplRoot )
+{
+ uno::Reference< XResultSet > xResultSet;
+ Sequence< OUString > aProps(1);
+ aProps[0] = OUString::createFromAscii( TITLE );
+
+ try
+ {
+ ResultSetInclude eInclude = INCLUDE_FOLDERS_ONLY;
+ Sequence< NumberedSortingInfo > aSortingInfo(1);
+ aSortingInfo.getArray()->ColumnIndex = 1;
+ aSortingInfo.getArray()->Ascending = sal_True;
+ xResultSet = rTemplRoot.createSortedCursor( aProps, aSortingInfo, m_rCompareFactory, eInclude );
+ }
+ catch ( Exception& ) {}
+
+ if ( xResultSet.is() )
+ {
+ uno::Reference< XCommandEnvironment > aCmdEnv;
+ uno::Reference< XContentAccess > xContentAccess( xResultSet, UNO_QUERY );
+ uno::Reference< XRow > xRow( xResultSet, UNO_QUERY );
+
+ try
+ {
+ while ( xResultSet->next() )
+ {
+ OUString aTitle( xRow->getString( 1 ) );
+
+ OUString aId = xContentAccess->queryContentIdentifierString();
+ Content aContent = Content( aId, aCmdEnv );
+
+ AddRegion( aTitle, aContent );
+ }
+ }
+ catch ( Exception& ) {}
+ }
+}
+
+// ------------------------------------------------------------------------
+sal_Bool SfxDocTemplate_Impl::Construct( )
+{
+ ::osl::MutexGuard aGuard( maMutex );
+
+ if ( mbConstructed )
+ return sal_True;
+
+ uno::Reference< XMultiServiceFactory > xFactory;
+ xFactory = ::comphelper::getProcessServiceFactory();
+
+ OUString aService( RTL_CONSTASCII_USTRINGPARAM( SERVICENAME_DOCINFO ) );
+ uno::Reference< XPersist > xInfo( xFactory->createInstance( aService ), UNO_QUERY );
+ mxInfo = xInfo;
+
+ aService = OUString( RTL_CONSTASCII_USTRINGPARAM( SERVICENAME_DOCTEMPLATES ) );
+ uno::Reference< XDocumentTemplates > xTemplates( xFactory->createInstance( aService ), UNO_QUERY );
+
+ if ( xTemplates.is() )
+ mxTemplates = xTemplates;
+ else
+ return sal_False;
+
+ uno::Reference< XLocalizable > xLocalizable( xTemplates, UNO_QUERY );
+
+ Sequence< Any > aCompareArg(1);
+ *(aCompareArg.getArray()) <<= xLocalizable->getLocale();;
+ m_rCompareFactory = uno::Reference< XAnyCompareFactory >(
+ xFactory->createInstanceWithArguments( OUString::createFromAscii( "com.sun.star.ucb.AnyCompareFactory" ),
+ aCompareArg ),
+ UNO_QUERY );
+
+ uno::Reference < XContent > aRootContent = xTemplates->getContent();
+ uno::Reference < XCommandEnvironment > aCmdEnv;
+
+ if ( ! aRootContent.is() )
+ return sal_False;
+
+ mbConstructed = sal_True;
+ maRootURL = aRootContent->getIdentifier()->getContentIdentifier();
+
+ ResStringArray aLongNames( SfxResId( TEMPLATE_LONG_NAMES_ARY ) );
+
+ if ( aLongNames.Count() )
+ maStandardGroup = aLongNames.GetString( 0 );
+
+ Content aTemplRoot( aRootContent, aCmdEnv );
+ CreateFromHierarchy( aTemplRoot );
+
+ return sal_True;
+}
+
+// -----------------------------------------------------------------------
+void SfxDocTemplate_Impl::ReInitFromComponent()
+{
+ uno::Reference< XDocumentTemplates > xTemplates = getDocTemplates();
+ if ( xTemplates.is() )
+ {
+ uno::Reference < XContent > aRootContent = xTemplates->getContent();
+ uno::Reference < XCommandEnvironment > aCmdEnv;
+ Content aTemplRoot( aRootContent, aCmdEnv );
+ Clear();
+ CreateFromHierarchy( aTemplRoot );
+ }
+}
+
+// -----------------------------------------------------------------------
+void SfxDocTemplate_Impl::GetTemplates( Content& rTargetFolder,
+ Content& /*rParentFolder*/,
+ RegionData_Impl* pRegion )
+{
+ uno::Reference< XResultSet > xResultSet;
+ Sequence< OUString > aProps(1);
+
+ aProps[0] = OUString::createFromAscii( TITLE );
+
+ try
+ {
+ ResultSetInclude eInclude = INCLUDE_DOCUMENTS_ONLY;
+ Sequence< NumberedSortingInfo > aSortingInfo(1);
+ aSortingInfo.getArray()->ColumnIndex = 1;
+ aSortingInfo.getArray()->Ascending = sal_True;
+ xResultSet = rTargetFolder.createSortedCursor( aProps, aSortingInfo, m_rCompareFactory, eInclude );
+ }
+ catch ( Exception& ) {}
+
+ if ( xResultSet.is() )
+ {
+ uno::Reference< XContentAccess > xContentAccess( xResultSet, UNO_QUERY );
+ uno::Reference< XRow > xRow( xResultSet, UNO_QUERY );
+
+ try
+ {
+ while ( xResultSet->next() )
+ {
+ OUString aTitle( xRow->getString(1) );
+
+ if ( aTitle.compareToAscii( "sfx.tlx" ) == 0 )
+ continue;
+
+ OUString aId = xContentAccess->queryContentIdentifierString();
+
+ DocTempl_EntryData_Impl* pEntry = pRegion->GetByTargetURL( aId );
+
+ if ( ! pEntry )
+ {
+ OUString aFullTitle;
+ if( !GetTitleFromURL( aId, aFullTitle ) )
+ {
+ DBG_ERRORFILE( "GetTemplates(): template of alien format" );
+ continue;
+ }
+
+ if ( aFullTitle.getLength() )
+ aTitle = aFullTitle;
+
+ pRegion->AddEntry( aTitle, aId );
+ }
+ }
+ }
+ catch ( Exception& ) {}
+ }
+}
+
+
+// -----------------------------------------------------------------------
+long SfxDocTemplate_Impl::GetRegionPos( const OUString& rTitle,
+ sal_Bool& rFound ) const
+{
+ int nCompVal = 1;
+ long nStart = 0;
+ long nEnd = maRegions.Count() - 1;
+ long nMid = 0;
+
+ RegionData_Impl* pMid;
+
+ while ( nCompVal && ( nStart <= nEnd ) )
+ {
+ nMid = ( nEnd - nStart ) / 2 + nStart;
+ pMid = maRegions.GetObject( nMid );
+
+ nCompVal = pMid->Compare( rTitle );
+
+ if ( nCompVal < 0 ) // pMid < pData
+ nStart = nMid + 1;
+ else
+ nEnd = nMid - 1;
+ }
+
+ if ( nCompVal == 0 )
+ rFound = sal_True;
+ else
+ {
+ if ( nCompVal < 0 ) // pMid < pData
+ nMid++;
+
+ rFound = sal_False;
+ }
+
+ return nMid;
+}
+
+// -----------------------------------------------------------------------
+sal_Bool SfxDocTemplate_Impl::InsertRegion( RegionData_Impl *pNew,
+ ULONG nPos )
+{
+ ::osl::MutexGuard aGuard( maMutex );
+ RegionData_Impl *pData = maRegions.First();
+
+ while ( pData && ( pData->Compare( pNew ) != 0 ) )
+ pData = maRegions.Next();
+
+ if ( ! pData )
+ {
+ // compare with the name of the standard group here to insert it
+ // first
+
+ if ( pNew->GetTitle() == maStandardGroup )
+ maRegions.Insert( pNew, (ULONG) 0 );
+ else
+ maRegions.Insert( pNew, nPos );
+ }
+
+ return ( pData == NULL );
+}
+
+// -----------------------------------------------------------------------
+void SfxDocTemplate_Impl::Rescan()
+{
+ Clear();
+
+ try
+ {
+ uno::Reference< XDocumentTemplates > xTemplates = getDocTemplates();
+ DBG_ASSERT( xTemplates.is(), "SfxDocTemplate_Impl::Rescan:invalid template instance!" );
+ if ( xTemplates.is() )
+ {
+ xTemplates->update();
+
+ uno::Reference < XContent > aRootContent = xTemplates->getContent();
+ uno::Reference < XCommandEnvironment > aCmdEnv;
+
+ Content aTemplRoot( aRootContent, aCmdEnv );
+ CreateFromHierarchy( aTemplRoot );
+ }
+ }
+ catch( const Exception& )
+ {
+ DBG_ERRORFILE( "SfxDocTemplate_Impl::Rescan: caught an exception while doing the update!" );
+ }
+}
+
+// -----------------------------------------------------------------------
+sal_Bool SfxDocTemplate_Impl::GetTitleFromURL( const OUString& rURL,
+ OUString& aTitle )
+{
+ if ( mxInfo.is() )
+ {
+ try
+ {
+ mxInfo->read( rURL );
+ }
+ catch ( Exception& )
+ {
+ // the document is not a StarOffice document
+ return sal_False;
+ }
+
+
+ try
+ {
+ uno::Reference< XPropertySet > aPropSet( mxInfo, UNO_QUERY );
+ if ( aPropSet.is() )
+ {
+ OUString aPropName( RTL_CONSTASCII_USTRINGPARAM( TITLE ) );
+ Any aValue = aPropSet->getPropertyValue( aPropName );
+ aValue >>= aTitle;
+ }
+ }
+ catch ( IOException& ) {}
+ catch ( UnknownPropertyException& ) {}
+ catch ( Exception& ) {}
+ }
+
+ if ( ! aTitle.getLength() )
+ {
+ INetURLObject aURL( rURL );
+ aURL.CutExtension();
+ aTitle = aURL.getName( INetURLObject::LAST_SEGMENT, true,
+ INetURLObject::DECODE_WITH_CHARSET );
+ }
+
+ return sal_True;
+}
+
+
+// -----------------------------------------------------------------------
+void SfxDocTemplate_Impl::Clear()
+{
+ ::osl::MutexGuard aGuard( maMutex );
+ if ( mnLockCounter )
+ return;
+
+ RegionData_Impl *pRegData = maRegions.First();
+
+ while ( pRegData )
+ {
+ delete pRegData;
+ pRegData = maRegions.Next();
+ }
+
+ maRegions.Clear();
+}
+
+// -----------------------------------------------------------------------
+// -----------------------------------------------------------------------
+// -----------------------------------------------------------------------
+sal_Bool getTextProperty_Impl( Content& rContent,
+ const OUString& rPropName,
+ OUString& rPropValue )
+{
+ sal_Bool bGotProperty = sal_False;
+
+ // Get the property
+ try
+ {
+ uno::Reference< XPropertySetInfo > aPropInfo = rContent.getProperties();
+
+ // check, wether or not the property exists
+ if ( !aPropInfo.is() || !aPropInfo->hasPropertyByName( rPropName ) )
+ {
+ return sal_False;
+ }
+
+ // now get the property
+ Any aAnyValue;
+
+ aAnyValue = rContent.getPropertyValue( rPropName );
+ aAnyValue >>= rPropValue;
+
+ if ( SfxURLRelocator_Impl::propertyCanContainOfficeDir( rPropName ) )
+ {
+ SfxURLRelocator_Impl aRelocImpl( ::comphelper::getProcessServiceFactory() );
+ aRelocImpl.makeAbsoluteURL( rPropValue );
+ }
+
+ bGotProperty = sal_True;
+ }
+ catch ( RuntimeException& ) {}
+ catch ( Exception& ) {}
+
+ return bGotProperty;
+}
+