1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_svtools.hxx"
26 #include <svtools/FilterConfigItem.hxx>
27 
28 #include <tools/debug.hxx>
29 #include <unotools/configmgr.hxx>
30 #include <unotools/processfactory.hxx>
31 #include <com/sun/star/beans/PropertyValue.hpp>
32 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
33 #include <com/sun/star/util/XChangesBatch.hpp>
34 #include <com/sun/star/beans/XPropertySetInfo.hpp>
35 #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
36 
37 using ::rtl::OUString;
38 using namespace ::utl						;	// getProcessServiceFactory
39 using namespace ::com::sun::star::lang		;	// XMultiServiceFactory
40 using namespace ::com::sun::star::beans		;	// PropertyValue
41 using namespace ::com::sun::star::uno		;	// Reference
42 using namespace ::com::sun::star::util		;	// XChangesBatch
43 using namespace ::com::sun::star::awt		;	// Size
44 using namespace ::com::sun::star::container ;	//
45 using namespace ::com::sun::star::task		;	// XStatusIndicator
46 
ImpIsTreeAvailable(Reference<XMultiServiceFactory> & rXCfgProv,const String & rTree)47 static sal_Bool ImpIsTreeAvailable( Reference< XMultiServiceFactory >& rXCfgProv, const String& rTree )
48 {
49 	sal_Bool	bAvailable = rTree.Len() != 0;
50 	if ( bAvailable )
51 	{
52 		xub_StrLen	nTokenCount = rTree.GetTokenCount( (sal_Unicode)'/' );
53 		xub_StrLen	i = 0;
54 
55 		if ( rTree.GetChar( 0 ) == (sal_Unicode)'/' )
56 			i++;
57 		if ( rTree.GetChar( rTree.Len() - 1 ) == (sal_Unicode)'/' )
58 			nTokenCount--;
59 
60 		Any aAny;
61 		aAny <<= (OUString)rTree.GetToken( i++, (sal_Unicode)'/' );
62 
63 		// creation arguments: nodepath
64 		PropertyValue aPathArgument;
65 		aPathArgument.Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "nodepath" ) );
66 		aPathArgument.Value = aAny;
67 
68 		Sequence< Any > aArguments( 1 );
69 		aArguments[ 0 ] <<= aPathArgument;
70 
71 		Reference< XInterface > xReadAccess;
72 		try
73 		{
74 			xReadAccess = rXCfgProv->createInstanceWithArguments(
75 				OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationAccess" ) ),
76 					aArguments );
77 		}
78 		catch ( ::com::sun::star::uno::Exception& )
79 		{
80 			bAvailable = sal_False;
81 		}
82 		if ( xReadAccess.is() )
83 		{
84 			for ( ; bAvailable && ( i < nTokenCount ); i++ )
85 			{
86 				Reference< XHierarchicalNameAccess > xHierarchicalNameAccess
87 					( xReadAccess, UNO_QUERY );
88 
89 				if ( !xHierarchicalNameAccess.is() )
90 					bAvailable = sal_False;
91 				else
92 				{
93 					String aNode( rTree.GetToken( i, (sal_Unicode)'/' ) );
94 					if ( !xHierarchicalNameAccess->hasByHierarchicalName( aNode ) )
95 						bAvailable = sal_False;
96 					else
97 					{
98 						Any a( xHierarchicalNameAccess->getByHierarchicalName( aNode ) );
99 						try
100 						{
101 							a >>= xReadAccess;
102 						}
103 						catch ( ::com::sun::star::uno::Exception& )
104 						{
105 							bAvailable = sal_False;
106 						}
107 					}
108 				}
109 			}
110 		}
111 	}
112 	return bAvailable;
113 }
114 
ImpInitTree(const String & rSubTree)115 void FilterConfigItem::ImpInitTree( const String& rSubTree )
116 {
117 	bModified = sal_False;
118 
119 	OUString sTree( ConfigManager::GetConfigBaseURL() );
120 	sTree += rSubTree;
121 	Reference< XMultiServiceFactory > xSMGR = getProcessServiceFactory();	// get global uno service manager
122 
123 	Reference< XMultiServiceFactory > xCfgProv(
124 		xSMGR->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationProvider" ) ) ),
125 			UNO_QUERY );
126 
127 	if ( xCfgProv.is() )
128 	{
129 		if ( ImpIsTreeAvailable( xCfgProv, String( sTree ) ) )
130 		{
131 			Any aAny;
132 			// creation arguments: nodepath
133 			PropertyValue aPathArgument;
134 			aAny <<= sTree;
135 			aPathArgument.Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "nodepath" ) );
136 			aPathArgument.Value = aAny;
137 
138 			// creation arguments: commit mode
139 			PropertyValue aModeArgument;
140 			sal_Bool bAsyncron = sal_True;
141 			aAny <<= bAsyncron;
142 			aModeArgument.Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "lazywrite" ) );
143 			aModeArgument.Value = aAny;
144 
145 			Sequence< Any > aArguments( 2 );
146 			aArguments[ 0 ] <<= aPathArgument;
147 			aArguments[ 1 ] <<= aModeArgument;
148 
149 			try
150 			{
151 				xUpdatableView = xCfgProv->createInstanceWithArguments(
152 					OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationUpdateAccess" ) ),
153 						aArguments );
154 				if ( xUpdatableView.is() )
155 					xPropSet = Reference< XPropertySet >( xUpdatableView, UNO_QUERY );
156 			}
157 			catch ( ::com::sun::star::uno::Exception& )
158 			{
159 				DBG_ERROR( "FilterConfigItem::FilterConfigItem - Could not access configuration Key" );
160 			}
161 		}
162 	}
163 }
164 
FilterConfigItem(const OUString & rSubTree)165 FilterConfigItem::FilterConfigItem( const OUString& rSubTree )
166 {
167 	ImpInitTree( rSubTree );
168 }
169 
FilterConfigItem(::com::sun::star::uno::Sequence<::com::sun::star::beans::PropertyValue> * pFilterData)170 FilterConfigItem::FilterConfigItem( ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >* pFilterData )
171 {
172 	if ( pFilterData )
173 		aFilterData = *pFilterData;
174 }
175 
FilterConfigItem(const OUString & rSubTree,::com::sun::star::uno::Sequence<::com::sun::star::beans::PropertyValue> * pFilterData)176 FilterConfigItem::FilterConfigItem( const OUString& rSubTree,
177 	::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >* pFilterData )
178 {
179 	ImpInitTree( rSubTree );
180 
181 	if ( pFilterData )
182 		aFilterData = *pFilterData;
183 };
184 
~FilterConfigItem()185 FilterConfigItem::~FilterConfigItem()
186 {
187 	if ( xUpdatableView.is() )
188 	{
189 		if ( xPropSet.is() && bModified )
190 		{
191 			Reference< XChangesBatch > xUpdateControl( xUpdatableView, UNO_QUERY );
192 			if ( xUpdateControl.is() )
193 			{
194 				try
195 				{
196 					xUpdateControl->commitChanges();
197 				}
198 				catch ( ::com::sun::star::uno::Exception& )
199 				{
200 					DBG_ERROR( "FilterConfigItem::FilterConfigItem - Could not update configuration data" );
201 				}
202 			}
203 		}
204 	}
205 }
206 
ImplGetPropertyValue(Any & rAny,const Reference<XPropertySet> & rXPropSet,const OUString & rString,sal_Bool bTestPropertyAvailability)207 sal_Bool FilterConfigItem::ImplGetPropertyValue( Any& rAny, const Reference< XPropertySet >& rXPropSet, const OUString& rString, sal_Bool bTestPropertyAvailability )
208 {
209     sal_Bool bRetValue = sal_True;
210 
211 	if ( rXPropSet.is() )
212 	{
213 		if ( bTestPropertyAvailability )
214 		{
215 			bRetValue = sal_False;
216 			try
217 			{
218 				Reference< XPropertySetInfo >
219 					aXPropSetInfo( rXPropSet->getPropertySetInfo() );
220 				if ( aXPropSetInfo.is() )
221 					bRetValue = aXPropSetInfo->hasPropertyByName( rString );
222 			}
223 			catch( ::com::sun::star::uno::Exception& )
224 			{
225 				//
226 			}
227 		}
228 		if ( bRetValue )
229 		{
230 			try
231 			{
232 				rAny = rXPropSet->getPropertyValue( rString );
233 				if ( !rAny.hasValue() )
234 					bRetValue = sal_False;
235 			}
236 			catch( ::com::sun::star::uno::Exception& )
237 			{
238 				bRetValue = sal_False;
239 			}
240 		}
241 	}
242 	else
243 		bRetValue = sal_False;
244     return bRetValue;
245 }
246 
247 
248 // if property is available it returns a pointer,
249 // otherwise the result is null
GetPropertyValue(Sequence<PropertyValue> & rPropSeq,const OUString & rName)250 PropertyValue* FilterConfigItem::GetPropertyValue( Sequence< PropertyValue >& rPropSeq, const OUString& rName )
251 {
252 	PropertyValue* pPropValue = NULL;
253 
254 	sal_Int32 i, nCount;
255 	for ( i = 0, nCount = rPropSeq.getLength(); i < nCount; i++ )
256 	{
257 		if ( rPropSeq[ i ].Name == rName )
258 		{
259 			pPropValue = &rPropSeq[ i ];
260 			break;
261 		}
262 	}
263     return pPropValue;
264 }
265 
266 /* if PropertySequence already includes a PropertyValue using the same name, the
267     corresponding PropertyValue is replaced, otherwise the given PropertyValue
268     will be appended */
269 
WritePropertyValue(Sequence<PropertyValue> & rPropSeq,const PropertyValue & rPropValue)270 sal_Bool FilterConfigItem::WritePropertyValue( Sequence< PropertyValue >& rPropSeq, const PropertyValue& rPropValue )
271 {
272 	sal_Bool bRet = sal_False;
273 	if ( rPropValue.Name.getLength() )
274 	{
275 		sal_Int32 i, nCount;
276 		for ( i = 0, nCount = rPropSeq.getLength(); i < nCount; i++ )
277 		{
278 			if ( rPropSeq[ i ].Name == rPropValue.Name )
279 				break;
280 		}
281 		if ( i == nCount )
282 			rPropSeq.realloc( ++nCount );
283 
284 		rPropSeq[ i ] = rPropValue;
285 
286 		bRet = sal_True;
287 	}
288 	return bRet;
289 }
290 
ReadBool(const OUString & rKey,sal_Bool bDefault)291 sal_Bool FilterConfigItem::ReadBool( const OUString& rKey, sal_Bool bDefault )
292 {
293 	Any aAny;
294 	sal_Bool bRetValue = bDefault;
295 	PropertyValue* pPropVal = GetPropertyValue( aFilterData, rKey );
296 	if ( pPropVal )
297 	{
298 		pPropVal->Value >>= bRetValue;
299 	}
300 	else if ( ImplGetPropertyValue( aAny, xPropSet, rKey, sal_True ) )
301 	{
302 		aAny >>= bRetValue;
303 	}
304 	PropertyValue aBool;
305 	aBool.Name = rKey;
306 	aBool.Value <<= bRetValue;
307 	WritePropertyValue( aFilterData, aBool );
308 	return bRetValue;
309 }
310 
ReadInt32(const OUString & rKey,sal_Int32 nDefault)311 sal_Int32 FilterConfigItem::ReadInt32( const OUString& rKey, sal_Int32 nDefault )
312 {
313 	Any aAny;
314 	sal_Int32 nRetValue = nDefault;
315 	PropertyValue* pPropVal = GetPropertyValue( aFilterData, rKey );
316 	if ( pPropVal )
317 	{
318 		pPropVal->Value >>= nRetValue;
319 	}
320 	else if ( ImplGetPropertyValue( aAny, xPropSet, rKey, sal_True ) )
321 	{
322 		aAny >>= nRetValue;
323 	}
324 	PropertyValue aInt32;
325 	aInt32.Name = rKey;
326 	aInt32.Value <<= nRetValue;
327 	WritePropertyValue( aFilterData, aInt32 );
328 	return nRetValue;
329 }
330 
331 
ReadSize(const OUString & rKey,const Size & rDefault)332 Size FilterConfigItem::ReadSize( const OUString& rKey, const Size& rDefault )
333 {
334 	Any aAny;
335 	Size aRetValue( rDefault );
336 
337 	const OUString sWidth( RTL_CONSTASCII_USTRINGPARAM( "LogicalWidth" ) );
338 	const OUString sHeight( RTL_CONSTASCII_USTRINGPARAM( "LogicalHeight" ) );
339 
340 	Reference< XPropertySet > aXPropSet;
341 	try
342 	{
343 		PropertyValue* pPropWidth = GetPropertyValue( aFilterData, sWidth  );
344 		PropertyValue* pPropHeight= GetPropertyValue( aFilterData, sHeight );
345 		if ( pPropWidth && pPropHeight )
346 		{
347 			pPropWidth->Value >>= aRetValue.Width;
348 			pPropHeight->Value >>= aRetValue.Height;
349 		}
350 		else if ( ImplGetPropertyValue( aAny, xPropSet, rKey, sal_True ) )
351 		{
352 			if ( aAny >>= aXPropSet )
353 			{
354 				if ( ImplGetPropertyValue( aAny, aXPropSet, sWidth, sal_True ) )
355 					aAny >>= aRetValue.Width;
356 				if ( ImplGetPropertyValue( aAny, aXPropSet, sHeight, sal_True ) )
357 					aAny >>= aRetValue.Height;
358 			}
359 		}
360 	}
361 	catch ( ::com::sun::star::uno::Exception& )
362 	{
363 		DBG_ERROR( "FilterConfigItem::ReadSize - could not read PropertyValue" );
364 	}
365 	PropertyValue aWidth;
366 	aWidth.Name = sWidth;
367 	aWidth.Value <<= aRetValue.Width;
368 	WritePropertyValue( aFilterData, aWidth );
369 	PropertyValue aHeight;
370 	aHeight.Name = sHeight;
371 	aHeight.Value <<= aRetValue.Height;
372 	WritePropertyValue( aFilterData, aHeight );
373 	return aRetValue;
374 }
375 
ReadString(const OUString & rKey,const OUString & rDefault)376 OUString FilterConfigItem::ReadString( const OUString& rKey, const OUString& rDefault )
377 {
378 	Any aAny;
379 	OUString aRetValue( rDefault );
380 	PropertyValue* pPropVal = GetPropertyValue( aFilterData, rKey );
381 	if ( pPropVal )
382 	{
383 		pPropVal->Value >>= aRetValue;
384 	}
385 	else if ( ImplGetPropertyValue( aAny, xPropSet, rKey, sal_True ) )
386 	{
387 		aAny >>= aRetValue;
388 	}
389 	PropertyValue aString;
390 	aString.Name = rKey;
391 	aString.Value <<= aRetValue;
392 	WritePropertyValue( aFilterData, aString );
393 	return aRetValue;
394 }
395 
ReadAny(const::rtl::OUString & rKey,const Any & rDefault)396 Any FilterConfigItem::ReadAny( const ::rtl::OUString& rKey, const Any& rDefault )
397 {
398 	Any aAny, aRetValue( rDefault );
399 	PropertyValue* pPropVal = GetPropertyValue( aFilterData, rKey );
400 	if ( pPropVal )
401 	{
402 		aRetValue = pPropVal->Value;
403 	}
404 	else if ( ImplGetPropertyValue( aAny, xPropSet, rKey, sal_True ) )
405 	{
406 		aRetValue = aAny;
407 	}
408 	PropertyValue aPropValue;
409 	aPropValue.Name = rKey;
410 	aPropValue.Value = aRetValue;
411 	WritePropertyValue( aFilterData, aPropValue );
412 	return aRetValue;
413 }
414 
WriteBool(const OUString & rKey,sal_Bool bNewValue)415 void FilterConfigItem::WriteBool( const OUString& rKey, sal_Bool bNewValue )
416 {
417 	PropertyValue aBool;
418 	aBool.Name = rKey;
419 	aBool.Value <<= bNewValue;
420 	WritePropertyValue( aFilterData, aBool );
421 
422 	if ( xPropSet.is() )
423 	{
424 		Any aAny;
425 		if ( ImplGetPropertyValue( aAny, xPropSet, rKey, sal_True ) )
426 		{
427 			sal_Bool bOldValue(sal_True);
428 			if ( aAny >>= bOldValue )
429 			{
430 				if ( bOldValue != bNewValue )
431 				{
432 					aAny <<= bNewValue;
433 					try
434 					{
435 						xPropSet->setPropertyValue( rKey, aAny );
436 						bModified = sal_True;
437 					}
438 					catch ( ::com::sun::star::uno::Exception& )
439 					{
440 						DBG_ERROR( "FilterConfigItem::WriteBool - could not set PropertyValue" );
441 					}
442 				}
443 			}
444 		}
445 	}
446 }
447 
WriteInt32(const OUString & rKey,sal_Int32 nNewValue)448 void FilterConfigItem::WriteInt32( const OUString& rKey, sal_Int32 nNewValue )
449 {
450 	PropertyValue aInt32;
451 	aInt32.Name = rKey;
452 	aInt32.Value <<= nNewValue;
453 	WritePropertyValue( aFilterData, aInt32 );
454 
455 	if ( xPropSet.is() )
456 	{
457 		Any aAny;
458 
459 		if ( ImplGetPropertyValue( aAny, xPropSet, rKey, sal_True ) )
460 		{
461 			sal_Int32 nOldValue = 0;
462 			if ( aAny >>= nOldValue )
463 			{
464 				if ( nOldValue != nNewValue )
465 				{
466 					aAny <<= nNewValue;
467 					try
468 					{
469 						xPropSet->setPropertyValue( rKey, aAny );
470 						bModified = sal_True;
471 					}
472 					catch ( ::com::sun::star::uno::Exception& )
473 					{
474 						DBG_ERROR( "FilterConfigItem::WriteInt32 - could not set PropertyValue" );
475 					}
476 				}
477 			}
478 		}
479 	}
480 }
481 
WriteSize(const OUString & rKey,const Size & rNewValue)482 void FilterConfigItem::WriteSize( const OUString& rKey, const Size& rNewValue )
483 {
484 	const OUString sWidth( RTL_CONSTASCII_USTRINGPARAM( "LogicalWidth" ) );
485 	const OUString sHeight( RTL_CONSTASCII_USTRINGPARAM( "LogicalHeight" ) );
486 
487 	PropertyValue aWidth;
488 	aWidth.Name = sWidth;
489 	aWidth.Value <<= rNewValue.Width;
490 	WritePropertyValue( aFilterData, aWidth );
491 
492 	PropertyValue aHeight;
493 	aHeight.Name = sHeight;
494 	aHeight.Value <<= rNewValue.Height;
495 	WritePropertyValue( aFilterData, aHeight );
496 
497 	if ( xPropSet.is() )
498 	{
499 		Any aAny;
500 		sal_Int32 nOldWidth = rNewValue.Width;
501 		sal_Int32 nOldHeight = rNewValue.Height;
502 
503 		if ( ImplGetPropertyValue( aAny, xPropSet, rKey, sal_True ) )
504 		{
505 			try
506 			{
507 				Reference< XPropertySet > aXPropSet;
508 				if ( aAny >>= aXPropSet )
509 				{
510 					if ( ImplGetPropertyValue( aAny, aXPropSet, sWidth, sal_True ) )
511 						aAny >>= nOldWidth;
512 					if ( ImplGetPropertyValue( aAny, aXPropSet, sHeight, sal_True ) )
513 						aAny >>= nOldHeight;
514 				}
515 				if ( ( nOldWidth != rNewValue.Width ) || ( nOldHeight != rNewValue.Height ) )
516 				{
517 					aAny <<= rNewValue.Width;
518 					aXPropSet->setPropertyValue( sWidth, aAny );
519 					aAny <<= rNewValue.Height;
520 					aXPropSet->setPropertyValue( sHeight, aAny );
521 					bModified = sal_True;
522 				}
523 			}
524 			catch ( ::com::sun::star::uno::Exception& )
525 			{
526 				DBG_ERROR( "FilterConfigItem::WriteSize - could not read PropertyValue" );
527 			}
528 		}
529 	}
530 }
531 
WriteString(const OUString & rKey,const OUString & rNewValue)532 void FilterConfigItem::WriteString( const OUString& rKey, const OUString& rNewValue )
533 {
534 	PropertyValue aString;
535 	aString.Name = rKey;
536 	aString.Value <<= rNewValue;
537 	WritePropertyValue( aFilterData, aString );
538 
539 	if ( xPropSet.is() )
540 	{
541 		Any aAny;
542 
543 		if ( ImplGetPropertyValue( aAny, xPropSet, rKey, sal_True ) )
544 		{
545 			OUString aOldValue;
546 			if ( aAny >>= aOldValue )
547 			{
548 				if ( aOldValue != rNewValue )
549 				{
550 					aAny <<= rNewValue;
551 					try
552 					{
553 						xPropSet->setPropertyValue( rKey, aAny );
554 						bModified = sal_True;
555 					}
556 					catch ( ::com::sun::star::uno::Exception& )
557 					{
558 						DBG_ERROR( "FilterConfigItem::WriteInt32 - could not set PropertyValue" );
559 					}
560 				}
561 			}
562 		}
563 	}
564 }
565 
WriteAny(const OUString & rKey,const Any & rNewAny)566 void FilterConfigItem::WriteAny( const OUString& rKey, const Any& rNewAny )
567 {
568 	PropertyValue aPropValue;
569 	aPropValue.Name = rKey;
570 	aPropValue.Value = rNewAny;
571 	WritePropertyValue( aFilterData, aPropValue );
572 	if ( xPropSet.is() )
573 	{
574 		Any aAny;
575 		if ( ImplGetPropertyValue( aAny, xPropSet, rKey, sal_True ) )
576 		{
577 			if ( aAny != rNewAny )
578 			{
579 				try
580 				{
581 					xPropSet->setPropertyValue( rKey, rNewAny );
582 					bModified = sal_True;
583 				}
584 				catch ( com::sun::star::uno::Exception& )
585 				{
586 					DBG_ERROR( "FilterConfigItem::WriteAny - could not set PropertyValue" );
587 
588 				}
589 			}
590 		}
591 	}
592 }
593 
594 // ------------------------------------------------------------------------
595 
GetFilterData() const596 Sequence< PropertyValue > FilterConfigItem::GetFilterData() const
597 {
598 	return aFilterData;
599 }
600 
601 // ------------------------------------------------------------------------
602 
GetStatusIndicator() const603 Reference< XStatusIndicator > FilterConfigItem::GetStatusIndicator() const
604 {
605 	Reference< XStatusIndicator > xStatusIndicator;
606 	const rtl::OUString sStatusIndicator( RTL_CONSTASCII_USTRINGPARAM( "StatusIndicator" ) );
607 
608 	sal_Int32 i, nCount = aFilterData.getLength();
609 	for ( i = 0; i < nCount; i++ )
610 	{
611 		if ( aFilterData[ i ].Name == sStatusIndicator )
612 		{
613 			aFilterData[ i ].Value >>= xStatusIndicator;
614 			break;
615 		}
616 	}
617 	return xStatusIndicator;
618 }
619 
620