/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: sfx2_doctempl.cxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: rt $ $Date: 2006/10/27 19:27:58 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library 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 for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#include <limits.h>

#ifndef _COM_SUN_STAR_UNO_ANY_H_
#include <com/sun/star/uno/Any.h>
#endif

#ifndef _VOS_MUTEX_HXX_
#include <vos/mutex.hxx>
#endif
#ifndef _VOS_THREAD_HXX_
#include <vos/thread.hxx>
#endif

#ifndef _SV_RESARY_HXX
#include <tools/resary.hxx>
#endif
#ifndef _SV_SVAPP_HXX
#include <vcl/svapp.hxx>
#endif
#ifndef _SV_SETTINGS_HXX
#include <vcl/settings.hxx>
#endif

#ifndef  _UNOTOOLS_LOCALEDATAWRAPPER_HXX
#include <unotools/localedatawrapper.hxx>
#endif

#ifndef INCLUDED_SVTOOLS_PATHOPTIONS_HXX
#include <svtools/pathoptions.hxx>
#endif
#ifndef _STRING_HXX
#include <tools/string.hxx>
#endif

#ifndef _URLOBJ_HXX
#include <tools/urlobj.hxx>
#endif

#ifndef _EHDL_HXX
#include <svtools/ehdl.hxx>
#endif
#ifndef _SFXECODE_HXX
#include <svtools/sfxecode.hxx>
#endif

#ifndef _COMPHELPER_PROCESSFACTORY_HXX_
#include <comphelper/processfactory.hxx>
#endif

#ifndef _UCBHELPER_CONTENT_HXX
#include <ucbhelper/content.hxx>
#endif

#ifndef _COM_SUN_STAR_BEANS_PROPERTYATTRIBUTE_HPP_
#include <com/sun/star/beans/PropertyAttribute.hpp>
#endif
#ifndef _COM_SUN_STAR_BEANS_PROPERTYVALUE_HPP_
#include <com/sun/star/beans/PropertyValue.hpp>
#endif
#ifndef _COM_SUN_STAR_BEANS_XPROPERTYCONTAINER_HPP_
#include <com/sun/star/beans/XPropertyContainer.hpp>
#endif
#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
#include <com/sun/star/beans/XPropertySet.hpp>
#endif
#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSETINFO_HPP_
#include <com/sun/star/beans/XPropertySetInfo.hpp>
#endif

#ifndef _COM_SUN_STAR_DOCUMENT_XTYPEDETECTION_HPP_
#include <com/sun/star/document/XTypeDetection.hpp>
#endif
#ifndef _COM_SUN_STAR_DOCUMENT_XDOCUMENTINFOSUPPLIER_HPP_
#include <com/sun/star/document/XDocumentInfoSupplier.hpp>
#endif

#ifndef _COM_SUN_STAR_FRAME_XCOMPONENTLOADER_HPP_
#include <com/sun/star/frame/XComponentLoader.hpp>
#endif
#ifndef _COM_SUN_STAR_FRAME_XDOCUMENTTEMPLATES_HPP_
#include <com/sun/star/frame/XDocumentTemplates.hpp>
#endif

#ifndef _COM_SUN_STAR_IO_XINPUTSTREAM_HPP_
#include <com/sun/star/io/XInputStream.hpp>
#endif
#ifndef _COM_SUN_STAR_IO_XPERSIST_HPP_
#include <com/sun/star/io/XPersist.hpp>
#endif

#ifndef  _COM_SUN_STAR_LANG_XLOCALIZABLE_HPP_
#include <com/sun/star/lang/XLocalizable.hpp>
#endif

#ifndef _COM_SUN_STAR_SDBC_XRESULTSET_HPP_
#include <com/sun/star/sdbc/XResultSet.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBC_XROW_HPP_
#include <com/sun/star/sdbc/XRow.hpp>
#endif
#ifndef _COM_SUN_STAR_UCB_CONTENTINFO_HPP_
#include <com/sun/star/ucb/ContentInfo.hpp>
#endif
#ifndef _COM_SUN_STAR_UCB_INSERTCOMMANDARGUMENT_HPP_
#include <com/sun/star/ucb/InsertCommandArgument.hpp>
#endif
#ifndef _COM_SUN_STAR_UCB_NAMECLASH_HPP_
#include <com/sun/star/ucb/NameClash.hpp>
#endif
#ifndef _COM_SUN_STAR_UCB_TRANSFERINFO_HPP_
#include <com/sun/star/ucb/TransferInfo.hpp>
#endif
#ifndef _COM_SUN_STAR_UCB_XCOMMANDPROCESSOR_HPP_
#include <com/sun/star/ucb/XCommandProcessor.hpp>
#endif
#ifndef _COM_SUN_STAR_UCB_XCONTENT_HPP_
#include <com/sun/star/ucb/XContent.hpp>
#endif
#ifndef _COM_SUN_STAR_UCB_XCONTENTCREATOR_HPP_
#include <com/sun/star/ucb/XContentCreator.hpp>
#endif
#ifndef _COM_SUN_STAR_UCB_XCONTENTACCESS_HPP_
#include <com/sun/star/ucb/XContentAccess.hpp>
#endif
#ifndef _COM_SUN_STAR_UCB_XANYCOMPAREFACTORY_HPP_
#include <com/sun/star/ucb/XAnyCompareFactory.hpp>
#endif
#ifndef _COM_SUN_STAR_UCB_XANYCOMPARE_HPP_
#include <com/sun/star/ucb/XAnyCompare.hpp>
#endif
#ifndef _COM_SUN_STAR_UCB_NUMBEREDSORTINGINFO_HPP_
#include <com/sun/star/ucb/NumberedSortingInfo.hpp>
#endif



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 ::ucb; //STRIP002 using namespace ucb;


