 /*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: sfx2_sfxhelp.cxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: rt $ $Date: 2006/10/27 18:59:32 $
 *
 *  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 "sfxhelp.hxx"

#include <algorithm>

#ifndef _COM_SUN_STAR_UNO_REFERENCE_H_
#include <com/sun/star/uno/Reference.h>
#endif
#ifndef _COM_SUN_STAR_FRAME_XFRAME_HPP_
#include <com/sun/star/frame/XFrame.hpp>
#endif
#ifndef _UNOTOOLS_PROCESSFACTORY_HXX
#include <comphelper/processfactory.hxx>
#endif
#ifndef _COM_SUN_STAR_AWT_XWINDOW_HPP_
#include <com/sun/star/awt/XWindow.hpp>
#endif
#ifndef _COM_SUN_STAR_AWT_XTOPWINDOW_HPP_
#include <com/sun/star/awt/XTopWindow.hpp>
#endif
#ifndef _COM_SUN_STAR_AWT_POSSIZE_HPP_
#include <com/sun/star/awt/PosSize.hpp>
#endif
#ifndef _COM_SUN_STAR_FRAME_XFRAMESSUPPLIER_HPP_
#include <com/sun/star/frame/XFramesSupplier.hpp>
#endif
#ifndef _COM_SUN_STAR_UTIL_XURLTRANSFORMER_HPP_
#include <com/sun/star/util/XURLTransformer.hpp>
#endif
#ifndef _COM_SUN_STAR_FRAME_XDISPATCH_HPP_
#include <com/sun/star/frame/XDispatch.hpp>
#endif
#ifndef _COM_SUN_STAR_FRAME_XDISPATCHPROVIDER_HPP_
#include <com/sun/star/frame/XDispatchProvider.hpp>
#endif
#include <com/sun/star/frame/FrameSearchFlag.hpp>
#include <toolkit/helper/vclunohelper.hxx>

#ifndef _UTL_CONFIGMGR_HXX_
#include <unotools/configmgr.hxx>
#endif
#ifndef _UTL_CONFIGITEM_HXX_
#include <unotools/configitem.hxx>
#endif

#ifndef INCLUDED_SVTOOLS_HELPOPT_HXX
#include <svtools/helpopt.hxx>
#endif
#ifndef INCLUDED_SVTOOLS_MODULEOPTIONS_HXX
#include <svtools/moduleoptions.hxx>
#endif
#ifndef _URLOBJ_HXX
#include <tools/urlobj.hxx>
#endif
#ifndef _UTL_CONFIGMGR_HXX_
#include <unotools/configmgr.hxx>
#endif
#ifndef _UCBHELPER_CONTENT_HXX
#include <ucbhelper/content.hxx>
#endif

#include <svtools/pathoptions.hxx>
#include <rtl/ustring.hxx>
#include <osl/process.h>

#define _SVSTDARR_STRINGSDTOR
#define _SVSTDARR_ULONGSSORT
#include <svtools/svstdarr.hxx>

#include "sfxsids.hrc"
#include "app.hxx"
#include "viewfrm.hxx"
#include "msgpool.hxx"
#include "newhelp.hxx"
#include "objsh.hxx"
#include "docfac.hxx"
#include "sfxresid.hxx"
#include "helper.hxx"
#include "app.hrc"

#ifndef _LEGACYBINFILTERMGR_HXX
#include <legacysmgr/legacy_binfilters_smgr.hxx>	//STRIP002 
#endif

#ifndef _SFX_SFXUNO_HXX
#include <bf_sfx2/sfxuno.hxx>
#endif

#ifndef _WINDOW_HXX
#include <vcl/window.hxx>
#endif

namespace binfilter {

using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::frame;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::util;

#define ERROR_TAG	String( DEFINE_CONST_UNICODE("Error: ") )
#define PATH_TAG	String( DEFINE_CONST_UNICODE("\nPath: ") )

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

#define STARTERLIST 0

/*N*/ void AppendConfigToken_Impl( String& rURL, sal_Bool bQuestionMark )
/*N*/ {
/*N*/ 	// this completes a help url with the system parameters "Language" and "System"
/*N*/ 	// detect installed locale
/*N*/ 	Any aLocale =
/*N*/ 		::utl::ConfigManager::GetConfigManager()->GetDirectConfigProperty( ::utl::ConfigManager::LOCALE );
/*N*/     ::rtl::OUString aLocaleStr;
/*N*/ 	if ( !( aLocale >>= aLocaleStr ) )
/*N*/ 		// fallback is english
/*?*/ 		aLocaleStr = ::rtl::OUString( DEFINE_CONST_UNICODE("en") );
/*N*/ 
/*N*/ 	// query part exists?
/*N*/ 	if ( bQuestionMark )
/*N*/ 		// no, so start with '?'
/*N*/ 		rURL += '?';
/*N*/ 	else
/*N*/ 		// yes, so only append with '&'
/*?*/ 		rURL += '&';
/*N*/ 
/*N*/ 	// set parameters
/*N*/ 	rURL += DEFINE_CONST_UNICODE("Language=");
/*N*/ 	rURL += String( aLocaleStr );
/*N*/ 	rURL += DEFINE_CONST_UNICODE("&System=");
/*N*/ 	rURL += SvtHelpOptions().GetSystem();
/*N*/ }

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

/*N*/ sal_Bool GetHelpAnchor_Impl( const String& _rURL, String& _rAnchor )
/*N*/ {
/*N*/ 	sal_Bool bRet = sal_False;
/*N*/ 	::rtl::OUString sAnchor;
/*N*/ 
/*N*/ 	try
/*N*/ 	{
/*N*/ 		::ucb::Content aCnt( INetURLObject( _rURL ).GetMainURL( INetURLObject::NO_DECODE ),
/*N*/ 							 Reference< ::com::sun::star::ucb::XCommandEnvironment > () );
/*N*/ 		if ( ( aCnt.getPropertyValue( ::rtl::OUString::createFromAscii( "AnchorName" ) ) >>= sAnchor ) )
/*N*/ 		{
/*N*/ 
/*N*/ 			if ( sAnchor.getLength() > 0 )
/*N*/ 			{
/*N*/ 				_rAnchor = String( sAnchor );
/*N*/ 				bRet = sal_True;
/*N*/ 			}
/*N*/ 		}
/*N*/ 		else
/*N*/ 		{
/*N*/ 			DBG_ERRORFILE( "Property 'AnchorName' is missing" );
/*N*/ 		}
/*N*/ 	}
/*N*/ 	catch( ::com::sun::star::uno::Exception& )
/*N*/ 	{
/*N*/ 	}
/*N*/ 
/*N*/ 	return bRet;
/*N*/ }

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

class SfxHelpOptions_Impl : public ::utl::ConfigItem
{
private:
    SvULongsSort*   m_pIds;

public:
                    SfxHelpOptions_Impl();
                    ~SfxHelpOptions_Impl();

    BOOL            HasId( ULONG nId ) { USHORT nDummy; return m_pIds ? m_pIds->Seek_Entry( nId, &nDummy ) : FALSE; }
};

/*N*/ static Sequence< ::rtl::OUString > GetPropertyNames()
/*N*/ {
/*N*/ 	static const char* aPropNames[] =
/*N*/ 	{
/*N*/         "HelpAgentStarterList",
/*N*/ 	};
/*N*/ 
/*N*/     const int nCount = sizeof( aPropNames ) / sizeof( const char* );
/*N*/ 	Sequence< ::rtl::OUString > aNames( nCount );
/*N*/ 	::rtl::OUString* pNames = aNames.getArray();
/*N*/ 	::rtl::OUString* pEnd	= pNames + aNames.getLength();
/*N*/ 	int i = 0;
/*N*/ 	for ( ; pNames != pEnd; ++pNames )
/*N*/ 		*pNames = ::rtl::OUString::createFromAscii( aPropNames[i++] );
/*N*/ 
/*N*/ 	return aNames;
/*N*/ }

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

/*N*/ SfxHelpOptions_Impl::SfxHelpOptions_Impl()
/*N*/     : ConfigItem( ::rtl::OUString::createFromAscii("Office.SFX/Help") )
/*N*/     , m_pIds( NULL )
/*N*/ {
/*N*/ 	Sequence< ::rtl::OUString > aNames = GetPropertyNames();
/*N*/ 	Sequence< Any > aValues = GetProperties( aNames );
/*N*/ 	EnableNotification( aNames );
/*N*/ 	const Any* pValues = aValues.getConstArray();
/*N*/ 	DBG_ASSERT( aValues.getLength() == aNames.getLength(), "GetProperties failed" );
/*N*/ 	if ( aValues.getLength() == aNames.getLength() )
/*N*/ 	{
/*N*/ 		for ( int nProp = 0; nProp < aNames.getLength(); nProp++ )
/*N*/ 		{
/*N*/ 			DBG_ASSERT( pValues[nProp].hasValue(), "property value missing" );
/*N*/ 			if ( pValues[nProp].hasValue() )
/*N*/ 			{
/*N*/ 				switch ( nProp )
/*N*/ 				{
/*N*/                     case STARTERLIST :
/*N*/                     {
/*N*/                         ::rtl::OUString aCodedList;
/*N*/                         if ( pValues[nProp] >>= aCodedList )
/*N*/                         {
/*N*/                             String aTmp( aCodedList );
/*N*/                             USHORT nCount = aTmp.GetTokenCount( ',' );
/*N*/                             m_pIds = new SvULongsSort();
/*N*/                             for ( USHORT n=0; n<nCount; n++ )
/*N*/                                 m_pIds->Insert( (ULONG) aTmp.GetToken( n, ',' ).ToInt64() );
/*N*/                         }
/*N*/                         else
/*N*/                             DBG_ERRORFILE( "Wrong property type!" );
/*N*/ 
/*N*/                         break;
/*N*/                     }
/*N*/ 
/*N*/ 					default:
/*N*/                         DBG_ERRORFILE( "Wrong property!" );
/*N*/                         break;
/*N*/ 				}
/*N*/ 			}
/*N*/ 		}
/*N*/ 	}
/*N*/ }

/*N*/ SfxHelpOptions_Impl::~SfxHelpOptions_Impl()
/*N*/ {
/*N*/     delete m_pIds;
/*N*/ }

// class SfxHelp_Impl ----------------------------------------------------

class SfxHelp_Impl
{
private:
	sal_Bool							m_bIsDebug;		// environment variable "help_debug=1"
    SfxHelpOptions_Impl*				m_pOpt;			// the options
	::std::vector< ::rtl::OUString >	m_aModulesList;	// list of all installed modules
	void					Load();

public:
    SfxHelp_Impl( sal_Bool bDebug );
    ~SfxHelp_Impl();

    SfxHelpOptions_Impl*	GetOptions();
	String					GetHelpText( ULONG nHelpId, const String& rModule );	// get "Active Help"
	sal_Bool				HasModule( const ::rtl::OUString& rModule );			// module installed
	sal_Bool				IsHelpInstalled();										// module list not empty
};

/*N*/ SfxHelp_Impl::SfxHelp_Impl( sal_Bool bDebug ) :
/*N*/ 
/*N*/ 	m_bIsDebug		( bDebug ),
/*N*/     m_pOpt      	( NULL )
/*N*/ 
/*N*/ {
}

SfxHelp_Impl::~SfxHelp_Impl()
{
    delete m_pOpt;
}

void SfxHelp_Impl::Load()
{
/*N*/ 	// fill modules list
/*N*/ 	// create the help url (empty, without module and helpid)
/*N*/ 	String sHelpURL( DEFINE_CONST_UNICODE("vnd.sun.star.help://") );
/*N*/ 	AppendConfigToken_Impl( sHelpURL, sal_True );
/*N*/ 	// open ucb content and get the list of the help modules
/*N*/ 	// the list contains strings with three tokens "ui title \t type \t url"
/*N*/ 	Sequence< ::rtl::OUString > aAllModulesList = SfxContentHelper::GetResultSet( sHelpURL );
/*N*/ 	sal_Int32 nLen = aAllModulesList.getLength();
/*N*/ 	m_aModulesList.reserve( nLen + 1 );
/*N*/ 	const ::rtl::OUString* pBegin = aAllModulesList.getConstArray();
/*N*/ 	const ::rtl::OUString* pEnd	= pBegin + nLen;
/*N*/ 	for ( ; pBegin != pEnd; ++pBegin )
/*N*/ 	{
/*N*/ 		// get one module string
/*N*/ 		String sModule( *pBegin );
/*N*/ 		// extract the url
/*N*/ 		String sURL = sModule.GetToken( 2, '\t' );
/*N*/ 		// insert the module (the host part of the "vnd.sun.star.help" url)
/*N*/ 		m_aModulesList.push_back( ::rtl::OUString( INetURLObject( sURL ).GetHost() ) );
/*N*/ 	}
/*N*/ }

/*N*/ String SfxHelp_Impl::GetHelpText( ULONG nHelpId, const String& rModule )
/*N*/ {
/*N*/ 	// create help url
/*N*/     String aHelpURL = SfxHelp::CreateHelpURL( nHelpId, rModule );
/*N*/ 	// added 'active' parameter
/*N*/ 	aHelpURL.Insert( String( DEFINE_CONST_UNICODE("&Active=true") ), aHelpURL.SearchBackward( '#' ) );
/*N*/ 	// load help string
/*N*/ 	return SfxContentHelper::GetActiveHelpString( aHelpURL );
/*N*/ }

/*N*/ SfxHelpOptions_Impl* SfxHelp_Impl::GetOptions()
/*N*/ {
/*N*/ 	// create if not exists
/*N*/     if ( !m_pOpt )
/*N*/         m_pOpt = new SfxHelpOptions_Impl;
/*N*/     return m_pOpt;
/*N*/ }

/*N*/ sal_Bool SfxHelp_Impl::HasModule( const ::rtl::OUString& rModule )
/*N*/ {
/*N*/ 	if ( !m_aModulesList.size() )
/*N*/ 		Load();
/*N*/ 	return ( ::std::find( m_aModulesList.begin(), m_aModulesList.end(), rModule ) != m_aModulesList.end() );
/*N*/ }

/*N*/ sal_Bool SfxHelp_Impl::IsHelpInstalled()
/*N*/ {
/*N*/ 	if ( !m_aModulesList.size() )
/*N*/ 		Load();
/*N*/ 	return ( m_aModulesList.begin() != m_aModulesList.end() );
/*N*/ }

// class SfxHelp ---------------------------------------------------------

/*N*/ SfxHelp::SfxHelp() :
/*N*/ 
/*N*/ 	bIsDebug( sal_False ),
/*N*/     pImp	( NULL )
/*N*/ 
/*N*/ {
/*N*/ 	// read the environment variable "HELP_DEBUG"
/*N*/ 	// if it's set, you will see debug output on active help
/*N*/ 	{
/*N*/ 		::rtl::OUString sHelpDebug;
/*N*/ 		::rtl::OUString sEnvVarName( RTL_CONSTASCII_USTRINGPARAM( "HELP_DEBUG" ) );
/*N*/ 		osl_getEnvironment( sEnvVarName.pData, &sHelpDebug.pData );
/*N*/ 		bIsDebug = ( 0 != sHelpDebug.getLength() );
/*N*/ 	}
/*N*/ 
/*N*/ 	pImp = new SfxHelp_Impl( bIsDebug );
/*N*/ 
/*N*/     Any aLocale =
/*N*/ 		::utl::ConfigManager::GetConfigManager()->GetDirectConfigProperty( ::utl::ConfigManager::LOCALE );
/*N*/     ::rtl::OUString aLocaleStr;
/*N*/     if ( !( aLocale >>= aLocaleStr ) )
/*?*/         aLocaleStr = ::rtl::OUString( DEFINE_CONST_UNICODE("en") );
/*N*/     sal_Int32 nSepPos = aLocaleStr.indexOf( '_' );
/*N*/     if ( nSepPos != -1 )
/*N*/     {
/*?*/         aLanguageStr = aLocaleStr.copy( 0, nSepPos );
/*?*/         aCountryStr = aLocaleStr.copy( nSepPos+1 );
/*N*/     }
/*N*/     else
/*N*/     {
/*N*/         nSepPos = aLocaleStr.indexOf( '-' );
/*N*/         if ( nSepPos != -1 )
/*N*/         {
/*N*/             aLanguageStr = aLocaleStr.copy( 0, nSepPos );
/*N*/             aCountryStr = aLocaleStr.copy( nSepPos+1 );
/*N*/         }
/*N*/         else
/*N*/         {
/*?*/             aLanguageStr = aLocaleStr;
/*N*/         }
/*N*/     }
/*N*/ }

/*N*/ SfxHelp::~SfxHelp()
/*N*/ {
/*N*/     delete pImp;
/*N*/ }

/*N*/ String GetFactoryName_Impl( const SfxViewFrame* pFrame )
/*N*/ {
/*N*/ 	// module name == short name of the factory (e.g. "swriter", "scalc",...)
/*N*/ 	String aName = String::CreateFromAscii( pFrame->GetObjectShell()->GetFactory().GetShortName() );
/*N*/ 	// cut sub factory, if exists (e.g. "swriter/web")
/*N*/ 	xub_StrLen nPos = aName.Search( '/' );
/*N*/ 	if ( nPos != STRING_NOTFOUND )
/*?*/ 		aName.Erase( nPos );
/*N*/ 	return aName;
/*N*/ }

/*N*/ String SfxHelp::GetHelpModuleName_Impl( ULONG nHelpId )
/*N*/ {
/*N*/     String aModuleName;
/*N*/     SfxViewFrame* pViewFrame = SfxViewFrame::Current();
/*N*/ 	if ( pViewFrame )
/*N*/ 	{
/*N*/ 	    SfxViewFrame* pParentViewFrame = pViewFrame->GetParentViewFrame_Impl();
/*N*/ 
/*N*/ 		// Wenn es ein Slot ist, kann es sein, da\s internes InPlace vorliegt
/*N*/ 		// und eine Container-SlotId gefragt ist
/*N*/ 		if ( nHelpId >= (ULONG) SID_SFX_START && nHelpId <= (ULONG) SHRT_MAX && pParentViewFrame )
/*N*/ 		{
/*N*/ 			// Ist es ein ContainerSlot ?
/*?*/             const SfxSlot* pSlot = SFX_APP()->GetSlotPool(pViewFrame).GetSlot( (USHORT) nHelpId );
/*?*/ 			if ( !pSlot || pSlot->IsMode( SFX_SLOT_CONTAINER ) )
/*?*/ 				pViewFrame = pParentViewFrame;
/*N*/ 		}
/*N*/ 
/*N*/ 		if ( pViewFrame->GetObjectShell() )
/*N*/ 		{
/*N*/             aModuleName = GetFactoryName_Impl( pViewFrame );
/*N*/ 			// help for module installed? If help isn't installed, module search will be disabled.
/*N*/ 			sal_Bool bHasModule = pImp->IsHelpInstalled() ? pImp->HasModule( aModuleName ) : sal_True;
/*N*/ 			// if not, search through the shell hierachy for an installed module
/*N*/ 			while ( !bHasModule && pParentViewFrame && pParentViewFrame->GetObjectShell() )
/*N*/ 			{
/*?*/ 	            aModuleName = GetFactoryName_Impl( pParentViewFrame );
/*?*/ 				bHasModule = pImp->HasModule( aModuleName );
/*?*/ 				pParentViewFrame = pParentViewFrame->GetParentViewFrame_Impl();
/*N*/ 			}
/*N*/ 		}
/*N*/ 	}
/*N*/ 
/*N*/ 	return aModuleName;
/*N*/ }

/*N*/ String SfxHelp::CreateHelpURL_Impl( ULONG nHelpId, const String& rModuleName )
/*N*/ {
/*N*/ 	String aModuleName( rModuleName );
/*N*/ 	if ( aModuleName.Len() == 0 )
/*N*/ 	{
/*N*/ 		// no active module (quicklaunch?) -> detect default module
/*N*/ 		SvtModuleOptions aModOpt;
/*N*/         if ( aModOpt.IsModuleInstalled( SvtModuleOptions::E_SWRITER ) )
/*?*/ 			aModuleName = DEFINE_CONST_UNICODE("swriter");
/*?*/         else if ( aModOpt.IsModuleInstalled( SvtModuleOptions::E_SCALC ) )
/*?*/ 			aModuleName = DEFINE_CONST_UNICODE("scalc");
/*?*/         else if ( aModOpt.IsModuleInstalled( SvtModuleOptions::E_SIMPRESS ) )
/*?*/ 			aModuleName = DEFINE_CONST_UNICODE("simpress");
/*?*/         else if ( aModOpt.IsModuleInstalled( SvtModuleOptions::E_SDRAW ) )
/*?*/ 			aModuleName = DEFINE_CONST_UNICODE("sdraw");
/*?*/         else if ( aModOpt.IsModuleInstalled( SvtModuleOptions::E_SMATH ) )
/*?*/ 			aModuleName = DEFINE_CONST_UNICODE("smath");
/*?*/         else if ( aModOpt.IsModuleInstalled( SvtModuleOptions::E_SCHART ) )
/*?*/ 			aModuleName = DEFINE_CONST_UNICODE("schart");
/*?*/         else if ( aModOpt.IsModuleInstalled( SvtModuleOptions::E_SBASIC ) )
/*?*/ 			aModuleName = DEFINE_CONST_UNICODE("sbasic");
/*N*/ 		else
/*N*/ 		{
/*N*/ 			DBG_ERRORFILE( "no installed module found" );
/*N*/ 		}
/*N*/ 	}
/*N*/ 
/*N*/ 	// build up the help URL
/*N*/     String aHelpURL;
/*N*/     if ( aTicket.Len() )
/*N*/     {
/*N*/         // if there is a ticket, we are inside a plugin, so a special Help URL must be sent
/*?*/         aHelpURL = DEFINE_CONST_UNICODE("vnd.sun.star.cmd:help?");
/*?*/         aHelpURL += DEFINE_CONST_UNICODE("HELP_Request_Mode=contextIndex&HELP_Session_Mode=context&HELP_CallMode=portal&HELP_Device=html");
/*?*/ 
/*?*/         if ( !nHelpId )
/*?*/         {
/*?*/ 			// no help id -> start page
/*?*/             aHelpURL += DEFINE_CONST_UNICODE("&HELP_ContextID=start");
/*?*/         }
/*?*/         else
/*?*/         {
/*?*/             aHelpURL += DEFINE_CONST_UNICODE("&HELP_ContextID=");
/*?*/             aHelpURL += String::CreateFromInt64( nHelpId );
/*?*/         }
/*?*/ 
/*?*/         aHelpURL += DEFINE_CONST_UNICODE("&HELP_ProgramID=");
/*?*/         aHelpURL += aModuleName;
/*?*/         aHelpURL += DEFINE_CONST_UNICODE("&HELP_User=");
/*?*/         aHelpURL += aUser;
/*?*/         aHelpURL += DEFINE_CONST_UNICODE("&HELP_Ticket=");
/*?*/         aHelpURL += aTicket;
/*?*/         aHelpURL += DEFINE_CONST_UNICODE("&HELP_Language=");
/*?*/         aHelpURL += aLanguageStr;
/*?*/         if ( aCountryStr.Len() )
/*?*/         {
/*?*/             aHelpURL += DEFINE_CONST_UNICODE("&HELP_Country=");
/*?*/             aHelpURL += aCountryStr;
/*?*/         }
/*N*/     }
/*N*/     else
/*N*/     {
/*N*/ 		sal_Bool bHasAnchor = sal_False;
/*N*/ 		String aAnchor;
/*N*/         aHelpURL = String::CreateFromAscii("vnd.sun.star.help://");
/*N*/         aHelpURL += aModuleName;
/*N*/ 
/*N*/         if ( !nHelpId )
/*N*/             aHelpURL += String::CreateFromAscii("/start");
/*N*/         else
/*N*/         {
/*N*/             aHelpURL += '/';
/*N*/             aHelpURL += String::CreateFromInt64( nHelpId );
/*N*/ 
/*N*/ 			String aTempURL = aHelpURL;
/*N*/ 	        AppendConfigToken_Impl( aTempURL, sal_True );
/*N*/ 			bHasAnchor = GetHelpAnchor_Impl( aTempURL, aAnchor );
/*N*/ 		}
/*N*/ 
/*N*/         AppendConfigToken_Impl( aHelpURL, sal_True );
/*N*/ 
/*N*/ 		if ( bHasAnchor )
/*N*/ 		{
/*N*/ 			aHelpURL += '#';
/*N*/ 			aHelpURL += aAnchor;
/*N*/ 		}
/*N*/     }
/*N*/ 
/*N*/     return aHelpURL;
/*N*/ }

/*?*/ BOOL SfxHelp::Start( const String& rURL, const Window* pWindow )
/*?*/ {DBG_BF_ASSERT(0, "STRIP"); return FALSE;//STRIP001 
/*?*/ }

/*?*/ BOOL SfxHelp::Start( ULONG nHelpId, const Window* pWindow )
/*?*/ {DBG_BF_ASSERT(0, "STRIP"); return FALSE;//STRIP001 
/*?*/ }

/*N*/ XubString SfxHelp::GetHelpText( ULONG nHelpId, const Window* pWindow )
/*N*/ {
/*N*/ 	String aModuleName = GetHelpModuleName_Impl( nHelpId );
/*N*/     String aHelpText = pImp->GetHelpText( nHelpId, aModuleName );
/*N*/ 	ULONG nNewHelpId = 0;
/*N*/ 
/*N*/ 	if ( pWindow && aHelpText.Len() == 0 )
/*N*/ 	{
/*N*/ 		// no help text found -> try with parent help id.
/*N*/ 		Window* pParent = pWindow->GetParent();
/*N*/ 		while ( pParent )
/*N*/ 		{
/*N*/ 			nNewHelpId = pParent->GetHelpId();
/*N*/ 			aHelpText = pImp->GetHelpText( nNewHelpId, aModuleName );
/*N*/ 
/*N*/ 			if ( aHelpText.Len() > 0 )
/*?*/ 				pParent = NULL;
/*N*/ 			else
/*N*/ 				pParent = pParent->GetParent();
/*N*/ 		}
/*N*/ 
/*N*/ 		if ( bIsDebug && aHelpText.Len() == 0 )
/*?*/ 			nNewHelpId = 0;
/*N*/ 	}
/*N*/ 
/*N*/ 	if ( bIsDebug )
/*N*/ 	{
/*?*/ 		aHelpText += DEFINE_CONST_UNICODE("\n\n");
/*?*/ 		aHelpText += aModuleName;
/*?*/ 		aHelpText += DEFINE_CONST_UNICODE(" - ");
/*?*/ 		aHelpText += String::CreateFromInt64( nHelpId );
/*?*/ 		if ( nNewHelpId )
/*?*/ 		{
/*?*/ 			aHelpText += DEFINE_CONST_UNICODE(" - ");
/*?*/ 			aHelpText += String::CreateFromInt64( nNewHelpId );
/*N*/ 		}
/*N*/ 	}
/*N*/ 
/*N*/ 	return aHelpText;
/*N*/ }

/*N*/ String SfxHelp::CreateHelpURL( ULONG nHelpId, const String& rModuleName )
/*N*/ {
/*N*/ 	String aURL;
/*N*/ 	SfxHelp* pHelp = SAL_STATIC_CAST( SfxHelp*, Application::GetHelp() );
/*N*/ 	if ( pHelp )
/*N*/ 		aURL = pHelp->CreateHelpURL_Impl( nHelpId, rModuleName );
/*N*/ 	return aURL;
/*N*/ }

/*N*/ void SfxHelp::OpenHelpAgent( SfxFrame *pFrame, ULONG nHelpId )
/*N*/ {
/*N*/ 	if ( SvtHelpOptions().IsHelpAgentAutoStartMode() )
/*N*/ 	{
/*N*/ 		SfxHelp* pHelp = SAL_STATIC_CAST( SfxHelp*, Application::GetHelp() );
/*N*/ 		if ( pHelp )
/*N*/ 		{
/*N*/ 			SfxHelpOptions_Impl *pOpt = pHelp->pImp->GetOptions();
/*N*/     		if ( !pOpt->HasId( nHelpId ) )
/*N*/         		return;
/*N*/ 
/*N*/ 			try
/*N*/ 			{
/*?*/ 				URL aURL;
/*?*/         		aURL.Complete = pHelp->CreateHelpURL_Impl( nHelpId, pHelp->GetHelpModuleName_Impl( nHelpId ) );
/*?*/         		Reference < XURLTransformer > xTrans( ::legacy_binfilters::getLegacyProcessServiceFactory()->createInstance(
/*?*/ 					::rtl::OUString::createFromAscii("com.sun.star.util.URLTransformer" ) ), UNO_QUERY );
/*?*/         		xTrans->parseStrict(aURL);
/*?*/ 
/*?*/         		Reference< XDispatchProvider > xDispProv( pFrame->GetTopFrame()->GetFrameInterface(), UNO_QUERY );
/*?*/ 				Reference< XDispatch > xHelpDispatch;
/*?*/ 				if ( xDispProv.is() )
/*?*/ 					xHelpDispatch = xDispProv->queryDispatch(
/*?*/ 						aURL, ::rtl::OUString::createFromAscii("_helpagent"),
/*?*/ 						FrameSearchFlag::PARENT | FrameSearchFlag::SELF );
/*?*/ 
/*?*/         		DBG_ASSERT( xHelpDispatch.is(), "OpenHelpAgent: could not get a dispatcher!" );
/*?*/ 				if ( xHelpDispatch.is() )
/*?*/ 					xHelpDispatch->dispatch( aURL, Sequence< PropertyValue >() );
/*N*/ 			}
/*N*/ 			catch( const Exception& )
/*N*/ 			{
/*N*/         		DBG_ERRORFILE( "OpenHelpAgent: caught an exception while executing the dispatch!" );
/*N*/ 			}
/*N*/ 		}
/*N*/ 	}
/*N*/ }

}
