LCOV - code coverage report
Current view: top level - libreoffice/sfx2/source/appl - sfxhelp.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 91 371 24.5 %
Date: 2012-12-27 Functions: 11 37 29.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include "sfx2/sfxhelp.hxx"
      21             : 
      22             : #include <set>
      23             : #include <algorithm>
      24             : #include <com/sun/star/uno/Reference.h>
      25             : #include <com/sun/star/frame/Desktop.hpp>
      26             : #include <com/sun/star/frame/XFrame.hpp>
      27             : #include <com/sun/star/frame/XComponentLoader.hpp>
      28             : #include <com/sun/star/lang/XComponent.hpp>
      29             : #include <comphelper/processfactory.hxx>
      30             : #include <com/sun/star/awt/XWindow.hpp>
      31             : #include <com/sun/star/awt/XTopWindow.hpp>
      32             : #include <com/sun/star/awt/PosSize.hpp>
      33             : #include <com/sun/star/frame/XDesktop.hpp>
      34             : #include <com/sun/star/util/URLTransformer.hpp>
      35             : #include <com/sun/star/util/XURLTransformer.hpp>
      36             : #include <com/sun/star/frame/XDispatch.hpp>
      37             : #include <com/sun/star/frame/XDispatchProvider.hpp>
      38             : #include <com/sun/star/beans/XPropertySet.hpp>
      39             : #include <com/sun/star/frame/FrameSearchFlag.hpp>
      40             : #include <toolkit/helper/vclunohelper.hxx>
      41             : #include <com/sun/star/frame/ModuleManager.hpp>
      42             : #include <com/sun/star/system/SystemShellExecute.hpp>
      43             : #include <com/sun/star/system/SystemShellExecuteFlags.hpp>
      44             : #include <unotools/configmgr.hxx>
      45             : #include <unotools/configitem.hxx>
      46             : #include <svtools/helpopt.hxx>
      47             : #include <unotools/moduleoptions.hxx>
      48             : #include <tools/urlobj.hxx>
      49             : #include <ucbhelper/content.hxx>
      50             : #include <unotools/pathoptions.hxx>
      51             : #include <rtl/ustring.hxx>
      52             : #include <osl/process.h>
      53             : #include <osl/file.hxx>
      54             : #include <unotools/bootstrap.hxx>
      55             : #include <rtl/uri.hxx>
      56             : #include <vcl/msgbox.hxx>
      57             : #include <svtools/ehdl.hxx>
      58             : #include <svtools/sfxecode.hxx>
      59             : 
      60             : #include "newhelp.hxx"
      61             : #include <sfx2/objsh.hxx>
      62             : #include <sfx2/docfac.hxx>
      63             : #include "sfx2/sfxresid.hxx"
      64             : #include "helper.hxx"
      65             : #include "app.hrc"
      66             : #include <sfx2/sfxuno.hxx>
      67             : #include <vcl/svapp.hxx>
      68             : #include <sfx2/frame.hxx>
      69             : #include <rtl/strbuf.hxx>
      70             : #include <rtl/string.hxx>
      71             : 
      72             : using namespace ::com::sun::star::beans;
      73             : using namespace ::com::sun::star::frame;
      74             : using namespace ::com::sun::star::uno;
      75             : using namespace ::com::sun::star::util;
      76             : using namespace ::com::sun::star::frame;
      77             : using namespace ::com::sun::star::lang;
      78             : using namespace ::com::sun::star::system;
      79             : 
      80           0 : class NoHelpErrorBox : public ErrorBox
      81             : {
      82             : public:
      83             :     NoHelpErrorBox( Window* _pParent );
      84             : 
      85             :     virtual void    RequestHelp( const HelpEvent& rHEvt );
      86             : };
      87             : 
      88           0 : NoHelpErrorBox::NoHelpErrorBox( Window* _pParent ) :
      89             : 
      90           0 :     ErrorBox( _pParent, WB_OK, SfxResId( RID_STR_HLPFILENOTEXIST ).toString() )
      91             : {
      92             :     // Error message: "No help available"
      93           0 : }
      94             : 
      95           0 : void NoHelpErrorBox::RequestHelp( const HelpEvent& )
      96             : {
      97             :     // do nothing, because no help available
      98           0 : }
      99             : 
     100             : #define STARTERLIST 0
     101             : 
     102             : static bool impl_hasHelpInstalled( const OUString &rLang );
     103             : 
     104             : /// Return the locale we prefer for displaying help
     105          19 : static OUString HelpLocaleString()
     106             : {
     107          19 :     static OUString aLocaleStr;
     108          19 :     if (aLocaleStr.isEmpty())
     109             :     {
     110          19 :         const OUString aEnglish( "en"  );
     111             :         // detect installed locale
     112          19 :         aLocaleStr = utl::ConfigManager::getLocale();
     113          19 :         bool bOk = !aLocaleStr.isEmpty();
     114          19 :         if ( !bOk )
     115          19 :             aLocaleStr = aEnglish;
     116             :         else
     117             :         {
     118           0 :             OUString aBaseInstallPath;
     119           0 :             utl::Bootstrap::locateBaseInstallation(aBaseInstallPath);
     120             :             static const char *szHelpPath = "/help/";
     121             : 
     122             :             OUString sHelpPath = aBaseInstallPath +
     123           0 :                 OUString::createFromAscii(szHelpPath) + aLocaleStr;
     124           0 :             osl::DirectoryItem aDirItem;
     125             : 
     126           0 :             if (!osl::DirectoryItem::get(sHelpPath, aDirItem) == osl::FileBase::E_None)
     127             :             {
     128           0 :                 bOk = false;
     129           0 :                 String sLang(aLocaleStr);
     130           0 :                 xub_StrLen nSepPos = sLang.Search( '-' );
     131           0 :                 if (nSepPos != STRING_NOTFOUND)
     132             :                 {
     133           0 :                     bOk = true;
     134           0 :                     sLang = sLang.Copy( 0, nSepPos );
     135             :                     sHelpPath = aBaseInstallPath +
     136           0 :                         OUString::createFromAscii(szHelpPath) + sLang;
     137           0 :                     if (!osl::DirectoryItem::get(sHelpPath, aDirItem) == osl::FileBase::E_None)
     138           0 :                         bOk = false;
     139           0 :                 }
     140           0 :             }
     141             :         }
     142             :         // if not OK, and not even English installed, we use online help, and
     143             :         // have to preserve the full locale name
     144          19 :         if ( !bOk && impl_hasHelpInstalled( aEnglish ) )
     145           0 :             aLocaleStr = aEnglish;
     146             :     }
     147          19 :     return aLocaleStr;
     148             : }
     149             : 
     150          19 : void AppendConfigToken( OUStringBuffer& rURL, sal_Bool bQuestionMark, const OUString &rLang )
     151             : {
     152          19 :     OUString aLocaleStr( rLang );
     153          19 :     if ( aLocaleStr.isEmpty() )
     154           0 :         aLocaleStr = HelpLocaleString();
     155             : 
     156             :     // query part exists?
     157          19 :     if ( bQuestionMark )
     158             :         // no, so start with '?'
     159          19 :         rURL.append('?');
     160             :     else
     161             :         // yes, so only append with '&'
     162           0 :         rURL.append('&');
     163             : 
     164             :     // set parameters
     165          19 :     rURL.append("Language=");
     166          19 :     rURL.append(aLocaleStr);
     167          19 :     rURL.append("&System=");
     168          19 :     rURL.append(SvtHelpOptions().GetSystem());
     169          19 :     rURL.append("&Version=");
     170          19 :     rURL.append(utl::ConfigManager::getProductVersion());
     171          19 : }
     172             : 
     173           0 : sal_Bool GetHelpAnchor_Impl( const OUString& _rURL, OUString& _rAnchor )
     174             : {
     175           0 :     sal_Bool bRet = sal_False;
     176           0 :     OUString sAnchor;
     177             : 
     178             :     try
     179             :     {
     180             :         ::ucbhelper::Content aCnt( INetURLObject( _rURL ).GetMainURL( INetURLObject::NO_DECODE ),
     181             :                              Reference< ::com::sun::star::ucb::XCommandEnvironment >(),
     182           0 :                              comphelper::getProcessComponentContext() );
     183           0 :         if ( ( aCnt.getPropertyValue( OUString("AnchorName") ) >>= sAnchor ) )
     184             :         {
     185             : 
     186           0 :             if ( !sAnchor.isEmpty() )
     187             :             {
     188           0 :                 _rAnchor = String( sAnchor );
     189           0 :                 bRet = sal_True;
     190             :             }
     191             :         }
     192             :         else
     193             :         {
     194             :             SAL_WARN( "sfx2.appl", "Property 'AnchorName' is missing" );
     195           0 :         }
     196             :     }
     197           0 :     catch (const ::com::sun::star::uno::Exception&)
     198             :     {
     199             :     }
     200             : 
     201           0 :     return bRet;
     202             : }
     203             : 
     204             : class SfxHelpOptions_Impl : public utl::ConfigItem
     205             : {
     206             : private:
     207             :     std::set < OString > m_aIds;
     208             : 
     209             : public:
     210             :                     SfxHelpOptions_Impl();
     211             :                     ~SfxHelpOptions_Impl();
     212             : 
     213         143 :     bool            HasId( const OString& rId ) { return m_aIds.size() ? m_aIds.find( rId ) != m_aIds.end() : false; }
     214             :     virtual void            Notify( const com::sun::star::uno::Sequence< OUString >& aPropertyNames );
     215             :     virtual void            Commit();
     216             : };
     217             : 
     218           8 : static Sequence< OUString > GetPropertyNames()
     219             : {
     220             :     static const char* aPropNames[] =
     221             :     {
     222             :         "HelpAgentStarterList",
     223             :     };
     224             : 
     225           8 :     const int nCount = sizeof( aPropNames ) / sizeof( const char* );
     226           8 :     Sequence< OUString > aNames( nCount );
     227           8 :     OUString* pNames = aNames.getArray();
     228           8 :     OUString* pEnd   = pNames + aNames.getLength();
     229           8 :     int i = 0;
     230          16 :     for ( ; pNames != pEnd; ++pNames )
     231           8 :         *pNames = OUString::createFromAscii( aPropNames[i++] );
     232             : 
     233           8 :     return aNames;
     234             : }
     235             : 
     236           8 : SfxHelpOptions_Impl::SfxHelpOptions_Impl()
     237           8 :     : ConfigItem( OUString("Office.SFX/Help") )
     238             : {
     239           8 :     Sequence< OUString > aNames = GetPropertyNames();
     240           8 :     Sequence< Any > aValues = GetProperties( aNames );
     241           8 :     EnableNotification( aNames );
     242           8 :     const Any* pValues = aValues.getConstArray();
     243             :     DBG_ASSERT( aValues.getLength() == aNames.getLength(), "GetProperties failed" );
     244           8 :     if ( aValues.getLength() == aNames.getLength() )
     245             :     {
     246          16 :         for ( int nProp = 0; nProp < aNames.getLength(); nProp++ )
     247             :         {
     248             :             DBG_ASSERT( pValues[nProp].hasValue(), "property value missing" );
     249           8 :             if ( pValues[nProp].hasValue() )
     250             :             {
     251           8 :                 switch ( nProp )
     252             :                 {
     253             :                     case STARTERLIST :
     254             :                     {
     255           8 :                         OUString aCodedList;
     256           8 :                         if ( pValues[nProp] >>= aCodedList )
     257             :                         {
     258             :                             OString aTmp(
     259             :                                 OUStringToOString(
     260           8 :                                     aCodedList, RTL_TEXTENCODING_UTF8));
     261           8 :                             sal_Int32 nIndex = 0;
     262         592 :                             do
     263             :                             {
     264         592 :                                 OString aToken = aTmp.getToken( 0, ',', nIndex );
     265         592 :                                 if ( !aToken.isEmpty() )
     266         592 :                                     m_aIds.insert( aToken );
     267             :                             }
     268           8 :                             while ( nIndex >= 0 );
     269             :                         }
     270             :                         else {
     271             :                             SAL_WARN( "sfx2.appl", "Wrong property type!" );
     272             :                         }
     273             : 
     274           8 :                         break;
     275             :                     }
     276             : 
     277             :                     default:
     278             :                         SAL_WARN( "sfx2.appl", "Wrong property!" );
     279           0 :                         break;
     280             :                 }
     281             :             }
     282             :         }
     283           8 :     }
     284           8 : }
     285             : 
     286           0 : SfxHelpOptions_Impl::~SfxHelpOptions_Impl()
     287             : {
     288           0 : }
     289             : 
     290             : 
     291           0 : void SfxHelpOptions_Impl::Notify( const com::sun::star::uno::Sequence< OUString >& )
     292             : {
     293           0 : }
     294             : 
     295           0 : void SfxHelpOptions_Impl::Commit()
     296             : {
     297           0 : }
     298             : 
     299             : class SfxHelp_Impl
     300             : {
     301             : private:
     302             :     SfxHelpOptions_Impl*                m_pOpt;         // the options
     303             :     ::std::vector< OUString >    m_aModulesList; // list of all installed modules
     304             : 
     305             : public:
     306             :     SfxHelp_Impl();
     307             :     ~SfxHelp_Impl();
     308             : 
     309             :     SfxHelpOptions_Impl*    GetOptions();
     310             :     static String           GetHelpText( const OUString& aCommandURL, const String& rModule );
     311             : };
     312             : 
     313          19 : SfxHelp_Impl::SfxHelp_Impl() :
     314             : 
     315          19 :     m_pOpt          ( NULL )
     316             : 
     317             : {
     318          19 : }
     319             : 
     320           0 : SfxHelp_Impl::~SfxHelp_Impl()
     321             : {
     322           0 :     delete m_pOpt;
     323           0 : }
     324             : 
     325           0 : String SfxHelp_Impl::GetHelpText( const OUString& aCommandURL, const String& rModule )
     326             : {
     327             :     // create help url
     328           0 :     String aHelpURL = SfxHelp::CreateHelpURL( aCommandURL, rModule );
     329             :     // added 'active' parameter
     330           0 :     aHelpURL.Insert( String( DEFINE_CONST_UNICODE("&Active=true") ), aHelpURL.SearchBackward( '#' ) );
     331             :     // load help string
     332           0 :     return SfxContentHelper::GetActiveHelpString( aHelpURL );
     333             : }
     334             : 
     335         143 : SfxHelpOptions_Impl* SfxHelp_Impl::GetOptions()
     336             : {
     337             :     // create if not exists
     338         143 :     if ( !m_pOpt )
     339           8 :         m_pOpt = new SfxHelpOptions_Impl;
     340         143 :     return m_pOpt;
     341             : }
     342             : 
     343          19 : SfxHelp::SfxHelp() :
     344             : 
     345             :     bIsDebug( sal_False ),
     346          19 :     pImp    ( NULL )
     347             : 
     348             : {
     349             :     // read the environment variable "HELP_DEBUG"
     350             :     // if it's set, you will see debug output on active help
     351             :     {
     352          19 :         OUString sHelpDebug;
     353          19 :         OUString sEnvVarName( "HELP_DEBUG"  );
     354          19 :         osl_getEnvironment( sEnvVarName.pData, &sHelpDebug.pData );
     355          19 :         bIsDebug = !sHelpDebug.isEmpty();
     356             :     }
     357             : 
     358          19 :     pImp = new SfxHelp_Impl();
     359             : 
     360          19 :     OUString aLocaleStr = HelpLocaleString();
     361             : 
     362          19 :     sal_Int32 nSepPos = aLocaleStr.indexOf( '_' );
     363          19 :     if ( nSepPos != -1 )
     364             :     {
     365           0 :         aLanguageStr = aLocaleStr.copy( 0, nSepPos );
     366           0 :         aCountryStr = aLocaleStr.copy( nSepPos+1 );
     367             :     }
     368             :     else
     369             :     {
     370          19 :         nSepPos = aLocaleStr.indexOf( '-' );
     371          19 :         if ( nSepPos != -1 )
     372             :         {
     373           0 :             aLanguageStr = aLocaleStr.copy( 0, nSepPos );
     374           0 :             aCountryStr = aLocaleStr.copy( nSepPos+1 );
     375             :         }
     376             :         else
     377             :         {
     378          19 :             aLanguageStr = aLocaleStr;
     379             :         }
     380          19 :     }
     381          19 : }
     382             : 
     383           0 : SfxHelp::~SfxHelp()
     384             : {
     385           0 :     delete pImp;
     386           0 : }
     387             : 
     388           0 : OUString getDefaultModule_Impl()
     389             : {
     390           0 :     OUString sDefaultModule;
     391           0 :     SvtModuleOptions aModOpt;
     392           0 :     if ( aModOpt.IsModuleInstalled( SvtModuleOptions::E_SWRITER ) )
     393           0 :         sDefaultModule = DEFINE_CONST_UNICODE("swriter");
     394           0 :     else if ( aModOpt.IsModuleInstalled( SvtModuleOptions::E_SCALC ) )
     395           0 :         sDefaultModule = DEFINE_CONST_UNICODE("scalc");
     396           0 :     else if ( aModOpt.IsModuleInstalled( SvtModuleOptions::E_SIMPRESS ) )
     397           0 :         sDefaultModule = DEFINE_CONST_UNICODE("simpress");
     398           0 :     else if ( aModOpt.IsModuleInstalled( SvtModuleOptions::E_SDRAW ) )
     399           0 :         sDefaultModule = DEFINE_CONST_UNICODE("sdraw");
     400           0 :     else if ( aModOpt.IsModuleInstalled( SvtModuleOptions::E_SMATH ) )
     401           0 :         sDefaultModule = DEFINE_CONST_UNICODE("smath");
     402           0 :     else if ( aModOpt.IsModuleInstalled( SvtModuleOptions::E_SCHART ) )
     403           0 :         sDefaultModule = DEFINE_CONST_UNICODE("schart");
     404           0 :     else if ( aModOpt.IsModuleInstalled( SvtModuleOptions::E_SBASIC ) )
     405           0 :         sDefaultModule = DEFINE_CONST_UNICODE("sbasic");
     406           0 :     else if ( aModOpt.IsModuleInstalled( SvtModuleOptions::E_SDATABASE ) )
     407           0 :         sDefaultModule = DEFINE_CONST_UNICODE("sdatabase");
     408             :     else
     409             :     {
     410             :         SAL_WARN( "sfx2.appl", "getDefaultModule_Impl(): no module installed" );
     411             :     }
     412           0 :     return sDefaultModule;
     413             : }
     414             : 
     415           0 : OUString getCurrentModuleIdentifier_Impl()
     416             : {
     417           0 :     OUString sIdentifier;
     418           0 :     Reference < XComponentContext > xContext = ::comphelper::getProcessComponentContext();
     419           0 :     Reference < XModuleManager2 > xModuleManager = ModuleManager::create(xContext);
     420           0 :     Reference < XDesktop2 > xDesktop = Desktop::create(xContext);
     421           0 :     Reference < XFrame > xCurrentFrame = xDesktop->getCurrentFrame();
     422             : 
     423           0 :     if ( xCurrentFrame.is() )
     424             :     {
     425             :         try
     426             :         {
     427           0 :             sIdentifier = xModuleManager->identify( xCurrentFrame );
     428             :         }
     429           0 :         catch (const ::com::sun::star::frame::UnknownModuleException&)
     430             :         {
     431             :             DBG_WARNING( "SfxHelp::getCurrentModuleIdentifier_Impl(): unknown module (help in help?)" );
     432             :         }
     433           0 :         catch (const Exception&)
     434             :         {
     435             :             SAL_WARN( "sfx2.appl", "SfxHelp::getCurrentModuleIdentifier_Impl(): exception of XModuleManager::identify()" );
     436             :         }
     437             :     }
     438             : 
     439           0 :     return sIdentifier;
     440             : }
     441             : 
     442           0 : OUString SfxHelp::GetHelpModuleName_Impl()
     443             : {
     444           0 :     OUString aFactoryShortName;
     445           0 :     OUString aModuleIdentifier = getCurrentModuleIdentifier_Impl();
     446             : 
     447           0 :     if ( !aModuleIdentifier.isEmpty() )
     448             :     {
     449             :         try
     450             :         {
     451             :             Reference < XModuleManager2 > xModuleManager(
     452           0 :                 ModuleManager::create(::comphelper::getProcessComponentContext()) );
     453           0 :             Sequence< PropertyValue > lProps;
     454           0 :             xModuleManager->getByName( aModuleIdentifier ) >>= lProps;
     455           0 :             for ( sal_Int32 i = 0; i < lProps.getLength(); ++i )
     456             :             {
     457           0 :                 if ( lProps[i].Name == "ooSetupFactoryShortName" )
     458             :                 {
     459           0 :                     lProps[i].Value >>= aFactoryShortName;
     460           0 :                     break;
     461             :                 }
     462           0 :             }
     463             :         }
     464           0 :         catch (const Exception&)
     465             :         {
     466             :             SAL_WARN( "sfx2.appl", "SfxHelp::GetHelpModuleName_Impl(): exception of XNameAccess::getByName()" );
     467             :         }
     468             :     }
     469             : 
     470           0 :     OUString sDefaultModule = getDefaultModule_Impl();
     471           0 :     if ( !aFactoryShortName.isEmpty() )
     472             :     {
     473             :         // Map some module identifiers to their "real" help module string.
     474           0 :         if ( aFactoryShortName == "chart2" )
     475           0 :             aFactoryShortName = OUString( "schart"  );
     476           0 :         else if ( aFactoryShortName == "BasicIDE" )
     477           0 :             aFactoryShortName = OUString( "sbasic"  );
     478           0 :         else if ( aFactoryShortName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("sweb"))
     479           0 :                 || aFactoryShortName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("sglobal"))
     480           0 :                 || aFactoryShortName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("swxform")) )
     481           0 :             aFactoryShortName = OUString( "swriter"  );
     482           0 :         else if ( aFactoryShortName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("dbquery"))
     483           0 :                 || aFactoryShortName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("dbbrowser"))
     484           0 :                 || aFactoryShortName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("dbrelation"))
     485           0 :                 || aFactoryShortName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("dbtable"))
     486           0 :                 || aFactoryShortName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("dbapp"))
     487           0 :                 || aFactoryShortName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("dbreport"))
     488           0 :                 || aFactoryShortName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("swreport"))
     489           0 :                 || aFactoryShortName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("dbbrowser"))
     490           0 :                 || aFactoryShortName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("swform")) )
     491           0 :             aFactoryShortName = OUString( "sdatabase"  );
     492           0 :         else if ( aFactoryShortName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("sbibliography"))
     493           0 :                 || aFactoryShortName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("StartModule")) )
     494           0 :             aFactoryShortName = sDefaultModule;
     495             :     }
     496             :     else
     497           0 :         aFactoryShortName = sDefaultModule;
     498             : 
     499           0 :     return aFactoryShortName;
     500             : }
     501             : 
     502           0 : OUString SfxHelp::CreateHelpURL_Impl( const OUString& aCommandURL, const OUString& rModuleName )
     503             : {
     504             :     // build up the help URL
     505           0 :     OUStringBuffer aHelpURL("vnd.sun.star.help://");
     506           0 :     sal_Bool bHasAnchor = sal_False;
     507           0 :     OUString aAnchor;
     508             : 
     509           0 :     OUString aModuleName( rModuleName );
     510           0 :     if (aModuleName.isEmpty())
     511           0 :         aModuleName = getDefaultModule_Impl();
     512             : 
     513           0 :     aHelpURL.append(aModuleName);
     514             : 
     515           0 :     if ( aCommandURL.isEmpty() )
     516           0 :         aHelpURL.append("/start");
     517             :     else
     518             :     {
     519           0 :         aHelpURL.append('/');
     520             :         aHelpURL.append(rtl::Uri::encode(aCommandURL,
     521             :                                               rtl_UriCharClassRelSegment,
     522             :                                               rtl_UriEncodeKeepEscapes,
     523           0 :                                               RTL_TEXTENCODING_UTF8));
     524             : 
     525           0 :         OUStringBuffer aTempURL = aHelpURL;
     526           0 :         AppendConfigToken( aTempURL, sal_True );
     527           0 :         bHasAnchor = GetHelpAnchor_Impl(aTempURL.makeStringAndClear(), aAnchor);
     528             :     }
     529             : 
     530           0 :     AppendConfigToken( aHelpURL, sal_True );
     531             : 
     532           0 :     if ( bHasAnchor )
     533             :     {
     534           0 :         aHelpURL.append('#');
     535           0 :         aHelpURL.append(aAnchor);
     536             :     }
     537             : 
     538           0 :     return aHelpURL.makeStringAndClear();
     539             : }
     540             : 
     541           0 : SfxHelpWindow_Impl* impl_createHelp(Reference< XFrame >& rHelpTask   ,
     542             :                                     Reference< XFrame >& rHelpContent)
     543             : {
     544           0 :     Reference < XDesktop2 > xDesktop = Desktop::create( ::comphelper::getProcessComponentContext() );
     545             : 
     546             :     // otherwhise - create new help task
     547           0 :     Reference< XFrame > xHelpTask = xDesktop->findFrame(
     548             :         OUString("OFFICE_HELP_TASK"),
     549           0 :         FrameSearchFlag::TASKS | FrameSearchFlag::CREATE);
     550           0 :     if (!xHelpTask.is())
     551           0 :         return 0;
     552             : 
     553             :     // create all internal windows and sub frames ...
     554           0 :     Reference< ::com::sun::star::awt::XWindow > xParentWindow = xHelpTask->getContainerWindow();
     555           0 :     Window*                                     pParentWindow = VCLUnoHelper::GetWindow( xParentWindow );
     556           0 :     SfxHelpWindow_Impl*                         pHelpWindow   = new SfxHelpWindow_Impl( xHelpTask, pParentWindow, WB_DOCKBORDER );
     557           0 :     Reference< ::com::sun::star::awt::XWindow > xHelpWindow   = VCLUnoHelper::GetInterface( pHelpWindow );
     558             : 
     559           0 :     Reference< XFrame > xHelpContent;
     560           0 :     if (xHelpTask->setComponent( xHelpWindow, Reference< XController >() ))
     561             :     {
     562             :         // Customize UI ...
     563           0 :         xHelpTask->setName( OUString("OFFICE_HELP_TASK") );
     564             : 
     565           0 :         Reference< XPropertySet > xProps(xHelpTask, UNO_QUERY);
     566           0 :         if (xProps.is())
     567           0 :             xProps->setPropertyValue(
     568             :                 DEFINE_CONST_UNICODE("Title"),
     569           0 :                 makeAny(SfxResId(STR_HELP_WINDOW_TITLE).toString()));
     570             : 
     571           0 :         pHelpWindow->setContainerWindow( xParentWindow );
     572           0 :         xParentWindow->setVisible(sal_True);
     573           0 :         xHelpWindow->setVisible(sal_True);
     574             : 
     575             :         // This sub frame is created internaly (if we called new SfxHelpWindow_Impl() ...)
     576             :         // It should exist :-)
     577           0 :         xHelpContent = xHelpTask->findFrame(OUString("OFFICE_HELP"), FrameSearchFlag::CHILDREN);
     578             :     }
     579             : 
     580           0 :     if (!xHelpContent.is())
     581           0 :         delete pHelpWindow;
     582             : 
     583           0 :     xHelpContent->setName(OUString("OFFICE_HELP"));
     584             : 
     585           0 :     rHelpTask    = xHelpTask;
     586           0 :     rHelpContent = xHelpContent;
     587           0 :     return pHelpWindow;
     588             : }
     589             : 
     590           0 : OUString SfxHelp::GetHelpText( const OUString& aCommandURL, const Window* pWindow )
     591             : {
     592           0 :     OUString sModuleName = GetHelpModuleName_Impl();
     593           0 :     OUString sHelpText = pImp->GetHelpText( aCommandURL, sModuleName );
     594             : 
     595           0 :     OString aNewHelpId;
     596             : 
     597           0 :     if (pWindow && sHelpText.isEmpty())
     598             :     {
     599             :         // no help text found -> try with parent help id.
     600           0 :         Window* pParent = pWindow->GetParent();
     601           0 :         while ( pParent )
     602             :         {
     603           0 :             aNewHelpId = pParent->GetHelpId();
     604           0 :             sHelpText = pImp->GetHelpText( OStringToOUString(aNewHelpId, RTL_TEXTENCODING_UTF8), sModuleName );
     605           0 :             if (!sHelpText.isEmpty())
     606           0 :                 pParent = NULL;
     607             :             else
     608           0 :                 pParent = pParent->GetParent();
     609             :         }
     610             : 
     611           0 :         if (bIsDebug && sHelpText.isEmpty())
     612           0 :             aNewHelpId = OString();
     613             :     }
     614             : 
     615             :     // add some debug information?
     616           0 :     if ( bIsDebug )
     617             :     {
     618           0 :         sHelpText += DEFINE_CONST_UNICODE("\n-------------\n");
     619           0 :         sHelpText += String( sModuleName );
     620           0 :         sHelpText += DEFINE_CONST_UNICODE(": ");
     621           0 :         sHelpText += aCommandURL;
     622           0 :         if ( !aNewHelpId.isEmpty() )
     623             :         {
     624           0 :             sHelpText += DEFINE_CONST_UNICODE(" - ");
     625           0 :             sHelpText += String(OStringToOUString(aNewHelpId, RTL_TEXTENCODING_UTF8));
     626             :         }
     627             :     }
     628             : 
     629           0 :     return sHelpText;
     630             : }
     631             : 
     632             : /// Check for built-in help
     633          19 : static bool impl_hasHelpInstalled( const OUString &rLang = OUString() )
     634             : {
     635          19 :     OUStringBuffer aHelpRootURL("vnd.sun.star.help://");
     636          19 :     AppendConfigToken(aHelpRootURL, sal_True, rLang);
     637          19 :     Sequence< OUString > aFactories = SfxContentHelper::GetResultSet(aHelpRootURL.makeStringAndClear());
     638             : 
     639          19 :     return ( aFactories.getLength() != 0   );
     640             : }
     641             : 
     642           0 : sal_Bool SfxHelp::SearchKeyword( const OUString& rKeyword )
     643             : {
     644           0 :     return Start_Impl( String(), NULL, rKeyword );
     645             : }
     646             : 
     647           0 : sal_Bool SfxHelp::Start( const OUString& rURL, const Window* pWindow )
     648             : {
     649           0 :     return Start_Impl( rURL, pWindow, OUString() );
     650             : }
     651             : 
     652             : /// Redirect the vnd.sun.star.help:// urls to http://help.libreoffice.org
     653           0 : static bool impl_showOnlineHelp( const String& rURL )
     654             : {
     655           0 :     String aInternal( "vnd.sun.star.help://"  );
     656           0 :     if ( rURL.Len() <= aInternal.Len() || rURL.Copy( 0, aInternal.Len() ) != aInternal )
     657           0 :         return false;
     658             : 
     659           0 :     OUString aHelpLink( "http://help.libreoffice.org/"  );
     660           0 :     aHelpLink += rURL.Copy( aInternal.Len() );
     661             :     try
     662             :     {
     663             :         Reference< XSystemShellExecute > xSystemShell(
     664           0 :                 SystemShellExecute::create(::comphelper::getProcessComponentContext()) );
     665             : 
     666           0 :         xSystemShell->execute( aHelpLink, OUString(), SystemShellExecuteFlags::URIS_ONLY );
     667           0 :         return true;
     668             :     }
     669           0 :     catch (const Exception&)
     670             :     {
     671             :     }
     672           0 :     return false;
     673             : }
     674             : 
     675           0 : sal_Bool SfxHelp::Start_Impl(const OUString& rURL, const Window* pWindow, const OUString& rKeyword)
     676             : {
     677           0 :     OUStringBuffer aHelpRootURL("vnd.sun.star.help://");
     678           0 :     AppendConfigToken(aHelpRootURL, sal_True);
     679           0 :     Sequence< OUString > aFactories = SfxContentHelper::GetResultSet(aHelpRootURL.makeStringAndClear());
     680             : 
     681             :     /* rURL may be
     682             :         - a "real" URL
     683             :         - a HelpID (formerly a long, now a string)
     684             :        If rURL is a URL, CreateHelpURL should be called for this URL
     685             :        If rURL is an arbitrary string, the same should happen, but the URL should be tried out
     686             :        if it delivers real help content. In case only the Help Error Document is returned, the
     687             :        parent of the window for that help was called, is asked for its HelpID.
     688             :        For compatibility reasons this upward search is not implemented for "real" URLs.
     689             :        Help keyword search now is implemented as own method; in former versions it
     690             :        was done via Help::Start, but this implementation conflicted with the upward search.
     691             :     */
     692           0 :     String aHelpURL;
     693           0 :     INetURLObject aParser( rURL );
     694           0 :     INetProtocol nProtocol = aParser.GetProtocol();
     695           0 :     String aHelpModuleName( GetHelpModuleName_Impl() );
     696             : 
     697           0 :     switch ( nProtocol )
     698             :     {
     699             :         case INET_PROT_VND_SUN_STAR_HELP:
     700             :             // already a vnd.sun.star.help URL -> nothing to do
     701           0 :             aHelpURL = rURL;
     702           0 :             break;
     703             :         default:
     704             :         {
     705             :             // no URL, just a HelpID (maybe empty in case of keyword search)
     706           0 :             aHelpURL = CreateHelpURL_Impl( rURL, aHelpModuleName );
     707             : 
     708           0 :             if ( impl_hasHelpInstalled() && pWindow && SfxContentHelper::IsHelpErrorDocument( aHelpURL ) )
     709             :             {
     710             :                 // no help found -> try with parent help id.
     711           0 :                 Window* pParent = pWindow->GetParent();
     712           0 :                 while ( pParent )
     713             :                 {
     714           0 :                     OString aHelpId = pParent->GetHelpId();
     715           0 :                     aHelpURL = CreateHelpURL( OStringToOUString(aHelpId, RTL_TEXTENCODING_UTF8), aHelpModuleName );
     716           0 :                     if ( !SfxContentHelper::IsHelpErrorDocument( aHelpURL ) )
     717             :                     {
     718             :                         break;
     719             :                     }
     720             :                     else
     721             :                     {
     722           0 :                         pParent = pParent->GetParent();
     723           0 :                         if ( !pParent )
     724             :                         {
     725             :                             // create help url of start page ( helpid == 0 -> start page)
     726           0 :                             aHelpURL = CreateHelpURL( String(), aHelpModuleName );
     727             :                         }
     728             :                     }
     729           0 :                 }
     730             :             }
     731           0 :             break;
     732             :         }
     733             :     }
     734             : 
     735           0 :     if ( !impl_hasHelpInstalled() )
     736             :     {
     737           0 :         if ( impl_showOnlineHelp( aHelpURL ) )
     738           0 :             return sal_True;
     739             :         else
     740             :         {
     741           0 :             NoHelpErrorBox aErrBox( const_cast< Window* >( pWindow ) );
     742           0 :             aErrBox.Execute();
     743           0 :             return sal_False;
     744             :         }
     745             :     }
     746             : 
     747           0 :     Reference < XDesktop2 > xDesktop = Desktop::create( ::comphelper::getProcessComponentContext() );
     748             : 
     749             :     // check if help window is still open
     750             :     // If not, create a new one and return access directly to the internal sub frame showing the help content
     751             :     // search must be done here; search one desktop level could return an arbitraty frame
     752           0 :     Reference< XFrame > xHelp = xDesktop->findFrame(
     753             :         OUString("OFFICE_HELP_TASK"),
     754           0 :         FrameSearchFlag::CHILDREN);
     755           0 :     Reference< XFrame > xHelpContent = xDesktop->findFrame(
     756             :         OUString("OFFICE_HELP"),
     757           0 :         FrameSearchFlag::CHILDREN);
     758             : 
     759           0 :     SfxHelpWindow_Impl* pHelpWindow = 0;
     760           0 :     if (!xHelp.is())
     761           0 :         pHelpWindow = impl_createHelp(xHelp, xHelpContent);
     762             :     else
     763           0 :         pHelpWindow = (SfxHelpWindow_Impl*)VCLUnoHelper::GetWindow(xHelp->getComponentWindow());
     764           0 :     if (!xHelp.is() || !xHelpContent.is() || !pHelpWindow)
     765           0 :         return sal_False;
     766             : 
     767             : #ifdef DBG_UTIL
     768             :     OStringBuffer aTmp(RTL_CONSTASCII_STRINGPARAM("SfxHelp: HelpId = "));
     769             :     aTmp.append(OUStringToOString(aHelpURL, RTL_TEXTENCODING_UTF8));
     770             :     OSL_TRACE( aTmp.getStr() );
     771             : #endif
     772             : 
     773           0 :     pHelpWindow->SetHelpURL( aHelpURL );
     774           0 :     pHelpWindow->loadHelpContent(aHelpURL);
     775           0 :     if (!rKeyword.isEmpty())
     776           0 :         pHelpWindow->OpenKeyword( rKeyword );
     777             : 
     778           0 :     Reference < ::com::sun::star::awt::XTopWindow > xTopWindow( xHelp->getContainerWindow(), UNO_QUERY );
     779           0 :     if ( xTopWindow.is() )
     780           0 :         xTopWindow->toFront();
     781             : 
     782           0 :     return sal_True;
     783             : }
     784             : 
     785           0 : OUString SfxHelp::CreateHelpURL(const OUString& aCommandURL, const OUString& rModuleName)
     786             : {
     787           0 :     SfxHelp* pHelp = static_cast< SfxHelp* >(Application::GetHelp());
     788           0 :     return pHelp ? pHelp->CreateHelpURL_Impl( aCommandURL, rModuleName ) : OUString();
     789             : }
     790             : 
     791         143 : void SfxHelp::OpenHelpAgent( SfxFrame*, const OString& sHelpId )
     792             : {
     793         143 :     SfxHelp* pHelp = (static_cast< SfxHelp* >(Application::GetHelp()) );
     794         143 :     if ( pHelp )
     795         143 :         pHelp->OpenHelpAgent( sHelpId );
     796         143 : }
     797             : 
     798         143 : void SfxHelp::OpenHelpAgent( const OString& sHelpId )
     799             : {
     800         143 :     if ( SvtHelpOptions().IsHelpAgentAutoStartMode() )
     801             :     {
     802         143 :             SfxHelpOptions_Impl *pOpt = pImp->GetOptions();
     803         143 :             if ( !pOpt->HasId( sHelpId ) )
     804         286 :                 return;
     805             : 
     806             :             try
     807             :             {
     808           0 :                 URL aURL;
     809           0 :                 aURL.Complete = CreateHelpURL_Impl( OStringToOUString(sHelpId, RTL_TEXTENCODING_UTF8), GetHelpModuleName_Impl() );
     810           0 :                 Reference< XURLTransformer > xTrans( URLTransformer::create( ::comphelper::getProcessComponentContext() ) );
     811           0 :                 xTrans->parseStrict(aURL);
     812             : 
     813           0 :                 Reference < XDesktop2 > xDesktop = Desktop::create( ::comphelper::getProcessComponentContext() );
     814           0 :                 Reference < XFrame > xCurrentFrame = xDesktop->getCurrentFrame();
     815             : 
     816           0 :                 Reference< XDispatchProvider > xDispProv( xCurrentFrame, UNO_QUERY );
     817           0 :                 Reference< XDispatch > xHelpDispatch;
     818           0 :                 if ( xDispProv.is() )
     819           0 :                     xHelpDispatch = xDispProv->queryDispatch(
     820             :                         aURL, OUString("_helpagent"),
     821           0 :                         FrameSearchFlag::PARENT | FrameSearchFlag::SELF );
     822             : 
     823             :                 DBG_ASSERT( xHelpDispatch.is(), "OpenHelpAgent: could not get a dispatcher!" );
     824           0 :                 if ( xHelpDispatch.is() )
     825           0 :                     xHelpDispatch->dispatch( aURL, Sequence< PropertyValue >() );
     826             :             }
     827           0 :             catch (const Exception&)
     828             :             {
     829             :                 SAL_WARN( "sfx2.appl", "OpenHelpAgent: caught an exception while executing the dispatch!" );
     830             :             }
     831             :     }
     832             : }
     833             : 
     834           0 : OUString SfxHelp::GetDefaultHelpModule()
     835             : {
     836           0 :     return getDefaultModule_Impl();
     837             : }
     838             : 
     839           0 : OUString SfxHelp::GetCurrentModuleIdentifier()
     840             : {
     841           0 :     return getCurrentModuleIdentifier_Impl();
     842             : }
     843             : 
     844             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10