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