Line data Source code
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 <sal/log.hxx>
23 : #include <unotools/useroptions.hxx>
24 : #include <unotools/syslocale.hxx>
25 : #include <unotools/configmgr.hxx>
26 : #include <com/sun/star/uno/Any.hxx>
27 : #include <com/sun/star/uno/Sequence.hxx>
28 : #include <osl/mutex.hxx>
29 : #include <rtl/instance.hxx>
30 : #include "itemholder1.hxx"
31 :
32 : #include <com/sun/star/beans/Property.hpp>
33 : #include <com/sun/star/beans/XPropertySet.hpp>
34 : #include <com/sun/star/beans/PropertyAttribute.hpp>
35 : #include <com/sun/star/container/XNameAccess.hpp>
36 : #include <com/sun/star/container/XNameContainer.hpp>
37 : #include <com/sun/star/lang/XSingleServiceFactory.hpp>
38 : #include <com/sun/star/util/XChangesListener.hpp>
39 : #include <com/sun/star/util/XChangesNotifier.hpp>
40 : #include <com/sun/star/util/ChangesEvent.hpp>
41 : #include <comphelper/configurationhelper.hxx>
42 : #include <comphelper/processfactory.hxx>
43 : #include <i18nlangtag/mslangid.hxx>
44 : #include <o3tl/enumarray.hxx>
45 :
46 : using namespace utl;
47 : using namespace com::sun::star;
48 :
49 : // vOptionNames[] -- names of the user option entries
50 : // The order corresponds to the #define USER_OPT_* list in useroptions.hxx.
51 : static o3tl::enumarray<UserOptToken, char const *> vOptionNames = {
52 : "l", // UserOptToken::City
53 : "o", // UserOptToken::Company
54 : "c", // UserOptToken::Country
55 : "mail", // UserOptToken::Email
56 : "facsimiletelephonenumber", // UserOptToken::Fax
57 : "givenname", // UserOptToken::FirstName
58 : "sn", // UserOptToken::LastName
59 : "position", // UserOptToken::Position
60 : "st", // UserOptToken::State
61 : "street", // UserOptToken::Street
62 : "homephone", // UserOptToken::TelephoneHome
63 : "telephonenumber", // UserOptToken::TelephoneWork
64 : "title", // UserOptToken::Title
65 : "initials", // UserOptToken::ID
66 : "postalcode", // UserOptToken::Zip
67 : "fathersname", // UserOptToken::FathersName
68 : "apartment" // UserOptToken::Apartment
69 : };
70 :
71 274 : std::weak_ptr<SvtUserOptions::Impl> SvtUserOptions::xSharedImpl;
72 :
73 110 : class SvtUserOptions::ChangeListener : public cppu::WeakImplHelper1<util::XChangesListener>
74 : {
75 : public:
76 87 : explicit ChangeListener (Impl& rParent): m_rParent(rParent) { }
77 :
78 : // XChangesListener
79 : virtual void SAL_CALL changesOccurred (util::ChangesEvent const& Event) throw(uno::RuntimeException, std::exception) SAL_OVERRIDE;
80 : // XEventListener
81 : virtual void SAL_CALL disposing (lang::EventObject const& Source) throw(uno::RuntimeException, std::exception) SAL_OVERRIDE;
82 :
83 : private:
84 : Impl& m_rParent;
85 : };
86 :
87 110 : class SvtUserOptions::Impl : public utl::ConfigurationBroadcaster
88 : {
89 : public:
90 : Impl ();
91 :
92 : OUString GetFullName () const;
93 :
94 : bool IsTokenReadonly (UserOptToken nToken) const;
95 : OUString GetToken (UserOptToken nToken) const;
96 : void SetToken (UserOptToken nToken, OUString const& rNewToken);
97 : void Notify ();
98 :
99 : private:
100 : uno::Reference<util::XChangesListener> m_xChangeListener;
101 : uno::Reference<container::XNameAccess> m_xCfg;
102 : uno::Reference<beans::XPropertySet> m_xData;
103 : };
104 :
105 2 : void SvtUserOptions::ChangeListener::changesOccurred (util::ChangesEvent const& rEvent) throw(uno::RuntimeException, std::exception)
106 : {
107 2 : if (rEvent.Changes.getLength())
108 2 : m_rParent.Notify();
109 2 : }
110 :
111 0 : void SvtUserOptions::ChangeListener::disposing (lang::EventObject const& rSource) throw(uno::RuntimeException, std::exception)
112 : {
113 : try
114 : {
115 0 : uno::Reference<util::XChangesNotifier> xChgNot(rSource.Source, uno::UNO_QUERY_THROW);
116 0 : xChgNot->removeChangesListener(this);
117 : }
118 0 : catch (uno::Exception&)
119 : {
120 : }
121 0 : }
122 :
123 87 : SvtUserOptions::Impl::Impl() :
124 87 : m_xChangeListener( new ChangeListener(*this) )
125 : {
126 : try
127 : {
128 174 : m_xCfg = uno::Reference<container::XNameAccess>(
129 : comphelper::ConfigurationHelper::openConfig(
130 : comphelper::getProcessComponentContext(),
131 : "org.openoffice.UserProfile/Data",
132 : comphelper::ConfigurationHelper::E_STANDARD
133 : ),
134 : uno::UNO_QUERY
135 87 : );
136 :
137 87 : m_xData = uno::Reference<beans::XPropertySet>(m_xCfg, uno::UNO_QUERY);
138 87 : uno::Reference<util::XChangesNotifier> xChgNot(m_xCfg, uno::UNO_QUERY);
139 : try
140 : {
141 87 : xChgNot->addChangesListener(m_xChangeListener);
142 : }
143 0 : catch (uno::RuntimeException&)
144 : {
145 87 : }
146 : }
147 0 : catch (uno::Exception const& ex)
148 : {
149 0 : m_xCfg.clear();
150 : SAL_WARN("unotools.config", "Caught unexpected: " << ex.Message);
151 : }
152 87 : }
153 :
154 8746 : OUString SvtUserOptions::Impl::GetToken (UserOptToken nToken) const
155 : {
156 8746 : OUString sToken;
157 : try
158 : {
159 8746 : if (m_xData.is())
160 8746 : m_xData->getPropertyValue(OUString::createFromAscii(vOptionNames[nToken])) >>= sToken;
161 : }
162 0 : catch (uno::Exception const& ex)
163 : {
164 : SAL_WARN("unotools.config", "Caught unexpected: " << ex.Message);
165 : }
166 8746 : return sToken;
167 : }
168 :
169 2 : void SvtUserOptions::Impl::SetToken (UserOptToken nToken, OUString const& sToken)
170 : {
171 : try
172 : {
173 2 : if (m_xData.is())
174 2 : m_xData->setPropertyValue(OUString::createFromAscii(vOptionNames[nToken]), uno::makeAny(sToken));
175 2 : comphelper::ConfigurationHelper::flush(m_xCfg);
176 : }
177 0 : catch (uno::Exception const& ex)
178 : {
179 : SAL_WARN("unotools.config", "Caught unexpected: " << ex.Message);
180 : }
181 2 : }
182 :
183 3392 : OUString SvtUserOptions::Impl::GetFullName () const
184 : {
185 3392 : OUString sFullName;
186 3392 : switch (LanguageType const eLang = SvtSysLocale().GetUILanguageTag().getLanguageType())
187 : {
188 : case LANGUAGE_RUSSIAN:
189 0 : sFullName = GetToken(UserOptToken::FirstName).trim();
190 0 : if (!sFullName.isEmpty())
191 0 : sFullName += " ";
192 0 : sFullName += GetToken(UserOptToken::FathersName).trim();
193 0 : if (!sFullName.isEmpty())
194 0 : sFullName += " ";
195 0 : sFullName += GetToken(UserOptToken::LastName).trim();
196 0 : break;
197 : default:
198 3392 : if (MsLangId::isFamilyNameFirst(eLang))
199 : {
200 0 : sFullName = GetToken(UserOptToken::LastName).trim();
201 0 : if (!sFullName.isEmpty())
202 0 : sFullName += " ";
203 0 : sFullName += GetToken(UserOptToken::FirstName).trim();
204 : }
205 : else
206 : {
207 3392 : sFullName = GetToken(UserOptToken::FirstName).trim();
208 3392 : if (!sFullName.isEmpty())
209 0 : sFullName += " ";
210 3392 : sFullName += GetToken(UserOptToken::LastName).trim();
211 : }
212 3392 : break;
213 : }
214 :
215 3392 : return sFullName;
216 : }
217 :
218 2 : void SvtUserOptions::Impl::Notify ()
219 : {
220 2 : NotifyListeners(0);
221 2 : }
222 :
223 0 : bool SvtUserOptions::Impl::IsTokenReadonly (UserOptToken nToken) const
224 : {
225 0 : uno::Reference<beans::XPropertySet> xData(m_xCfg, uno::UNO_QUERY);
226 0 : uno::Reference<beans::XPropertySetInfo> xInfo = xData->getPropertySetInfo();
227 0 : beans::Property aProp = xInfo->getPropertyByName(OUString::createFromAscii(vOptionNames[nToken]));
228 0 : return ((aProp.Attributes & beans::PropertyAttribute::READONLY) ==
229 0 : beans::PropertyAttribute::READONLY);
230 : }
231 :
232 1069 : SvtUserOptions::SvtUserOptions ()
233 : {
234 : // Global access, must be guarded (multithreading)
235 1069 : osl::MutexGuard aGuard(GetInitMutex());
236 :
237 1069 : if (xSharedImpl.expired())
238 : {
239 87 : xImpl.reset(new Impl);
240 87 : xSharedImpl = xImpl;
241 87 : ItemHolder1::holdConfigItem(E_USEROPTIONS);
242 : }
243 1069 : xImpl = xSharedImpl.lock();
244 1069 : xImpl->AddListener(this);
245 1069 : }
246 :
247 2185 : SvtUserOptions::~SvtUserOptions()
248 : {
249 : // Global access, must be guarded (multithreading)
250 1036 : osl::MutexGuard aGuard( GetInitMutex() );
251 1036 : xImpl->RemoveListener(this);
252 1149 : }
253 :
254 : namespace
255 : {
256 : class theUserOptionsMutex : public rtl::Static<osl::Mutex, theUserOptionsMutex>{};
257 : }
258 :
259 7461 : osl::Mutex& SvtUserOptions::GetInitMutex()
260 : {
261 7461 : return theUserOptionsMutex::get();
262 : }
263 :
264 30 : OUString SvtUserOptions::GetCompany () const { return GetToken(UserOptToken::Company); }
265 153 : OUString SvtUserOptions::GetFirstName () const { return GetToken(UserOptToken::FirstName); }
266 309 : OUString SvtUserOptions::GetLastName () const { return GetToken(UserOptToken::LastName); }
267 336 : OUString SvtUserOptions::GetID () const { return GetToken(UserOptToken::ID); }
268 30 : OUString SvtUserOptions::GetStreet () const { return GetToken(UserOptToken::Street); }
269 30 : OUString SvtUserOptions::GetCity () const { return GetToken(UserOptToken::City); }
270 0 : OUString SvtUserOptions::GetState () const { return GetToken(UserOptToken::State); }
271 0 : OUString SvtUserOptions::GetZip () const { return GetToken(UserOptToken::Zip); }
272 0 : OUString SvtUserOptions::GetCountry () const { return GetToken(UserOptToken::Country); }
273 30 : OUString SvtUserOptions::GetPosition () const { return GetToken(UserOptToken::Position); }
274 30 : OUString SvtUserOptions::GetTitle () const { return GetToken(UserOptToken::Title); }
275 0 : OUString SvtUserOptions::GetTelephoneHome () const { return GetToken(UserOptToken::TelephoneHome); }
276 0 : OUString SvtUserOptions::GetTelephoneWork () const { return GetToken(UserOptToken::TelephoneWork); }
277 0 : OUString SvtUserOptions::GetFax () const { return GetToken(UserOptToken::Fax); }
278 30 : OUString SvtUserOptions::GetEmail () const { return GetToken(UserOptToken::Email); }
279 :
280 0 : bool SvtUserOptions::IsTokenReadonly (UserOptToken nToken) const
281 : {
282 0 : osl::MutexGuard aGuard(GetInitMutex());
283 0 : return xImpl->IsTokenReadonly(nToken);
284 : }
285 :
286 1962 : OUString SvtUserOptions::GetToken (UserOptToken nToken) const
287 : {
288 1962 : osl::MutexGuard aGuard(GetInitMutex());
289 1962 : return xImpl->GetToken(nToken);
290 : }
291 :
292 2 : void SvtUserOptions::SetToken (UserOptToken nToken, OUString const& rNewToken)
293 : {
294 2 : osl::MutexGuard aGuard(GetInitMutex());
295 2 : xImpl->SetToken(nToken, rNewToken);
296 2 : }
297 :
298 3392 : OUString SvtUserOptions::GetFullName () const
299 : {
300 3392 : osl::MutexGuard aGuard(GetInitMutex());
301 3392 : return xImpl->GetFullName();
302 822 : }
303 :
304 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|