calc: on editing invalidation of view with different zoom is wrong
[LibreOffice.git] / framework / source / jobs / helponstartup.cxx
blob2795a3f45057777d37e12e048cd18aa0bb6e9620
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 <utility>
31 #include <vcl/svapp.hxx>
32 #include <vcl/help.hxx>
34 // include interfaces
35 #include <com/sun/star/frame/FrameSearchFlag.hpp>
36 #include <com/sun/star/frame/ModuleManager.hpp>
37 #include <com/sun/star/frame/XFramesSupplier.hpp>
38 #include <com/sun/star/frame/Desktop.hpp>
39 #include <cppuhelper/supportsservice.hxx>
41 namespace framework{
43 // XInterface, XTypeProvider, XServiceInfo
45 OUString SAL_CALL HelpOnStartup::getImplementationName()
47 return "com.sun.star.comp.framework.HelpOnStartup";
50 sal_Bool SAL_CALL HelpOnStartup::supportsService( const OUString& sServiceName )
52 return cppu::supportsService(this, sServiceName);
55 css::uno::Sequence< OUString > SAL_CALL HelpOnStartup::getSupportedServiceNames()
57 return { SERVICENAME_JOB };
60 HelpOnStartup::HelpOnStartup(css::uno::Reference< css::uno::XComponentContext > xContext)
61 : m_xContext (std::move(xContext))
63 // create some needed uno services and cache it
64 m_xModuleManager = css::frame::ModuleManager::create( m_xContext );
66 m_xDesktop = css::frame::Desktop::create(m_xContext);
68 // ask for office locale
69 m_sLocale = officecfg::Setup::L10N::ooLocale::get();
71 // detect system
72 m_sSystem = officecfg::Office::Common::Help::System::get();
74 // Start listening for disposing events of these services,
75 // so we can react e.g. for an office shutdown
76 css::uno::Reference< css::lang::XComponent > xComponent;
77 xComponent.set(m_xModuleManager, css::uno::UNO_QUERY);
78 if (xComponent.is())
79 xComponent->addEventListener(static_cast< css::lang::XEventListener* >(this));
80 if (m_xDesktop.is())
81 m_xDesktop->addEventListener(static_cast< css::lang::XEventListener* >(this));
82 xComponent.set(m_xConfig, css::uno::UNO_QUERY);
83 if (xComponent.is())
84 xComponent->addEventListener(static_cast< css::lang::XEventListener* >(this));
87 HelpOnStartup::~HelpOnStartup()
91 // css.task.XJob
92 css::uno::Any SAL_CALL HelpOnStartup::execute(const css::uno::Sequence< css::beans::NamedValue >& lArguments)
94 // Analyze the given arguments; try to locate a model there and
95 // classify it's used application module.
96 OUString sModule = its_getModuleIdFromEnv(lArguments);
98 // Attention: we are bound to events for opening any document inside the office.
99 // That includes e.g. the help module itself. But we have to do nothing then!
100 if (sModule.isEmpty())
101 return css::uno::Any();
103 // check current state of the help module
104 // a) help isn't open => show default page for the detected module
105 // b) help shows any other default page(!) => show default page for the detected module
106 // c) help shows any other content => do nothing (user travelled to any other content and leaved the set of default pages)
107 OUString sCurrentHelpURL = its_getCurrentHelpURL();
108 bool bCurrentHelpURLIsAnyDefaultURL = its_isHelpUrlADefaultOne(sCurrentHelpURL);
109 bool bShowIt = false;
111 // a)
112 if (sCurrentHelpURL.isEmpty())
113 bShowIt = true;
114 // b)
115 else if (bCurrentHelpURLIsAnyDefaultURL)
116 bShowIt = true;
118 if (bShowIt)
120 // retrieve the help URL for the detected application module
121 OUString sModuleDependentHelpURL = its_checkIfHelpEnabledAndGetURL(sModule);
122 if (!sModuleDependentHelpURL.isEmpty())
124 // Show this help page.
125 // Note: The help window brings itself to front ...
126 Help* pHelp = Application::GetHelp();
127 if (pHelp)
128 pHelp->Start(sModuleDependentHelpURL);
132 return css::uno::Any();
135 void SAL_CALL HelpOnStartup::disposing(const css::lang::EventObject& aEvent)
137 std::unique_lock g(m_mutex);
138 if (aEvent.Source == m_xModuleManager)
139 m_xModuleManager.clear();
140 else if (aEvent.Source == m_xDesktop)
141 m_xDesktop.clear();
142 else if (aEvent.Source == m_xConfig)
143 m_xConfig.clear();
146 OUString HelpOnStartup::its_getModuleIdFromEnv(const css::uno::Sequence< css::beans::NamedValue >& lArguments)
148 ::comphelper::SequenceAsHashMap lArgs (lArguments);
149 ::comphelper::SequenceAsHashMap lEnvironment = lArgs.getUnpackedValueOrDefault("Environment", css::uno::Sequence< css::beans::NamedValue >());
151 // check for right environment.
152 // If it's not a DocumentEvent, which triggered this job,
153 // we can't work correctly! => return immediately and do nothing
154 OUString sEnvType = lEnvironment.getUnpackedValueOrDefault("EnvType", OUString());
155 if (sEnvType != "DOCUMENTEVENT")
156 return OUString();
158 css::uno::Reference< css::frame::XModel > xDoc = lEnvironment.getUnpackedValueOrDefault("Model", css::uno::Reference< css::frame::XModel >());
159 if (!xDoc.is())
160 return OUString();
162 // be sure that we work on top level documents only, which are registered
163 // on the desktop instance. Ignore e.g. life previews, which are top frames too ...
164 // but not registered at this global desktop instance.
165 css::uno::Reference< css::frame::XDesktop > xDesktopCheck;
166 css::uno::Reference< css::frame::XFrame > xFrame;
167 css::uno::Reference< css::frame::XController > xController = xDoc->getCurrentController();
168 if (xController.is())
169 xFrame = xController->getFrame();
170 if (xFrame.is() && xFrame->isTop())
171 xDesktopCheck.set(xFrame->getCreator(), css::uno::UNO_QUERY);
172 if (!xDesktopCheck.is())
173 return OUString();
175 // OK - now we are sure this document is a top level document.
176 // Classify it.
177 // SAFE ->
178 std::unique_lock aLock(m_mutex);
179 css::uno::Reference< css::frame::XModuleManager2 > xModuleManager = m_xModuleManager;
180 aLock.unlock();
181 // <- SAFE
183 OUString sModuleId;
186 sModuleId = xModuleManager->identify(xDoc);
188 catch(const css::uno::RuntimeException&)
189 { throw; }
190 catch(const css::uno::Exception&)
191 { sModuleId.clear(); }
193 return sModuleId;
196 OUString HelpOnStartup::its_getCurrentHelpURL()
198 // SAFE ->
199 std::unique_lock aLock(m_mutex);
200 css::uno::Reference< css::frame::XDesktop2 > xDesktop = m_xDesktop;
201 aLock.unlock();
202 // <- SAFE
204 if (!xDesktop.is())
205 return OUString();
207 css::uno::Reference< css::frame::XFrame > xHelp = xDesktop->findFrame(SPECIALTARGET_HELPTASK, css::frame::FrameSearchFlag::CHILDREN);
208 if (!xHelp.is())
209 return OUString();
211 OUString sCurrentHelpURL;
214 css::uno::Reference< css::frame::XFramesSupplier > xHelpRoot (xHelp , css::uno::UNO_QUERY_THROW);
215 css::uno::Reference< css::container::XIndexAccess > xHelpChildren(xHelpRoot->getFrames(), css::uno::UNO_QUERY_THROW);
217 css::uno::Reference< css::frame::XFrame > xHelpChild;
218 css::uno::Reference< css::frame::XController > xHelpView;
219 css::uno::Reference< css::frame::XModel > xHelpContent;
221 xHelpChildren->getByIndex(0) >>= xHelpChild;
222 if (xHelpChild.is())
223 xHelpView = xHelpChild->getController();
224 if (xHelpView.is())
225 xHelpContent = xHelpView->getModel();
226 if (xHelpContent.is())
227 sCurrentHelpURL = xHelpContent->getURL();
229 catch(const css::uno::RuntimeException&)
230 { throw; }
231 catch(const css::uno::Exception&)
232 { sCurrentHelpURL.clear(); }
234 return sCurrentHelpURL;
237 bool HelpOnStartup::its_isHelpUrlADefaultOne(std::u16string_view sHelpURL)
239 if (sHelpURL.empty())
240 return false;
242 // SAFE ->
243 std::unique_lock aLock(m_mutex);
244 css::uno::Reference< css::container::XNameAccess > xConfig = m_xConfig;
245 OUString sLocale = m_sLocale;
246 OUString sSystem = m_sSystem;
247 aLock.unlock();
248 // <- SAFE
250 if (!xConfig.is())
251 return false;
253 // check given help url against all default ones
254 const css::uno::Sequence< OUString > lModules = xConfig->getElementNames();
255 const OUString* pModules = lModules.getConstArray();
256 ::sal_Int32 c = lModules.getLength();
257 ::sal_Int32 i = 0;
259 for (i=0; i<c; ++i)
263 css::uno::Reference< css::container::XNameAccess > xModuleConfig;
264 xConfig->getByName(pModules[i]) >>= xModuleConfig;
265 if (!xModuleConfig.is())
266 continue;
268 OUString sHelpBaseURL;
269 xModuleConfig->getByName("ooSetupFactoryHelpBaseURL") >>= sHelpBaseURL;
270 OUString sHelpURLForModule = HelpOnStartup::ist_createHelpURL(sHelpBaseURL, sLocale, sSystem);
271 if (sHelpURL == sHelpURLForModule)
272 return true;
274 catch(const css::uno::RuntimeException&)
275 { throw; }
276 catch(const css::uno::Exception&)
280 return false;
283 OUString HelpOnStartup::its_checkIfHelpEnabledAndGetURL(const OUString& sModule)
285 // SAFE ->
286 std::unique_lock aLock(m_mutex);
287 css::uno::Reference< css::container::XNameAccess > xConfig = m_xConfig;
288 OUString sLocale = m_sLocale;
289 OUString sSystem = m_sSystem;
290 aLock.unlock();
291 // <- SAFE
293 OUString sHelpURL;
297 css::uno::Reference< css::container::XNameAccess > xModuleConfig;
298 if (xConfig.is())
299 xConfig->getByName(sModule) >>= xModuleConfig;
301 bool bHelpEnabled = false;
302 if (xModuleConfig.is())
303 xModuleConfig->getByName("ooSetupFactoryHelpOnOpen") >>= bHelpEnabled;
305 if (bHelpEnabled)
307 OUString sHelpBaseURL;
308 xModuleConfig->getByName("ooSetupFactoryHelpBaseURL") >>= sHelpBaseURL;
309 sHelpURL = HelpOnStartup::ist_createHelpURL(sHelpBaseURL, sLocale, sSystem);
312 catch(const css::uno::RuntimeException&)
313 { throw; }
314 catch(const css::uno::Exception&)
315 { sHelpURL.clear(); }
317 return sHelpURL;
320 OUString HelpOnStartup::ist_createHelpURL(std::u16string_view sBaseURL,
321 std::u16string_view sLocale ,
322 std::u16string_view sSystem )
324 return OUString::Concat(sBaseURL) + "?Language=" + sLocale + "&System=" + sSystem;
327 } // namespace framework
329 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
330 framework_HelpOnStartup_get_implementation(
331 css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const& )
333 return cppu::acquire(new framework::HelpOnStartup(context));
336 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */