Avoid potential negative array index access to cached text.
[LibreOffice.git] / framework / source / accelerators / documentacceleratorconfiguration.cxx
blobc86895f0de32b64b5a3f6f8930b59df81e2ff0a3
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 <accelerators/acceleratorconfiguration.hxx>
21 #include <accelerators/presethandler.hxx>
23 #include <com/sun/star/lang/XServiceInfo.hpp>
25 #include <cppuhelper/implbase.hxx>
26 #include <cppuhelper/supportsservice.hxx>
27 #include <comphelper/sequenceashashmap.hxx>
28 #include <i18nlangtag/languagetag.hxx>
29 #include <vcl/svapp.hxx>
31 using namespace framework;
33 constexpr OUStringLiteral RESOURCETYPE_ACCELERATOR = u"accelerator";
35 namespace {
37 /**
38 implements a read/write access to a document
39 based accelerator configuration.
42 typedef ::cppu::ImplInheritanceHelper<
43 XMLBasedAcceleratorConfiguration,
44 css::lang::XServiceInfo> DocumentAcceleratorConfiguration_BASE;
46 class DocumentAcceleratorConfiguration : public DocumentAcceleratorConfiguration_BASE
48 private:
50 /** points to the root storage of the outside document,
51 where we can read/save our configuration data. */
52 css::uno::Reference< css::embed::XStorage > m_xDocumentRoot;
54 public:
56 /** initialize this instance and fill the internal cache.
58 @param xSMGR
59 reference to a uno service manager, which is used internally.
61 DocumentAcceleratorConfiguration(
62 const css::uno::Reference< css::uno::XComponentContext >& xContext,
63 const css::uno::Sequence< css::uno::Any >& lArguments);
65 virtual ~DocumentAcceleratorConfiguration() override;
67 virtual OUString SAL_CALL getImplementationName() override
69 return "com.sun.star.comp.framework.DocumentAcceleratorConfiguration";
72 virtual sal_Bool SAL_CALL supportsService(OUString const & ServiceName) override
74 return cppu::supportsService(this, ServiceName);
77 virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override
79 return {"com.sun.star.ui.DocumentAcceleratorConfiguration"};
82 // XUIConfigurationStorage
83 virtual void SAL_CALL setStorage(const css::uno::Reference< css::embed::XStorage >& xStorage) override;
85 virtual sal_Bool SAL_CALL hasStorage() override;
87 /** read all data into the cache. */
88 void fillCache();
91 DocumentAcceleratorConfiguration::DocumentAcceleratorConfiguration(
92 const css::uno::Reference< css::uno::XComponentContext >& xContext,
93 const css::uno::Sequence< css::uno::Any >& lArguments)
94 : DocumentAcceleratorConfiguration_BASE(xContext)
96 SolarMutexGuard g;
97 css::uno::Reference<css::embed::XStorage> xRoot;
98 if (lArguments.getLength() == 1 && (lArguments[0] >>= xRoot))
100 m_xDocumentRoot = xRoot;
102 else
104 ::comphelper::SequenceAsHashMap lArgs(lArguments);
105 m_xDocumentRoot = lArgs.getUnpackedValueOrDefault(
106 "DocumentRoot",
107 css::uno::Reference< css::embed::XStorage >());
111 DocumentAcceleratorConfiguration::~DocumentAcceleratorConfiguration()
113 m_aPresetHandler.removeStorageListener(this);
116 void SAL_CALL DocumentAcceleratorConfiguration::setStorage(const css::uno::Reference< css::embed::XStorage >& xStorage)
118 // Attention! xStorage must be accepted too, if it's NULL !
120 bool bForgetOldStorages;
122 SolarMutexGuard g;
123 bForgetOldStorages = m_xDocumentRoot.is();
124 m_xDocumentRoot = xStorage;
127 if (bForgetOldStorages)
128 /* forget all currently cached data AND(!) forget all currently used storages. */
129 m_aPresetHandler.forgetCachedStorages();
131 if (xStorage.is())
132 fillCache();
135 sal_Bool SAL_CALL DocumentAcceleratorConfiguration::hasStorage()
137 SolarMutexGuard g;
138 return m_xDocumentRoot.is();
141 void DocumentAcceleratorConfiguration::fillCache()
143 css::uno::Reference< css::embed::XStorage > xDocumentRoot;
145 SolarMutexGuard g;
146 xDocumentRoot = m_xDocumentRoot;
149 // Sometimes we must live without a document root.
150 // E.g. if the document is readonly ...
151 if (!xDocumentRoot.is())
152 return;
154 // get current office locale ... but don't cache it.
155 // Otherwise we must be listener on the configuration layer
156 // which seems to superfluous for this small implementation .-)
157 LanguageTag aLanguageTag( impl_ts_getLocale());
159 // May be the current document does not contain any
160 // accelerator config? Handle it gracefully :-)
163 // Note: The used preset class is threadsafe by itself ... and live if we live!
164 // We do not need any mutex here.
166 // open the folder, where the configuration exists
167 m_aPresetHandler.connectToResource(
168 PresetHandler::E_DOCUMENT,
169 RESOURCETYPE_ACCELERATOR,
170 u"",
171 xDocumentRoot,
172 aLanguageTag);
174 DocumentAcceleratorConfiguration::reload();
175 m_aPresetHandler.addStorageListener(this);
177 catch(const css::uno::Exception&)
181 } // namespace framework
183 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
184 com_sun_star_comp_framework_DocumentAcceleratorConfiguration_get_implementation(
185 css::uno::XComponentContext *context,
186 css::uno::Sequence<css::uno::Any> const &arguments)
188 rtl::Reference<DocumentAcceleratorConfiguration> inst = new DocumentAcceleratorConfiguration(context, arguments);
189 css::uno::XInterface *acquired_inst = cppu::acquire(inst.get());
191 inst->fillCache();
193 return acquired_inst;
196 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */