LibreOffice Module vcl (master) 1
FilterConfigItem.cxx
Go to the documentation of this file.
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
21
25#include <o3tl/string_view.hxx>
26#include <osl/diagnose.h>
27#include <com/sun/star/beans/PropertyValue.hpp>
28#include <com/sun/star/configuration/theDefaultProvider.hpp>
29#include <com/sun/star/lang/XMultiServiceFactory.hpp>
30#include <com/sun/star/util/XChangesBatch.hpp>
31#include <com/sun/star/beans/XPropertySetInfo.hpp>
32#include <com/sun/star/beans/XPropertySet.hpp>
33#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
34#include <com/sun/star/awt/Size.hpp>
35#include <com/sun/star/task/XStatusIndicator.hpp>
36
37using namespace ::com::sun::star::lang ; // XMultiServiceFactory
38using namespace ::com::sun::star::beans ; // PropertyValue
39using namespace ::com::sun::star::uno ; // Reference
40using namespace ::com::sun::star::util ; // XChangesBatch
41using namespace ::com::sun::star::awt ; // Size
42using namespace ::com::sun::star::container ;
43using namespace ::com::sun::star::configuration;
44using namespace ::com::sun::star::task ; // XStatusIndicator
45
46static bool ImpIsTreeAvailable( Reference< XMultiServiceFactory > const & rXCfgProv, std::u16string_view rTree )
47{
48 bool bAvailable = !rTree.empty();
49 if ( bAvailable )
50 {
51 sal_Int32 nIdx{0};
52 if ( rTree[0] == '/' )
53 ++nIdx;
54
55 // creation arguments: nodepath
56 PropertyValue aPathArgument = comphelper::makePropertyValue("nodepath",
57 OUString(o3tl::getToken(rTree, 0, '/', nIdx)));
58 Sequence< Any > aArguments{ Any(aPathArgument) };
59
60 Reference< XInterface > xReadAccess;
61 try
62 {
63 xReadAccess = rXCfgProv->createInstanceWithArguments(
64 "com.sun.star.configuration.ConfigurationAccess",
65 aArguments );
66 }
67 catch (const css::uno::Exception&)
68 {
69 bAvailable = false;
70 }
71 if ( xReadAccess.is() )
72 {
73 const sal_Int32 nEnd = rTree.size();
74 while (bAvailable && nIdx>=0 && nIdx<nEnd)
75 {
76 Reference< XHierarchicalNameAccess > xHierarchicalNameAccess
77 ( xReadAccess, UNO_QUERY );
78
79 if ( !xHierarchicalNameAccess.is() )
80 bAvailable = false;
81 else
82 {
83 const OUString aNode( o3tl::getToken(rTree, 0, '/', nIdx) );
84 if ( !xHierarchicalNameAccess->hasByHierarchicalName( aNode ) )
85 bAvailable = false;
86 else
87 {
88 Any a( xHierarchicalNameAccess->getByHierarchicalName( aNode ) );
89 bAvailable = (a >>= xReadAccess);
90 }
91 }
92 }
93 }
94 }
95 return bAvailable;
96}
97
98void FilterConfigItem::ImpInitTree( std::u16string_view rSubTree )
99{
100 bModified = false;
101
102 Reference< XComponentContext > xContext( comphelper::getProcessComponentContext() );
103
104 Reference< XMultiServiceFactory > xCfgProv = theDefaultProvider::get( xContext );
105
106 OUString sTree = OUString::Concat("/org.openoffice.") + rSubTree;
107 if ( !ImpIsTreeAvailable(xCfgProv, sTree) )
108 return;
109
110 // creation arguments: nodepath
111 PropertyValue aPathArgument;
112 aPathArgument.Name = "nodepath";
113 aPathArgument.Value <<= sTree;
114
115 Sequence< Any > aArguments{ Any(aPathArgument) };
116
117 try
118 {
119 xUpdatableView = xCfgProv->createInstanceWithArguments(
120 "com.sun.star.configuration.ConfigurationUpdateAccess",
121 aArguments );
122 if ( xUpdatableView.is() )
123 xPropSet.set( xUpdatableView, UNO_QUERY );
124 }
125 catch ( css::uno::Exception& )
126 {
127 OSL_FAIL( "FilterConfigItem::FilterConfigItem - Could not access configuration Key" );
128 }
129}
130
131FilterConfigItem::FilterConfigItem( std::u16string_view rSubTree )
132{
133 ImpInitTree( rSubTree );
134}
135
136FilterConfigItem::FilterConfigItem( css::uno::Sequence< css::beans::PropertyValue > const * pFilterData )
137 : bModified(false)
138{
139 if ( pFilterData )
140 aFilterData = *pFilterData;
141}
142
143FilterConfigItem::FilterConfigItem( std::u16string_view rSubTree,
144 css::uno::Sequence< css::beans::PropertyValue > const * pFilterData )
145{
146 ImpInitTree( rSubTree );
147
148 if ( pFilterData )
149 aFilterData = *pFilterData;
150};
151
153{
155}
156
158{
159 if ( !xUpdatableView.is() )
160 return;
161
162 if ( !(xPropSet.is() && bModified) )
163 return;
164
165 Reference< XChangesBatch > xUpdateControl( xUpdatableView, UNO_QUERY );
166 if ( xUpdateControl.is() )
167 {
168 try
169 {
170 xUpdateControl->commitChanges();
171 bModified = false;
172 }
173 catch ( css::uno::Exception& )
174 {
175 OSL_FAIL( "FilterConfigItem::FilterConfigItem - Could not update configuration data" );
176 }
177 }
178}
179
180bool FilterConfigItem::ImplGetPropertyValue( Any& rAny, const Reference< XPropertySet >& rXPropSet, const OUString& rString )
181{
182 bool bRetValue = true;
183
184 if ( rXPropSet.is() )
185 {
186 bRetValue = false;
187 try
188 {
189 Reference< XPropertySetInfo >
190 aXPropSetInfo( rXPropSet->getPropertySetInfo() );
191 if ( aXPropSetInfo.is() )
192 bRetValue = aXPropSetInfo->hasPropertyByName( rString );
193 }
194 catch( css::uno::Exception& )
195 {
196 }
197 if ( bRetValue )
198 {
199 try
200 {
201 rAny = rXPropSet->getPropertyValue( rString );
202 if ( !rAny.hasValue() )
203 bRetValue = false;
204 }
205 catch( css::uno::Exception& )
206 {
207 bRetValue = false;
208 }
209 }
210 }
211 else
212 bRetValue = false;
213 return bRetValue;
214}
215
216// if property is available it returns a pointer,
217// otherwise the result is null
218const PropertyValue* FilterConfigItem::GetPropertyValue( const Sequence< PropertyValue >& rPropSeq, const OUString& rName )
219{
220 auto pProp = std::find_if(rPropSeq.begin(), rPropSeq.end(),
221 [&rName](const PropertyValue& rProp) { return rProp.Name == rName; });
222 if (pProp != rPropSeq.end())
223 return pProp;
224 return nullptr;
225}
226
227/* if PropertySequence already includes a PropertyValue using the same name, the
228 corresponding PropertyValue is replaced, otherwise the given PropertyValue
229 will be appended */
230
231bool FilterConfigItem::WritePropertyValue( Sequence< PropertyValue >& rPropSeq, const PropertyValue& rPropValue )
232{
233 bool bRet = false;
234 if ( !rPropValue.Name.isEmpty() )
235 {
236 auto pProp = std::find_if(std::cbegin(rPropSeq), std::cend(rPropSeq),
237 [&rPropValue](const PropertyValue& rProp) { return rProp.Name == rPropValue.Name; });
238 sal_Int32 i = std::distance(std::cbegin(rPropSeq), pProp);
239 sal_Int32 nCount = rPropSeq.getLength();
240 if ( i == nCount )
241 rPropSeq.realloc( ++nCount );
242
243 rPropSeq.getArray()[ i ] = rPropValue;
244
245 bRet = true;
246 }
247 return bRet;
248}
249
250bool FilterConfigItem::ReadBool( const OUString& rKey, bool bDefault )
251{
252 Any aAny;
253 bool bRetValue = bDefault;
254 const PropertyValue* pPropVal = GetPropertyValue( aFilterData, rKey );
255 if ( pPropVal )
256 {
257 pPropVal->Value >>= bRetValue;
258 }
259 else if ( ImplGetPropertyValue( aAny, xPropSet, rKey ) )
260 {
261 aAny >>= bRetValue;
262 }
263 PropertyValue aBool;
264 aBool.Name = rKey;
265 aBool.Value <<= bRetValue;
267 return bRetValue;
268}
269
270sal_Int32 FilterConfigItem::ReadInt32( const OUString& rKey, sal_Int32 nDefault )
271{
272 Any aAny;
273 sal_Int32 nRetValue = nDefault;
274 const PropertyValue* pPropVal = GetPropertyValue( aFilterData, rKey );
275 if ( pPropVal )
276 {
277 pPropVal->Value >>= nRetValue;
278 }
279 else if ( ImplGetPropertyValue( aAny, xPropSet, rKey ) )
280 {
281 aAny >>= nRetValue;
282 }
283 PropertyValue aInt32;
284 aInt32.Name = rKey;
285 aInt32.Value <<= nRetValue;
287 return nRetValue;
288}
289
290OUString FilterConfigItem::ReadString( const OUString& rKey, const OUString& rDefault )
291{
292 Any aAny;
293 OUString aRetValue( rDefault );
294 const PropertyValue* pPropVal = GetPropertyValue( aFilterData, rKey );
295 if ( pPropVal )
296 {
297 pPropVal->Value >>= aRetValue;
298 }
299 else if ( ImplGetPropertyValue( aAny, xPropSet, rKey ) )
300 {
301 aAny >>= aRetValue;
302 }
303 PropertyValue aString;
304 aString.Name = rKey;
305 aString.Value <<= aRetValue;
307 return aRetValue;
308}
309
310void FilterConfigItem::WriteBool( const OUString& rKey, bool bNewValue )
311{
312 PropertyValue aBool;
313 aBool.Name = rKey;
314 aBool.Value <<= bNewValue;
316
317 if ( !xPropSet.is() )
318 return;
319
320 Any aAny;
321 if ( !ImplGetPropertyValue( aAny, xPropSet, rKey ) )
322 return;
323
324 bool bOldValue(true);
325 if ( !(aAny >>= bOldValue) )
326 return;
327
328 if ( bOldValue != bNewValue )
329 {
330 try
331 {
332 xPropSet->setPropertyValue( rKey, Any(bNewValue) );
333 bModified = true;
334 }
335 catch ( css::uno::Exception& )
336 {
337 OSL_FAIL( "FilterConfigItem::WriteBool - could not set PropertyValue" );
338 }
339 }
340}
341
342void FilterConfigItem::WriteInt32( const OUString& rKey, sal_Int32 nNewValue )
343{
344 PropertyValue aInt32;
345 aInt32.Name = rKey;
346 aInt32.Value <<= nNewValue;
348
349 if ( !xPropSet.is() )
350 return;
351
352 Any aAny;
353
354 if ( !ImplGetPropertyValue( aAny, xPropSet, rKey ) )
355 return;
356
357 sal_Int32 nOldValue = 0;
358 if ( !(aAny >>= nOldValue) )
359 return;
360
361 if ( nOldValue != nNewValue )
362 {
363 try
364 {
365 xPropSet->setPropertyValue( rKey, Any(nNewValue) );
366 bModified = true;
367 }
368 catch ( css::uno::Exception& )
369 {
370 OSL_FAIL( "FilterConfigItem::WriteInt32 - could not set PropertyValue" );
371 }
372 }
373}
374
375
376Reference< XStatusIndicator > FilterConfigItem::GetStatusIndicator() const
377{
378 Reference< XStatusIndicator > xStatusIndicator;
379
380 auto pPropVal = std::find_if(aFilterData.begin(), aFilterData.end(),
381 [](const css::beans::PropertyValue& rPropVal) {
382 return rPropVal.Name == "StatusIndicator"; });
383 if (pPropVal != aFilterData.end())
384 {
385 pPropVal->Value >>= xStatusIndicator;
386 }
387 return xStatusIndicator;
388}
389
390/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
static bool ImpIsTreeAvailable(Reference< XMultiServiceFactory > const &rXCfgProv, std::u16string_view rTree)
FilterConfigItem(std::u16string_view rSubTree)
static const css::beans::PropertyValue * GetPropertyValue(const css::uno::Sequence< css::beans::PropertyValue > &rPropSeq, const OUString &rName)
css::uno::Sequence< css::beans::PropertyValue > aFilterData
css::uno::Reference< css::beans::XPropertySet > xPropSet
css::uno::Reference< css::uno::XInterface > xUpdatableView
css::uno::Reference< css::task::XStatusIndicator > GetStatusIndicator() const
OUString ReadString(const OUString &rKey, const OUString &rDefault)
bool ReadBool(const OUString &rKey, bool bDefault)
void WriteBool(const OUString &rKey, bool bValue)
~FilterConfigItem()
Writes config in destructor.
static bool ImplGetPropertyValue(css::uno::Any &rAny, const css::uno::Reference< css::beans::XPropertySet > &rXPropSet, const OUString &rPropName)
static bool WritePropertyValue(css::uno::Sequence< css::beans::PropertyValue > &rPropSeq, const css::beans::PropertyValue &rPropValue)
void WriteModifiedConfig()
Writes config and sets unmodified state again.
void WriteInt32(const OUString &rKey, sal_Int32 nValue)
void ImpInitTree(std::u16string_view rTree)
sal_Int32 ReadInt32(const OUString &rKey, sal_Int32 nDefault)
int nCount
Sequence< PropertyValue > aArguments
uno_Any a
Reference< XComponentContext > getProcessComponentContext()
css::beans::PropertyValue makePropertyValue(const OUString &rName, T &&rValue)
int i
std::basic_string_view< charT, traits > getToken(std::basic_string_view< charT, traits > sv, charT delimiter, std::size_t &position)