Get the style color and number just once
[LibreOffice.git] / vcl / source / filter / FilterConfigItem.cxx
blobc3e508cd86657a41412d10c4333eaac0e8182f48
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <vcl/FilterConfigItem.hxx>
22 #include <unotools/configmgr.hxx>
23 #include <comphelper/processfactory.hxx>
24 #include <comphelper/propertyvalue.hxx>
25 #include <o3tl/string_view.hxx>
26 #include <osl/diagnose.h>
27 #include <com/sun/star/beans/PropertyAttribute.hpp>
28 #include <com/sun/star/beans/PropertyValue.hpp>
29 #include <com/sun/star/configuration/theDefaultProvider.hpp>
30 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
31 #include <com/sun/star/util/XChangesBatch.hpp>
32 #include <com/sun/star/beans/XPropertySetInfo.hpp>
33 #include <com/sun/star/beans/XPropertySet.hpp>
34 #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
35 #include <com/sun/star/awt/Size.hpp>
36 #include <com/sun/star/task/XStatusIndicator.hpp>
38 using namespace ::com::sun::star::lang ; // XMultiServiceFactory
39 using namespace ::com::sun::star::beans ; // PropertyValue
40 using namespace ::com::sun::star::uno ; // Reference
41 using namespace ::com::sun::star::util ; // XChangesBatch
42 using namespace ::com::sun::star::container ;
43 using namespace ::com::sun::star::configuration;
44 using namespace ::com::sun::star::task ; // XStatusIndicator
46 static bool ImpIsTreeAvailable( Reference< XMultiServiceFactory > const & rXCfgProv, std::u16string_view rTree )
48 bool bAvailable = !rTree.empty();
49 if ( bAvailable )
51 sal_Int32 nIdx{0};
52 if ( rTree[0] == '/' )
53 ++nIdx;
55 // creation arguments: nodepath
56 PropertyValue aPathArgument = comphelper::makePropertyValue(u"nodepath"_ustr,
57 OUString(o3tl::getToken(rTree, 0, '/', nIdx)));
58 Sequence< Any > aArguments{ Any(aPathArgument) };
60 Reference< XInterface > xReadAccess;
61 try
63 xReadAccess = rXCfgProv->createInstanceWithArguments(
64 u"com.sun.star.configuration.ConfigurationAccess"_ustr,
65 aArguments );
67 catch (const css::uno::Exception&)
69 bAvailable = false;
71 if ( xReadAccess.is() )
73 const sal_Int32 nEnd = rTree.size();
74 while (bAvailable && nIdx>=0 && nIdx<nEnd)
76 Reference< XHierarchicalNameAccess > xHierarchicalNameAccess
77 ( xReadAccess, UNO_QUERY );
79 if ( !xHierarchicalNameAccess.is() )
80 bAvailable = false;
81 else
83 const OUString aNode( o3tl::getToken(rTree, 0, '/', nIdx) );
84 if ( !xHierarchicalNameAccess->hasByHierarchicalName( aNode ) )
85 bAvailable = false;
86 else
88 Any a( xHierarchicalNameAccess->getByHierarchicalName( aNode ) );
89 bAvailable = (a >>= xReadAccess);
95 return bAvailable;
98 void FilterConfigItem::ImpInitTree( std::u16string_view rSubTree )
100 bModified = false;
102 const Reference< XComponentContext >& xContext( comphelper::getProcessComponentContext() );
104 Reference< XMultiServiceFactory > xCfgProv = theDefaultProvider::get( xContext );
106 OUString sTree = OUString::Concat("/org.openoffice.") + rSubTree;
107 if ( !ImpIsTreeAvailable(xCfgProv, sTree) )
108 return;
110 // creation arguments: nodepath
111 PropertyValue aPathArgument;
112 aPathArgument.Name = "nodepath";
113 aPathArgument.Value <<= sTree;
115 Sequence< Any > aArguments{ Any(aPathArgument) };
119 xUpdatableView = xCfgProv->createInstanceWithArguments(
120 u"com.sun.star.configuration.ConfigurationUpdateAccess"_ustr,
121 aArguments );
122 if ( xUpdatableView.is() )
123 xPropSet.set( xUpdatableView, UNO_QUERY );
125 catch ( css::uno::Exception& )
127 OSL_FAIL( "FilterConfigItem::FilterConfigItem - Could not access configuration Key" );
131 FilterConfigItem::FilterConfigItem( std::u16string_view rSubTree )
133 ImpInitTree( rSubTree );
136 FilterConfigItem::FilterConfigItem( css::uno::Sequence< css::beans::PropertyValue > const * pFilterData )
137 : bModified(false)
139 if ( pFilterData )
140 aFilterData = *pFilterData;
143 FilterConfigItem::FilterConfigItem( std::u16string_view rSubTree,
144 css::uno::Sequence< css::beans::PropertyValue > const * pFilterData )
146 ImpInitTree( rSubTree );
148 if ( pFilterData )
149 aFilterData = *pFilterData;
152 FilterConfigItem::~FilterConfigItem()
154 WriteModifiedConfig();
157 void FilterConfigItem::WriteModifiedConfig()
159 if ( !xUpdatableView.is() )
160 return;
162 if ( !(xPropSet.is() && bModified) )
163 return;
165 Reference< XChangesBatch > xUpdateControl( xUpdatableView, UNO_QUERY );
166 if ( xUpdateControl.is() )
170 xUpdateControl->commitChanges();
171 bModified = false;
173 catch ( css::uno::Exception& )
175 OSL_FAIL( "FilterConfigItem::FilterConfigItem - Could not update configuration data" );
180 bool FilterConfigItem::ImplGetPropertyValue( Any& rAny, const Reference< XPropertySet >& rXPropSet, const OUString& rString )
182 bool bRetValue = true;
184 if ( rXPropSet.is() )
186 bRetValue = false;
189 Reference< XPropertySetInfo >
190 aXPropSetInfo( rXPropSet->getPropertySetInfo() );
191 if ( aXPropSetInfo.is() )
192 bRetValue = aXPropSetInfo->hasPropertyByName( rString );
194 catch( css::uno::Exception& )
197 if ( bRetValue )
201 rAny = rXPropSet->getPropertyValue( rString );
202 if ( !rAny.hasValue() )
203 bRetValue = false;
205 catch( css::uno::Exception& )
207 bRetValue = false;
211 else
212 bRetValue = false;
213 return bRetValue;
216 // if property is available it returns a pointer,
217 // otherwise the result is null
218 const PropertyValue* FilterConfigItem::GetPropertyValue( const Sequence< PropertyValue >& rPropSeq, const OUString& rName )
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;
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 */
231 bool FilterConfigItem::WritePropertyValue( Sequence< PropertyValue >& rPropSeq, const PropertyValue& rPropValue )
233 bool bRet = false;
234 if ( !rPropValue.Name.isEmpty() )
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 );
243 rPropSeq.getArray()[ i ] = rPropValue;
245 bRet = true;
247 return bRet;
250 bool FilterConfigItem::IsReadOnly(const OUString& rName)
252 if (!xPropSet.is())
253 return false;
255 const Reference<XPropertySetInfo> xInfo(xPropSet->getPropertySetInfo());
256 if (!xInfo.is() || !xInfo->hasPropertyByName(rName))
257 return false;
259 const css::beans::Property aProp(xInfo->getPropertyByName(rName));
260 return (aProp.Attributes & PropertyAttribute::READONLY);
263 bool FilterConfigItem::ReadBool( const OUString& rKey, bool bDefault )
265 Any aAny;
266 bool bRetValue = bDefault;
267 const PropertyValue* pPropVal = GetPropertyValue( aFilterData, rKey );
268 if ( pPropVal )
270 pPropVal->Value >>= bRetValue;
272 else if ( ImplGetPropertyValue( aAny, xPropSet, rKey ) )
274 aAny >>= bRetValue;
276 PropertyValue aBool;
277 aBool.Name = rKey;
278 aBool.Value <<= bRetValue;
279 WritePropertyValue( aFilterData, aBool );
280 return bRetValue;
283 sal_Int32 FilterConfigItem::ReadInt32( const OUString& rKey, sal_Int32 nDefault )
285 Any aAny;
286 sal_Int32 nRetValue = nDefault;
287 const PropertyValue* pPropVal = GetPropertyValue( aFilterData, rKey );
288 if ( pPropVal )
290 pPropVal->Value >>= nRetValue;
292 else if ( ImplGetPropertyValue( aAny, xPropSet, rKey ) )
294 aAny >>= nRetValue;
296 PropertyValue aInt32;
297 aInt32.Name = rKey;
298 aInt32.Value <<= nRetValue;
299 WritePropertyValue( aFilterData, aInt32 );
300 return nRetValue;
303 OUString FilterConfigItem::ReadString( const OUString& rKey, const OUString& rDefault )
305 Any aAny;
306 OUString aRetValue( rDefault );
307 const PropertyValue* pPropVal = GetPropertyValue( aFilterData, rKey );
308 if ( pPropVal )
310 pPropVal->Value >>= aRetValue;
312 else if ( ImplGetPropertyValue( aAny, xPropSet, rKey ) )
314 aAny >>= aRetValue;
316 PropertyValue aString;
317 aString.Name = rKey;
318 aString.Value <<= aRetValue;
319 WritePropertyValue( aFilterData, aString );
320 return aRetValue;
323 void FilterConfigItem::WriteBool( const OUString& rKey, bool bNewValue )
325 PropertyValue aBool;
326 aBool.Name = rKey;
327 aBool.Value <<= bNewValue;
328 WritePropertyValue( aFilterData, aBool );
330 if ( !xPropSet.is() )
331 return;
333 Any aAny;
334 if ( !ImplGetPropertyValue( aAny, xPropSet, rKey ) )
335 return;
337 bool bOldValue(true);
338 if ( !(aAny >>= bOldValue) )
339 return;
341 if ( bOldValue != bNewValue )
345 xPropSet->setPropertyValue( rKey, Any(bNewValue) );
346 bModified = true;
348 catch ( css::uno::Exception& )
350 OSL_FAIL( "FilterConfigItem::WriteBool - could not set PropertyValue" );
355 void FilterConfigItem::WriteInt32( const OUString& rKey, sal_Int32 nNewValue )
357 PropertyValue aInt32;
358 aInt32.Name = rKey;
359 aInt32.Value <<= nNewValue;
360 WritePropertyValue( aFilterData, aInt32 );
362 if ( !xPropSet.is() )
363 return;
365 Any aAny;
367 if ( !ImplGetPropertyValue( aAny, xPropSet, rKey ) )
368 return;
370 sal_Int32 nOldValue = 0;
371 if ( !(aAny >>= nOldValue) )
372 return;
374 if ( nOldValue != nNewValue )
378 xPropSet->setPropertyValue( rKey, Any(nNewValue) );
379 bModified = true;
381 catch ( css::uno::Exception& )
383 OSL_FAIL( "FilterConfigItem::WriteInt32 - could not set PropertyValue" );
389 Reference< XStatusIndicator > FilterConfigItem::GetStatusIndicator() const
391 Reference< XStatusIndicator > xStatusIndicator;
393 auto pPropVal = std::find_if(aFilterData.begin(), aFilterData.end(),
394 [](const css::beans::PropertyValue& rPropVal) {
395 return rPropVal.Name == "StatusIndicator"; });
396 if (pPropVal != aFilterData.end())
398 pPropVal->Value >>= xStatusIndicator;
400 return xStatusIndicator;
403 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */