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

Generated by: LCOV version 1.11