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

Generated by: LCOV version 1.10