nss: upgrade to release 3.73
[LibreOffice.git] / framework / source / jobs / helponstartup.cxx
blobb78c4ed50dadd8510c763d58dd01df7c25b32b5a
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 // include own header
21 #include <jobs/helponstartup.hxx>
22 #include <services.h>
23 #include <targets.h>
25 #include <officecfg/Office/Common.hxx>
26 #include <officecfg/Setup.hxx>
28 // include others
29 #include <comphelper/sequenceashashmap.hxx>
30 #include <vcl/svapp.hxx>
31 #include <vcl/help.hxx>
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 #include <cppuhelper/supportsservice.hxx>
40 namespace framework{
42 // XInterface, XTypeProvider, XServiceInfo
44 OUString SAL_CALL HelpOnStartup::getImplementationName()
46 return "com.sun.star.comp.framework.HelpOnStartup";
49 sal_Bool SAL_CALL HelpOnStartup::supportsService( const OUString& sServiceName )
51 return cppu::supportsService(this, sServiceName);
54 css::uno::Sequence< OUString > SAL_CALL HelpOnStartup::getSupportedServiceNames()
56 return { SERVICENAME_JOB };
59 HelpOnStartup::HelpOnStartup(const css::uno::Reference< css::uno::XComponentContext >& xContext)
60 : m_xContext (xContext)
62 // create some needed uno services and cache it
63 m_xModuleManager = css::frame::ModuleManager::create( m_xContext );
65 m_xDesktop = css::frame::Desktop::create(m_xContext);
67 // ask for office locale
68 m_sLocale = officecfg::Setup::L10N::ooLocale::get(m_xContext);
70 // detect system
71 m_sSystem = officecfg::Office::Common::Help::System::get(m_xContext);
73 // Start listening for disposing events of these services,
74 // so we can react e.g. for an office shutdown
75 css::uno::Reference< css::lang::XComponent > xComponent;
76 xComponent.set(m_xModuleManager, css::uno::UNO_QUERY);
77 if (xComponent.is())
78 xComponent->addEventListener(static_cast< css::lang::XEventListener* >(this));
79 if (m_xDesktop.is())
80 m_xDesktop->addEventListener(static_cast< css::lang::XEventListener* >(this));
81 xComponent.set(m_xConfig, css::uno::UNO_QUERY);
82 if (xComponent.is())
83 xComponent->addEventListener(static_cast< css::lang::XEventListener* >(this));
86 HelpOnStartup::~HelpOnStartup()
90 // css.task.XJob
91 css::uno::Any SAL_CALL HelpOnStartup::execute(const css::uno::Sequence< css::beans::NamedValue >& lArguments)
93 // Analyze the given arguments; try to locate a model there and
94 // classify it's used application module.
95 OUString sModule = its_getModuleIdFromEnv(lArguments);
97 // Attention: we are bound to events for opening any document inside the office.
98 // That includes e.g. the help module itself. But we have to do nothing then!
99 if (sModule.isEmpty())
100 return css::uno::Any();
102 // check current state of the help module
103 // a) help isn't open => show default page for the detected module
104 // b) help shows any other default page(!) => show default page for the detected module
105 // c) help shows any other content => do nothing (user travelled to any other content and leaved the set of default pages)
106 OUString sCurrentHelpURL = its_getCurrentHelpURL();
107 bool bCurrentHelpURLIsAnyDefaultURL = its_isHelpUrlADefaultOne(sCurrentHelpURL);
108 bool bShowIt = false;
110 // a)
111 if (sCurrentHelpURL.isEmpty())
112 bShowIt = true;
113 // b)
114 else if (bCurrentHelpURLIsAnyDefaultURL)
115 bShowIt = true;
117 if (bShowIt)
119 // retrieve the help URL for the detected application module
120 OUString sModuleDependentHelpURL = its_checkIfHelpEnabledAndGetURL(sModule);
121 if (!sModuleDependentHelpURL.isEmpty())
123 // Show this help page.
124 // Note: The help window brings itself to front ...
125 Help* pHelp = Application::GetHelp();
126 if (pHelp)
127 pHelp->Start(sModuleDependentHelpURL, static_cast<vcl::Window*>(nullptr));
131 return css::uno::Any();
134 void SAL_CALL HelpOnStartup::disposing(const css::lang::EventObject& aEvent)
136 osl::MutexGuard g(m_mutex);
137 if (aEvent.Source == m_xModuleManager)
138 m_xModuleManager.clear();
139 else if (aEvent.Source == m_xDesktop)
140 m_xDesktop.clear();
141 else if (aEvent.Source == m_xConfig)
142 m_xConfig.clear();
145 OUString HelpOnStartup::its_getModuleIdFromEnv(const css::uno::Sequence< css::beans::NamedValue >& lArguments)
147 ::comphelper::SequenceAsHashMap lArgs (lArguments);
148 ::comphelper::SequenceAsHashMap lEnvironment = lArgs.getUnpackedValueOrDefault("Environment", css::uno::Sequence< css::beans::NamedValue >());
150 // check for right environment.
151 // If it's not a DocumentEvent, which triggered this job,
152 // we can't work correctly! => return immediately and do nothing
153 OUString sEnvType = lEnvironment.getUnpackedValueOrDefault("EnvType", OUString());
154 if (sEnvType != "DOCUMENTEVENT")
155 return OUString();
157 css::uno::Reference< css::frame::XModel > xDoc = lEnvironment.getUnpackedValueOrDefault("Model", css::uno::Reference< css::frame::XModel >());
158 if (!xDoc.is())
159 return OUString();
161 // be sure that we work on top level documents only, which are registered
162 // on the desktop instance. Ignore e.g. life previews, which are top frames too ...
163 // but not registered at this global desktop instance.
164 css::uno::Reference< css::frame::XDesktop > xDesktopCheck;
165 css::uno::Reference< css::frame::XFrame > xFrame;
166 css::uno::Reference< css::frame::XController > xController = xDoc->getCurrentController();
167 if (xController.is())
168 xFrame = xController->getFrame();
169 if (xFrame.is() && xFrame->isTop())
170 xDesktopCheck.set(xFrame->getCreator(), css::uno::UNO_QUERY);
171 if (!xDesktopCheck.is())
172 return OUString();
174 // OK - now we are sure this document is a top level document.
175 // Classify it.
176 // SAFE ->
177 osl::ClearableMutexGuard aLock(m_mutex);
178 css::uno::Reference< css::frame::XModuleManager2 > xModuleManager = m_xModuleManager;
179 aLock.clear();
180 // <- SAFE
182 OUString sModuleId;
185 sModuleId = xModuleManager->identify(xDoc);
187 catch(const css::uno::RuntimeException&)
188 { throw; }
189 catch(const css::uno::Exception&)
190 { sModuleId.clear(); }
192 return sModuleId;
195 OUString HelpOnStartup::its_getCurrentHelpURL()
197 // SAFE ->
198 osl::ClearableMutexGuard aLock(m_mutex);
199 css::uno::Reference< css::frame::XDesktop2 > xDesktop = m_xDesktop;
200 aLock.clear();
201 // <- SAFE
203 if (!xDesktop.is())
204 return OUString();
206 css::uno::Reference< css::frame::XFrame > xHelp = xDesktop->findFrame(SPECIALTARGET_HELPTASK, css::frame::FrameSearchFlag::CHILDREN);
207 if (!xHelp.is())
208 return OUString();
210 OUString sCurrentHelpURL;
213 css::uno::Reference< css::frame::XFramesSupplier > xHelpRoot (xHelp , css::uno::UNO_QUERY_THROW);
214 css::uno::Reference< css::container::XIndexAccess > xHelpChildren(xHelpRoot->getFrames(), css::uno::UNO_QUERY_THROW);
216 css::uno::Reference< css::frame::XFrame > xHelpChild;
217 css::uno::Reference< css::frame::XController > xHelpView;
218 css::uno::Reference< css::frame::XModel > xHelpContent;
220 xHelpChildren->getByIndex(0) >>= xHelpChild;
221 if (xHelpChild.is())
222 xHelpView = xHelpChild->getController();
223 if (xHelpView.is())
224 xHelpContent = xHelpView->getModel();
225 if (xHelpContent.is())
226 sCurrentHelpURL = xHelpContent->getURL();
228 catch(const css::uno::RuntimeException&)
229 { throw; }
230 catch(const css::uno::Exception&)
231 { sCurrentHelpURL.clear(); }
233 return sCurrentHelpURL;
236 bool HelpOnStartup::its_isHelpUrlADefaultOne(const OUString& sHelpURL)
238 if (sHelpURL.isEmpty())
239 return false;
241 // SAFE ->
242 osl::ClearableMutexGuard aLock(m_mutex);
243 css::uno::Reference< css::container::XNameAccess > xConfig = m_xConfig;
244 OUString sLocale = m_sLocale;
245 OUString sSystem = m_sSystem;
246 aLock.clear();
247 // <- SAFE
249 if (!xConfig.is())
250 return false;
252 // check given help url against all default ones
253 const css::uno::Sequence< OUString > lModules = xConfig->getElementNames();
254 const OUString* pModules = lModules.getConstArray();
255 ::sal_Int32 c = lModules.getLength();
256 ::sal_Int32 i = 0;
258 for (i=0; i<c; ++i)
262 css::uno::Reference< css::container::XNameAccess > xModuleConfig;
263 xConfig->getByName(pModules[i]) >>= xModuleConfig;
264 if (!xModuleConfig.is())
265 continue;
267 OUString sHelpBaseURL;
268 xModuleConfig->getByName("ooSetupFactoryHelpBaseURL") >>= sHelpBaseURL;
269 OUString sHelpURLForModule = HelpOnStartup::ist_createHelpURL(sHelpBaseURL, sLocale, sSystem);
270 if (sHelpURL == sHelpURLForModule)
271 return true;
273 catch(const css::uno::RuntimeException&)
274 { throw; }
275 catch(const css::uno::Exception&)
279 return false;
282 OUString HelpOnStartup::its_checkIfHelpEnabledAndGetURL(const OUString& sModule)
284 // SAFE ->
285 osl::ClearableMutexGuard aLock(m_mutex);
286 css::uno::Reference< css::container::XNameAccess > xConfig = m_xConfig;
287 OUString sLocale = m_sLocale;
288 OUString sSystem = m_sSystem;
289 aLock.clear();
290 // <- SAFE
292 OUString sHelpURL;
296 css::uno::Reference< css::container::XNameAccess > xModuleConfig;
297 if (xConfig.is())
298 xConfig->getByName(sModule) >>= xModuleConfig;
300 bool bHelpEnabled = false;
301 if (xModuleConfig.is())
302 xModuleConfig->getByName("ooSetupFactoryHelpOnOpen") >>= bHelpEnabled;
304 if (bHelpEnabled)
306 OUString sHelpBaseURL;
307 xModuleConfig->getByName("ooSetupFactoryHelpBaseURL") >>= sHelpBaseURL;
308 sHelpURL = HelpOnStartup::ist_createHelpURL(sHelpBaseURL, sLocale, sSystem);
311 catch(const css::uno::RuntimeException&)
312 { throw; }
313 catch(const css::uno::Exception&)
314 { sHelpURL.clear(); }
316 return sHelpURL;
319 OUString HelpOnStartup::ist_createHelpURL(const OUString& sBaseURL,
320 const OUString& sLocale ,
321 const OUString& sSystem )
323 return sBaseURL + "?Language=" + sLocale + "&System=" + sSystem;
326 } // namespace framework
328 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
329 framework_HelpOnStartup_get_implementation(
330 css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const& )
332 return cppu::acquire(new framework::HelpOnStartup(context));
335 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */