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