1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20 #include <sal/config.h>
21
22 #include <unotools/useroptions.hxx>
23 #include <unotools/syslocale.hxx>
24 #include <com/sun/star/uno/Any.hxx>
25 #include <osl/mutex.hxx>
26 #include <rtl/instance.hxx>
27 #include "itemholder1.hxx"
28
29 #include <cppuhelper/implbase.hxx>
30 #include <com/sun/star/beans/Property.hpp>
31 #include <com/sun/star/beans/XPropertySet.hpp>
32 #include <com/sun/star/beans/PropertyAttribute.hpp>
33 #include <com/sun/star/container/XNameAccess.hpp>
34 #include <com/sun/star/util/XChangesListener.hpp>
35 #include <com/sun/star/util/XChangesNotifier.hpp>
36 #include <com/sun/star/util/ChangesEvent.hpp>
37 #include <comphelper/configurationhelper.hxx>
38 #include <comphelper/processfactory.hxx>
39 #include <i18nlangtag/mslangid.hxx>
40 #include <i18nlangtag/languagetag.hxx>
41 #include <o3tl/enumarray.hxx>
42 #include <tools/diagnose_ex.h>
43
44 using namespace utl;
45 using namespace com::sun::star;
46
47 // vOptionNames[] -- names of the user option entries
48 // The order must correspond to the enum class UserOptToken in useroptions.hxx.
49 static o3tl::enumarray<UserOptToken, char const *> vOptionNames = {
50 "l", // UserOptToken::City
51 "o", // UserOptToken::Company
52 "c", // UserOptToken::Country
53 "mail", // UserOptToken::Email
54 "facsimiletelephonenumber", // UserOptToken::Fax
55 "givenname", // UserOptToken::FirstName
56 "sn", // UserOptToken::LastName
57 "position", // UserOptToken::Position
58 "st", // UserOptToken::State
59 "street", // UserOptToken::Street
60 "homephone", // UserOptToken::TelephoneHome
61 "telephonenumber", // UserOptToken::TelephoneWork
62 "title", // UserOptToken::Title
63 "initials", // UserOptToken::ID
64 "postalcode", // UserOptToken::Zip
65 "fathersname", // UserOptToken::FathersName
66 "apartment", // UserOptToken::Apartment
67 "signingkey", // UserOptToken::SigningKey
68 "encryptionkey", // UserOptToken::EncryptionKey
69 "encrypttoself" // UserOptToken::EncryptToSelf
70 };
71
72 std::weak_ptr<SvtUserOptions::Impl> SvtUserOptions::xSharedImpl;
73
74 class SvtUserOptions::ChangeListener : public cppu::WeakImplHelper<util::XChangesListener>
75 {
76 public:
ChangeListener(Impl & rParent)77 explicit ChangeListener (Impl& rParent): m_rParent(rParent) { }
78
79 // XChangesListener
80 virtual void SAL_CALL changesOccurred (util::ChangesEvent const& Event) override;
81 // XEventListener
82 virtual void SAL_CALL disposing (lang::EventObject const& Source) override;
83
84 private:
85 Impl& m_rParent;
86 };
87
88 class SvtUserOptions::Impl : public utl::ConfigurationBroadcaster
89 {
90 public:
91 Impl ();
92
93 OUString GetFullName () const;
94
95 bool IsTokenReadonly (UserOptToken nToken) const;
96 OUString GetToken (UserOptToken nToken) const;
97 void SetToken (UserOptToken nToken, OUString const& rNewToken);
98 bool GetBoolValue (UserOptToken nToken) const;
99 void SetBoolValue (UserOptToken nToken, bool bNewValue);
100 void Notify ();
101
102 private:
103 uno::Reference<util::XChangesListener> m_xChangeListener;
104 uno::Reference<container::XNameAccess> m_xCfg;
105 uno::Reference<beans::XPropertySet> m_xData;
106
107 template < typename ValueType >
108 ValueType GetValue_Impl( UserOptToken nToken ) const;
109 template < typename ValueType >
110 void SetValue_Impl( UserOptToken nToken, ValueType const& rNewValue );
111 };
112
changesOccurred(util::ChangesEvent const & rEvent)113 void SvtUserOptions::ChangeListener::changesOccurred (util::ChangesEvent const& rEvent)
114 {
115 if (rEvent.Changes.hasElements())
116 m_rParent.Notify();
117 }
118
disposing(lang::EventObject const & rSource)119 void SvtUserOptions::ChangeListener::disposing (lang::EventObject const& rSource)
120 {
121 try
122 {
123 uno::Reference<util::XChangesNotifier> xChgNot(rSource.Source, uno::UNO_QUERY_THROW);
124 xChgNot->removeChangesListener(this);
125 }
126 catch (uno::Exception&)
127 {
128 }
129 }
130
Impl()131 SvtUserOptions::Impl::Impl() :
132 m_xChangeListener( new ChangeListener(*this) )
133 {
134 try
135 {
136 m_xCfg.set(
137 comphelper::ConfigurationHelper::openConfig(
138 comphelper::getProcessComponentContext(),
139 "org.openoffice.UserProfile/Data",
140 comphelper::EConfigurationModes::Standard
141 ),
142 uno::UNO_QUERY
143 );
144
145 m_xData.set(m_xCfg, uno::UNO_QUERY);
146 uno::Reference<util::XChangesNotifier> xChgNot(m_xCfg, uno::UNO_QUERY);
147 try
148 {
149 xChgNot->addChangesListener(m_xChangeListener);
150 }
151 catch (uno::RuntimeException&)
152 {
153 }
154 }
155 catch (uno::Exception const&)
156 {
157 DBG_UNHANDLED_EXCEPTION("unotools.config");
158 m_xCfg.clear();
159 }
160 }
161
162 template < typename ValueType >
GetValue_Impl(UserOptToken nToken) const163 ValueType SvtUserOptions::Impl::GetValue_Impl (UserOptToken nToken) const
164 {
165 ValueType sToken = ValueType();
166 try
167 {
168 if (m_xData.is())
169 m_xData->getPropertyValue(OUString::createFromAscii(vOptionNames[nToken])) >>= sToken;
170 }
171 catch (uno::Exception const&)
172 {
173 DBG_UNHANDLED_EXCEPTION("unotools.config");
174 }
175 return sToken;
176 }
177
178 template < typename ValueType >
SetValue_Impl(UserOptToken nToken,ValueType const & sToken)179 void SvtUserOptions::Impl::SetValue_Impl (UserOptToken nToken, ValueType const& sToken)
180 {
181 try
182 {
183 if (m_xData.is())
184 m_xData->setPropertyValue(OUString::createFromAscii(vOptionNames[nToken]), uno::makeAny(sToken));
185 comphelper::ConfigurationHelper::flush(m_xCfg);
186 }
187 catch (uno::Exception const&)
188 {
189 DBG_UNHANDLED_EXCEPTION("unotools.config");
190 }
191 }
192
GetToken(UserOptToken nToken) const193 OUString SvtUserOptions::Impl::GetToken (UserOptToken nToken) const
194 {
195 return GetValue_Impl<OUString>( nToken );
196 }
197
SetToken(UserOptToken nToken,OUString const & sToken)198 void SvtUserOptions::Impl::SetToken (UserOptToken nToken, OUString const& sToken)
199 {
200 SetValue_Impl<OUString>( nToken, sToken );
201 }
202
GetBoolValue(UserOptToken nToken) const203 bool SvtUserOptions::Impl::GetBoolValue (UserOptToken nToken) const
204 {
205 return GetValue_Impl<bool>( nToken );
206 }
207
SetBoolValue(UserOptToken nToken,bool bNewValue)208 void SvtUserOptions::Impl::SetBoolValue (UserOptToken nToken, bool bNewValue)
209 {
210 SetValue_Impl<bool>( nToken, bNewValue );
211 }
212
GetFullName() const213 OUString SvtUserOptions::Impl::GetFullName () const
214 {
215 OUString sFullName;
216 LanguageType const eLang = SvtSysLocale().GetUILanguageTag().getLanguageType();
217 if (eLang == LANGUAGE_RUSSIAN)
218 {
219 sFullName = GetToken(UserOptToken::FirstName).trim();
220 if (!sFullName.isEmpty())
221 sFullName += " ";
222 sFullName += GetToken(UserOptToken::FathersName).trim();
223 if (!sFullName.isEmpty())
224 sFullName += " ";
225 sFullName += GetToken(UserOptToken::LastName).trim();
226 }
227 else
228 {
229 if (MsLangId::isFamilyNameFirst(eLang))
230 {
231 sFullName = GetToken(UserOptToken::LastName).trim();
232 if (!sFullName.isEmpty())
233 sFullName += " ";
234 sFullName += GetToken(UserOptToken::FirstName).trim();
235 }
236 else
237 {
238 sFullName = GetToken(UserOptToken::FirstName).trim();
239 if (!sFullName.isEmpty())
240 sFullName += " ";
241 sFullName += GetToken(UserOptToken::LastName).trim();
242 }
243 }
244
245 return sFullName;
246 }
247
Notify()248 void SvtUserOptions::Impl::Notify ()
249 {
250 NotifyListeners(ConfigurationHints::NONE);
251 }
252
IsTokenReadonly(UserOptToken nToken) const253 bool SvtUserOptions::Impl::IsTokenReadonly (UserOptToken nToken) const
254 {
255 uno::Reference<beans::XPropertySet> xData(m_xCfg, uno::UNO_QUERY);
256 uno::Reference<beans::XPropertySetInfo> xInfo = xData->getPropertySetInfo();
257 beans::Property aProp = xInfo->getPropertyByName(OUString::createFromAscii(vOptionNames[nToken]));
258 return ((aProp.Attributes & beans::PropertyAttribute::READONLY) ==
259 beans::PropertyAttribute::READONLY);
260 }
261
SvtUserOptions()262 SvtUserOptions::SvtUserOptions ()
263 {
264 // Global access, must be guarded (multithreading)
265 osl::MutexGuard aGuard(GetInitMutex());
266
267 if (xSharedImpl.expired())
268 {
269 xImpl.reset(new Impl);
270 xSharedImpl = xImpl;
271 ItemHolder1::holdConfigItem(EItem::UserOptions);
272 }
273 xImpl = xSharedImpl.lock();
274 xImpl->AddListener(this);
275 }
276
~SvtUserOptions()277 SvtUserOptions::~SvtUserOptions()
278 {
279 // Global access, must be guarded (multithreading)
280 osl::MutexGuard aGuard( GetInitMutex() );
281 xImpl->RemoveListener(this);
282 }
283
284 namespace
285 {
286 class theUserOptionsMutex : public rtl::Static<osl::Mutex, theUserOptionsMutex>{};
287 }
288
GetInitMutex()289 osl::Mutex& SvtUserOptions::GetInitMutex()
290 {
291 return theUserOptionsMutex::get();
292 }
293
GetCompany() const294 OUString SvtUserOptions::GetCompany () const { return GetToken(UserOptToken::Company); }
GetFirstName() const295 OUString SvtUserOptions::GetFirstName () const { return GetToken(UserOptToken::FirstName); }
GetLastName() const296 OUString SvtUserOptions::GetLastName () const { return GetToken(UserOptToken::LastName); }
GetID() const297 OUString SvtUserOptions::GetID () const { return GetToken(UserOptToken::ID); }
GetStreet() const298 OUString SvtUserOptions::GetStreet () const { return GetToken(UserOptToken::Street); }
GetCity() const299 OUString SvtUserOptions::GetCity () const { return GetToken(UserOptToken::City); }
GetState() const300 OUString SvtUserOptions::GetState () const { return GetToken(UserOptToken::State); }
GetZip() const301 OUString SvtUserOptions::GetZip () const { return GetToken(UserOptToken::Zip); }
GetCountry() const302 OUString SvtUserOptions::GetCountry () const { return GetToken(UserOptToken::Country); }
GetPosition() const303 OUString SvtUserOptions::GetPosition () const { return GetToken(UserOptToken::Position); }
GetTitle() const304 OUString SvtUserOptions::GetTitle () const { return GetToken(UserOptToken::Title); }
GetTelephoneHome() const305 OUString SvtUserOptions::GetTelephoneHome () const { return GetToken(UserOptToken::TelephoneHome); }
GetTelephoneWork() const306 OUString SvtUserOptions::GetTelephoneWork () const { return GetToken(UserOptToken::TelephoneWork); }
GetFax() const307 OUString SvtUserOptions::GetFax () const { return GetToken(UserOptToken::Fax); }
GetEmail() const308 OUString SvtUserOptions::GetEmail () const { return GetToken(UserOptToken::Email); }
GetSigningKey() const309 OUString SvtUserOptions::GetSigningKey () const { return GetToken(UserOptToken::SigningKey); }
GetEncryptionKey() const310 OUString SvtUserOptions::GetEncryptionKey () const { return GetToken(UserOptToken::EncryptionKey); }
311
IsTokenReadonly(UserOptToken nToken) const312 bool SvtUserOptions::IsTokenReadonly (UserOptToken nToken) const
313 {
314 osl::MutexGuard aGuard(GetInitMutex());
315 return xImpl->IsTokenReadonly(nToken);
316 }
317
GetToken(UserOptToken nToken) const318 OUString SvtUserOptions::GetToken (UserOptToken nToken) const
319 {
320 osl::MutexGuard aGuard(GetInitMutex());
321 return xImpl->GetToken(nToken);
322 }
323
SetToken(UserOptToken nToken,OUString const & rNewToken)324 void SvtUserOptions::SetToken (UserOptToken nToken, OUString const& rNewToken)
325 {
326 osl::MutexGuard aGuard(GetInitMutex());
327 xImpl->SetToken(nToken, rNewToken);
328 }
329
SetBoolValue(UserOptToken nToken,bool bNewValue)330 void SvtUserOptions::SetBoolValue (UserOptToken nToken, bool bNewValue)
331 {
332 osl::MutexGuard aGuard(GetInitMutex());
333 xImpl->SetBoolValue(nToken, bNewValue);
334 }
335
GetEncryptToSelf() const336 bool SvtUserOptions::GetEncryptToSelf() const
337 {
338 osl::MutexGuard aGuard(GetInitMutex());
339 return xImpl->GetBoolValue(UserOptToken::EncryptToSelf);
340 }
341
GetFullName() const342 OUString SvtUserOptions::GetFullName () const
343 {
344 osl::MutexGuard aGuard(GetInitMutex());
345 return xImpl->GetFullName();
346 }
347
348 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
349