LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/sfx2/source/appl - sfxhelp.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 162 315 51.4 %
Date: 2013-07-09 Functions: 16 27 59.3 %
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/XFrame2.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::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             : static bool impl_hasHelpInstalled( const OUString &rLang );
     100             : 
     101             : /// Return the locale we prefer for displaying help
     102         775 : static OUString HelpLocaleString()
     103             : {
     104         775 :     static OUString aLocaleStr;
     105         775 :     if (aLocaleStr.isEmpty())
     106             :     {
     107         133 :         const OUString aEnglish( "en"  );
     108             :         // detect installed locale
     109         133 :         aLocaleStr = utl::ConfigManager::getLocale();
     110         133 :         bool bOk = !aLocaleStr.isEmpty();
     111         133 :         if ( !bOk )
     112          50 :             aLocaleStr = aEnglish;
     113             :         else
     114             :         {
     115          83 :             OUString aBaseInstallPath;
     116          83 :             utl::Bootstrap::locateBaseInstallation(aBaseInstallPath);
     117             :             static const char *szHelpPath = "/help/";
     118             : 
     119         166 :             OUString sHelpPath = aBaseInstallPath +
     120         332 :                 OUString::createFromAscii(szHelpPath) + aLocaleStr;
     121         166 :             osl::DirectoryItem aDirItem;
     122             : 
     123          83 :             if (!osl::DirectoryItem::get(sHelpPath, aDirItem) == osl::FileBase::E_None)
     124             :             {
     125          83 :                 bOk = false;
     126          83 :                 OUString sLang(aLocaleStr);
     127          83 :                 sal_Int32 nSepPos = sLang.indexOf( '-' );
     128          83 :                 if (nSepPos != -1)
     129             :                 {
     130          83 :                     bOk = true;
     131          83 :                     sLang = sLang.copy( 0, nSepPos );
     132         332 :                     sHelpPath = aBaseInstallPath +
     133         415 :                         OUString::createFromAscii(szHelpPath) + sLang;
     134          83 :                     if (!osl::DirectoryItem::get(sHelpPath, aDirItem) == osl::FileBase::E_None)
     135          83 :                         bOk = false;
     136          83 :                 }
     137          83 :             }
     138             :         }
     139             :         // if not OK, and not even English installed, we use online help, and
     140             :         // have to preserve the full locale name
     141         133 :         if ( !bOk && impl_hasHelpInstalled( aEnglish ) )
     142           0 :             aLocaleStr = aEnglish;
     143             :     }
     144         775 :     return aLocaleStr;
     145             : }
     146             : 
     147         775 : void AppendConfigToken( OUStringBuffer& rURL, sal_Bool bQuestionMark, const OUString &rLang )
     148             : {
     149         775 :     OUString aLocaleStr( rLang );
     150         775 :     if ( aLocaleStr.isEmpty() )
     151         642 :         aLocaleStr = HelpLocaleString();
     152             : 
     153             :     // query part exists?
     154         775 :     if ( bQuestionMark )
     155             :         // no, so start with '?'
     156         775 :         rURL.append('?');
     157             :     else
     158             :         // yes, so only append with '&'
     159           0 :         rURL.append('&');
     160             : 
     161             :     // set parameters
     162         775 :     rURL.append("Language=");
     163         775 :     rURL.append(aLocaleStr);
     164         775 :     rURL.append("&System=");
     165         775 :     rURL.append(SvtHelpOptions().GetSystem());
     166         775 :     rURL.append("&Version=");
     167         775 :     rURL.append(utl::ConfigManager::getProductVersion());
     168         775 : }
     169             : 
     170         248 : sal_Bool GetHelpAnchor_Impl( const OUString& _rURL, OUString& _rAnchor )
     171             : {
     172         248 :     sal_Bool bRet = sal_False;
     173         248 :     OUString sAnchor;
     174             : 
     175             :     try
     176             :     {
     177             :         ::ucbhelper::Content aCnt( INetURLObject( _rURL ).GetMainURL( INetURLObject::NO_DECODE ),
     178             :                              Reference< ::com::sun::star::ucb::XCommandEnvironment >(),
     179         248 :                              comphelper::getProcessComponentContext() );
     180         248 :         if ( ( aCnt.getPropertyValue("AnchorName") >>= sAnchor ) )
     181             :         {
     182             : 
     183         248 :             if ( !sAnchor.isEmpty() )
     184             :             {
     185           0 :                 _rAnchor = sAnchor;
     186           0 :                 bRet = sal_True;
     187             :             }
     188             :         }
     189             :         else
     190             :         {
     191             :             SAL_WARN( "sfx2.appl", "Property 'AnchorName' is missing" );
     192         248 :         }
     193             :     }
     194           0 :     catch (const ::com::sun::star::uno::Exception&)
     195             :     {
     196             :     }
     197             : 
     198         248 :     return bRet;
     199             : }
     200             : 
     201             : class SfxHelp_Impl
     202             : {
     203             : public:
     204             :     static OUString GetHelpText( const OUString& aCommandURL, const OUString& rModule );
     205             : };
     206             : 
     207         394 : OUString SfxHelp_Impl::GetHelpText( const OUString& aCommandURL, const OUString& rModule )
     208             : {
     209             :     // create help url
     210         394 :     OUStringBuffer aHelpURL( SfxHelp::CreateHelpURL( aCommandURL, rModule ) );
     211             :     // added 'active' parameter
     212         394 :     sal_Int32 nIndex = aHelpURL.lastIndexOf( '#' );
     213         394 :     if ( nIndex < 0 )
     214         394 :         nIndex = aHelpURL.getLength();
     215         394 :     aHelpURL.insert( nIndex, "&Active=true" );
     216             :     // load help string
     217         394 :     return SfxContentHelper::GetActiveHelpString( aHelpURL.makeStringAndClear() );
     218             : }
     219             : 
     220         133 : SfxHelp::SfxHelp() :
     221             :     bIsDebug( sal_False ),
     222         133 :     pImp    ( NULL )
     223             : {
     224             :     // read the environment variable "HELP_DEBUG"
     225             :     // if it's set, you will see debug output on active help
     226             :     {
     227         133 :         OUString sHelpDebug;
     228         266 :         OUString sEnvVarName( "HELP_DEBUG"  );
     229         133 :         osl_getEnvironment( sEnvVarName.pData, &sHelpDebug.pData );
     230         266 :         bIsDebug = !sHelpDebug.isEmpty();
     231             :     }
     232             : 
     233         133 :     pImp = new SfxHelp_Impl();
     234             : 
     235         133 :     OUString aLocaleStr = HelpLocaleString();
     236             : 
     237         133 :     sal_Int32 nSepPos = aLocaleStr.indexOf( '_' );
     238         133 :     if ( nSepPos != -1 )
     239             :     {
     240           0 :         aLanguageStr = aLocaleStr.copy( 0, nSepPos );
     241           0 :         aCountryStr = aLocaleStr.copy( nSepPos+1 );
     242             :     }
     243             :     else
     244             :     {
     245         133 :         nSepPos = aLocaleStr.indexOf( '-' );
     246         133 :         if ( nSepPos != -1 )
     247             :         {
     248          83 :             aLanguageStr = aLocaleStr.copy( 0, nSepPos );
     249          83 :             aCountryStr = aLocaleStr.copy( nSepPos+1 );
     250             :         }
     251             :         else
     252             :         {
     253          50 :             aLanguageStr = aLocaleStr;
     254             :         }
     255         133 :     }
     256         133 : }
     257             : 
     258         249 : SfxHelp::~SfxHelp()
     259             : {
     260          83 :     delete pImp;
     261         166 : }
     262             : 
     263         239 : OUString getDefaultModule_Impl()
     264             : {
     265         239 :     OUString sDefaultModule;
     266         478 :     SvtModuleOptions aModOpt;
     267         239 :     if ( aModOpt.IsModuleInstalled( SvtModuleOptions::E_SWRITER ) )
     268         239 :         sDefaultModule = "swriter";
     269           0 :     else if ( aModOpt.IsModuleInstalled( SvtModuleOptions::E_SCALC ) )
     270           0 :         sDefaultModule = "scalc";
     271           0 :     else if ( aModOpt.IsModuleInstalled( SvtModuleOptions::E_SIMPRESS ) )
     272           0 :         sDefaultModule = "simpress";
     273           0 :     else if ( aModOpt.IsModuleInstalled( SvtModuleOptions::E_SDRAW ) )
     274           0 :         sDefaultModule = "sdraw";
     275           0 :     else if ( aModOpt.IsModuleInstalled( SvtModuleOptions::E_SMATH ) )
     276           0 :         sDefaultModule = "smath";
     277           0 :     else if ( aModOpt.IsModuleInstalled( SvtModuleOptions::E_SCHART ) )
     278           0 :         sDefaultModule = "schart";
     279           0 :     else if ( aModOpt.IsModuleInstalled( SvtModuleOptions::E_SBASIC ) )
     280           0 :         sDefaultModule = "sbasic";
     281           0 :     else if ( aModOpt.IsModuleInstalled( SvtModuleOptions::E_SDATABASE ) )
     282           0 :         sDefaultModule = "sdatabase";
     283             :     else
     284             :     {
     285             :         SAL_WARN( "sfx2.appl", "getDefaultModule_Impl(): no module installed" );
     286             :     }
     287         478 :     return sDefaultModule;
     288             : }
     289             : 
     290         239 : OUString getCurrentModuleIdentifier_Impl()
     291             : {
     292         239 :     OUString sIdentifier;
     293         478 :     Reference < XComponentContext > xContext = ::comphelper::getProcessComponentContext();
     294         478 :     Reference < XModuleManager2 > xModuleManager = ModuleManager::create(xContext);
     295         478 :     Reference < XDesktop2 > xDesktop = Desktop::create(xContext);
     296         478 :     Reference < XFrame > xCurrentFrame = xDesktop->getCurrentFrame();
     297             : 
     298         239 :     if ( xCurrentFrame.is() )
     299             :     {
     300             :         try
     301             :         {
     302         239 :             sIdentifier = xModuleManager->identify( xCurrentFrame );
     303             :         }
     304           0 :         catch (const ::com::sun::star::frame::UnknownModuleException&)
     305             :         {
     306             :             DBG_WARNING( "SfxHelp::getCurrentModuleIdentifier_Impl(): unknown module (help in help?)" );
     307             :         }
     308           0 :         catch (const Exception&)
     309             :         {
     310             :             SAL_WARN( "sfx2.appl", "SfxHelp::getCurrentModuleIdentifier_Impl(): exception of XModuleManager::identify()" );
     311             :         }
     312             :     }
     313             : 
     314         478 :     return sIdentifier;
     315             : }
     316             : 
     317         239 : OUString SfxHelp::GetHelpModuleName_Impl()
     318             : {
     319         239 :     OUString aFactoryShortName;
     320         478 :     OUString aModuleIdentifier = getCurrentModuleIdentifier_Impl();
     321             : 
     322         239 :     if ( !aModuleIdentifier.isEmpty() )
     323             :     {
     324             :         try
     325             :         {
     326             :             Reference < XModuleManager2 > xModuleManager(
     327         239 :                 ModuleManager::create(::comphelper::getProcessComponentContext()) );
     328         478 :             Sequence< PropertyValue > lProps;
     329         239 :             xModuleManager->getByName( aModuleIdentifier ) >>= lProps;
     330        2151 :             for ( sal_Int32 i = 0; i < lProps.getLength(); ++i )
     331             :             {
     332        2151 :                 if ( lProps[i].Name == "ooSetupFactoryShortName" )
     333             :                 {
     334         239 :                     lProps[i].Value >>= aFactoryShortName;
     335         239 :                     break;
     336             :                 }
     337         239 :             }
     338             :         }
     339           0 :         catch (const Exception&)
     340             :         {
     341             :             SAL_WARN( "sfx2.appl", "SfxHelp::GetHelpModuleName_Impl(): exception of XNameAccess::getByName()" );
     342             :         }
     343             :     }
     344             : 
     345         478 :     OUString sDefaultModule = getDefaultModule_Impl();
     346         239 :     if ( !aFactoryShortName.isEmpty() )
     347             :     {
     348             :         // Map some module identifiers to their "real" help module string.
     349         239 :         if ( aFactoryShortName == "chart2" )
     350           0 :             aFactoryShortName = OUString( "schart"  );
     351         239 :         else if ( aFactoryShortName == "BasicIDE" )
     352           0 :             aFactoryShortName = OUString( "sbasic"  );
     353         478 :         else if ( aFactoryShortName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("sweb"))
     354         239 :                 || aFactoryShortName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("sglobal"))
     355         478 :                 || aFactoryShortName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("swxform")) )
     356           0 :             aFactoryShortName = OUString( "swriter"  );
     357         478 :         else if ( aFactoryShortName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("dbquery"))
     358         239 :                 || aFactoryShortName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("dbbrowser"))
     359         239 :                 || aFactoryShortName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("dbrelation"))
     360         239 :                 || aFactoryShortName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("dbtable"))
     361         239 :                 || aFactoryShortName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("dbapp"))
     362         239 :                 || aFactoryShortName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("dbreport"))
     363         239 :                 || aFactoryShortName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("swreport"))
     364         239 :                 || aFactoryShortName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("dbbrowser"))
     365         478 :                 || aFactoryShortName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("swform")) )
     366           0 :             aFactoryShortName = OUString( "sdatabase"  );
     367         478 :         else if ( aFactoryShortName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("sbibliography"))
     368         239 :                 || aFactoryShortName.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("StartModule")) )
     369           0 :             aFactoryShortName = sDefaultModule;
     370             :     }
     371             :     else
     372           0 :         aFactoryShortName = sDefaultModule;
     373             : 
     374         478 :     return aFactoryShortName;
     375             : }
     376             : 
     377         394 : OUString SfxHelp::CreateHelpURL_Impl( const OUString& aCommandURL, const OUString& rModuleName )
     378             : {
     379             :     // build up the help URL
     380         394 :     OUStringBuffer aHelpURL("vnd.sun.star.help://");
     381         394 :     sal_Bool bHasAnchor = sal_False;
     382         788 :     OUString aAnchor;
     383             : 
     384         788 :     OUString aModuleName( rModuleName );
     385         394 :     if (aModuleName.isEmpty())
     386           0 :         aModuleName = getDefaultModule_Impl();
     387             : 
     388         394 :     aHelpURL.append(aModuleName);
     389             : 
     390         394 :     if ( aCommandURL.isEmpty() )
     391         146 :         aHelpURL.append("/start");
     392             :     else
     393             :     {
     394         248 :         aHelpURL.append('/');
     395             :         aHelpURL.append(rtl::Uri::encode(aCommandURL,
     396             :                                               rtl_UriCharClassRelSegment,
     397             :                                               rtl_UriEncodeKeepEscapes,
     398         248 :                                               RTL_TEXTENCODING_UTF8));
     399             : 
     400         248 :         OUStringBuffer aTempURL = aHelpURL;
     401         248 :         AppendConfigToken( aTempURL, sal_True );
     402         248 :         bHasAnchor = GetHelpAnchor_Impl(aTempURL.makeStringAndClear(), aAnchor);
     403             :     }
     404             : 
     405         394 :     AppendConfigToken( aHelpURL, sal_True );
     406             : 
     407         394 :     if ( bHasAnchor )
     408             :     {
     409           0 :         aHelpURL.append('#');
     410           0 :         aHelpURL.append(aAnchor);
     411             :     }
     412             : 
     413         788 :     return aHelpURL.makeStringAndClear();
     414             : }
     415             : 
     416           0 : SfxHelpWindow_Impl* impl_createHelp(Reference< XFrame2 >& rHelpTask   ,
     417             :                                     Reference< XFrame >& rHelpContent)
     418             : {
     419           0 :     Reference < XDesktop2 > xDesktop = Desktop::create( ::comphelper::getProcessComponentContext() );
     420             : 
     421             :     // otherwise - create new help task
     422             :     Reference< XFrame2 > xHelpTask(
     423           0 :         xDesktop->findFrame(  "OFFICE_HELP_TASK", FrameSearchFlag::TASKS | FrameSearchFlag::CREATE),
     424           0 :         UNO_QUERY);
     425           0 :     if (!xHelpTask.is())
     426           0 :         return 0;
     427             : 
     428             :     // create all internal windows and sub frames ...
     429           0 :     Reference< ::com::sun::star::awt::XWindow > xParentWindow = xHelpTask->getContainerWindow();
     430           0 :     Window*                                     pParentWindow = VCLUnoHelper::GetWindow( xParentWindow );
     431           0 :     SfxHelpWindow_Impl*                         pHelpWindow   = new SfxHelpWindow_Impl( xHelpTask, pParentWindow, WB_DOCKBORDER );
     432           0 :     Reference< ::com::sun::star::awt::XWindow > xHelpWindow   = VCLUnoHelper::GetInterface( pHelpWindow );
     433             : 
     434           0 :     Reference< XFrame > xHelpContent;
     435           0 :     if (xHelpTask->setComponent( xHelpWindow, Reference< XController >() ))
     436             :     {
     437             :         // Customize UI ...
     438           0 :         xHelpTask->setName("OFFICE_HELP_TASK");
     439             : 
     440           0 :         Reference< XPropertySet > xProps(xHelpTask, UNO_QUERY);
     441           0 :         if (xProps.is())
     442           0 :             xProps->setPropertyValue(
     443             :                 "Title",
     444           0 :                 makeAny(SfxResId(STR_HELP_WINDOW_TITLE).toString()));
     445             : 
     446           0 :         pHelpWindow->setContainerWindow( xParentWindow );
     447           0 :         xParentWindow->setVisible(sal_True);
     448           0 :         xHelpWindow->setVisible(sal_True);
     449             : 
     450             :         // This sub frame is created internaly (if we called new SfxHelpWindow_Impl() ...)
     451             :         // It should exist :-)
     452           0 :         xHelpContent = xHelpTask->findFrame(OUString("OFFICE_HELP"), FrameSearchFlag::CHILDREN);
     453             :     }
     454             : 
     455           0 :     if (!xHelpContent.is())
     456             :     {
     457           0 :         delete pHelpWindow;
     458           0 :         return NULL;
     459             :     }
     460             : 
     461           0 :     xHelpContent->setName("OFFICE_HELP");
     462             : 
     463           0 :     rHelpTask    = xHelpTask;
     464           0 :     rHelpContent = xHelpContent;
     465           0 :     return pHelpWindow;
     466             : }
     467             : 
     468         239 : OUString SfxHelp::GetHelpText( const OUString& aCommandURL, const Window* pWindow )
     469             : {
     470         239 :     OUString sModuleName = GetHelpModuleName_Impl();
     471         239 :     OUString sHelpText = SfxHelp_Impl::GetHelpText( aCommandURL, sModuleName );
     472             : 
     473         478 :     OString aNewHelpId;
     474             : 
     475         239 :     if (pWindow && sHelpText.isEmpty())
     476             :     {
     477             :         // no help text found -> try with parent help id.
     478          38 :         Window* pParent = pWindow->GetParent();
     479         231 :         while ( pParent )
     480             :         {
     481         155 :             aNewHelpId = pParent->GetHelpId();
     482         155 :             sHelpText = SfxHelp_Impl::GetHelpText( OStringToOUString(aNewHelpId, RTL_TEXTENCODING_UTF8), sModuleName );
     483         155 :             if (!sHelpText.isEmpty())
     484           0 :                 pParent = NULL;
     485             :             else
     486         155 :                 pParent = pParent->GetParent();
     487             :         }
     488             : 
     489          38 :         if (bIsDebug && sHelpText.isEmpty())
     490           0 :             aNewHelpId = OString();
     491             :     }
     492             : 
     493             :     // add some debug information?
     494         239 :     if ( bIsDebug )
     495             :     {
     496           0 :         sHelpText += "\n-------------\n";
     497           0 :         sHelpText += sModuleName;
     498           0 :         sHelpText += ": ";
     499           0 :         sHelpText += aCommandURL;
     500           0 :         if ( !aNewHelpId.isEmpty() )
     501             :         {
     502           0 :             sHelpText += " - ";
     503           0 :             sHelpText += OStringToOUString(aNewHelpId, RTL_TEXTENCODING_UTF8);
     504             :         }
     505             :     }
     506             : 
     507         478 :     return sHelpText;
     508             : }
     509             : 
     510             : /// Check for built-in help
     511         133 : static bool impl_hasHelpInstalled( const OUString &rLang = OUString() )
     512             : {
     513         133 :     OUStringBuffer aHelpRootURL("vnd.sun.star.help://");
     514         133 :     AppendConfigToken(aHelpRootURL, sal_True, rLang);
     515         266 :     std::vector< OUString > aFactories = SfxContentHelper::GetResultSet(aHelpRootURL.makeStringAndClear());
     516             : 
     517         266 :     return !aFactories.empty();
     518             : }
     519             : 
     520           0 : sal_Bool SfxHelp::SearchKeyword( const OUString& rKeyword )
     521             : {
     522           0 :     return Start_Impl( OUString(), NULL, rKeyword );
     523             : }
     524             : 
     525           0 : sal_Bool SfxHelp::Start( const OUString& rURL, const Window* pWindow )
     526             : {
     527           0 :     return Start_Impl( rURL, pWindow, OUString() );
     528             : }
     529             : 
     530             : /// Redirect the vnd.sun.star.help:// urls to http://help.libreoffice.org
     531           0 : static bool impl_showOnlineHelp( const OUString& rURL )
     532             : {
     533           0 :     OUString aInternal( "vnd.sun.star.help://"  );
     534           0 :     if ( rURL.getLength() <= aInternal.getLength() || !rURL.startsWith(aInternal) )
     535           0 :         return false;
     536             : 
     537           0 :     OUString aHelpLink( "http://help.libreoffice.org/"  );
     538           0 :     aHelpLink += rURL.copy( aInternal.getLength() );
     539           0 :     aHelpLink = aHelpLink.replaceAll("%2F","/");
     540             :     try
     541             :     {
     542             :         Reference< XSystemShellExecute > xSystemShell(
     543           0 :                 SystemShellExecute::create(::comphelper::getProcessComponentContext()) );
     544             : 
     545           0 :         xSystemShell->execute( aHelpLink, OUString(), SystemShellExecuteFlags::URIS_ONLY );
     546           0 :         return true;
     547             :     }
     548           0 :     catch (const Exception&)
     549             :     {
     550             :     }
     551           0 :     return false;
     552             : }
     553             : 
     554           0 : sal_Bool SfxHelp::Start_Impl(const OUString& rURL, const Window* pWindow, const OUString& rKeyword)
     555             : {
     556           0 :     OUStringBuffer aHelpRootURL("vnd.sun.star.help://");
     557           0 :     AppendConfigToken(aHelpRootURL, sal_True);
     558           0 :     SfxContentHelper::GetResultSet(aHelpRootURL.makeStringAndClear());
     559             : 
     560             :     /* rURL may be
     561             :         - a "real" URL
     562             :         - a HelpID (formerly a long, now a string)
     563             :        If rURL is a URL, CreateHelpURL should be called for this URL
     564             :        If rURL is an arbitrary string, the same should happen, but the URL should be tried out
     565             :        if it delivers real help content. In case only the Help Error Document is returned, the
     566             :        parent of the window for that help was called, is asked for its HelpID.
     567             :        For compatibility reasons this upward search is not implemented for "real" URLs.
     568             :        Help keyword search now is implemented as own method; in former versions it
     569             :        was done via Help::Start, but this implementation conflicted with the upward search.
     570             :     */
     571           0 :     OUString aHelpURL;
     572           0 :     INetURLObject aParser( rURL );
     573           0 :     INetProtocol nProtocol = aParser.GetProtocol();
     574             : 
     575           0 :     switch ( nProtocol )
     576             :     {
     577             :         case INET_PROT_VND_SUN_STAR_HELP:
     578             :             // already a vnd.sun.star.help URL -> nothing to do
     579           0 :             aHelpURL = rURL;
     580           0 :             break;
     581             :         default:
     582             :         {
     583           0 :             OUString aHelpModuleName( GetHelpModuleName_Impl() );
     584             :             // no URL, just a HelpID (maybe empty in case of keyword search)
     585           0 :             aHelpURL = CreateHelpURL_Impl( rURL, aHelpModuleName );
     586             : 
     587           0 :             if ( impl_hasHelpInstalled() && pWindow && SfxContentHelper::IsHelpErrorDocument( aHelpURL ) )
     588             :             {
     589             :                 // no help found -> try with parent help id.
     590           0 :                 Window* pParent = pWindow->GetParent();
     591           0 :                 bool bTriedTabPage = false;
     592           0 :                 while ( pParent )
     593             :                 {
     594           0 :                     OString aHelpId = pParent->GetHelpId();
     595           0 :                     aHelpURL = CreateHelpURL( OStringToOUString(aHelpId, RTL_TEXTENCODING_UTF8), aHelpModuleName );
     596           0 :                     if ( !SfxContentHelper::IsHelpErrorDocument( aHelpURL ) )
     597             :                     {
     598           0 :                         break;
     599             :                     }
     600             :                     else
     601             :                     {
     602           0 :                         pParent = pParent->GetParent();
     603           0 :                         if (!pParent)
     604             :                         {
     605             :                             // create help url of start page ( helpid == 0 -> start page)
     606           0 :                             aHelpURL = CreateHelpURL( OUString(), aHelpModuleName );
     607             :                         }
     608           0 :                         else if (pParent->IsDialog() && !bTriedTabPage)
     609             :                         {
     610             :                             //During help fallback, before we ask a dialog for its help
     611             :                             //see if it has a TabControl and ask the active tab of
     612             :                             //that for help
     613           0 :                             bTriedTabPage = true;
     614           0 :                             TabControl *pCtrl = ((Dialog*)pParent)->get<TabControl>("tabcontrol");
     615           0 :                             TabPage* pTabPage = pCtrl ? pCtrl->GetTabPage(pCtrl->GetCurPageId()) : NULL;
     616           0 :                             Window *pTabChild = pTabPage ? pTabPage->GetWindow(WINDOW_FIRSTCHILD) : NULL;
     617           0 :                             if (pTabChild)
     618           0 :                                 pParent = pTabChild;
     619             :                         }
     620             :                     }
     621           0 :                 }
     622             :             }
     623           0 :             break;
     624             :         }
     625             :     }
     626             : 
     627           0 :     if ( !impl_hasHelpInstalled() )
     628             :     {
     629           0 :         if ( impl_showOnlineHelp( aHelpURL ) )
     630           0 :             return sal_True;
     631             :         else
     632             :         {
     633           0 :             NoHelpErrorBox aErrBox( const_cast< Window* >( pWindow ) );
     634           0 :             aErrBox.Execute();
     635           0 :             return sal_False;
     636             :         }
     637             :     }
     638             : 
     639           0 :     Reference < XDesktop2 > xDesktop = Desktop::create( ::comphelper::getProcessComponentContext() );
     640             : 
     641             :     // check if help window is still open
     642             :     // If not, create a new one and return access directly to the internal sub frame showing the help content
     643             :     // search must be done here; search one desktop level could return an arbitraty frame
     644             :     Reference< XFrame2 > xHelp(
     645           0 :         xDesktop->findFrame( "OFFICE_HELP_TASK", FrameSearchFlag::CHILDREN),
     646           0 :         UNO_QUERY);
     647           0 :     Reference< XFrame > xHelpContent = xDesktop->findFrame(
     648             :         OUString("OFFICE_HELP"),
     649           0 :         FrameSearchFlag::CHILDREN);
     650             : 
     651           0 :     SfxHelpWindow_Impl* pHelpWindow = 0;
     652           0 :     if (!xHelp.is())
     653           0 :         pHelpWindow = impl_createHelp(xHelp, xHelpContent);
     654             :     else
     655           0 :         pHelpWindow = (SfxHelpWindow_Impl*)VCLUnoHelper::GetWindow(xHelp->getComponentWindow());
     656           0 :     if (!xHelp.is() || !xHelpContent.is() || !pHelpWindow)
     657           0 :         return sal_False;
     658             : 
     659             : #ifdef DBG_UTIL
     660             :     OStringBuffer aTmp(RTL_CONSTASCII_STRINGPARAM("SfxHelp: HelpId = "));
     661             :     aTmp.append(OUStringToOString(aHelpURL, RTL_TEXTENCODING_UTF8));
     662             :     OSL_TRACE( aTmp.getStr() );
     663             : #endif
     664             : 
     665           0 :     pHelpWindow->SetHelpURL( aHelpURL );
     666           0 :     pHelpWindow->loadHelpContent(aHelpURL);
     667           0 :     if (!rKeyword.isEmpty())
     668           0 :         pHelpWindow->OpenKeyword( rKeyword );
     669             : 
     670           0 :     Reference < ::com::sun::star::awt::XTopWindow > xTopWindow( xHelp->getContainerWindow(), UNO_QUERY );
     671           0 :     if ( xTopWindow.is() )
     672           0 :         xTopWindow->toFront();
     673             : 
     674           0 :     return sal_True;
     675             : }
     676             : 
     677         394 : OUString SfxHelp::CreateHelpURL(const OUString& aCommandURL, const OUString& rModuleName)
     678             : {
     679         394 :     SfxHelp* pHelp = static_cast< SfxHelp* >(Application::GetHelp());
     680         394 :     return pHelp ? pHelp->CreateHelpURL_Impl( aCommandURL, rModuleName ) : OUString();
     681             : }
     682             : 
     683           0 : OUString SfxHelp::GetDefaultHelpModule()
     684             : {
     685           0 :     return getDefaultModule_Impl();
     686             : }
     687             : 
     688           0 : OUString SfxHelp::GetCurrentModuleIdentifier()
     689             : {
     690           0 :     return getCurrentModuleIdentifier_Impl();
     691         408 : }
     692             : 
     693             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10