14 #include <string_view>
15 #include <unordered_map>
17 #include <com/sun/star/beans/NamedValue.hpp>
18 #include <com/sun/star/beans/PropertyAttribute.hpp>
19 #include <com/sun/star/configuration/ReadOnlyAccess.hpp>
20 #include <com/sun/star/configuration/ReadWriteAccess.hpp>
21 #include <com/sun/star/configuration/XReadWriteAccess.hpp>
22 #include <com/sun/star/configuration/theDefaultProvider.hpp>
23 #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
24 #include <com/sun/star/container/XHierarchicalNameReplace.hpp>
25 #include <com/sun/star/container/XNameAccess.hpp>
26 #include <com/sun/star/container/XNameContainer.hpp>
27 #include <com/sun/star/lang/XLocalizable.hpp>
28 #include <com/sun/star/uno/Any.hxx>
29 #include <com/sun/star/uno/Reference.hxx>
30 #include <com/sun/star/util/XChangesListener.hpp>
31 #include <com/sun/star/util/XChangesNotifier.hpp>
36 #include <rtl/ustring.hxx>
44 OUString getDefaultLocale(
45 css::uno::Reference< css::uno::XComponentContext >
const & context)
48 css::uno::Reference< css::lang::XLocalizable >(
49 css::configuration::theDefaultProvider::get(context),
50 css::uno::UNO_QUERY_THROW)->
54 OUString extendLocalizedPath(std::u16string_view path, OUString
const & locale) {
56 locale.match(
"*"),
"comphelper",
57 "Locale \"" << locale <<
"\" starts with \"*\"");
58 assert(locale.indexOf(
'&') == -1);
59 assert(locale.indexOf(
'"') == -1);
60 assert(locale.indexOf(
'\'') == -1);
61 return OUString::Concat(path) +
"/['*" + locale +
"']";
66 std::shared_ptr< comphelper::ConfigurationChanges >
79 css::uno::Reference< css::uno::XComponentContext >
const & context):
82 context, getDefaultLocale(context)))
86 OUString
const & path, css::uno::Any
const &
value)
const
88 access_->replaceByHierarchicalName(path, value);
91 css::uno::Reference< css::container::XHierarchicalNameReplace >
94 return css::uno::Reference< css::container::XHierarchicalNameReplace >(
95 access_->getByHierarchicalName(path), css::uno::UNO_QUERY_THROW);
98 css::uno::Reference< css::container::XNameContainer >
101 return css::uno::Reference< css::container::XNameContainer >(
102 access_->getByHierarchicalName(path), css::uno::UNO_QUERY_THROW);
115 std::unordered_map<OUString, css::uno::Any> gPropertyCache;
116 css::uno::Reference< css::util::XChangesNotifier > gNotifier;
117 css::uno::Reference< css::util::XChangesListener > gListener;
119 class ConfigurationChangesListener
120 :
public ::cppu::WeakImplHelper<css::util::XChangesListener>
123 ConfigurationChangesListener()
126 virtual void SAL_CALL changesOccurred(
const css::util::ChangesEvent& )
override
128 std::scoped_lock aGuard(gMutex);
129 gPropertyCache.clear();
131 virtual void SAL_CALL disposing(
const css::lang::EventObject&)
override {}
143 css::uno::Reference< css::lang::XMultiServiceFactory > xConfigProvider(
144 css::configuration::theDefaultProvider::get(
context_ ) );
147 css::uno::Sequence< css::uno::Any > params {
148 css::uno::Any( css::beans::NamedValue{
"nodepath", css::uno::Any( OUString(
"/"))} ),
149 css::uno::Any( css::beans::NamedValue{
"locale", css::uno::Any( OUString(
"*"))} ) };
151 css::uno::Reference< css::uno::XInterface > xCfg
152 = xConfigProvider->createInstanceWithArguments(
u"com.sun.star.configuration.ConfigurationAccess",
155 gNotifier = css::uno::Reference< css::util::XChangesNotifier >(xCfg, css::uno::UNO_QUERY);
156 assert(gNotifier.is());
157 gListener = css::uno::Reference< ConfigurationChangesListener >(
new ConfigurationChangesListener());
158 gNotifier->addChangesListener(gListener);
160 catch(
const css::uno::Exception&)
168 gPropertyCache.clear();
177 (
access_->getPropertyByHierarchicalName(path).Attributes
178 & css::beans::PropertyAttribute::READONLY)
184 std::scoped_lock aGuard(gMutex);
186 auto it = gPropertyCache.find(path);
187 if( it != gPropertyCache.end())
190 sal_Int32
idx = path.lastIndexOf(
"/");
192 OUString parentPath = path.copy(0,
idx);
193 OUString childName = path.copy(
idx+1);
195 css::uno::Reference<css::container::XNameAccess> access(
196 access_->getByHierarchicalName(parentPath), css::uno::UNO_QUERY_THROW);
197 css::uno::Any
property = access->getByName(childName);
198 gPropertyCache.emplace(path,
property);
203 std::shared_ptr< ConfigurationChanges >
const & batch,
204 OUString
const & path, css::uno::Any
const &
value)
207 batch->setPropertyValue(path, value);
212 std::u16string_view path)
const
214 return access_->getByHierarchicalName(
215 extendLocalizedPath(path, getDefaultLocale(
context_)));
219 std::shared_ptr< ConfigurationChanges >
const & batch,
220 OUString
const & path, css::uno::Any
const &
value)
223 batch->setPropertyValue(path, value);
226 css::uno::Reference< css::container::XHierarchicalNameAccess >
228 OUString
const & path)
const
230 return css::uno::Reference< css::container::XHierarchicalNameAccess >(
231 (css::configuration::ReadOnlyAccess::create(
233 getByHierarchicalName(path)),
234 css::uno::UNO_QUERY_THROW);
237 css::uno::Reference< css::container::XHierarchicalNameReplace >
239 std::shared_ptr< ConfigurationChanges >
const & batch,
240 OUString
const & path)
243 return batch->getGroup(path);
246 css::uno::Reference< css::container::XNameAccess >
248 OUString
const & path)
const
250 return css::uno::Reference< css::container::XNameAccess >(
251 (css::configuration::ReadOnlyAccess::create(
253 getByHierarchicalName(path)),
254 css::uno::UNO_QUERY_THROW);
257 css::uno::Reference< css::container::XNameContainer >
259 std::shared_ptr< ConfigurationChanges >
const & batch,
260 OUString
const & path)
263 return batch->getSet(path);
266 std::shared_ptr< comphelper::ConfigurationChanges >
268 return std::shared_ptr< ConfigurationChanges >(
274 maListeners.push_back( pListener );
275 mxConfig->addPropertyChangeListener( pListener->
maName,
this );
281 auto it =
std::find( maListeners.begin(), maListeners.end(), pListener );
282 if ( it != maListeners.end() )
284 maListeners.erase( it );
285 mxConfig->removePropertyChangeListener( pListener->
maName,
this );
291 for (
auto const& listener : maListeners)
293 mxConfig->removePropertyChangeListener( listener->maName,
this );
306 css::beans::PropertyChangeEvent
const &rEvt )
317 assert( rEvt.Source == mxConfig );
318 for (
auto const& listener : maListeners)
320 if ( listener->maName == rEvt.PropertyName )
323 css::uno::Any aValue = mxConfig->getPropertyValue( listener->maName );
324 listener->setProperty( aValue );
static void setPropertyValue(std::shared_ptr< ConfigurationChanges > const &batch, OUString const &path, css::uno::Any const &value)
static std::shared_ptr< ConfigurationChanges > create()
SAL_DLLPRIVATE css::uno::Reference< css::container::XHierarchicalNameReplace > getGroup(OUString const &path) const
static css::uno::Reference< css::container::XHierarchicalNameReplace > getGroupReadWrite(std::shared_ptr< ConfigurationChanges > const &batch, OUString const &path)
const OUString & getBcp47(bool bResolveSystem=true) const
void dispose()
Release various circular references.
SAL_DLLPRIVATE ConfigurationWrapper()
css::uno::Reference< css::configuration::XReadWriteAccess > access_
uno::Reference< uno::XComponentContext > context_
static ConfigurationWrapper const & get()
css::uno::Any getPropertyValue(OUString const &path) const
Reference< deployment::XPackageRegistry > create(Reference< deployment::XPackageRegistry > const &xRootRegistry, OUString const &context, OUString const &cachePath, Reference< XComponentContext > const &xComponentContext)
css::uno::Reference< css::container::XNameAccess > getSetReadOnly(OUString const &path) const
void addListener(ConfigurationListenerPropertyBase *pListener)
Listen for the specific property denoted by the listener.
virtual void SAL_CALL disposing(css::lang::EventObject const &) override
css::uno::Any getLocalizedPropertyValue(std::u16string_view path) const
static void setLocalizedPropertyValue(std::shared_ptr< ConfigurationChanges > const &batch, OUString const &path, css::uno::Any const &value)
void removeListener(ConfigurationListenerPropertyBase *pListener)
Stop listening.
exports com.sun.star. configuration
static PropertyMapEntry const * find(const rtl::Reference< PropertySetInfo > &mxInfo, const OUString &aName) noexcept
const LanguageTag & getLocale()
Get the current LOK's locale.
#define SAL_WARN_IF(condition, area, stream)
A batch of configuration changes that is committed as a whole.
virtual void SAL_CALL propertyChange(css::beans::PropertyChangeEvent const &rEvt) override
Notify of the property change.
static SolarMutex * get()
Help components to get the SolarMutex easily.
css::uno::Reference< css::uno::XComponentContext > context_
Reference< XComponentContext > getProcessComponentContext()
This function gets the process service factory's default component context.
bool isReadOnly(OUString const &path) const
SAL_DLLPRIVATE ~ConfigurationWrapper()
css::uno::Reference< css::uno::XInterface > access_
static css::uno::Reference< css::container::XNameContainer > getSetReadWrite(std::shared_ptr< ConfigurationChanges > const &batch, OUString const &path)
css::uno::Reference< css::container::XHierarchicalNameAccess > getGroupReadOnly(OUString const &path) const
SAL_DLLPRIVATE css::uno::Reference< css::container::XNameContainer > getSet(OUString const &path) const
virtual void setProperty(const css::uno::Any &aProperty)=0
SAL_DLLPRIVATE void setPropertyValue(OUString const &path, css::uno::Any const &value) const
std::shared_ptr< ConfigurationChanges > createChanges() const
ConfigurationChanges(const ConfigurationChanges &)=delete