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

Generated by: LCOV version 1.10