LCOV - code coverage report
Current view: top level - framework/source/jobs - helponstartup.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 11 150 7.3 %
Date: 2015-06-13 12:38:46 Functions: 9 18 50.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 own header
      21             : #include <jobs/helponstartup.hxx>
      22             : #include <loadenv/targethelper.hxx>
      23             : #include <services.h>
      24             : 
      25             : // include others
      26             : #include <comphelper/configurationhelper.hxx>
      27             : #include <comphelper/sequenceashashmap.hxx>
      28             : #include <unotools/configmgr.hxx>
      29             : #include <vcl/svapp.hxx>
      30             : #include <vcl/help.hxx>
      31             : #include <rtl/ustrbuf.hxx>
      32             : 
      33             : // include interfaces
      34             : #include <com/sun/star/frame/FrameSearchFlag.hpp>
      35             : #include <com/sun/star/frame/ModuleManager.hpp>
      36             : #include <com/sun/star/frame/XFramesSupplier.hpp>
      37             : #include <com/sun/star/frame/Desktop.hpp>
      38             : 
      39             : namespace framework{
      40             : 
      41          11 : DEFINE_XSERVICEINFO_MULTISERVICE_2(HelpOnStartup                   ,
      42             :                                       ::cppu::OWeakObject             ,
      43             :                                       SERVICENAME_JOB                 ,
      44             :                                       IMPLEMENTATIONNAME_HELPONSTARTUP)
      45             : 
      46           1 : DEFINE_INIT_SERVICE(HelpOnStartup,
      47             :                     {
      48             :                         /*  Attention
      49             :                             I think we don't need any mutex or lock here ... because we are called by our own static method impl_createInstance()
      50             :                             to create a new instance of this class by our own supported service factory.
      51             :                             see macro DEFINE_XSERVICEINFO_MULTISERVICE and "impl_initService()" for further information!
      52             :                         */
      53             :                         // create some needed uno services and cache it
      54             :                         m_xModuleManager = css::frame::ModuleManager::create( m_xContext );
      55             : 
      56             :                         m_xDesktop = css::frame::Desktop::create(m_xContext);
      57             : 
      58             :                         m_xConfig = css::uno::Reference< css::container::XNameAccess >(
      59             :                             ::comphelper::ConfigurationHelper::openConfig(
      60             :                                 m_xContext,
      61             :                                 "/org.openoffice.Setup/Office/Factories",
      62             :                                 ::comphelper::ConfigurationHelper::E_READONLY),
      63             :                             css::uno::UNO_QUERY_THROW);
      64             : 
      65             :                         // ask for office locale
      66             :                         ::comphelper::ConfigurationHelper::readDirectKey(
      67             :                             m_xContext,
      68             :                             "/org.openoffice.Setup",
      69             :                             "L10N",
      70             :                             "ooLocale",
      71             :                             ::comphelper::ConfigurationHelper::E_READONLY) >>= m_sLocale;
      72             : 
      73             :                         // detect system
      74             :                         ::comphelper::ConfigurationHelper::readDirectKey(
      75             :                             m_xContext,
      76             :                             "/org.openoffice.Office.Common",
      77             :                             "Help",
      78             :                             "System",
      79             :                             ::comphelper::ConfigurationHelper::E_READONLY) >>= m_sSystem;
      80             : 
      81             :                         // Start listening for disposing events of these services,
      82             :                         // so we can react e.g. for an office shutdown
      83             :                         css::uno::Reference< css::lang::XComponent > xComponent;
      84             :                         xComponent = css::uno::Reference< css::lang::XComponent >(m_xModuleManager, css::uno::UNO_QUERY);
      85             :                         if (xComponent.is())
      86             :                             xComponent->addEventListener(static_cast< css::lang::XEventListener* >(this));
      87             :                         xComponent = css::uno::Reference< css::lang::XComponent >(m_xDesktop, css::uno::UNO_QUERY);
      88             :                         if (xComponent.is())
      89             :                             xComponent->addEventListener(static_cast< css::lang::XEventListener* >(this));
      90             :                         xComponent = css::uno::Reference< css::lang::XComponent >(m_xConfig, css::uno::UNO_QUERY);
      91             :                         if (xComponent.is())
      92             :                             xComponent->addEventListener(static_cast< css::lang::XEventListener* >(this));
      93             :                     }
      94             :                    )
      95             : 
      96           1 : HelpOnStartup::HelpOnStartup(const css::uno::Reference< css::uno::XComponentContext >& xContext)
      97           1 :     : m_xContext    (xContext)
      98             : {
      99           1 : }
     100             : 
     101           0 : HelpOnStartup::~HelpOnStartup()
     102             : {
     103           0 : }
     104             : 
     105             : // css.task.XJob
     106           0 : css::uno::Any SAL_CALL HelpOnStartup::execute(const css::uno::Sequence< css::beans::NamedValue >& lArguments)
     107             :     throw(css::lang::IllegalArgumentException,
     108             :           css::uno::Exception                ,
     109             :           css::uno::RuntimeException, std::exception         )
     110             : {
     111             :     // Analyze the given arguments; try to locate a model there and
     112             :     // classify it's used application module.
     113           0 :     OUString sModule = its_getModuleIdFromEnv(lArguments);
     114             : 
     115             :     // Attention: We are bound to events for openeing any document inside the office.
     116             :     // That includes e.g. the help module itself. But we have to do nothing then!
     117           0 :     if (sModule.isEmpty())
     118           0 :         return css::uno::Any();
     119             : 
     120             :     // check current state of the help module
     121             :     // a) help isn't open                       => show default page for the detected module
     122             :     // b) help shows any other default page(!) => show default page for the detected module
     123             :     // c) help shows any other content         => do nothing (user travelled to any other content and leaved the set of default pages)
     124           0 :     OUString sCurrentHelpURL                = its_getCurrentHelpURL();
     125           0 :     bool        bCurrentHelpURLIsAnyDefaultURL = its_isHelpUrlADefaultOne(sCurrentHelpURL);
     126           0 :     bool        bShowIt                        = false;
     127             : 
     128             :     // a)
     129           0 :     if (sCurrentHelpURL.isEmpty())
     130           0 :         bShowIt = true;
     131             :     // b)
     132           0 :     else if (bCurrentHelpURLIsAnyDefaultURL)
     133           0 :         bShowIt = true;
     134             : 
     135           0 :     if (bShowIt)
     136             :     {
     137             :         // retrieve the help URL for the detected application module
     138           0 :         OUString sModuleDependendHelpURL = its_checkIfHelpEnabledAndGetURL(sModule);
     139           0 :         if (!sModuleDependendHelpURL.isEmpty())
     140             :         {
     141             :             // Show this help page.
     142             :             // Note: The help window brings itself to front ...
     143           0 :             Help* pHelp = Application::GetHelp();
     144           0 :             if (pHelp)
     145           0 :                 pHelp->Start(sModuleDependendHelpURL, 0);
     146           0 :         }
     147             :     }
     148             : 
     149           0 :     return css::uno::Any();
     150             : }
     151             : 
     152           1 : void SAL_CALL HelpOnStartup::disposing(const css::lang::EventObject& aEvent)
     153             :     throw(css::uno::RuntimeException, std::exception)
     154             : {
     155           1 :     osl::MutexGuard g(m_mutex);
     156           1 :     if (aEvent.Source == m_xModuleManager)
     157           0 :         m_xModuleManager.clear();
     158           1 :     else if (aEvent.Source == m_xDesktop)
     159           1 :         m_xDesktop.clear();
     160           0 :     else if (aEvent.Source == m_xConfig)
     161           0 :         m_xConfig.clear();
     162           1 : }
     163             : 
     164           0 : OUString HelpOnStartup::its_getModuleIdFromEnv(const css::uno::Sequence< css::beans::NamedValue >& lArguments)
     165             : {
     166           0 :     ::comphelper::SequenceAsHashMap lArgs        (lArguments);
     167           0 :     ::comphelper::SequenceAsHashMap lEnvironment = lArgs.getUnpackedValueOrDefault("Environment", css::uno::Sequence< css::beans::NamedValue >());
     168           0 :     ::comphelper::SequenceAsHashMap lJobConfig   = lArgs.getUnpackedValueOrDefault("JobConfig", css::uno::Sequence< css::beans::NamedValue >());
     169             : 
     170             :     // check for right environment.
     171             :     // If its not a DocumentEvent, which triggered this job,
     172             :     // we can't work correctly! => return immediately and do nothing
     173           0 :     OUString sEnvType = lEnvironment.getUnpackedValueOrDefault("EnvType", OUString());
     174           0 :     if (sEnvType != "DOCUMENTEVENT")
     175           0 :         return OUString();
     176             : 
     177           0 :     css::uno::Reference< css::frame::XModel > xDoc = lEnvironment.getUnpackedValueOrDefault("Model", css::uno::Reference< css::frame::XModel >());
     178           0 :     if (!xDoc.is())
     179           0 :         return OUString();
     180             : 
     181             :     // be sure that we work on top level documents only, which are registered
     182             :     // on the desktop instance. Ignore e.g. life previews, which are top frames too ...
     183             :     // but not registered at this global desktop instance.
     184           0 :     css::uno::Reference< css::frame::XDesktop >    xDesktopCheck;
     185           0 :     css::uno::Reference< css::frame::XFrame >      xFrame;
     186           0 :     css::uno::Reference< css::frame::XController > xController  = xDoc->getCurrentController();
     187           0 :     if (xController.is())
     188           0 :         xFrame = xController->getFrame();
     189           0 :     if (xFrame.is() && xFrame->isTop())
     190           0 :         xDesktopCheck = css::uno::Reference< css::frame::XDesktop >(xFrame->getCreator(), css::uno::UNO_QUERY);
     191           0 :     if (!xDesktopCheck.is())
     192           0 :         return OUString();
     193             : 
     194             :     // OK - now we are sure this document is a top level document.
     195             :     // Classify it.
     196             :     // SAFE ->
     197           0 :     osl::ClearableMutexGuard aLock(m_mutex);
     198           0 :     css::uno::Reference< css::frame::XModuleManager2 > xModuleManager = m_xModuleManager;
     199           0 :     aLock.clear();
     200             :     // <- SAFE
     201             : 
     202           0 :     OUString sModuleId;
     203             :     try
     204             :     {
     205           0 :         sModuleId = xModuleManager->identify(xDoc);
     206             :     }
     207           0 :     catch(const css::uno::RuntimeException&)
     208           0 :         { throw; }
     209           0 :     catch(const css::uno::Exception&)
     210           0 :         { sModuleId.clear(); }
     211             : 
     212           0 :     return sModuleId;
     213             : }
     214             : 
     215           0 : OUString HelpOnStartup::its_getCurrentHelpURL()
     216             : {
     217             :     // SAFE ->
     218           0 :     osl::ClearableMutexGuard aLock(m_mutex);
     219           0 :     css::uno::Reference< css::frame::XDesktop2 > xDesktop = m_xDesktop;
     220           0 :     aLock.clear();
     221             :     // <- SAFE
     222             : 
     223           0 :     if (!xDesktop.is())
     224           0 :         return OUString();
     225             : 
     226           0 :     css::uno::Reference< css::frame::XFrame > xHelp = xDesktop->findFrame(SPECIALTARGET_HELPTASK, css::frame::FrameSearchFlag::CHILDREN);
     227           0 :     if (!xHelp.is())
     228           0 :         return OUString();
     229             : 
     230           0 :     OUString sCurrentHelpURL;
     231             :     try
     232             :     {
     233           0 :         css::uno::Reference< css::frame::XFramesSupplier >  xHelpRoot  (xHelp                 , css::uno::UNO_QUERY_THROW);
     234           0 :         css::uno::Reference< css::container::XIndexAccess > xHelpChildren(xHelpRoot->getFrames(), css::uno::UNO_QUERY_THROW);
     235             : 
     236           0 :         css::uno::Reference< css::frame::XFrame >      xHelpChild;
     237           0 :         css::uno::Reference< css::frame::XController > xHelpView;
     238           0 :         css::uno::Reference< css::frame::XModel >      xHelpContent;
     239             : 
     240           0 :         xHelpChildren->getByIndex(0) >>= xHelpChild;
     241           0 :         if (xHelpChild.is())
     242           0 :             xHelpView = xHelpChild->getController();
     243           0 :         if (xHelpView.is())
     244           0 :             xHelpContent = xHelpView->getModel();
     245           0 :         if (xHelpContent.is())
     246           0 :             sCurrentHelpURL = xHelpContent->getURL();
     247             :     }
     248           0 :     catch(const css::uno::RuntimeException&)
     249           0 :         { throw; }
     250           0 :     catch(const css::uno::Exception&)
     251           0 :         { sCurrentHelpURL.clear(); }
     252             : 
     253           0 :     return sCurrentHelpURL;
     254             : }
     255             : 
     256           0 : bool HelpOnStartup::its_isHelpUrlADefaultOne(const OUString& sHelpURL)
     257             : {
     258           0 :     if (sHelpURL.isEmpty())
     259           0 :         return false;
     260             : 
     261             :     // SAFE ->
     262           0 :     osl::ClearableMutexGuard aLock(m_mutex);
     263           0 :     css::uno::Reference< css::container::XNameAccess >     xConfig = m_xConfig;
     264           0 :     OUString                                        sLocale = m_sLocale;
     265           0 :     OUString                                        sSystem = m_sSystem;
     266           0 :     aLock.clear();
     267             :     // <- SAFE
     268             : 
     269           0 :     if (!xConfig.is())
     270           0 :         return false;
     271             : 
     272             :     // check given help url against all default ones
     273           0 :     const css::uno::Sequence< OUString > lModules = xConfig->getElementNames();
     274           0 :     const OUString*                      pModules = lModules.getConstArray();
     275           0 :           ::sal_Int32                           c        = lModules.getLength();
     276           0 :           ::sal_Int32                           i        = 0;
     277             : 
     278           0 :     for (i=0; i<c; ++i)
     279             :     {
     280             :         try
     281             :         {
     282           0 :             css::uno::Reference< css::container::XNameAccess > xModuleConfig;
     283           0 :             xConfig->getByName(pModules[i]) >>= xModuleConfig;
     284           0 :             if (!xModuleConfig.is())
     285           0 :                 continue;
     286             : 
     287           0 :             OUString sHelpBaseURL;
     288           0 :             xModuleConfig->getByName("ooSetupFactoryHelpBaseURL") >>= sHelpBaseURL;
     289           0 :             OUString sHelpURLForModule = HelpOnStartup::ist_createHelpURL(sHelpBaseURL, sLocale, sSystem);
     290           0 :             if (sHelpURL.equals(sHelpURLForModule))
     291           0 :                 return true;
     292             :         }
     293           0 :         catch(const css::uno::RuntimeException&)
     294           0 :             { throw; }
     295           0 :         catch(const css::uno::Exception&)
     296             :             {}
     297             :     }
     298             : 
     299           0 :     return false;
     300             : }
     301             : 
     302           0 : OUString HelpOnStartup::its_checkIfHelpEnabledAndGetURL(const OUString& sModule)
     303             : {
     304             :     // SAFE ->
     305           0 :     osl::ClearableMutexGuard aLock(m_mutex);
     306           0 :     css::uno::Reference< css::container::XNameAccess > xConfig = m_xConfig;
     307           0 :     OUString                                    sLocale = m_sLocale;
     308           0 :     OUString                                    sSystem = m_sSystem;
     309           0 :     aLock.clear();
     310             :     // <- SAFE
     311             : 
     312           0 :     OUString sHelpURL;
     313             : 
     314             :     try
     315             :     {
     316           0 :         css::uno::Reference< css::container::XNameAccess > xModuleConfig;
     317           0 :         if (xConfig.is())
     318           0 :             xConfig->getByName(sModule) >>= xModuleConfig;
     319             : 
     320           0 :         bool bHelpEnabled = false;
     321           0 :         if (xModuleConfig.is())
     322           0 :             xModuleConfig->getByName("ooSetupFactoryHelpOnOpen") >>= bHelpEnabled;
     323             : 
     324           0 :         if (bHelpEnabled)
     325             :         {
     326           0 :             OUString sHelpBaseURL;
     327           0 :             xModuleConfig->getByName("ooSetupFactoryHelpBaseURL") >>= sHelpBaseURL;
     328           0 :             sHelpURL = HelpOnStartup::ist_createHelpURL(sHelpBaseURL, sLocale, sSystem);
     329           0 :         }
     330             :     }
     331           0 :     catch(const css::uno::RuntimeException&)
     332           0 :         { throw; }
     333           0 :     catch(const css::uno::Exception&)
     334           0 :         { sHelpURL.clear(); }
     335             : 
     336           0 :     return sHelpURL;
     337             : }
     338             : 
     339           0 : OUString HelpOnStartup::ist_createHelpURL(const OUString& sBaseURL,
     340             :                                                  const OUString& sLocale ,
     341             :                                                  const OUString& sSystem )
     342             : {
     343           0 :     OUStringBuffer sHelpURL(256);
     344           0 :     sHelpURL.append     (sBaseURL    );
     345           0 :     sHelpURL.appendAscii("?Language=");
     346           0 :     sHelpURL.append     (sLocale     );
     347           0 :     sHelpURL.appendAscii("&System="  );
     348           0 :     sHelpURL.append     (sSystem     );
     349             : 
     350           0 :     return sHelpURL.makeStringAndClear();
     351             : }
     352             : 
     353             : } // namespace framework
     354             : 
     355             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11