fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / framework / source / jobs / helponstartup.cxx
blob198af2d038afdd9006417e640c4f7e4a10b02eea
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 <loadenv/targethelper.hxx>
23 #include <services.h>
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>
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>
39 namespace framework{
41 DEFINE_XSERVICEINFO_MULTISERVICE_2(HelpOnStartup ,
42 ::cppu::OWeakObject ,
43 SERVICENAME_JOB ,
44 IMPLEMENTATIONNAME_HELPONSTARTUP)
46 DEFINE_INIT_SERVICE(HelpOnStartup,
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!
53 // create some needed uno services and cache it
54 m_xModuleManager = css::frame::ModuleManager::create( m_xContext );
56 m_xDesktop = css::frame::Desktop::create(m_xContext);
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);
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;
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;
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));
96 HelpOnStartup::HelpOnStartup(const css::uno::Reference< css::uno::XComponentContext >& xContext)
97 : m_xContext (xContext)
101 HelpOnStartup::~HelpOnStartup()
105 // css.task.XJob
106 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 )
111 // Analyze the given arguments; try to locate a model there and
112 // classify it's used application module.
113 OUString sModule = its_getModuleIdFromEnv(lArguments);
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 if (sModule.isEmpty())
118 return css::uno::Any();
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 OUString sCurrentHelpURL = its_getCurrentHelpURL();
125 bool bCurrentHelpURLIsAnyDefaultURL = its_isHelpUrlADefaultOne(sCurrentHelpURL);
126 bool bShowIt = false;
128 // a)
129 if (sCurrentHelpURL.isEmpty())
130 bShowIt = true;
131 // b)
132 else if (bCurrentHelpURLIsAnyDefaultURL)
133 bShowIt = true;
135 if (bShowIt)
137 // retrieve the help URL for the detected application module
138 OUString sModuleDependendHelpURL = its_checkIfHelpEnabledAndGetURL(sModule);
139 if (!sModuleDependendHelpURL.isEmpty())
141 // Show this help page.
142 // Note: The help window brings itself to front ...
143 Help* pHelp = Application::GetHelp();
144 if (pHelp)
145 pHelp->Start(sModuleDependendHelpURL, 0);
149 return css::uno::Any();
152 void SAL_CALL HelpOnStartup::disposing(const css::lang::EventObject& aEvent)
153 throw(css::uno::RuntimeException, std::exception)
155 osl::MutexGuard g(m_mutex);
156 if (aEvent.Source == m_xModuleManager)
157 m_xModuleManager.clear();
158 else if (aEvent.Source == m_xDesktop)
159 m_xDesktop.clear();
160 else if (aEvent.Source == m_xConfig)
161 m_xConfig.clear();
164 OUString HelpOnStartup::its_getModuleIdFromEnv(const css::uno::Sequence< css::beans::NamedValue >& lArguments)
166 ::comphelper::SequenceAsHashMap lArgs (lArguments);
167 ::comphelper::SequenceAsHashMap lEnvironment = lArgs.getUnpackedValueOrDefault("Environment", css::uno::Sequence< css::beans::NamedValue >());
168 ::comphelper::SequenceAsHashMap lJobConfig = lArgs.getUnpackedValueOrDefault("JobConfig", css::uno::Sequence< css::beans::NamedValue >());
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 OUString sEnvType = lEnvironment.getUnpackedValueOrDefault("EnvType", OUString());
174 if (sEnvType != "DOCUMENTEVENT")
175 return OUString();
177 css::uno::Reference< css::frame::XModel > xDoc = lEnvironment.getUnpackedValueOrDefault("Model", css::uno::Reference< css::frame::XModel >());
178 if (!xDoc.is())
179 return OUString();
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 css::uno::Reference< css::frame::XDesktop > xDesktopCheck;
185 css::uno::Reference< css::frame::XFrame > xFrame;
186 css::uno::Reference< css::frame::XController > xController = xDoc->getCurrentController();
187 if (xController.is())
188 xFrame = xController->getFrame();
189 if (xFrame.is() && xFrame->isTop())
190 xDesktopCheck = css::uno::Reference< css::frame::XDesktop >(xFrame->getCreator(), css::uno::UNO_QUERY);
191 if (!xDesktopCheck.is())
192 return OUString();
194 // OK - now we are sure this document is a top level document.
195 // Classify it.
196 // SAFE ->
197 osl::ClearableMutexGuard aLock(m_mutex);
198 css::uno::Reference< css::frame::XModuleManager2 > xModuleManager = m_xModuleManager;
199 aLock.clear();
200 // <- SAFE
202 OUString sModuleId;
205 sModuleId = xModuleManager->identify(xDoc);
207 catch(const css::uno::RuntimeException&)
208 { throw; }
209 catch(const css::uno::Exception&)
210 { sModuleId.clear(); }
212 return sModuleId;
215 OUString HelpOnStartup::its_getCurrentHelpURL()
217 // SAFE ->
218 osl::ClearableMutexGuard aLock(m_mutex);
219 css::uno::Reference< css::frame::XDesktop2 > xDesktop = m_xDesktop;
220 aLock.clear();
221 // <- SAFE
223 if (!xDesktop.is())
224 return OUString();
226 css::uno::Reference< css::frame::XFrame > xHelp = xDesktop->findFrame(SPECIALTARGET_HELPTASK, css::frame::FrameSearchFlag::CHILDREN);
227 if (!xHelp.is())
228 return OUString();
230 OUString sCurrentHelpURL;
233 css::uno::Reference< css::frame::XFramesSupplier > xHelpRoot (xHelp , css::uno::UNO_QUERY_THROW);
234 css::uno::Reference< css::container::XIndexAccess > xHelpChildren(xHelpRoot->getFrames(), css::uno::UNO_QUERY_THROW);
236 css::uno::Reference< css::frame::XFrame > xHelpChild;
237 css::uno::Reference< css::frame::XController > xHelpView;
238 css::uno::Reference< css::frame::XModel > xHelpContent;
240 xHelpChildren->getByIndex(0) >>= xHelpChild;
241 if (xHelpChild.is())
242 xHelpView = xHelpChild->getController();
243 if (xHelpView.is())
244 xHelpContent = xHelpView->getModel();
245 if (xHelpContent.is())
246 sCurrentHelpURL = xHelpContent->getURL();
248 catch(const css::uno::RuntimeException&)
249 { throw; }
250 catch(const css::uno::Exception&)
251 { sCurrentHelpURL.clear(); }
253 return sCurrentHelpURL;
256 bool HelpOnStartup::its_isHelpUrlADefaultOne(const OUString& sHelpURL)
258 if (sHelpURL.isEmpty())
259 return false;
261 // SAFE ->
262 osl::ClearableMutexGuard aLock(m_mutex);
263 css::uno::Reference< css::container::XNameAccess > xConfig = m_xConfig;
264 OUString sLocale = m_sLocale;
265 OUString sSystem = m_sSystem;
266 aLock.clear();
267 // <- SAFE
269 if (!xConfig.is())
270 return false;
272 // check given help url against all default ones
273 const css::uno::Sequence< OUString > lModules = xConfig->getElementNames();
274 const OUString* pModules = lModules.getConstArray();
275 ::sal_Int32 c = lModules.getLength();
276 ::sal_Int32 i = 0;
278 for (i=0; i<c; ++i)
282 css::uno::Reference< css::container::XNameAccess > xModuleConfig;
283 xConfig->getByName(pModules[i]) >>= xModuleConfig;
284 if (!xModuleConfig.is())
285 continue;
287 OUString sHelpBaseURL;
288 xModuleConfig->getByName("ooSetupFactoryHelpBaseURL") >>= sHelpBaseURL;
289 OUString sHelpURLForModule = HelpOnStartup::ist_createHelpURL(sHelpBaseURL, sLocale, sSystem);
290 if (sHelpURL.equals(sHelpURLForModule))
291 return true;
293 catch(const css::uno::RuntimeException&)
294 { throw; }
295 catch(const css::uno::Exception&)
299 return false;
302 OUString HelpOnStartup::its_checkIfHelpEnabledAndGetURL(const OUString& sModule)
304 // SAFE ->
305 osl::ClearableMutexGuard aLock(m_mutex);
306 css::uno::Reference< css::container::XNameAccess > xConfig = m_xConfig;
307 OUString sLocale = m_sLocale;
308 OUString sSystem = m_sSystem;
309 aLock.clear();
310 // <- SAFE
312 OUString sHelpURL;
316 css::uno::Reference< css::container::XNameAccess > xModuleConfig;
317 if (xConfig.is())
318 xConfig->getByName(sModule) >>= xModuleConfig;
320 bool bHelpEnabled = false;
321 if (xModuleConfig.is())
322 xModuleConfig->getByName("ooSetupFactoryHelpOnOpen") >>= bHelpEnabled;
324 if (bHelpEnabled)
326 OUString sHelpBaseURL;
327 xModuleConfig->getByName("ooSetupFactoryHelpBaseURL") >>= sHelpBaseURL;
328 sHelpURL = HelpOnStartup::ist_createHelpURL(sHelpBaseURL, sLocale, sSystem);
331 catch(const css::uno::RuntimeException&)
332 { throw; }
333 catch(const css::uno::Exception&)
334 { sHelpURL.clear(); }
336 return sHelpURL;
339 OUString HelpOnStartup::ist_createHelpURL(const OUString& sBaseURL,
340 const OUString& sLocale ,
341 const OUString& sSystem )
343 OUStringBuffer sHelpURL(256);
344 sHelpURL.append (sBaseURL );
345 sHelpURL.appendAscii("?Language=");
346 sHelpURL.append (sLocale );
347 sHelpURL.appendAscii("&System=" );
348 sHelpURL.append (sSystem );
350 return sHelpURL.makeStringAndClear();
353 } // namespace framework
355 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */