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 "PresenterConfigurationAccess.hxx"
21 
22 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
23 #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
24 #include <com/sun/star/configuration/theDefaultProvider.hpp>
25 #include <com/sun/star/util/XChangesBatch.hpp>
26 #include <comphelper/propertysequence.hxx>
27 #include <osl/diagnose.h>
28 #include <tools/diagnose_ex.h>
29 #include <sal/log.hxx>
30 
31 using namespace ::com::sun::star;
32 using namespace ::com::sun::star::uno;
33 
34 namespace sdext::presenter {
35 
PresenterConfigurationAccess(const Reference<XComponentContext> & rxContext,const OUString & rsRootName,WriteMode eMode)36 PresenterConfigurationAccess::PresenterConfigurationAccess (
37     const Reference<XComponentContext>& rxContext,
38     const OUString& rsRootName,
39     WriteMode eMode)
40     : mxRoot(),
41       maNode()
42 {
43     try
44     {
45         if (rxContext.is())
46         {
47             uno::Sequence<uno::Any> aCreationArguments(comphelper::InitAnyPropertySequence(
48             {
49                 {"nodepath", uno::Any(rsRootName)},
50                 {"depth", uno::Any(sal_Int32(-1))}
51             }));
52 
53             OUString sAccessService;
54             if (eMode == READ_ONLY)
55                 sAccessService = "com.sun.star.configuration.ConfigurationAccess";
56             else
57                 sAccessService = "com.sun.star.configuration.ConfigurationUpdateAccess";
58 
59             Reference<lang::XMultiServiceFactory> xProvider =
60                 configuration::theDefaultProvider::get( rxContext );
61             mxRoot = xProvider->createInstanceWithArguments(
62                 sAccessService, aCreationArguments);
63             maNode <<= mxRoot;
64         }
65     }
66     catch (const Exception&)
67     {
68         DBG_UNHANDLED_EXCEPTION("sdext.presenter", "caught exception while opening configuration");
69     }
70 }
71 
~PresenterConfigurationAccess()72 PresenterConfigurationAccess::~PresenterConfigurationAccess()
73 {
74 }
75 
IsValid() const76 bool PresenterConfigurationAccess::IsValid() const
77 {
78     return mxRoot.is();
79 }
80 
GetConfigurationNode(const OUString & sPathToNode)81 Any PresenterConfigurationAccess::GetConfigurationNode (const OUString& sPathToNode)
82 {
83     return GetConfigurationNode(
84         Reference<container::XHierarchicalNameAccess>(mxRoot, UNO_QUERY),
85         sPathToNode);
86 }
87 
GoToChild(const OUString & rsPathToNode)88 bool PresenterConfigurationAccess::GoToChild (const OUString& rsPathToNode)
89 {
90     if ( ! IsValid())
91         return false;
92 
93     Reference<container::XHierarchicalNameAccess> xNode (maNode, UNO_QUERY);
94     if (xNode.is())
95     {
96         maNode = GetConfigurationNode(
97             Reference<container::XHierarchicalNameAccess>(maNode, UNO_QUERY),
98             rsPathToNode);
99         if (Reference<XInterface>(maNode, UNO_QUERY).is())
100             return true;
101     }
102 
103     mxRoot = nullptr;
104     return false;
105 }
106 
GoToChild(const Predicate & rPredicate)107 bool PresenterConfigurationAccess::GoToChild (const Predicate& rPredicate)
108 {
109     if ( ! IsValid())
110         return false;
111 
112     maNode = Find(Reference<container::XNameAccess>(maNode,UNO_QUERY), rPredicate);
113     if (Reference<XInterface>(maNode, UNO_QUERY).is())
114         return true;
115 
116     mxRoot = nullptr;
117     return false;
118 }
119 
SetProperty(const OUString & rsPropertyName,const Any & rValue)120 bool PresenterConfigurationAccess::SetProperty (
121     const OUString& rsPropertyName,
122     const Any& rValue)
123 {
124     Reference<beans::XPropertySet> xProperties (maNode, UNO_QUERY);
125     if (xProperties.is())
126     {
127         xProperties->setPropertyValue(rsPropertyName, rValue);
128         return true;
129     }
130     else
131         return false;
132 }
133 
GetConfigurationNode(const css::uno::Reference<css::container::XHierarchicalNameAccess> & rxNode,const OUString & sPathToNode)134 Any PresenterConfigurationAccess::GetConfigurationNode (
135     const css::uno::Reference<css::container::XHierarchicalNameAccess>& rxNode,
136     const OUString& sPathToNode)
137 {
138     if (sPathToNode.isEmpty())
139         return Any(rxNode);
140 
141     try
142     {
143         if (rxNode.is())
144         {
145             return rxNode->getByHierarchicalName(sPathToNode);
146         }
147     }
148     catch (const Exception&)
149     {
150         TOOLS_WARN_EXCEPTION("sdext.presenter", "caught exception while getting configuration node " << sPathToNode);
151     }
152 
153     return Any();
154 }
155 
GetNodeProperties(const css::uno::Reference<css::container::XHierarchicalNameAccess> & rxNode,const OUString & rsPathToNode)156 Reference<beans::XPropertySet> PresenterConfigurationAccess::GetNodeProperties (
157     const css::uno::Reference<css::container::XHierarchicalNameAccess>& rxNode,
158     const OUString& rsPathToNode)
159 {
160     return Reference<beans::XPropertySet>(GetConfigurationNode(rxNode, rsPathToNode), UNO_QUERY);
161 }
162 
CommitChanges()163 void PresenterConfigurationAccess::CommitChanges()
164 {
165     Reference<util::XChangesBatch> xConfiguration (mxRoot, UNO_QUERY);
166     if (xConfiguration.is())
167         xConfiguration->commitChanges();
168 }
169 
ForAll(const Reference<container::XNameAccess> & rxContainer,const::std::vector<OUString> & rArguments,const ItemProcessor & rProcessor)170 void PresenterConfigurationAccess::ForAll (
171     const Reference<container::XNameAccess>& rxContainer,
172     const ::std::vector<OUString>& rArguments,
173     const ItemProcessor& rProcessor)
174 {
175     if (!rxContainer.is())
176         return;
177 
178     ::std::vector<Any> aValues(rArguments.size());
179     const Sequence<OUString> aKeys (rxContainer->getElementNames());
180     for (const OUString& rsKey : aKeys)
181     {
182         bool bHasAllValues (true);
183         Reference<container::XNameAccess> xSetItem (rxContainer->getByName(rsKey), UNO_QUERY);
184         Reference<beans::XPropertySet> xSet (xSetItem, UNO_QUERY);
185         OSL_ASSERT(xSet.is());
186         if (xSetItem.is())
187         {
188             // Get from the current item of the container the children
189             // that match the names in the rArguments list.
190             for (size_t nValueIndex=0; nValueIndex<aValues.size(); ++nValueIndex)
191             {
192                 if ( ! xSetItem->hasByName(rArguments[nValueIndex]))
193                     bHasAllValues = false;
194                 else
195                     aValues[nValueIndex] = xSetItem->getByName(rArguments[nValueIndex]);
196             }
197         }
198         else
199             bHasAllValues = false;
200         if (bHasAllValues)
201             rProcessor(aValues);
202     }
203 }
204 
ForAll(const Reference<container::XNameAccess> & rxContainer,const PropertySetProcessor & rProcessor)205 void PresenterConfigurationAccess::ForAll (
206     const Reference<container::XNameAccess>& rxContainer,
207     const PropertySetProcessor& rProcessor)
208 {
209     if (rxContainer.is())
210     {
211         const Sequence<OUString> aKeys (rxContainer->getElementNames());
212         for (const OUString& rsKey : aKeys)
213         {
214             Reference<beans::XPropertySet> xSet (rxContainer->getByName(rsKey), UNO_QUERY);
215             if (xSet.is())
216                 rProcessor(rsKey, xSet);
217         }
218     }
219 }
220 
Find(const Reference<container::XNameAccess> & rxContainer,const Predicate & rPredicate)221 Any PresenterConfigurationAccess::Find (
222     const Reference<container::XNameAccess>& rxContainer,
223     const Predicate& rPredicate)
224 {
225     if (rxContainer.is())
226     {
227         const Sequence<OUString> aKeys (rxContainer->getElementNames());
228         for (const auto& rKey : aKeys)
229         {
230             Reference<beans::XPropertySet> xProperties (
231                 rxContainer->getByName(rKey),
232                 UNO_QUERY);
233             if (xProperties.is())
234                 if (rPredicate(rKey, xProperties))
235                     return Any(xProperties);
236         }
237     }
238     return Any();
239 }
240 
IsStringPropertyEqual(std::u16string_view rsValue,const OUString & rsPropertyName,const css::uno::Reference<css::beans::XPropertySet> & rxNode)241 bool PresenterConfigurationAccess::IsStringPropertyEqual (
242     std::u16string_view rsValue,
243     const OUString& rsPropertyName,
244     const css::uno::Reference<css::beans::XPropertySet>& rxNode)
245 {
246     OUString sValue;
247     if (GetProperty(rxNode, rsPropertyName) >>= sValue)
248         return sValue == rsValue;
249     else
250         return false;
251 }
252 
GetProperty(const Reference<beans::XPropertySet> & rxProperties,const OUString & rsKey)253 Any PresenterConfigurationAccess::GetProperty (
254     const Reference<beans::XPropertySet>& rxProperties,
255     const OUString& rsKey)
256 {
257     OSL_ASSERT(rxProperties.is());
258     if ( ! rxProperties.is())
259         return Any();
260     try
261     {
262         Reference<beans::XPropertySetInfo> xInfo (rxProperties->getPropertySetInfo());
263         if (xInfo.is())
264             if ( ! xInfo->hasPropertyByName(rsKey))
265                 return Any();
266         return rxProperties->getPropertyValue(rsKey);
267     }
268     catch (beans::UnknownPropertyException&)
269     {
270     }
271     return Any();
272 }
273 
274 } // end of namespace sdext::presenter
275 
276 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
277