cid#1636561 Dereference after null check
[LibreOffice.git] / unotools / source / config / useroptions.cxx
blob3ce4665289bf73d4742dacd0ddff08d227317fb3
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 <sal/config.h>
22 #include <unotools/useroptions.hxx>
23 #include <unotools/syslocale.hxx>
24 #include <com/sun/star/uno/Any.hxx>
25 #include "itemholder1.hxx"
27 #include <cppuhelper/implbase.hxx>
28 #include <com/sun/star/beans/Property.hpp>
29 #include <com/sun/star/beans/XPropertySet.hpp>
30 #include <com/sun/star/beans/PropertyAttribute.hpp>
31 #include <com/sun/star/container/XNameAccess.hpp>
32 #include <com/sun/star/util/XChangesListener.hpp>
33 #include <com/sun/star/util/XChangesNotifier.hpp>
34 #include <com/sun/star/util/ChangesEvent.hpp>
35 #include <comphelper/configurationhelper.hxx>
36 #include <comphelper/processfactory.hxx>
37 #include <i18nlangtag/mslangid.hxx>
38 #include <i18nlangtag/languagetag.hxx>
39 #include <o3tl/enumarray.hxx>
40 #include <o3tl/string_view.hxx>
41 #include <comphelper/diagnose_ex.hxx>
43 using namespace utl;
44 using namespace com::sun::star;
46 // vOptionNames[] -- names of the user option entries
47 // The order must correspond to the enum class UserOptToken in useroptions.hxx.
48 constexpr o3tl::enumarray<UserOptToken, OUString> vOptionNames = {
49 u"l"_ustr, // UserOptToken::City
50 u"o"_ustr, // UserOptToken::Company
51 u"c"_ustr, // UserOptToken::Country
52 u"mail"_ustr, // UserOptToken::Email
53 u"facsimiletelephonenumber"_ustr, // UserOptToken::Fax
54 u"givenname"_ustr, // UserOptToken::FirstName
55 u"sn"_ustr, // UserOptToken::LastName
56 u"position"_ustr, // UserOptToken::Position
57 u"st"_ustr, // UserOptToken::State
58 u"street"_ustr, // UserOptToken::Street
59 u"homephone"_ustr, // UserOptToken::TelephoneHome
60 u"telephonenumber"_ustr, // UserOptToken::TelephoneWork
61 u"title"_ustr, // UserOptToken::Title
62 u"initials"_ustr, // UserOptToken::ID
63 u"postalcode"_ustr, // UserOptToken::Zip
64 u"fathersname"_ustr, // UserOptToken::FathersName
65 u"apartment"_ustr, // UserOptToken::Apartment
66 u"signingkey"_ustr, // UserOptToken::SigningKey
67 u"encryptionkey"_ustr, // UserOptToken::EncryptionKey
68 u"encrypttoself"_ustr, // UserOptToken::EncryptToSelf
69 u"signingkeydisplayname"_ustr, // UserOptToken::SigningKeyDisplayName
70 u"encryptionkeydisplayname"_ustr, // UserOptToken::EncryptionKeyDisplayName
73 std::weak_ptr<SvtUserOptions::Impl> SvtUserOptions::xSharedImpl;
75 class SvtUserOptions::ChangeListener : public cppu::WeakImplHelper<util::XChangesListener>
77 public:
78 explicit ChangeListener (Impl& rParent): m_rParent(rParent) { }
80 // XChangesListener
81 virtual void SAL_CALL changesOccurred (util::ChangesEvent const& Event) override;
82 // XEventListener
83 virtual void SAL_CALL disposing (lang::EventObject const& Source) override;
85 private:
86 Impl& m_rParent;
89 class SvtUserOptions::Impl : public utl::ConfigurationBroadcaster
91 public:
92 Impl ();
94 OUString GetFullName () const;
96 bool IsTokenReadonly (UserOptToken nToken) const;
97 OUString GetToken (UserOptToken nToken) const;
98 void SetToken (UserOptToken nToken, OUString const& rNewToken);
99 bool GetBoolValue (UserOptToken nToken) const;
100 void SetBoolValue (UserOptToken nToken, bool bNewValue);
101 void Notify ();
103 private:
104 uno::Reference<util::XChangesListener> m_xChangeListener;
105 uno::Reference<container::XNameAccess> m_xCfg;
106 uno::Reference<beans::XPropertySet> m_xData;
108 template < typename ValueType >
109 ValueType GetValue_Impl( UserOptToken nToken ) const;
110 template < typename ValueType >
111 void SetValue_Impl( UserOptToken nToken, ValueType const& rNewValue );
114 void SvtUserOptions::ChangeListener::changesOccurred (util::ChangesEvent const& rEvent)
116 if (rEvent.Changes.hasElements())
117 m_rParent.Notify();
120 void SvtUserOptions::ChangeListener::disposing (lang::EventObject const& rSource)
124 uno::Reference<util::XChangesNotifier> xChgNot(rSource.Source, uno::UNO_QUERY);
125 if (xChgNot)
126 xChgNot->removeChangesListener(this);
128 catch (uno::Exception&)
133 SvtUserOptions::Impl::Impl() :
134 m_xChangeListener( new ChangeListener(*this) )
138 m_xCfg.set(
139 comphelper::ConfigurationHelper::openConfig(
140 comphelper::getProcessComponentContext(),
141 u"org.openoffice.UserProfile/Data"_ustr,
142 comphelper::EConfigurationModes::Standard
144 uno::UNO_QUERY
147 m_xData.set(m_xCfg, uno::UNO_QUERY);
148 uno::Reference<util::XChangesNotifier> xChgNot(m_xCfg, uno::UNO_QUERY);
151 xChgNot->addChangesListener(m_xChangeListener);
153 catch (uno::RuntimeException&)
157 catch (uno::Exception const&)
159 DBG_UNHANDLED_EXCEPTION("unotools.config");
160 m_xCfg.clear();
164 template < typename ValueType >
165 ValueType SvtUserOptions::Impl::GetValue_Impl (UserOptToken nToken) const
167 ValueType sToken = ValueType();
170 if (m_xData.is())
171 m_xData->getPropertyValue(vOptionNames[nToken]) >>= sToken;
173 catch (uno::Exception const&)
175 DBG_UNHANDLED_EXCEPTION("unotools.config");
177 return sToken;
180 template < typename ValueType >
181 void SvtUserOptions::Impl::SetValue_Impl (UserOptToken nToken, ValueType const& sToken)
185 if (m_xData.is())
186 m_xData->setPropertyValue(vOptionNames[nToken], uno::Any(sToken));
187 comphelper::ConfigurationHelper::flush(m_xCfg);
189 catch (uno::Exception const&)
191 DBG_UNHANDLED_EXCEPTION("unotools.config");
195 OUString SvtUserOptions::Impl::GetToken (UserOptToken nToken) const
197 return GetValue_Impl<OUString>( nToken );
200 void SvtUserOptions::Impl::SetToken (UserOptToken nToken, OUString const& sToken)
202 SetValue_Impl<OUString>( nToken, sToken );
205 bool SvtUserOptions::Impl::GetBoolValue (UserOptToken nToken) const
207 return GetValue_Impl<bool>( nToken );
210 void SvtUserOptions::Impl::SetBoolValue (UserOptToken nToken, bool bNewValue)
212 SetValue_Impl<bool>( nToken, bNewValue );
215 OUString SvtUserOptions::Impl::GetFullName () const
217 OUString sFullName;
218 LanguageType const eLang = SvtSysLocale().GetUILanguageTag().getLanguageType();
219 if (eLang == LANGUAGE_RUSSIAN)
221 sFullName = GetToken(UserOptToken::FirstName).trim();
222 if (!sFullName.isEmpty())
223 sFullName += " ";
224 sFullName += o3tl::trim(GetToken(UserOptToken::FathersName));
225 if (!sFullName.isEmpty())
226 sFullName += " ";
227 sFullName += o3tl::trim(GetToken(UserOptToken::LastName));
229 else
231 if (MsLangId::isFamilyNameFirst(eLang))
233 sFullName = GetToken(UserOptToken::LastName).trim();
234 if (!sFullName.isEmpty())
235 sFullName += " ";
236 sFullName += o3tl::trim(GetToken(UserOptToken::FirstName));
238 else
240 sFullName = GetToken(UserOptToken::FirstName).trim();
241 if (!sFullName.isEmpty())
242 sFullName += " ";
243 sFullName += o3tl::trim(GetToken(UserOptToken::LastName));
246 sFullName = sFullName.trim();
248 return sFullName;
251 void SvtUserOptions::Impl::Notify ()
253 NotifyListeners(ConfigurationHints::NONE);
256 bool SvtUserOptions::Impl::IsTokenReadonly (UserOptToken nToken) const
258 uno::Reference<beans::XPropertySet> xData(m_xCfg, uno::UNO_QUERY);
259 uno::Reference<beans::XPropertySetInfo> xInfo = xData->getPropertySetInfo();
260 beans::Property aProp = xInfo->getPropertyByName(vOptionNames[nToken]);
261 return ((aProp.Attributes & beans::PropertyAttribute::READONLY) ==
262 beans::PropertyAttribute::READONLY);
265 static std::recursive_mutex& GetInitMutex()
267 static std::recursive_mutex gMutex;
268 return gMutex;
272 SvtUserOptions::SvtUserOptions ()
274 // Global access, must be guarded (multithreading)
275 std::unique_lock aGuard(GetInitMutex());
277 xImpl = xSharedImpl.lock();
278 if (!xImpl)
280 xImpl = std::make_shared<Impl>();
281 xSharedImpl = xImpl;
282 aGuard.unlock(); // because holdConfigItem will call this constructor
283 ItemHolder1::holdConfigItem(EItem::UserOptions);
285 xImpl->AddListener(this);
288 SvtUserOptions::~SvtUserOptions()
290 // Global access, must be guarded (multithreading)
291 std::unique_lock aGuard( GetInitMutex() );
292 xImpl->RemoveListener(this);
295 OUString SvtUserOptions::GetCompany () const { return GetToken(UserOptToken::Company); }
296 OUString SvtUserOptions::GetFirstName () const { return GetToken(UserOptToken::FirstName); }
297 OUString SvtUserOptions::GetLastName () const { return GetToken(UserOptToken::LastName); }
298 OUString SvtUserOptions::GetID () const { return GetToken(UserOptToken::ID); }
299 OUString SvtUserOptions::GetStreet () const { return GetToken(UserOptToken::Street); }
300 OUString SvtUserOptions::GetCity () const { return GetToken(UserOptToken::City); }
301 OUString SvtUserOptions::GetState () const { return GetToken(UserOptToken::State); }
302 OUString SvtUserOptions::GetZip () const { return GetToken(UserOptToken::Zip); }
303 OUString SvtUserOptions::GetCountry () const { return GetToken(UserOptToken::Country); }
304 OUString SvtUserOptions::GetPosition () const { return GetToken(UserOptToken::Position); }
305 OUString SvtUserOptions::GetTitle () const { return GetToken(UserOptToken::Title); }
306 OUString SvtUserOptions::GetTelephoneHome () const { return GetToken(UserOptToken::TelephoneHome); }
307 OUString SvtUserOptions::GetTelephoneWork () const { return GetToken(UserOptToken::TelephoneWork); }
308 OUString SvtUserOptions::GetFax () const { return GetToken(UserOptToken::Fax); }
309 OUString SvtUserOptions::GetEmail () const { return GetToken(UserOptToken::Email); }
310 OUString SvtUserOptions::GetSigningKey () const { return GetToken(UserOptToken::SigningKey); }
311 OUString SvtUserOptions::GetEncryptionKey () const { return GetToken(UserOptToken::EncryptionKey); }
312 OUString SvtUserOptions::GetSigningKeyDisplayName () const { return GetToken(UserOptToken::SigningKeyDisplayName); }
313 OUString SvtUserOptions::GetEncryptionKeyDisplayName () const { return GetToken(UserOptToken::EncryptionKeyDisplayName); }
315 bool SvtUserOptions::IsTokenReadonly (UserOptToken nToken) const
317 std::unique_lock aGuard(GetInitMutex());
318 return xImpl->IsTokenReadonly(nToken);
321 OUString SvtUserOptions::GetToken (UserOptToken nToken) const
323 std::unique_lock aGuard(GetInitMutex());
324 return xImpl->GetToken(nToken);
327 void SvtUserOptions::SetToken (UserOptToken nToken, OUString const& rNewToken)
329 std::unique_lock aGuard(GetInitMutex());
330 xImpl->SetToken(nToken, rNewToken);
333 void SvtUserOptions::SetBoolValue (UserOptToken nToken, bool bNewValue)
335 std::unique_lock aGuard(GetInitMutex());
336 xImpl->SetBoolValue(nToken, bNewValue);
339 bool SvtUserOptions::GetEncryptToSelf() const
341 std::unique_lock aGuard(GetInitMutex());
342 return xImpl->GetBoolValue(UserOptToken::EncryptToSelf);
345 OUString SvtUserOptions::GetFullName () const
347 std::unique_lock aGuard(GetInitMutex());
348 return xImpl->GetFullName();
351 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */