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

Generated by: LCOV version 1.10