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.cxx2599
1 files changed, 2599 insertions, 0 deletions
diff --git a/sfx2/source/doc/doctempl.cxx b/sfx2/source/doc/doctempl.cxx
new file mode 100644
index 000000000000..d28d0e6c5c72
--- /dev/null
+++ b/sfx2/source/doc/doctempl.cxx
@@ -0,0 +1,2599 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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 <osl/mutex.hxx>
+#include <osl/thread.hxx>
+
+#include <tools/resary.hxx>
+#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 "sfx2/sfxresid.hxx"
+#include "doc.hrc"
+#include <sfx2/fcontnr.hxx>
+#include <svtools/templatefoldercache.hxx>
+
+#include <comphelper/storagehelper.hxx>
+#include <unotools/ucbhelper.hxx>
+
+#include <vector>
+using ::std::vector;
+using ::std::advance;
+
+//========================================================================
+
+// #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_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;
+
+ // the following member must be SfxObjectShellLock since it controlls that SfxObjectShell lifetime by design
+ // and users of this class expect it to be so.
+ 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
+{
+ const SfxDocTemplate_Impl* mpParent;
+ vector< DocTempl_EntryData_Impl* > maEntries;
+ OUString maTitle;
+ OUString maOwnURL;
+ OUString maTargetURL;
+
+private:
+ size_t 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( size_t 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();
+
+ size_t GetCount() const;
+
+ void SetTitle( const OUString& rTitle ) { maTitle = rTitle; }
+
+ void AddEntry( const OUString& rTitle,
+ const OUString& rTargetURL,
+ size_t *pPos = NULL );
+ void DeleteEntry( size_t nIndex );
+
+ int Compare( const OUString& rTitle ) const
+ { return maTitle.compareTo( rTitle ); }
+ int Compare( RegionData_Impl* pCompareWith ) const;
+};
+
+typedef vector< RegionData_Impl* > RegionList_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( size_t nIndex );
+
+ size_t GetRegionCount() const
+ { return maRegions.size(); }
+ RegionData_Impl* GetRegion( const OUString& rName ) const;
+ RegionData_Impl* GetRegion( size_t nIndex ) const;
+ void GetTemplates( Content& rTargetFolder,
+ Content& rParentFolder,
+ RegionData_Impl* pRegion );
+
+ size_t GetRegionPos( const OUString& rTitle, sal_Bool& rFound ) const;
+
+ sal_Bool GetTitleFromURL( const OUString& rURL, OUString& aTitle );
+ sal_Bool InsertRegion( RegionData_Impl *pData, size_t nPos = size_t(-1) );
+ 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
+(
+ sal_uInt16 nIdx // Region Index
+) const
+
+/* [Description]
+
+ Returns the logical name of a region and its path
+
+ [Return value] Reference to the Region name
+
+*/
+
+{
+ // 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
+(
+ sal_uInt16 nIdx // Region Index
+) const
+
+/* [Description]
+
+ Returns the logical name of a region
+
+ [Return value]
+
+ const String& Reference to the Region name
+
+*/
+{
+ 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;
+}
+
+
+//------------------------------------------------------------------------
+
+sal_uInt16 SfxDocumentTemplates::GetRegionNo
+(
+ const String &rRegion // Region Name
+) const
+
+/* [Description]
+
+ Returns the Index for a logical Region Name.
+
+ [Return value]
+
+ sal_uInt16 Index of 'rRegion' or USHRT_MAX if unknown
+
+*/
+{
+ DocTemplLocker_Impl aLocker( *pImp );
+
+ if ( !pImp->Construct() )
+ return USHRT_MAX;
+
+ sal_Bool bFound;
+ size_t nIndex = pImp->GetRegionPos( rRegion, bFound );
+
+ if ( bFound )
+ return (sal_uInt16) nIndex;
+ else
+ return USHRT_MAX;
+}
+
+
+//------------------------------------------------------------------------
+
+sal_uInt16 SfxDocumentTemplates::GetRegionCount() const
+
+/* [Description]
+
+ Returns the number of Regions
+
+ [Return value]
+
+ sal_uInt16 Number of Regions
+*/
+{
+ DocTemplLocker_Impl aLocker( *pImp );
+
+ if ( !pImp->Construct() )
+ return 0;
+
+ sal_uIntPtr nCount = pImp->GetRegionCount();
+
+ return (sal_uInt16) nCount;
+}
+
+//------------------------------------------------------------------------
+
+sal_Bool SfxDocumentTemplates::IsRegionLoaded( sal_uInt16 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;
+}
+
+//------------------------------------------------------------------------
+
+sal_uInt16 SfxDocumentTemplates::GetCount
+(
+ const String& rName /* Region Name, for which the entries
+ should be counted */
+
+) const
+
+/* [Description]
+
+ Number of entries in Region
+
+ [Return value]
+
+ sal_uInt16 Number of entries
+*/
+
+{
+ DocTemplLocker_Impl aLocker( *pImp );
+
+ if ( !pImp->Construct() )
+ return 0;
+
+ RegionData_Impl *pData = pImp->GetRegion( rName );
+ sal_uIntPtr nCount = 0;
+
+ if ( pData )
+ nCount = pData->GetCount();
+
+ return (sal_uInt16) nCount;
+}
+
+//------------------------------------------------------------------------
+
+sal_uInt16 SfxDocumentTemplates::GetCount
+(
+ sal_uInt16 nRegion /* Region index whose number is
+ to be determined */
+
+) const
+
+/* [Description]
+
+ Number of entries in Region
+
+ [Return value] Number of entries
+*/
+
+{
+ DocTemplLocker_Impl aLocker( *pImp );
+
+ if ( !pImp->Construct() )
+ return 0;
+
+ RegionData_Impl *pData = pImp->GetRegion( nRegion );
+ sal_uIntPtr nCount = 0;
+
+ if ( pData )
+ nCount = pData->GetCount();
+
+ return (sal_uInt16) nCount;
+}
+
+//------------------------------------------------------------------------
+
+const String& SfxDocumentTemplates::GetName
+(
+ sal_uInt16 nRegion, // Region Index, in which the entry lies
+ sal_uInt16 nIdx // Index of the entry
+) const
+
+/* [Description]
+
+ Returns the logical name of an entry in Region
+
+ [Return value]
+
+ const String& Entry Name
+*/
+
+{
+ 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
+(
+ sal_uInt16 nRegion, // Region Index, in which the entry lies
+ sal_uInt16 nIdx // Index of the entry
+) const
+
+/* [Description]
+
+ Returns the file name of an entry in Region
+
+ [Return value] File name of the entry
+*/
+{
+ 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
+(
+ sal_uInt16 nRegion, // Region Index, in which the entry lies
+ sal_uInt16 nIdx // Index of the entry
+) const
+
+/* [Description]
+
+ Returns the file name with full path to the file assigned to an entry
+
+ [Return value]
+
+ String File name with full path
+*/
+{
+ 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
+(
+ sal_uInt16 nRegion, // Region Index, in which the entry lies
+ const String& rLongName // logical Entry Name
+) const
+
+/* [Description]
+
+ Returns the file name with full path to the file assigned to an entry
+
+ [Return value]
+
+ String File name with full path
+*/
+{
+ 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
+)
+
+/* [Description]
+
+ Returns the default location for templates
+
+ [Return value]
+
+ String Default location for templates
+*/
+{
+ 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();
+
+}
+
+//------------------------------------------------------------------------
+
+::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 // Save Directory
+)
+
+/* [Description]
+
+ Saves the Directory rDir
+
+ [Return value]
+
+ sal_Bool sal_False, Write error
+ sal_True, Saved
+*/
+
+{
+ return sal_True;
+}
+
+//------------------------------------------------------------------------
+
+void SfxDocumentTemplates::NewTemplate
+(
+ sal_uInt16 nRegion, /* Region Index, in which the template
+ should be applied */
+
+ const String& rLongName, // logical name of the new template
+ const String& rFileName // File name of the new template
+)
+
+/* [Description]
+
+ Submit a new template in the administrative structures
+ overwriting a template of the same name is prevented (! Error message)
+*/
+
+{
+ 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
+(
+ sal_uInt16 nTargetRegion, // Target Region Index
+ sal_uInt16 nTargetIdx, // Target position Index
+ sal_uInt16 nSourceRegion, // Source Region Index
+ sal_uInt16 nSourceIdx, /* Index to be copied / to moved template */
+ sal_Bool bMove // Copy / Move
+)
+
+/* [Description]
+
+ Copy or move a document template
+
+ [Return value]
+
+ sal_Bool sal_True, Action could be performed
+ sal_False, Action could not be performed
+
+ [Cross-references]
+
+ <SfxDocumentTemplates::Move(sal_uInt16,sal_uInt16,sal_uInt16,sal_uInt16)>
+ <SfxDocumentTemplates::Copy(sal_uInt16,sal_uInt16,sal_uInt16,sal_uInt16)>
+*/
+
+{
+ /* 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;
+ }
+
+ 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
+ }
+ }
+
+ // todo: fix SfxDocumentTemplates to handle size_t instead of sal_uInt16
+ size_t temp_nTargetIdx = nTargetIdx;
+ pTargetRgn->AddEntry( aTitle, aNewTargetURL, &temp_nTargetIdx );
+
+ return sal_True;
+ }
+
+ // --**-- if the current file is opened,
+ // it must be re-opened afterwards.
+
+ return sal_False;
+}
+
+//------------------------------------------------------------------------
+
+sal_Bool SfxDocumentTemplates::Move
+(
+ sal_uInt16 nTargetRegion, // Target Region Index
+ sal_uInt16 nTargetIdx, // Target position Index
+ sal_uInt16 nSourceRegion, // Source Region Index
+ sal_uInt16 nSourceIdx /* Index to be copied / to moved template */
+)
+
+/* [Description]
+
+ Moving a template
+
+ [Return value]
+
+ sal_Bool sal_True, Action could be performed
+ sal_False, Action could not be performed
+
+ [Cross-references]
+
+ <SfxDocumentTemplates::CopyOrMove(sal_uInt16,sal_uInt16,sal_uInt16,sal_uInt16,sal_Bool)>
+*/
+{
+ DocTemplLocker_Impl aLocker( *pImp );
+
+ return CopyOrMove( nTargetRegion, nTargetIdx,
+ nSourceRegion, nSourceIdx, sal_True );
+}
+
+//------------------------------------------------------------------------
+
+sal_Bool SfxDocumentTemplates::Copy
+(
+ sal_uInt16 nTargetRegion, // Target Region Index
+ sal_uInt16 nTargetIdx, // Target position Index
+ sal_uInt16 nSourceRegion, // Source Region Index
+ sal_uInt16 nSourceIdx /* Index to be copied / to moved template */
+)
+
+/* [Description]
+
+ Copying a template
+
+ [Return value]
+
+ sal_Bool sal_True, Action could be performed
+ sal_False, Action could not be performed
+
+ [Cross-references]
+
+ <SfxDocumentTemplates::CopyOrMove(sal_uInt16,sal_uInt16,sal_uInt16,sal_uInt16,sal_Bool)>
+*/
+
+{
+ DocTemplLocker_Impl aLocker( *pImp );
+
+ return CopyOrMove( nTargetRegion, nTargetIdx,
+ nSourceRegion, nSourceIdx, sal_False );
+}
+
+//------------------------------------------------------------------------
+
+sal_Bool SfxDocumentTemplates::CopyTo
+(
+ sal_uInt16 nRegion, // Region of the template to be exported
+ sal_uInt16 nIdx, // Index of the template to be exported
+ const String& rName /* File name under which the template is to
+ be created */
+) const
+
+/* [Description]
+
+ Exporting a template into the file system
+
+ [Return value]
+
+ sal_Bool sal_True, Action could be performed
+ sal_False, Action could not be performed
+
+ [Cross-references]
+
+ <SfxDocumentTemplates::CopyFrom(sal_uInt16,sal_uInt16,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
+(
+ sal_uInt16 nRegion, /* Region in which the template is to be
+ imported */
+ sal_uInt16 nIdx, // Index of the new template in this Region
+ String& rName /* File name of the template to be imported
+ as an out parameter of the (automatically
+ generated from the file name) logical name
+ of the template */
+)
+
+/* [Description]
+
+ Import a template from the file system
+
+ [Return value] Sucess (sal_True) or serfpTargetDirectory->GetContent());
+
+ sal_Bool sal_True, Action could be performed
+ sal_False, Action could not be performed
+
+ [Cross-references]
+
+ <SfxDocumentTemplates::CopyTo(sal_uInt16,sal_uInt16,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(RTL_CONSTASCII_USTRINGPARAM("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(RTL_CONSTASCII_USTRINGPARAM("_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;
+
+ // todo: fix SfxDocumentTemplates to handle size_t instead of sal_uInt16
+ size_t temp_nIdx = nIdx;
+ pTargetRgn->AddEntry( aTitle, aTemplName, &temp_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
+(
+ sal_uInt16 nRegion, // Region Index
+ sal_uInt16 nIdx /* Index of the entry or USHRT_MAX,
+ if a directory is meant. */
+)
+
+/* [Description]
+
+ Deleting an entry or a directory
+
+ [Return value]
+
+ sal_Bool sal_True, Action could be performed
+ sal_False, Action could not be performed
+
+ [Cross-references]
+
+ <SfxDocumentTemplates::InsertDir(const String&,sal_uInt16)>
+ <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, // the logical name of the new Region
+ sal_uInt16 nRegion // Region Index
+)
+
+/* [Description]
+
+ Insert an index
+
+ [Return value]
+
+ sal_Bool sal_True, Action could be performed
+ sal_False, Action could not be performed
+
+ [Cross-references]
+
+ <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
+ sal_uInt16 nRegion, // Region Index
+ sal_uInt16 nIdx /* Index of the entry oder USHRT_MAX,
+ if a directory is meant. */
+)
+
+/* [Description]
+
+ Change the name of an entry or a directory
+
+ [Return value]
+
+ sal_Bool sal_True, Action could be performed
+ sal_False, Action could not be performed
+
+*/
+
+{
+ 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()
+
+/* [Description]
+
+ Comparison of administrative data with the current state on disk.
+ The logical name for which no file exists, will be removed from the
+ administrative structure. Files for which no record exists will be included.
+
+ [Return value]
+
+ sal_Bool sal_True, Action could be performed
+ sal_False, Action could not be performed
+
+ [Cross-references]
+
+ <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
+(
+ sal_uInt16 nRegion, // Region Index
+ sal_uInt16 nIdx // Index of the entry
+)
+
+/* [Description]
+
+ Access to the document shell of an entry
+
+ [Return value]
+
+ SfxObjectShellRef Referece to the ObjectShell
+
+ [Cross-references]
+
+ <SfxTemplateDirEntry::CreateObjectShell()>
+ <SfxDocumentTemplates::DeleteObjectShell(sal_uInt16, sal_uInt16)>
+*/
+
+{
+ 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
+(
+ sal_uInt16 nRegion, // Region Index
+ sal_uInt16 nIdx // Index of the entry
+)
+
+/* [Description]
+
+ Releasing the ObjectShell of an entry
+
+ [Return value]
+
+ sal_Bool sal_True, Action could be performed
+ sal_False, Action could not be performed
+
+ [Cross-references]
+
+ <SfxTemplateDirEntry::DeleteObjectShell()>
+ <SfxDocumentTemplates::CreateObjectShell(sal_uInt16, sal_uInt16)>
+*/
+
+{
+ 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, // Region Name
+ const String &rName, // Template Name
+ String &rPath // Out: Path + File name
+)
+
+/* [Description]
+
+ Returns Path + File name of the template specified by rRegion and rName.
+
+ [Return value]
+
+ sal_Bool sal_True, Action could be performed
+ sal_False, Action could not be performed
+
+ [Cross-references]
+
+ <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 sal_uInt16 nCount = GetRegionCount();
+
+ for ( sal_uInt16 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, // Full Path to the template
+ String &rRegion, // Out: Region name
+ String &rName // Out: Template name
+) const
+
+/* [Description]
+
+ Returns and logical path name to the template specified by rPath
+
+ [Return value]
+
+ sal_Bool sal_True, Action could be performed
+ sal_False, Action could not be performed
+
+ [Cross-references]
+
+ <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;
+
+ sal_uIntPtr nCount = GetRegionCount();
+
+ for ( sal_uIntPtr i=0; !bFound && (i<nCount); i++ )
+ {
+ pData = pImp->GetRegion( i );
+ if ( pData )
+ {
+ sal_uIntPtr nChildCount = pData->GetCount();
+
+ for ( sal_uIntPtr 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()
+
+/* [Description]
+
+ Constructor
+*/
+{
+ if ( !gpTemplateData )
+ gpTemplateData = new SfxDocTemplate_Impl;
+
+ pImp = gpTemplateData;
+}
+
+//-------------------------------------------------------------------------
+
+void SfxDocumentTemplates::Construct()
+
+// Delayed build-up of administrative data
+
+{
+}
+
+//------------------------------------------------------------------------
+
+SfxDocumentTemplates::~SfxDocumentTemplates()
+
+/* [Description]
+
+ Destructor
+ Release of administrative data
+*/
+
+{
+ 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(sal_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;
+ sal_uIntPtr 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;
+}
+
+//------------------------------------------------------------------------
+sal_Bool DocTempl_EntryData_Impl::DeleteObjectShell()
+{
+ sal_Bool bRet = sal_True;
+
+ if ( mxObjShell.Is() )
+ {
+ if( mxObjShell->IsModified() )
+ {
+ // Here we also save, if the Template is being processed ...
+ 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()
+{
+ for ( size_t i = 0, n = maEntries.size(); i < n; ++i )
+ delete maEntries[ i ];
+ maEntries.clear();
+}
+
+// -----------------------------------------------------------------------
+size_t RegionData_Impl::GetEntryPos( const OUString& rTitle, sal_Bool& rFound ) const
+{
+#if 1 // Don't use binary search today
+ size_t i;
+ size_t nCount = maEntries.size();
+
+ for ( i=0; i<nCount; i++ )
+ {
+ DocTempl_EntryData_Impl *pData = maEntries[ 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;
+ size_t nStart = 0;
+ size_t nEnd = maEntries.size() - 1;
+ size_t nMid;
+
+ DocTempl_EntryData_Impl* pMid;
+
+ rFound = sal_False;
+
+ while ( nCompVal && ( nStart <= nEnd ) )
+ {
+ nMid = ( nEnd - nStart ) / 2 + nStart;
+ pMid = maEntries[ 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,
+ size_t *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;
+ size_t nPos = GetEntryPos( rTitle, bFound );
+
+ if ( bFound )
+ {
+ pEntry = maEntries[ nPos ];
+ }
+ else
+ {
+ if ( pPos )
+ nPos = *pPos;
+
+ pEntry = new DocTempl_EntryData_Impl( this, rTitle );
+ pEntry->SetTargetURL( rTargetURL );
+ pEntry->SetHierarchyURL( aLinkURL );
+ if ( nPos < maEntries.size() ) {
+ vector< DocTempl_EntryData_Impl* >::iterator it = maEntries.begin();
+ advance( it, nPos );
+ maEntries.insert( it, pEntry );
+ }
+ else
+ maEntries.push_back( pEntry );
+ }
+}
+
+// -----------------------------------------------------------------------
+size_t RegionData_Impl::GetCount() const
+{
+ return maEntries.size();
+}
+
+// -----------------------------------------------------------------------
+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 );
+ // The targeturl must be substituted: $(baseinsturl) (#i32656#)
+ 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[ nPos ];
+ else
+ return NULL;
+}
+
+// -----------------------------------------------------------------------
+DocTempl_EntryData_Impl* RegionData_Impl::GetByTargetURL( const OUString& rName ) const
+{
+ for ( size_t i = 0, n = maEntries.size(); i < n; ++i )
+ {
+ DocTempl_EntryData_Impl *pEntry = maEntries[ i ];
+ if ( pEntry->GetTargetURL() == rName )
+ return pEntry;
+ }
+ return NULL;
+}
+
+// -----------------------------------------------------------------------
+DocTempl_EntryData_Impl* RegionData_Impl::GetEntry( size_t nIndex ) const
+{
+ if ( nIndex < maEntries.size() )
+ return maEntries[ nIndex ];
+ return NULL;
+}
+
+// -----------------------------------------------------------------------
+void RegionData_Impl::DeleteEntry( size_t nIndex )
+{
+ if ( nIndex < maEntries.size() )
+ {
+ delete maEntries[ nIndex ];
+ vector< DocTempl_EntryData_Impl*>::iterator it = maEntries.begin();
+ advance( it, nIndex );
+ maEntries.erase( it );
+ }
+}
+
+// -----------------------------------------------------------------------
+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( size_t nIndex ) const
+{
+ if ( nIndex < maRegions.size() )
+ return maRegions[ nIndex ];
+ return NULL;
+}
+
+// -----------------------------------------------------------------------
+RegionData_Impl* SfxDocTemplate_Impl::GetRegion( const OUString& rName )
+ const
+{
+ for ( size_t i = 0, n = maRegions.size(); i < n; ++i )
+ {
+ RegionData_Impl* pData = maRegions[ i ];
+ if( pData->GetTitle() == rName )
+ return pData;
+ }
+ return NULL;
+}
+
+// -----------------------------------------------------------------------
+void SfxDocTemplate_Impl::DeleteRegion( size_t nIndex )
+{
+ if ( nIndex < maRegions.size() )
+ {
+ delete maRegions[ nIndex ];
+ RegionList_Impl::iterator it = maRegions.begin();
+ advance( it, nIndex );
+ maRegions.erase( it );
+ }
+}
+
+// -----------------------------------------------------------------------
+/* 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(RTL_CONSTASCII_USTRINGPARAM( TITLE ));
+ aProps[1] = OUString(RTL_CONSTASCII_USTRINGPARAM( 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(RTL_CONSTASCII_USTRINGPARAM( 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(RTL_CONSTASCII_USTRINGPARAM("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(RTL_CONSTASCII_USTRINGPARAM( 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& ) {}
+ }
+}
+
+
+// -----------------------------------------------------------------------
+size_t SfxDocTemplate_Impl::GetRegionPos( const OUString& rTitle, sal_Bool& rFound ) const
+{
+ int nCompVal = 1;
+ size_t nStart = 0;
+ size_t nEnd = maRegions.size() - 1;
+ size_t nMid = 0;
+
+ RegionData_Impl* pMid;
+
+ while ( nCompVal && ( nStart <= nEnd ) )
+ {
+ nMid = ( nEnd - nStart ) / 2 + nStart;
+ pMid = maRegions[ 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, size_t nPos )
+{
+ ::osl::MutexGuard aGuard( maMutex );
+
+ // return false (not inserted) if the entry already exists
+ for ( size_t i = 0, n = maRegions.size(); i < n; ++i )
+ if ( maRegions[ i ]->Compare( pNew ) == 0 )
+ return sal_False;
+
+ size_t newPos = nPos;
+ if ( pNew->GetTitle() == maStandardGroup )
+ newPos = 0;
+
+ if ( newPos < maRegions.size() )
+ {
+ RegionList_Impl::iterator it = maRegions.begin();
+ advance( it, newPos );
+ maRegions.insert( it, pNew );
+ }
+ else
+ maRegions.push_back( pNew );
+
+ return sal_True;
+}
+
+// -----------------------------------------------------------------------
+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;
+
+ for ( size_t i = 0, n = maRegions.size(); i < n; ++i )
+ delete maRegions[ i ];
+ 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;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */