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

Generated by: LCOV version 1.10