#include "doctempl.hxx"
#include "docfac.hxx"
#include "docfile.hxx"
#include "objsh.hxx"
#include "sfxtypes.hxx"
#include "app.hxx"
#include "sfxresid.hxx"
#include "doc.hrc"
#include "fcontnr.hxx"

#ifndef SFX2_TEMPLATEFOLDERCACHE_HXX
#include <svtools/templatefoldercache.hxx>
#endif
#ifndef _LEGACYBINFILTERMGR_HXX
#include <legacysmgr/legacy_binfilters_smgr.hxx>	//STRIP002 
#endif
namespace binfilter {
//========================================================================

// #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;

/*N*/ namespace DocTempl {
/*N*/ 
/*N*/ class EntryData_Impl
/*N*/ {
/*N*/     RegionData_Impl*    mpParent;
/*N*/     SfxObjectShellLock  mxObjShell;
/*N*/     SvStorageRef        mxStor;
/*N*/     OUString            maTitle;
/*N*/     OUString            maOwnURL;
/*N*/     OUString            maTargetURL;
/*N*/     sal_Bool            mbIsOwner   : 1;
/*N*/     sal_Bool            mbDidConvert: 1;
/*N*/ 
/*N*/ private:
/*N*/     RegionData_Impl*    GetParent() const { return mpParent; }
/*N*/ 
/*N*/ public:
/*N*/                         EntryData_Impl( RegionData_Impl* pParent,
/*N*/                                         const OUString& rTitle );
/*N*/ 
/*N*/     const OUString&     GetTitle() const { return maTitle; }
    const OUString&     GetTargetURL();
/*N*/ 
/*N*/     void                SetTitle( const OUString& rTitle ) { maTitle = rTitle; }
/*N*/     void                SetTargetURL( const OUString& rURL ) { maTargetURL = rURL; }
/*N*/     void                SetHierarchyURL( const OUString& rURL) { maOwnURL = rURL; }
/*N*/ 
/*N*/     int                 Compare( const OUString& rTitle ) const;
/*N*/ 
/*N*/ };
/*N*/ 
/*N*/ }//STRIP008 ;

/*N*/ using namespace DocTempl;
/*N*/ 
/*N*/ DECLARE_LIST( EntryList_Impl, EntryData_Impl* )//STRIP008 ;

// ------------------------------------------------------------------------

/*N*/ class RegionData_Impl
/*N*/ {
/*N*/     const SfxDocTemplate_Impl*  mpParent;
/*N*/     EntryList_Impl              maEntries;
/*N*/     OUString                    maTitle;
/*N*/     OUString                    maOwnURL;
/*N*/     OUString                    maTargetURL;
/*N*/ 
/*N*/ private:
/*N*/     long                        GetEntryPos( const OUString& rTitle,
/*N*/                                              sal_Bool& rFound ) const;
/*N*/     const SfxDocTemplate_Impl*  GetParent() const { return mpParent; }
/*N*/ 
/*N*/ public:
/*N*/                         RegionData_Impl( const SfxDocTemplate_Impl* pParent,
/*N*/                                          const OUString& rTitle );
/*N*/                         ~RegionData_Impl();
/*N*/ 
/*N*/     void                SetTargetURL( const OUString& rURL ) { maTargetURL = rURL; }
/*N*/     void                SetHierarchyURL( const OUString& rURL) { maOwnURL = rURL; }
/*N*/ 
/*N*/     EntryData_Impl*     GetEntry( ULONG nIndex ) const;
/*N*/     EntryData_Impl*     GetEntry( const OUString& rName ) const;
/*N*/     EntryData_Impl*     GetByTargetURL( const OUString& rName ) const;
/*N*/ 
/*N*/     const OUString&     GetTitle() const { return maTitle; }
/*N*/     const OUString&     GetTargetURL();
/*N*/     const OUString&     GetHierarchyURL();
/*N*/ 
/*N*/     ULONG               GetCount() const;
/*N*/ 
/*N*/     void                SetTitle( const OUString& rTitle ) { maTitle = rTitle; }
/*N*/ 
/*N*/     void                AddEntry( const OUString& rTitle,
/*N*/                                   const OUString& rTargetURL,
/*N*/                                   USHORT *pPos = NULL );
/*N*/     void                DeleteEntry( ULONG nIndex );
/*N*/ 
/*N*/     int                 Compare( const OUString& rTitle ) const
/*N*/                             { return maTitle.compareTo( rTitle ); }
/*N*/     int                 Compare( RegionData_Impl* pCompareWith ) const;
/*N*/ };
/*N*/ 
/*N*/ DECLARE_LIST( RegionList_Impl, RegionData_Impl* )//STRIP008 ;

// ------------------------------------------------------------------------

/*N*/ class SfxDocTemplate_Impl : public SvRefBase
/*N*/ {
/*N*/     Reference< XPersist >               mxInfo;
/*N*/     Reference< XDocumentTemplates >     mxTemplates;
/*N*/ 
/*N*/     ::osl::Mutex        maMutex;
/*N*/     OUString            maRootURL;
/*N*/     OUString            maStandardGroup;
/*N*/     RegionList_Impl     maRegions;
/*N*/     sal_Bool            mbConstructed;
/*N*/ 
/*N*/ 	Reference< XAnyCompareFactory > m_rCompareFactory;

/*N*/ private:
/*N*/     void                Clear();
/*N*/ 
/*N*/ public:
/*N*/                         SfxDocTemplate_Impl();
/*N*/                         ~SfxDocTemplate_Impl();
/*N*/ 
/*N*/     sal_Bool            Construct( );
/*N*/     void                CreateFromHierarchy( Content &rTemplRoot );
/*N*/     void                AddRegion( const OUString& rTitle,
/*N*/                                    Content& rContent );
/*N*/ 
/*N*/     void                Rescan();
/*N*/ 
/*N*/     void                DeleteRegion( ULONG nIndex );
/*N*/ 
/*N*/     ULONG               GetRegionCount() const
/*N*/                             { return maRegions.Count(); }
/*N*/     RegionData_Impl*    GetRegion( const OUString& rName ) const;
/*N*/     RegionData_Impl*    GetRegion( ULONG nIndex ) const;
/*N*/     void                GetTemplates( Content& rTargetFolder,
/*N*/                                       Content& rParentFolder,
/*N*/                                       RegionData_Impl* pRegion );
/*N*/ 
/*N*/     long                GetRegionPos( const OUString& rTitle,
/*N*/                                       sal_Bool& rFound ) const;
/*N*/ 
/*N*/     sal_Bool            GetTitleFromURL( const OUString& rURL, OUString& aTitle );
/*N*/     sal_Bool            InsertRegion( RegionData_Impl *pData, ULONG nPos = LIST_APPEND );
/*N*/     OUString            GetRootURL() const { return maRootURL; }
/*N*/ 
/*N*/     Reference< XDocumentTemplates >     getDocTemplates() { return mxTemplates; }
/*N*/ };

// ------------------------------------------------------------------------

#ifndef SFX_DECL_DOCTEMPLATES_DEFINED
#define SFX_DECL_DOCTEMPLATES_DEFINED
/*?*/ SV_DECL_REF(SfxDocTemplate_Impl)
#endif

/*?*/ SV_IMPL_REF(SfxDocTemplate_Impl)

// ------------------------------------------------------------------------

/*N*/ SfxDocTemplate_Impl *gpTemplateData = 0;

// -----------------------------------------------------------------------

/*N*/ static sal_Bool getTextProperty_Impl( Content& rContent,
/*N*/                                       const OUString& rPropName,
/*N*/                                       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;
/*?*/ 
/*?*/     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;
/*?*/ 
/*?*/     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

*/
/*?*/ {
/*?*/     if ( !pImp->Construct() )
/*?*/         return USHRT_MAX;
/*?*/ 
/*?*/     sal_Bool    bFound;
/*?*/     ULONG       nIndex = pImp->GetRegionPos( rRegion, bFound );
/*?*/ 
/*?*/     if ( bFound )
/*?*/         return (USHORT) nIndex;
/*?*/     else
/*?*/         return USHRT_MAX;
/*?*/ }


//------------------------------------------------------------------------

/*N*/ USHORT SfxDocumentTemplates::GetRegionCount() const

/*  [Beschreibung]

    Liefert die Anzahl der Bereiche


    [R"uckgabewert]

    USHORT                  Anzahl der Bereiche

*/
/*N*/ {
/*N*/     if ( !pImp->Construct() )
/*N*/         return 0;
/*N*/ 
/*N*/     ULONG nCount = pImp->GetRegionCount();
/*N*/ 
/*N*/     return (USHORT) nCount;
}

//------------------------------------------------------------------------

/*?*/ BOOL SfxDocumentTemplates::IsRegionLoaded( USHORT nIdx ) const
/*?*/ {
/*?*/     if ( !pImp->Construct() )
/*?*/         return FALSE;
/*?*/ 
/*?*/     RegionData_Impl *pData = pImp->GetRegion( nIdx );
/*?*/ 
/*?*/     if ( pData )
/*?*/         return TRUE;
/*?*/     else
/*?*/         return 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

*/

/*?*/ {
/*?*/     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

*/

/*?*/ {
/*?*/     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

*/

/*?*/ {
/*?*/     static String maTmpString;
/*?*/ 
/*?*/     if ( pImp->Construct() )
/*?*/     {
/*?*/         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

*/
/*?*/ {DBG_BF_ASSERT(0, "STRIP"); //STRIP001 
/*?*/         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

*/
/*?*/ {DBG_BF_ASSERT(0, "STRIP"); //STRIP001 
/*?*/         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

*/
/*?*/ {
/*?*/     if ( !pImp->Construct() )
/*?*/         return String();
/*?*/ 
/*?*/     EntryData_Impl  *pEntry = NULL;
/*?*/     RegionData_Impl *pRegion = pImp->GetRegion( nRegion );
/*?*/ 
/*?*/     if ( pRegion )
/*?*/         pEntry = pRegion->GetEntry( rLongName );
/*?*/ 
/*?*/     if ( pEntry )
/*?*/         return pEntry->GetTargetURL();
/*?*/     else if ( pRegion )
/*?*/     {
/*?*/         // --**-- 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

*/
/*?*/ {
/*?*/     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 );
/*?*/     EntryData_Impl  *pEntry = NULL;
/*?*/ 
/*?*/     if ( pRegion )
/*?*/         pEntry = pRegion->GetEntry( rLongName );
/*?*/ 
/*?*/     if ( pEntry )
/*?*/         return pEntry->GetTargetURL();
/*?*/     else if ( pRegion )
/*?*/     {
/*?*/         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, 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();
*/
/*?*/ }

//------------------------------------------------------------------------

/*?*/ BOOL SfxDocumentTemplates::SaveDir
/*?*/ (
/*?*/ //  SfxTemplateDir& rDir        //  das zu speichernde Directory
/*?*/ )

/*  [Beschreibung]

    Speichert das Directory rDir


    [R"uckgabewert]

    BOOL                        FALSE,
                                Schreibfehler

                                TRUE
                                gespeichert

*/

/*?*/ {
/*?*/     return 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)

*/

/*?*/ {
/*?*/     if ( ! pImp->Construct() )
/*?*/         return;
/*?*/ 
/*?*/     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;
/*?*/ 
/*?*/     Reference< XDocumentTemplates > xTemplates = pImp->getDocTemplates();
/*?*/ 
/*?*/     if ( xTemplates->addTemplate( pRegion->GetTitle(), rLongName, rFileName ) )
/*?*/         pRegion->AddEntry( rLongName, rFileName );
/*?*/ }

//------------------------------------------------------------------------


/*  [Beschreibung]

    Kopieren oder Verschieben einer Dokumentvorlage

    [R"uckgabewert]

    BOOL                            TRUE
                                    Aktion konnte ausgef"uhrt werden

                                    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 )
       ...
    */


    // --**-- wenn aktuell das File geoeffnet ist,
    // muss es hinterher wieder geoeffnet werden


//------------------------------------------------------------------------


/*  [Beschreibung]

    Verschieben einer Dokumentvorlage


    [R"uckgabewert]

    BOOL                            TRUE
                                    Aktion konnte ausgef"uhrt werden

                                    FALSE
                                    Aktion konnte nicht ausgef2uhrt werden

    [Querverweise]

    <SfxDocumentTemplates::CopyOrMove(USHORT,USHORT,USHORT,USHORT,BOOL)>
*/

//------------------------------------------------------------------------


/*  [Beschreibung]

    Kopieren einer Dokumentvorlage


    [R"uckgabewert]

    BOOL                            TRUE
                                    Aktion konnte ausgef"uhrt werden

                                    FALSE
                                    Aktion konnte nicht ausgef"uhrt werden

    [Querverweise]

    <SfxDocumentTemplates::CopyOrMove(USHORT,USHORT,USHORT,USHORT,BOOL)>
*/


//------------------------------------------------------------------------


/*  [Beschreibung]

    Exportieren einer Dokumentvorlage in das Dateisystem


    [R"uckgabewert]

    BOOL                            TRUE
                                    Aktion konnte ausgef"uhrt werden

                                    FALSE
                                    Aktion konnte nicht ausgef"uhrt werden


    [Querverweise]

    <SfxDocumentTemplates::CopyFrom(USHORT,USHORT,String&)>
*/


//------------------------------------------------------------------------


/*  [Beschreibung]

    Importieren einer Dokumentvorlage aus dem Dateisystem


    [R"uckgabewert]                 Erfolg (TRUE) oder Mi"serfpTargetDirectory->GetContent());

    BOOL                            TRUE
                                    Aktion konnte ausgef"uhrt werden

                                    FALSE
                                    Aktion konnte nicht ausgef"uhrt werden

    [Querverweise]

    <SfxDocumentTemplates::CopyTo(USHORT,USHORT,const String&)>
*/


//------------------------------------------------------------------------


/*  [Beschreibung]

    "oschen eines Eintrags oder eines Verzeichnisses


    [R"uckgabewert]

    BOOL                            TRUE
                                    Aktion konnte ausgef"uhrt werden

                                    FALSE
                                    Aktion konnte nicht ausgef"uhrt werden


    [Querverweise]

    <SfxDocumentTemplates::InsertDir(const String&,USHORT)>
    <SfxDocumentTemplates::KillDir(SfxTemplateDir&)>
    <SfxDocumentTemplates::SaveDir(SfxTemplateDir&)>
*/


//------------------------------------------------------------------------


/*  [Beschreibung]

    Einf"ugen eines Verzeichnisses


    [R"uckgabewert]

    BOOL                            TRUE
                                    Aktion konnte ausgef"uhrt werden

                                    FALSE
                                    Aktion konnte nicht ausgef"uhrt werden

    [Querverweise]

    <SfxDocumentTemplates::KillDir(SfxTemplateDir&)>
    <SfxDocumentTemplates::SaveDir(SfxTemplateDir&)>
*/

//------------------------------------------------------------------------


/*  [Beschreibung]

    "Andern des Namens eines Eintrags oder eines Verzeichnisses


    [R"uckgabewert]

    BOOL                            TRUE
                                    Aktion konnte ausgef"uhrt werden

                                    FALSE
                                    Aktion konnte nicht ausgef"uhrt werden

*/


//------------------------------------------------------------------------


/*  [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]

    BOOL                            TRUE
                                    Aktion konnte ausgef"uhrt werden

                                    FALSE
                                    Aktion konnte nicht ausgef"uhrt werden


    [Querverweise]

    <SfxTemplateDir::Scan(BOOL bDirectory, BOOL bSave)>
    <SfxTemplateDir::Freshen(const SfxTemplateDir &rNew)>
*/

//------------------------------------------------------------------------


//------------------------------------------------------------------------


/*  [Beschreibung]

    Freigeben der ObjectShell eines Eintrags


    [R"uckgabewert]

    BOOL                            TRUE
                                    Aktion konnte ausgef"uhrt werden

                                    FALSE
                                    Aktion konnte nicht ausgef"uhrt werden

    [Querverweise]

    <SfxTemplateDirEntry::DeleteObjectShell()>
    <SfxDocumentTemplates::CreateObjectShell(USHORT, USHORT)>
*/


//------------------------------------------------------------------------


//------------------------------------------------------------------------

/*N*/ BOOL SfxDocumentTemplates::GetLogicNames
/*N*/ (
/*N*/     const String &rPath,            // vollst"andiger Pfad zu der Vorlage
/*N*/     String &rRegion,                // Out: der Bereichsname
/*N*/     String &rName                   // Out: der Vorlagenname
/*N*/ ) const

/*  [Beschreibung]

    Liefert Pfad und logischen Namen zu der durch rPath bezeichneten
    Vorlage

    [R"uckgabewert]

    BOOL                            TRUE
                                    Aktion konnte ausgef"uhrt werden

                                    FALSE
                                    Aktion konnte nicht ausgef"uhrt werden


    [Querverweise]

    <SfxDocumentTemplates::GetFull(const String&,const String&,DirEntry&)>
*/

/*N*/ {
/*N*/     if ( ! pImp->Construct() )
/*N*/         return FALSE;
/*N*/ 
/*N*/     INetURLObject aFullPath;
/*N*/ 
/*N*/     aFullPath.SetSmartProtocol( INET_PROT_FILE );
/*N*/     aFullPath.SetURL( rPath );
/*N*/     aFullPath.CutLastName();
/*N*/ 
/*N*/     OUString aPathTo = aFullPath.GetMainURL( INetURLObject::NO_DECODE );
/*N*/ 
/*N*/     RegionData_Impl *pData = NULL;
/*N*/     EntryData_Impl  *pEntry = NULL;
/*N*/     sal_Bool         bFound = sal_False;
/*N*/ 
/*N*/     ULONG nCount = GetRegionCount();
/*N*/ 
/*N*/     for ( ULONG i=0; !bFound && (i<nCount); i++ )
/*N*/     {
/*N*/         pData = pImp->GetRegion( i );
/*N*/         if ( pData->GetTargetURL() == aPathTo )
/*N*/         {
/*?*/             ULONG nChildCount = pData->GetCount();
/*?*/             OUString aPath( rPath );
/*?*/ 
/*?*/             for ( ULONG j=0; !bFound && (j<nChildCount); j++ )
/*?*/             {
/*?*/                 pEntry = pData->GetEntry( j );
/*?*/                 if ( pEntry->GetTargetURL() == aPath )
/*?*/                 {
/*?*/                     bFound = sal_True;
/*?*/                 }
/*?*/             }
/*N*/         }
/*N*/     }
/*N*/ 
/*N*/     if ( bFound )
/*N*/     {
/*?*/         rRegion = pData->GetTitle();
/*?*/         rName = pEntry->GetTitle();
/*N*/     }
/*N*/ 
/*N*/     return bFound;
/*N*/ }

//------------------------------------------------------------------------

/*N*/ SfxDocumentTemplates::SfxDocumentTemplates()

/*  [Beschreibung]

    Konstruktor
*/
/*N*/ {
/*N*/     if ( !gpTemplateData )
/*N*/         gpTemplateData = new SfxDocTemplate_Impl;
/*N*/ 
/*N*/     pImp = gpTemplateData;
/*N*/ }

//-------------------------------------------------------------------------

/*N*/ void SfxDocumentTemplates::Construct()

//  verz"ogerter Aufbau der Verwaltungsdaten

/*N*/ {
/*N*/ //  pImp->Construct();
/*N*/ }

//------------------------------------------------------------------------

/*N*/ SfxDocumentTemplates::~SfxDocumentTemplates()

/*  [Beschreibung]

    Destruktor
    Freigeben der Verwaltungsdaten
*/

/*N*/ {
/*N*/     pImp = NULL;
/*N*/ }



// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
/*N*/ EntryData_Impl::EntryData_Impl( RegionData_Impl* pParent,
/*N*/                                 const OUString& rTitle )
/*N*/ {
/*N*/     mpParent    = pParent;
/*N*/     maTitle     = rTitle;
/*N*/     mbIsOwner   = sal_False;
/*N*/     mbDidConvert= sal_False;
/*N*/ }

// -----------------------------------------------------------------------
/*N*/ int EntryData_Impl::Compare( const OUString& rTitle ) const
/*N*/ {
/*N*/     return maTitle.compareTo( rTitle );
/*N*/ }

//------------------------------------------------------------------------

//------------------------------------------------------------------------

// -----------------------------------------------------------------------

// -----------------------------------------------------------------------
/*N*/ const OUString& EntryData_Impl::GetTargetURL()
/*N*/ {DBG_BF_ASSERT(0, "STRIP"); return maTargetURL;//STRIP001 
/*N*/ }

// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
/*N*/ RegionData_Impl::RegionData_Impl( const SfxDocTemplate_Impl* pParent,
/*N*/                                   const OUString& rTitle )
/*N*/ {
/*N*/     maTitle     = rTitle;
/*N*/     mpParent    = pParent;
/*N*/ }

// -----------------------------------------------------------------------
/*N*/ RegionData_Impl::~RegionData_Impl()
/*N*/ {
/*N*/     EntryData_Impl *pData = maEntries.First();
/*N*/ 
/*N*/     while ( pData )
/*N*/     {
/*N*/         delete pData;
/*N*/         pData = maEntries.Next();
/*N*/     }
/*N*/ }

// -----------------------------------------------------------------------
/*N*/ long RegionData_Impl::GetEntryPos( const OUString& rTitle,
/*N*/                                    sal_Bool& rFound ) const
/*N*/ {
/*N*/ #if 1   // Don't use binary search today
/*N*/     ULONG i;
/*N*/     ULONG nCount = maEntries.Count();
/*N*/ 
/*N*/     for ( i=0; i<nCount; i++ )
/*N*/     {
/*N*/         EntryData_Impl *pData = maEntries.GetObject( i );
/*N*/ 
/*N*/         if ( pData->Compare( rTitle ) == 0 )
/*N*/         {
/*N*/             rFound = sal_True;
/*N*/             return i;
/*N*/         }
/*N*/     }
/*N*/ 
/*N*/     rFound = sal_False;
/*N*/     return i;
/*N*/ 
/*N*/ #else
/*N*/     // use binary search to find the correct position
/*N*/     // in the maEntries list
/*N*/ 
/*N*/     int     nCompVal = 1;
/*N*/     long    nStart = 0;
/*N*/     long    nEnd = maEntries.Count() - 1;
/*N*/     long    nMid;
/*N*/ 
/*N*/     EntryData_Impl* pMid;
/*N*/ 
/*N*/     rFound = sal_False;
/*N*/ 
/*N*/     while ( nCompVal && ( nStart <= nEnd ) )
/*N*/     {
/*N*/         nMid = ( nEnd - nStart ) / 2 + nStart;
/*N*/         pMid = maEntries.GetObject( nMid );
/*N*/ 
/*N*/         nCompVal = pMid->Compare( rTitle );
/*N*/ 
/*N*/         if ( nCompVal < 0 )     // pMid < pData
/*N*/             nStart = nMid + 1;
/*N*/         else
/*N*/             nEnd = nMid - 1;
/*N*/     }
/*N*/ 
/*N*/     if ( nCompVal == 0 )
/*N*/     {
/*N*/         rFound = sal_True;
/*N*/     }
/*N*/     else
/*N*/     {
/*N*/         if ( nCompVal < 0 )     // pMid < pData
/*N*/             nMid++;
/*N*/     }
/*N*/ 
/*N*/     return nMid;
/*N*/ #endif
/*N*/ }

// -----------------------------------------------------------------------
/*N*/ void RegionData_Impl::AddEntry( const OUString& rTitle,
/*N*/                                 const OUString& rTargetURL,
/*N*/                                 USHORT *pPos )
/*N*/ {
/*N*/     INetURLObject aLinkObj( GetHierarchyURL() );
/*N*/     aLinkObj.insertName( rTitle, false,
/*N*/                       INetURLObject::LAST_SEGMENT, true,
/*N*/                       INetURLObject::ENCODE_ALL );
/*N*/     OUString aLinkURL = aLinkObj.GetMainURL( INetURLObject::NO_DECODE );
/*N*/ 
/*N*/     EntryData_Impl *pEntry;
/*N*/     sal_Bool        bFound = sal_False;
/*N*/     long            nPos = GetEntryPos( rTitle, bFound );
/*N*/ 
/*N*/     if ( bFound )
/*N*/     {
/*?*/         pEntry = maEntries.GetObject( nPos );
/*N*/     }
/*N*/     else
/*N*/     {
/*N*/         if ( pPos )
/*N*/             nPos = *pPos;
/*N*/ 
/*N*/         pEntry = new EntryData_Impl( this, rTitle );
/*N*/         pEntry->SetTargetURL( rTargetURL );
/*N*/         pEntry->SetHierarchyURL( aLinkURL );
/*N*/         maEntries.Insert( pEntry, nPos );
/*N*/     }
/*N*/ }

// -----------------------------------------------------------------------
/*?*/ ULONG RegionData_Impl::GetCount() const
/*?*/ {
/*?*/     return maEntries.Count();
/*?*/ }

// -----------------------------------------------------------------------
/*N*/ const OUString& RegionData_Impl::GetHierarchyURL()
/*N*/ {
/*N*/     if ( !maOwnURL.getLength() )
/*N*/     {
/*N*/         INetURLObject aRegionObj( GetParent()->GetRootURL() );
/*N*/ 
/*N*/         aRegionObj.insertName( GetTitle(), false,
/*N*/                      INetURLObject::LAST_SEGMENT, true,
/*N*/                      INetURLObject::ENCODE_ALL );
/*N*/ 
/*N*/         maOwnURL = aRegionObj.GetMainURL( INetURLObject::NO_DECODE );
/*N*/         DBG_ASSERT( maOwnURL.getLength(), "GetHierarchyURL(): Could not create URL!" );
/*N*/     }
/*N*/ 
/*N*/     return maOwnURL;
/*N*/ }

// -----------------------------------------------------------------------
/*N*/ const OUString& RegionData_Impl::GetTargetURL()
/*N*/ {
/*N*/     if ( !maTargetURL.getLength() )
/*N*/     {
/*N*/         Reference< XCommandEnvironment > aCmdEnv;
/*N*/         Content aRegion;
/*N*/ 
/*N*/         if ( Content::create( GetHierarchyURL(), aCmdEnv, aRegion ) )
/*N*/         {
/*N*/             OUString aPropName( RTL_CONSTASCII_USTRINGPARAM( TARGET_DIR_URL ) );
/*N*/ 
/*N*/             getTextProperty_Impl( aRegion, aPropName, maTargetURL );
/*N*/         }
/*N*/         else
/*N*/         {
/*N*/             DBG_ERRORFILE( "GetTargetURL(): Could not create hierarchy content!" );
/*N*/         }
/*N*/     }
/*N*/ 
/*N*/     return maTargetURL;
/*N*/ }

// -----------------------------------------------------------------------
/*?*/ 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;
/*?*/ }

// -----------------------------------------------------------------------
/*?*/ EntryData_Impl* RegionData_Impl::GetByTargetURL( const OUString& rName ) const
/*?*/ {
/*?*/     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;
/*?*/ }

// -----------------------------------------------------------------------
/*?*/ EntryData_Impl* RegionData_Impl::GetEntry( ULONG nIndex ) const
/*?*/ {
/*?*/     return maEntries.GetObject( nIndex );
/*?*/ }

// -----------------------------------------------------------------------
/*?*/ void RegionData_Impl::DeleteEntry( ULONG nIndex )
/*?*/ {
/*?*/     EntryData_Impl *pEntry = maEntries.GetObject( nIndex );
/*?*/ 
/*?*/     if ( pEntry )
/*?*/     {
/*?*/         delete pEntry;
/*?*/         maEntries.Remove( (ULONG) nIndex );
/*?*/     }
/*?*/ }

// -----------------------------------------------------------------------
/*N*/ int RegionData_Impl::Compare( RegionData_Impl* pCompare ) const
/*N*/ {
/*N*/     int nCompare = maTitle.compareTo( pCompare->maTitle );
/*N*/ 
/*N*/     return nCompare;
/*N*/ }

// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------

/*N*/ SfxDocTemplate_Impl::SfxDocTemplate_Impl()
/*N*/ {
/*N*/     mbConstructed = sal_False;
/*N*/ }

// -----------------------------------------------------------------------
/*N*/ SfxDocTemplate_Impl::~SfxDocTemplate_Impl()
/*N*/ {
/*N*/     Clear();
/*N*/ 
/*N*/     gpTemplateData = NULL;
/*N*/ }

// -----------------------------------------------------------------------
/*N*/ RegionData_Impl* SfxDocTemplate_Impl::GetRegion( ULONG nIndex ) const
/*N*/ {
/*N*/     return maRegions.GetObject( nIndex );
/*N*/ }

// -----------------------------------------------------------------------
/*?*/ 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
*/
/*N*/ void SfxDocTemplate_Impl::AddRegion( const OUString& rTitle,
/*N*/                                      Content& rContent )
/*N*/ {
/*N*/     RegionData_Impl* pRegion;
/*N*/     pRegion = new RegionData_Impl( this, rTitle );
/*N*/ 
/*N*/     if ( ! InsertRegion( pRegion ) )
/*N*/     {
/*N*/         delete pRegion;
/*N*/         return;
/*N*/     }
/*N*/ 
/*N*/     // now get the content of the region
/*N*/     Reference< XResultSet > xResultSet;
/*N*/     Sequence< OUString > aProps(2);
/*N*/     aProps[0] = OUString::createFromAscii( TITLE );
/*N*/     aProps[1] = OUString::createFromAscii( TARGET_URL );
/*N*/ 
/*N*/     try
/*N*/     {
/*N*/         ResultSetInclude eInclude = INCLUDE_DOCUMENTS_ONLY;
/*N*/ 		Sequence< NumberedSortingInfo > 	aSortingInfo(1);
/*N*/ 		aSortingInfo.getArray()->ColumnIndex = 1;
/*N*/ 		aSortingInfo.getArray()->Ascending = sal_True;
/*N*/         xResultSet = rContent.createSortedCursor( aProps, aSortingInfo, m_rCompareFactory, eInclude );
/*N*/     }
/*N*/     catch ( Exception& ) {}
/*N*/ 
/*N*/     if ( xResultSet.is() )
/*N*/     {
/*N*/         Reference< XContentAccess > xContentAccess( xResultSet, UNO_QUERY );
/*N*/         Reference< XRow > xRow( xResultSet, UNO_QUERY );
/*N*/ 
/*N*/         try
/*N*/         {
/*N*/             while ( xResultSet->next() )
/*N*/             {
/*N*/                 OUString aTitle( xRow->getString( 1 ) );
/*N*/                 OUString aTargetDir( xRow->getString( 2 ) );
/*N*/ 
/*N*/                 pRegion->AddEntry( aTitle, aTargetDir );
/*N*/             }
/*N*/         }
/*N*/         catch ( Exception& ) {}
/*N*/     }
/*N*/ }

// -----------------------------------------------------------------------
/*N*/ void SfxDocTemplate_Impl::CreateFromHierarchy( Content &rTemplRoot )
/*N*/ {
/*N*/     Reference< XResultSet > xResultSet;
/*N*/     Sequence< OUString > aProps(1);
/*N*/     aProps[0] = OUString::createFromAscii( TITLE );
/*N*/ 
/*N*/     try
/*N*/     {
/*N*/         ResultSetInclude eInclude = INCLUDE_FOLDERS_ONLY;
/*N*/ 		Sequence< NumberedSortingInfo > 	aSortingInfo(1);
/*N*/ 		aSortingInfo.getArray()->ColumnIndex = 1;
/*N*/ 		aSortingInfo.getArray()->Ascending = sal_True;
/*N*/         xResultSet = rTemplRoot.createSortedCursor( aProps, aSortingInfo, m_rCompareFactory, eInclude );
/*N*/     }
/*N*/     catch ( Exception& ) {}
/*N*/ 
/*N*/     if ( xResultSet.is() )
/*N*/     {
/*N*/         Reference< XCommandEnvironment > aCmdEnv;
/*N*/         Reference< XContentAccess > xContentAccess( xResultSet, UNO_QUERY );
/*N*/         Reference< XRow > xRow( xResultSet, UNO_QUERY );
/*N*/ 
/*N*/         try
/*N*/         {
/*N*/             while ( xResultSet->next() )
/*N*/             {
/*N*/                 OUString aTitle( xRow->getString( 1 ) );
/*N*/ 
/*N*/                 OUString aId = xContentAccess->queryContentIdentifierString();
/*N*/                 Content  aContent = Content( aId, aCmdEnv );
/*N*/ 
/*N*/                 AddRegion( aTitle, aContent );
/*N*/             }
/*N*/         }
/*N*/         catch ( Exception& ) {}
/*N*/     }
/*N*/ }

// ------------------------------------------------------------------------
/*N*/ sal_Bool SfxDocTemplate_Impl::Construct( )
/*N*/ {
/*N*/     ::osl::MutexGuard aGuard( maMutex );
/*N*/ 
/*N*/     if ( mbConstructed )
/*N*/ 		return sal_True;
/*N*/ 
/*N*/     Reference< XMultiServiceFactory >   xFactory;
/*N*/     xFactory = ::legacy_binfilters::getLegacyProcessServiceFactory();
/*N*/ 
/*N*/     OUString aService( RTL_CONSTASCII_USTRINGPARAM( SERVICENAME_DOCINFO ) );
/*N*/     Reference< XPersist > xInfo( xFactory->createInstance( aService ), UNO_QUERY );
/*N*/     mxInfo = xInfo;
/*N*/ 
/*N*/     aService = OUString( RTL_CONSTASCII_USTRINGPARAM( SERVICENAME_DOCTEMPLATES ) );
/*N*/     Reference< XDocumentTemplates > xTemplates( xFactory->createInstance( aService ), UNO_QUERY );
/*N*/ 
/*N*/     if ( xTemplates.is() )
/*N*/         mxTemplates = xTemplates;
/*N*/     else
/*N*/         return sal_False;
/*N*/ 
/*N*/     AllSettings aSettings;
/*N*/     Locale      aLocale = aSettings.GetLocale();
/*N*/ 
/*N*/     Reference< XLocalizable > xLocalizable( xTemplates, UNO_QUERY );
/*N*/ 
/*N*/     xLocalizable->setLocale( aLocale );
/*N*/ 
/*N*/ 	Sequence< Any > aCompareArg(1);
/*N*/ 	*(aCompareArg.getArray()) <<= aLocale;
/*N*/ 	m_rCompareFactory = Reference< XAnyCompareFactory >(
/*N*/ 					xFactory->createInstanceWithArguments( OUString::createFromAscii( "com.sun.star.ucb.AnyCompareFactory" ),
/*N*/ 														   aCompareArg ),
/*N*/ 					UNO_QUERY );
/*N*/ 
/*N*/     Reference < XContent > aRootContent = xTemplates->getContent();
/*N*/     Reference < XCommandEnvironment > aCmdEnv;
/*N*/ 
/*N*/     if ( ! aRootContent.is() )
/*N*/         return sal_False;
/*N*/ 
/*N*/     mbConstructed = sal_True;
/*N*/     maRootURL = aRootContent->getIdentifier()->getContentIdentifier();
/*N*/ 
/*N*/     ResStringArray  aLongNames( SfxResId( TEMPLATE_LONG_NAMES_ARY ) );
/*N*/ 
/*N*/     if ( aLongNames.Count() )
/*N*/         maStandardGroup = aLongNames.GetString( 0 );
/*N*/ 
/*N*/     Content aTemplRoot( aRootContent, aCmdEnv );
/*N*/     CreateFromHierarchy( aTemplRoot );
/*N*/ 
/*N*/     return sal_True;
/*N*/ }


// -----------------------------------------------------------------------
/*?*/ void SfxDocTemplate_Impl::GetTemplates( Content& rTargetFolder,
/*?*/                                         Content& rParentFolder,
/*?*/                                         RegionData_Impl* pRegion )
/*?*/ {
/*?*/     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() )
/*?*/     {
/*?*/         Reference< XContentAccess > xContentAccess( xResultSet, UNO_QUERY );
/*?*/         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();
/*?*/ 
/*?*/                 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;
/*?*/ 
/*?*/     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 = TRUE;
/*?*/     else
/*?*/     {
/*?*/         if ( nCompVal < 0 )     // pMid < pData
/*?*/             nMid++;
/*?*/ 
/*?*/         rFound = sal_False;
/*?*/     }
/*?*/ 
/*?*/     return nMid;
/*?*/ }

// -----------------------------------------------------------------------
/*N*/ sal_Bool SfxDocTemplate_Impl::InsertRegion( RegionData_Impl *pNew,
/*N*/                                             ULONG nPos )
/*N*/ {
/*N*/     ::osl::MutexGuard   aGuard( maMutex );
/*N*/     RegionData_Impl    *pData = maRegions.First();
/*N*/ 
/*N*/     while ( pData && ( pData->Compare( pNew ) != 0 ) )
/*N*/         pData = maRegions.Next();
/*N*/ 
/*N*/     if ( ! pData )
/*N*/     {
/*N*/         // compare with the name of the standard group here to insert it
/*N*/         // first
/*N*/ 
/*N*/         if ( pNew->GetTitle() == maStandardGroup )
/*N*/             maRegions.Insert( pNew, (ULONG) 0 );
/*N*/         else
/*N*/             maRegions.Insert( pNew, nPos );
/*N*/     }
/*N*/ 
/*N*/     return ( pData == NULL );
/*N*/ }

// -----------------------------------------------------------------------
/*?*/ void SfxDocTemplate_Impl::Rescan()
/*?*/ {
/*?*/ 	Clear();
/*?*/ 
/*?*/ 	try
/*?*/ 	{
/*?*/ 		Reference< XDocumentTemplates > xTemplates = getDocTemplates();
/*?*/ 		DBG_ASSERT( xTemplates.is(), "SfxDocTemplate_Impl::Rescan:invalid template instance!" );
/*?*/ 		if ( xTemplates.is() )
/*?*/ 		{
/*?*/ 			xTemplates->update();
/*?*/ 
/*?*/ 			Reference < XContent > aRootContent = xTemplates->getContent();
/*?*/ 			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
/*?*/         {
/*?*/             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;
/*?*/ }


// -----------------------------------------------------------------------
/*N*/ void SfxDocTemplate_Impl::Clear()
/*N*/ {
/*N*/     RegionData_Impl *pRegData = maRegions.First();
/*N*/ 
/*N*/     while ( pRegData )
/*N*/     {
/*N*/         delete pRegData;
/*N*/         pRegData = maRegions.Next();
/*N*/     }
/*N*/ 
/*N*/     maRegions.Clear();
/*N*/ }

// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
/*N*/ sal_Bool getTextProperty_Impl( Content& rContent,
/*N*/                                const OUString& rPropName,
/*N*/                                OUString& rPropValue )
/*N*/ {
/*N*/     sal_Bool bGotProperty = sal_False;
/*N*/ 
/*N*/     // Get the property
/*N*/     try
/*N*/     {
/*N*/         Reference< XPropertySetInfo > aPropInfo = rContent.getProperties();
/*N*/ 
/*N*/         // check, wether or not the property exists
/*N*/         if ( !aPropInfo.is() || !aPropInfo->hasPropertyByName( rPropName ) )
/*N*/         {
/*N*/             return sal_False;
/*N*/         }
/*N*/ 
/*N*/         // now get the property
/*N*/         Any aAnyValue;
/*N*/ 
/*N*/         aAnyValue = rContent.getPropertyValue( rPropName );
/*N*/         aAnyValue >>= rPropValue;
/*N*/ 
/*N*/         bGotProperty = sal_True;
/*N*/     }
/*N*/     catch ( RuntimeException& ) {}
/*N*/     catch ( Exception& ) {}
/*N*/ 
/*N*/     return bGotProperty;
/*N*/ }

}
