1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_toolkit.hxx"
30 #include <com/sun/star/beans/PropertyState.hpp>
31 #include <com/sun/star/beans/PropertyAttribute.hpp>
32 #include <com/sun/star/awt/FontDescriptor.hpp>
33 #include <com/sun/star/awt/FontWidth.hpp>
34 #include <com/sun/star/awt/FontWeight.hpp>
35 #include <com/sun/star/awt/FontSlant.hpp>
36 #include <com/sun/star/awt/MouseWheelBehavior.hpp>
37 #include <com/sun/star/graphic/XGraphicProvider.hpp>
38 #include <com/sun/star/awt/XDevice.hpp>
39 #include <com/sun/star/text/WritingMode2.hpp>
40 #include <com/sun/star/io/XMarkableStream.hpp>
41 #include <toolkit/controls/unocontrolmodel.hxx>
42 #include <toolkit/helper/macros.hxx>
43 #include <cppuhelper/typeprovider.hxx>
44 #include <rtl/memory.h>
45 #include <rtl/uuid.h>
46 #include <tools/diagnose_ex.h>
47 #include <tools/string.hxx>
48 #include <tools/table.hxx>
49 #include <tools/date.hxx>
50 #include <tools/time.hxx>
51 #include <tools/urlobj.hxx>
52 #include <tools/debug.hxx>
53 #include <toolkit/helper/property.hxx>
54 #include <toolkit/helper/vclunohelper.hxx>
55 #include <toolkit/helper/emptyfontdescriptor.hxx>
56 #include <com/sun/star/lang/Locale.hpp>
57 #include <unotools/localedatawrapper.hxx>
58 #include <unotools/configmgr.hxx>
59 #include <comphelper/processfactory.hxx>
60 #include <comphelper/sequence.hxx>
61 #include <comphelper/extract.hxx>
62 #include <vcl/svapp.hxx>
63 #include <uno/data.h>
64 
65 #include <memory>
66 
67 using namespace ::com::sun::star;
68 using namespace ::com::sun::star::uno;
69 using namespace ::com::sun::star::lang;
70 using namespace ::com::sun::star::i18n;
71 using ::com::sun::star::awt::FontDescriptor;
72 
73 struct ImplControlProperty
74 {
75 private:
76 	sal_uInt16					nId;
77 	::com::sun::star::uno::Any	aValue;
78 
79 public:
80 	ImplControlProperty( const ImplControlProperty& rProp ) : aValue( rProp.aValue )
81 	{
82 		nId = rProp.nId;
83 	}
84 
85 	ImplControlProperty( sal_uInt16 nT )
86 	{
87 		nId = nT;
88 	}
89 
90 	ImplControlProperty( sal_uInt16 nT, const ::com::sun::star::uno::Any& rValue ) : aValue( rValue )
91 	{
92 		nId = nT;
93 	}
94 
95 	sal_uInt16							GetId() const 											{ return nId; }
96 	const ::com::sun::star::uno::Any&	GetValue() const 										{ return aValue; }
97 	void								SetValue( const ::com::sun::star::uno::Any& rValue )	{ aValue = rValue; }
98 };
99 
100 DECLARE_TABLE( ImplPropertyTable, ImplControlProperty* )
101 
102 #define UNOCONTROL_STREAMVERSION	(short)2
103 
104 static void lcl_ImplMergeFontProperty( FontDescriptor& rFD, sal_uInt16 nPropId, const Any& rValue )
105 {
106 	// some props are defined with other types than the matching FontDescriptor members have
107 	// (e.g. FontWidth, FontSlant)
108 	// 78474 - 09/19/2000 - FS
109 	float		nExtractFloat = 0;
110 	sal_Int16	nExtractShort = 0;
111 
112 	switch ( nPropId )
113 	{
114 		case BASEPROPERTY_FONTDESCRIPTORPART_NAME: 			rValue >>= rFD.Name;
115 															break;
116 		case BASEPROPERTY_FONTDESCRIPTORPART_STYLENAME:		rValue >>= rFD.StyleName;
117 															break;
118 		case BASEPROPERTY_FONTDESCRIPTORPART_FAMILY: 		rValue >>= rFD.Family;
119 															break;
120 		case BASEPROPERTY_FONTDESCRIPTORPART_CHARSET: 		rValue >>= rFD.CharSet;
121 															break;
122 		case BASEPROPERTY_FONTDESCRIPTORPART_HEIGHT: 		rValue >>= nExtractFloat; rFD.Height = (sal_Int16)nExtractFloat;
123 															break;
124 		case BASEPROPERTY_FONTDESCRIPTORPART_WEIGHT: 		rValue >>= rFD.Weight;
125 															break;
126 		case BASEPROPERTY_FONTDESCRIPTORPART_SLANT: 		if ( rValue >>= nExtractShort )
127 																rFD.Slant = (::com::sun::star::awt::FontSlant)nExtractShort;
128 															else
129 																rValue >>= rFD.Slant;
130 															break;
131 		case BASEPROPERTY_FONTDESCRIPTORPART_UNDERLINE:		rValue >>= rFD.Underline;
132 															break;
133 		case BASEPROPERTY_FONTDESCRIPTORPART_STRIKEOUT:		rValue >>= rFD.Strikeout;
134 															break;
135 		case BASEPROPERTY_FONTDESCRIPTORPART_WIDTH:			rValue >>= rFD.Width;
136 															break;
137 		case BASEPROPERTY_FONTDESCRIPTORPART_PITCH:			rValue >>= rFD.Pitch;
138 															break;
139 		case BASEPROPERTY_FONTDESCRIPTORPART_CHARWIDTH:		rValue >>= rFD.CharacterWidth;
140 															break;
141 		case BASEPROPERTY_FONTDESCRIPTORPART_ORIENTATION: 	rValue >>= rFD.Orientation;
142 															break;
143 		case BASEPROPERTY_FONTDESCRIPTORPART_KERNING: 		rValue >>= rFD.Kerning;
144 															break;
145 		case BASEPROPERTY_FONTDESCRIPTORPART_WORDLINEMODE: 	rValue >>= rFD.WordLineMode;
146 															break;
147 		case BASEPROPERTY_FONTDESCRIPTORPART_TYPE:			rValue >>= rFD.Type;
148 															break;
149 		default: 											DBG_ERROR( "FontProperty?!" );
150 	}
151 }
152 
153 //	----------------------------------------------------
154 //	class UnoControlModel
155 //	----------------------------------------------------
156 UnoControlModel::UnoControlModel()
157     :UnoControlModel_Base()
158     ,MutexAndBroadcastHelper()
159     ,OPropertySetHelper( BrdcstHelper )
160     ,maDisposeListeners( *this )
161     ,maContext( ::comphelper::getProcessServiceFactory() )
162 {
163     OSL_ENSURE( false, "UnoControlModel::UnoControlModel: not implemented. Well, not really." );
164     // just implemented to let the various FooImplInheritanceHelper compile, you should use the
165     // version taking a service factory
166 	mpData = new ImplPropertyTable;
167 }
168 
169 UnoControlModel::UnoControlModel( const Reference< XMultiServiceFactory >& i_factory )
170     :UnoControlModel_Base()
171     ,MutexAndBroadcastHelper()
172     ,OPropertySetHelper( BrdcstHelper )
173     ,maDisposeListeners( *this )
174     ,maContext( i_factory )
175 {
176 	// Die Properties muessen vom Model in die Tabelle gestopft werden,
177 	// nur vorhandene Properties sind gueltige Properties, auch wenn VOID.
178 	mpData = new ImplPropertyTable;
179 }
180 
181 UnoControlModel::UnoControlModel( const UnoControlModel& rModel )
182 	: UnoControlModel_Base()
183     , MutexAndBroadcastHelper()
184     , OPropertySetHelper( BrdcstHelper )
185     , maDisposeListeners( *this )
186     , maContext( rModel.maContext )
187 {
188 	mpData = new ImplPropertyTable;
189 
190 	for ( sal_uInt32 n = rModel.mpData->Count(); n; )
191 	{
192 		ImplControlProperty* pProp = rModel.mpData->GetObject( --n );
193 		ImplControlProperty* pNew = new ImplControlProperty( *pProp );
194 		mpData->Insert( pNew->GetId(), pNew );
195 	}
196 }
197 
198 UnoControlModel::~UnoControlModel()
199 {
200 	for ( sal_uInt32 n = mpData->Count(); n; )
201 		delete mpData->GetObject( --n );
202 	delete mpData;
203 }
204 
205 UnoControlModel* UnoControlModel::Clone() const
206 {
207 	DBG_ERROR( "UnoControlModel::Clone() ?!" );
208 	return NULL;
209 }
210 
211 ::com::sun::star::uno::Sequence<sal_Int32> UnoControlModel::ImplGetPropertyIds() const
212 {
213 	sal_uInt32 nIDs = mpData->Count();
214 	::com::sun::star::uno::Sequence<sal_Int32>	aIDs( nIDs );
215 	sal_Int32* pIDs = aIDs.getArray();
216 	for ( sal_uInt32 n = 0; n < nIDs; n++ )
217 		pIDs[n] = mpData->GetObjectKey( n );
218 	return aIDs;
219 }
220 
221 sal_Bool UnoControlModel::ImplHasProperty( sal_uInt16 nPropId ) const
222 {
223 	if ( ( nPropId >= BASEPROPERTY_FONTDESCRIPTORPART_START ) && ( nPropId <= BASEPROPERTY_FONTDESCRIPTORPART_END ) )
224 		nPropId = BASEPROPERTY_FONTDESCRIPTOR;
225 
226 	return mpData->Get( nPropId ) ? sal_True : sal_False;
227 }
228 
229 ::com::sun::star::uno::Any UnoControlModel::ImplGetDefaultValue( sal_uInt16 nPropId ) const
230 {
231 	::com::sun::star::uno::Any aDefault;
232 
233     if (
234         (nPropId == BASEPROPERTY_FONTDESCRIPTOR) ||
235         (
236          (nPropId >= BASEPROPERTY_FONTDESCRIPTORPART_START) &&
237          (nPropId <= BASEPROPERTY_FONTDESCRIPTORPART_END)
238         )
239        )
240 	{
241 		EmptyFontDescriptor aFD;
242 		switch ( nPropId )
243 		{
244 			case BASEPROPERTY_FONTDESCRIPTOR: 					aDefault <<= aFD;					break;
245 			case BASEPROPERTY_FONTDESCRIPTORPART_NAME: 			aDefault <<= aFD.Name;				break;
246 			case BASEPROPERTY_FONTDESCRIPTORPART_STYLENAME:		aDefault <<= aFD.StyleName;			break;
247 			case BASEPROPERTY_FONTDESCRIPTORPART_FAMILY: 		aDefault <<= aFD.Family;			break;
248 			case BASEPROPERTY_FONTDESCRIPTORPART_CHARSET: 		aDefault <<= aFD.CharSet;			break;
249 			case BASEPROPERTY_FONTDESCRIPTORPART_HEIGHT: 		aDefault <<= (float)aFD.Height;		break;
250 			case BASEPROPERTY_FONTDESCRIPTORPART_WEIGHT: 		aDefault <<= aFD.Weight;			break;
251 			case BASEPROPERTY_FONTDESCRIPTORPART_SLANT: 		aDefault <<= (sal_Int16)aFD.Slant;	break;
252 			case BASEPROPERTY_FONTDESCRIPTORPART_UNDERLINE:		aDefault <<= aFD.Underline;			break;
253 			case BASEPROPERTY_FONTDESCRIPTORPART_STRIKEOUT:		aDefault <<= aFD.Strikeout;			break;
254 			case BASEPROPERTY_FONTDESCRIPTORPART_WIDTH:			aDefault <<= aFD.Width;				break;
255 			case BASEPROPERTY_FONTDESCRIPTORPART_PITCH:			aDefault <<= aFD.Pitch;				break;
256 			case BASEPROPERTY_FONTDESCRIPTORPART_CHARWIDTH:		aDefault <<= aFD.CharacterWidth;	break;
257 			case BASEPROPERTY_FONTDESCRIPTORPART_ORIENTATION:	aDefault <<= aFD.Orientation;		break;
258 			case BASEPROPERTY_FONTDESCRIPTORPART_KERNING:		aDefault <<= aFD.Kerning;			break;
259 			case BASEPROPERTY_FONTDESCRIPTORPART_WORDLINEMODE:	aDefault <<= aFD.WordLineMode;		break;
260 			case BASEPROPERTY_FONTDESCRIPTORPART_TYPE:			aDefault <<= aFD.Type;				break;
261 			default: DBG_ERROR( "FontProperty?!" );
262 		}
263 	}
264     else
265     {
266         switch ( nPropId )
267         {
268 			case BASEPROPERTY_GRAPHIC:
269                 aDefault <<= Reference< graphic::XGraphic >();
270                 break;
271 
272             case BASEPROPERTY_REFERENCE_DEVICE:
273                 aDefault <<= Reference< awt::XDevice >();
274                 break;
275 
276             case BASEPROPERTY_ITEM_SEPARATOR_POS:
277             case BASEPROPERTY_VERTICALALIGN:
278             case BASEPROPERTY_BORDERCOLOR:
279             case BASEPROPERTY_SYMBOL_COLOR:
280             case BASEPROPERTY_TABSTOP:
281             case BASEPROPERTY_TEXTCOLOR:
282             case BASEPROPERTY_TEXTLINECOLOR:
283             case BASEPROPERTY_DATE:
284             case BASEPROPERTY_DATESHOWCENTURY:
285             case BASEPROPERTY_TIME:
286             case BASEPROPERTY_VALUE_DOUBLE:
287             case BASEPROPERTY_PROGRESSVALUE:
288             case BASEPROPERTY_SCROLLVALUE:
289             case BASEPROPERTY_VISIBLESIZE:
290             case BASEPROPERTY_BACKGROUNDCOLOR:
291             case BASEPROPERTY_FILLCOLOR:            break;  // Void
292 
293             case BASEPROPERTY_FONTRELIEF:
294             case BASEPROPERTY_FONTEMPHASISMARK:
295             case BASEPROPERTY_MAXTEXTLEN:
296             case BASEPROPERTY_STATE:
297             case BASEPROPERTY_EXTDATEFORMAT:
298             case BASEPROPERTY_EXTTIMEFORMAT:
299             case BASEPROPERTY_ECHOCHAR:             aDefault <<= (sal_Int16) 0; break;
300             case BASEPROPERTY_BORDER:               aDefault <<= (sal_Int16) 1; break;
301             case BASEPROPERTY_DECIMALACCURACY:      aDefault <<= (sal_Int16) 2; break;
302             case BASEPROPERTY_LINECOUNT:            aDefault <<= (sal_Int16) 5; break;
303             case BASEPROPERTY_ALIGN:                aDefault <<= (sal_Int16) PROPERTY_ALIGN_LEFT; break;
304             case BASEPROPERTY_IMAGEALIGN:           aDefault <<= (sal_Int16) 1 /*ImageAlign::TOP*/; break;
305             case BASEPROPERTY_IMAGEPOSITION:        aDefault <<= (sal_Int16) 12 /*ImagePosition::Centered*/; break;
306             case BASEPROPERTY_PUSHBUTTONTYPE:       aDefault <<= (sal_Int16) 0 /*PushButtonType::STANDARD*/; break;
307             case BASEPROPERTY_MOUSE_WHEEL_BEHAVIOUR:aDefault <<= (sal_Int16) awt::MouseWheelBehavior::SCROLL_FOCUS_ONLY; break;
308 
309             case BASEPROPERTY_DATEMAX:              aDefault <<= (sal_Int32) Date( 31, 12, 2200 ).GetDate();    break;
310             case BASEPROPERTY_DATEMIN:              aDefault <<= (sal_Int32) Date( 1, 1, 1900 ).GetDate();  break;
311             case BASEPROPERTY_TIMEMAX:              aDefault <<= (sal_Int32) Time( 23, 59 ).GetTime();  break;
312             case BASEPROPERTY_TIMEMIN:              aDefault <<= (sal_Int32) 0;     break;
313             case BASEPROPERTY_VALUEMAX_DOUBLE:      aDefault <<= (double) 1000000;  break;
314             case BASEPROPERTY_VALUEMIN_DOUBLE:      aDefault <<= (double) -1000000; break;
315             case BASEPROPERTY_VALUESTEP_DOUBLE:     aDefault <<= (double ) 1;       break;
316             case BASEPROPERTY_PROGRESSVALUE_MAX:    aDefault <<= (sal_Int32) 100;   break;
317             case BASEPROPERTY_PROGRESSVALUE_MIN:    aDefault <<= (sal_Int32)   0;   break;
318             case BASEPROPERTY_SCROLLVALUE_MAX:		aDefault <<= (sal_Int32) 100;	break;
319             case BASEPROPERTY_SCROLLVALUE_MIN:		aDefault <<= (sal_Int32)   0;	break;
320             case BASEPROPERTY_LINEINCREMENT:		aDefault <<= (sal_Int32)   1;	break;
321             case BASEPROPERTY_BLOCKINCREMENT:		aDefault <<= (sal_Int32)  10;	break;
322             case BASEPROPERTY_ORIENTATION:			aDefault <<= (sal_Int32)   0;	break;
323             case BASEPROPERTY_SPINVALUE:            aDefault <<= (sal_Int32)   0;   break;
324             case BASEPROPERTY_SPININCREMENT:        aDefault <<= (sal_Int32)   1;   break;
325             case BASEPROPERTY_SPINVALUE_MIN:        aDefault <<= (sal_Int32)   0;   break;
326             case BASEPROPERTY_SPINVALUE_MAX:        aDefault <<= (sal_Int32) 100;   break;
327             case BASEPROPERTY_REPEAT_DELAY:         aDefault <<= (sal_Int32)  50;   break;    // 50 milliseconds
328             case BASEPROPERTY_DEFAULTCONTROL:       aDefault <<= ((UnoControlModel*)this)->getServiceName();    break;
329 
330             case BASEPROPERTY_AUTOHSCROLL:
331             case BASEPROPERTY_AUTOVSCROLL:
332             case BASEPROPERTY_MOVEABLE:
333             case BASEPROPERTY_CLOSEABLE:
334             case BASEPROPERTY_SIZEABLE:
335             case BASEPROPERTY_HSCROLL:
336             case BASEPROPERTY_DEFAULTBUTTON:
337             case BASEPROPERTY_MULTILINE:
338             case BASEPROPERTY_MULTISELECTION:
339             case BASEPROPERTY_TRISTATE:
340             case BASEPROPERTY_DROPDOWN:
341             case BASEPROPERTY_SPIN:
342             case BASEPROPERTY_READONLY:
343             case BASEPROPERTY_VSCROLL:
344             case BASEPROPERTY_NUMSHOWTHOUSANDSEP:
345             case BASEPROPERTY_STRICTFORMAT:
346             case BASEPROPERTY_REPEAT:
347             case BASEPROPERTY_PAINTTRANSPARENT:
348             case BASEPROPERTY_DESKTOP_AS_PARENT:
349             case BASEPROPERTY_HARDLINEBREAKS:
350             case BASEPROPERTY_NOLABEL:              aDefault <<= (sal_Bool) sal_False; break;
351 
352             case BASEPROPERTY_MULTISELECTION_SIMPLEMODE:
353             case BASEPROPERTY_HIDEINACTIVESELECTION:
354 			case BASEPROPERTY_ENFORCE_FORMAT:
355             case BASEPROPERTY_AUTOCOMPLETE:
356             case BASEPROPERTY_SCALEIMAGE:
357             case BASEPROPERTY_ENABLED:
358             case BASEPROPERTY_PRINTABLE:
359             case BASEPROPERTY_ENABLEVISIBLE:
360             case BASEPROPERTY_DECORATION:           aDefault <<= (sal_Bool) sal_True; break;
361 
362             case BASEPROPERTY_HELPTEXT:
363             case BASEPROPERTY_HELPURL:
364 	        case BASEPROPERTY_IMAGEURL:
365 	        case BASEPROPERTY_DIALOGSOURCEURL:
366             case BASEPROPERTY_EDITMASK:
367             case BASEPROPERTY_LITERALMASK:
368             case BASEPROPERTY_LABEL:
369             case BASEPROPERTY_TITLE:
370             case BASEPROPERTY_TEXT:                 aDefault <<= ::rtl::OUString(); break;
371 
372             case BASEPROPERTY_WRITING_MODE:
373             case BASEPROPERTY_CONTEXT_WRITING_MODE:
374                 aDefault <<= text::WritingMode2::CONTEXT;
375                 break;
376 
377             case BASEPROPERTY_STRINGITEMLIST:
378             {
379                 ::com::sun::star::uno::Sequence< ::rtl::OUString> aStringSeq;
380                 aDefault <<= aStringSeq;
381 
382             }
383             break;
384             case BASEPROPERTY_SELECTEDITEMS:
385             {
386                 ::com::sun::star::uno::Sequence<sal_Int16> aINT16Seq;
387                 aDefault <<= aINT16Seq;
388             }
389             break;
390             case BASEPROPERTY_CURRENCYSYMBOL:
391             {
392 				Any aDefaultCurrency = ::utl::ConfigManager::GetDirectConfigProperty(::utl::ConfigManager::DEFAULTCURRENCY);
393 				DBG_ASSERT( TypeClass_STRING == aDefaultCurrency.getValueTypeClass(), "UnoControlModel::ImplGetDefaultValue: invalid currency config value!" );
394 
395 				::rtl::OUString sDefaultCurrency;
396 				aDefaultCurrency >>= sDefaultCurrency;
397 
398 				// extract the bank symbol
399 				sal_Int32 nSepPos = sDefaultCurrency.indexOf( '-' );
400 				::rtl::OUString sBankSymbol;
401 				if ( nSepPos >= 0 )
402 				{
403 					sBankSymbol = sDefaultCurrency.copy( 0, nSepPos );
404 					sDefaultCurrency = sDefaultCurrency.copy( nSepPos + 1 );
405 				}
406 
407 				// the remaming is the locale
408 				Locale aLocale;
409 				nSepPos = sDefaultCurrency.indexOf( '-' );
410 				if ( nSepPos >= 0 )
411 				{
412 					aLocale.Language = sDefaultCurrency.copy( 0, nSepPos );
413 					aLocale.Country = sDefaultCurrency.copy( nSepPos + 1 );
414 				}
415 
416 				LocaleDataWrapper aLocaleInfo( maContext.getLegacyServiceFactory(), aLocale );
417 				if ( !sBankSymbol.getLength() )
418 					sBankSymbol = aLocaleInfo.getCurrBankSymbol();
419 
420 				// look for the currency entry (for this language) which has the given bank symbol
421 				Sequence< Currency2 > aAllCurrencies = aLocaleInfo.getAllCurrencies();
422 				const Currency2* pAllCurrencies		=						aAllCurrencies.getConstArray();
423 				const Currency2* pAllCurrenciesEnd	=	pAllCurrencies	+	aAllCurrencies.getLength();
424 
425 				::rtl::OUString sCurrencySymbol = aLocaleInfo.getCurrSymbol();
426 				if ( !sBankSymbol.getLength() )
427 				{
428 					DBG_ASSERT( pAllCurrencies != pAllCurrenciesEnd, "UnoControlModel::ImplGetDefaultValue: no currencies at all!" );
429 					if ( pAllCurrencies != pAllCurrenciesEnd )
430 					{
431 						sBankSymbol = pAllCurrencies->BankSymbol;
432 						sCurrencySymbol = pAllCurrencies->Symbol;
433 					}
434 				}
435 
436 				if ( sBankSymbol.getLength() )
437 				{
438                     bool bLegacy = false;
439 					for ( ;pAllCurrencies != pAllCurrenciesEnd; ++pAllCurrencies )
440 						if ( pAllCurrencies->BankSymbol == sBankSymbol )
441 						{
442                             sCurrencySymbol = pAllCurrencies->Symbol;
443                             if ( pAllCurrencies->LegacyOnly )
444                                 bLegacy = true;
445                             else
446                                 break;
447 						}
448 					DBG_ASSERT( bLegacy || pAllCurrencies != pAllCurrenciesEnd, "UnoControlModel::ImplGetDefaultValue: did not find the given bank symbol!" );
449 				}
450 
451 				aDefault <<= sCurrencySymbol;
452             }
453             break;
454 
455             default:    DBG_ERROR( "ImplGetDefaultValue - unknown Property" );
456         }
457     }
458 
459 	return aDefault;
460 }
461 
462 void UnoControlModel::ImplRegisterProperty( sal_uInt16 nPropId, const ::com::sun::star::uno::Any& rDefault )
463 {
464 	ImplControlProperty* pProp = new ImplControlProperty( nPropId, rDefault );
465 	mpData->Insert( nPropId, pProp );
466 }
467 
468 void UnoControlModel::ImplRegisterProperty( sal_uInt16 nPropId )
469 {
470 	ImplRegisterProperty( nPropId, ImplGetDefaultValue( nPropId ) );
471 
472     if ( nPropId == BASEPROPERTY_FONTDESCRIPTOR )
473     {
474         // some properties are not included in the FontDescriptor, but everytime
475         // when we have a FontDescriptor we want to have these properties too.
476         // => Easier to register the here, istead everywhere where I register the FontDescriptor...
477 
478         ImplRegisterProperty( BASEPROPERTY_TEXTCOLOR );
479         ImplRegisterProperty( BASEPROPERTY_TEXTLINECOLOR );
480         ImplRegisterProperty( BASEPROPERTY_FONTRELIEF );
481         ImplRegisterProperty( BASEPROPERTY_FONTEMPHASISMARK );
482     }
483 }
484 
485 void UnoControlModel::ImplRegisterProperties( const std::list< sal_uInt16 > &rIds )
486 {
487     std::list< sal_uInt16 >::const_iterator iter;
488     for( iter = rIds.begin(); iter != rIds.end(); iter++) {
489         if( !ImplHasProperty( *iter ) )
490             ImplRegisterProperty( *iter, ImplGetDefaultValue( *iter ) );
491     }
492 }
493 
494 // ::com::sun::star::uno::XInterface
495 ::com::sun::star::uno::Any UnoControlModel::queryAggregation( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException)
496 {
497     Any aRet = UnoControlModel_Base::queryAggregation( rType );
498     if ( !aRet.hasValue() )
499         aRet = ::cppu::OPropertySetHelper::queryInterface( rType );
500     return aRet;
501 }
502 
503 // ::com::sun::star::lang::XUnoTunnel
504 IMPL_XUNOTUNNEL( UnoControlModel )
505 
506 // XInterface
507 IMPLEMENT_FORWARD_REFCOUNT( UnoControlModel, UnoControlModel_Base )
508 
509 // ::com::sun::star::lang::XTypeProvider
510 IMPLEMENT_FORWARD_XTYPEPROVIDER2( UnoControlModel, UnoControlModel_Base, ::cppu::OPropertySetHelper )
511 
512 
513 uno::Reference< util::XCloneable > UnoControlModel::createClone() throw(::com::sun::star::uno::RuntimeException)
514 {
515 	UnoControlModel* pClone = Clone();
516 	uno::Reference< util::XCloneable > xClone( (::cppu::OWeakObject*) pClone, uno::UNO_QUERY );
517 	return xClone;
518 }
519 
520 // ::com::sun::star::lang::XComponent
521 void UnoControlModel::dispose(  ) throw(::com::sun::star::uno::RuntimeException)
522 {
523 	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
524 
525 	::com::sun::star::lang::EventObject aEvt;
526 	aEvt.Source = (::com::sun::star::uno::XAggregation*)(::cppu::OWeakAggObject*)this;
527 	maDisposeListeners.disposeAndClear( aEvt );
528 
529 	BrdcstHelper.aLC.disposeAndClear( aEvt );
530 
531 	// let the property set helper notify our property listeners
532 	OPropertySetHelper::disposing();
533 }
534 
535 void UnoControlModel::addEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& rxListener ) throw(::com::sun::star::uno::RuntimeException)
536 {
537 	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
538 
539 	maDisposeListeners.addInterface( rxListener );
540 }
541 
542 void UnoControlModel::removeEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& rxListener ) throw(::com::sun::star::uno::RuntimeException)
543 {
544 	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
545 
546 	maDisposeListeners.removeInterface( rxListener );
547 }
548 
549 
550 // ::com::sun::star::beans::XPropertyState
551 ::com::sun::star::beans::PropertyState UnoControlModel::getPropertyState( const ::rtl::OUString& PropertyName ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException)
552 {
553 	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
554 
555 	sal_uInt16 nPropId = GetPropertyId( PropertyName );
556 
557 	::com::sun::star::uno::Any aValue = getPropertyValue( PropertyName );
558 	::com::sun::star::uno::Any aDefault = ImplGetDefaultValue( nPropId );
559 
560 	return CompareProperties( aValue, aDefault ) ? ::com::sun::star::beans::PropertyState_DEFAULT_VALUE : ::com::sun::star::beans::PropertyState_DIRECT_VALUE;
561 }
562 
563 ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyState > UnoControlModel::getPropertyStates( const ::com::sun::star::uno::Sequence< ::rtl::OUString >& PropertyNames ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException)
564 {
565 	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
566 
567 	sal_uInt32 nNames = PropertyNames.getLength();
568 	const ::rtl::OUString* pNames = PropertyNames.getConstArray();
569 
570 	::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyState > aStates( nNames );
571 	::com::sun::star::beans::PropertyState* pStates = aStates.getArray();
572 
573 	for ( sal_uInt32 n = 0; n < nNames; n++ )
574 		pStates[n] = getPropertyState( pNames[n] );
575 
576 	return aStates;
577 }
578 
579 void UnoControlModel::setPropertyToDefault( const ::rtl::OUString& PropertyName ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException)
580 {
581     Any aDefaultValue;
582     {
583 	    ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
584         aDefaultValue = ImplGetDefaultValue( GetPropertyId( PropertyName ) );
585     }
586 	setPropertyValue( PropertyName, aDefaultValue );
587 }
588 
589 ::com::sun::star::uno::Any UnoControlModel::getPropertyDefault( const ::rtl::OUString& rPropertyName ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException)
590 {
591 	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
592 
593 	return ImplGetDefaultValue( GetPropertyId( rPropertyName ) );
594 }
595 
596 
597 // ::com::sun::star::io::XPersistObjec
598 ::rtl::OUString UnoControlModel::getServiceName(  ) throw(::com::sun::star::uno::RuntimeException)
599 {
600 	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
601 
602 	DBG_ERROR( "ServiceName von UnoControlModel ?!" );
603 	return ::rtl::OUString();
604 }
605 
606 void UnoControlModel::write( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectOutputStream >& OutStream ) throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException)
607 {
608 	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
609 
610 	::com::sun::star::uno::Reference< ::com::sun::star::io::XMarkableStream > xMark( OutStream, ::com::sun::star::uno::UNO_QUERY );
611 	DBG_ASSERT( xMark.is(), "write: no ::com::sun::star::io::XMarkableStream!" );
612 
613 	OutStream->writeShort( UNOCONTROL_STREAMVERSION );
614 
615 	ImplPropertyTable aProps;
616 	sal_uInt32 i;
617 	for ( i = mpData->Count(); i; )
618 	{
619 		ImplControlProperty* pProp = mpData->GetObject( --i );
620 		if ( ( ( GetPropertyAttribs( pProp->GetId() ) & ::com::sun::star::beans::PropertyAttribute::TRANSIENT ) == 0 )
621 			&& ( getPropertyState( GetPropertyName( pProp->GetId() ) ) != ::com::sun::star::beans::PropertyState_DEFAULT_VALUE ) )
622 		{
623 			aProps.Insert( pProp->GetId(), pProp );
624 		}
625 	}
626 
627 	sal_uInt32 nProps = aProps.Count();
628 
629 	// FontProperty wegen fehlender Unterscheidung zwischen 5.0 / 5.1
630 	// immer im alten Format mitspeichern.
631 	OutStream->writeLong( (long) aProps.IsKeyValid( BASEPROPERTY_FONTDESCRIPTOR ) ? ( nProps + 3 ) : nProps );
632 	for ( i = 0; i < nProps; i++ )
633 	{
634 		sal_Int32 nPropDataBeginMark = xMark->createMark();
635 		OutStream->writeLong( 0L );	// DataLen
636 
637 		ImplControlProperty* pProp = aProps.GetObject( i );
638 		OutStream->writeShort( pProp->GetId() );
639 
640 		sal_Bool bVoid = pProp->GetValue().getValueType().getTypeClass() == ::com::sun::star::uno::TypeClass_VOID;
641 
642 		OutStream->writeBoolean( bVoid );
643 
644 		if ( !bVoid )
645 		{
646 			const ::com::sun::star::uno::Any& rValue = pProp->GetValue();
647 			const ::com::sun::star::uno::Type& rType = rValue.getValueType();
648 
649 			if ( rType == ::getBooleanCppuType() )
650 			{
651 				sal_Bool b = false;
652 				rValue >>= b;
653 				OutStream->writeBoolean( b );
654 			}
655 			else if ( rType == ::getCppuType((const ::rtl::OUString*)0) )
656 			{
657 				::rtl::OUString aUString;
658 				rValue >>= aUString;
659 				OutStream->writeUTF( aUString );
660 			}
661 			else if ( rType == ::getCppuType((const sal_uInt16*)0) )
662 			{
663 				sal_uInt16 n = 0;
664 				rValue >>= n;
665 				OutStream->writeShort( n );
666 			}
667 			else if ( rType == ::getCppuType((const sal_Int16*)0) )
668 			{
669 				sal_Int16 n = 0;
670 				rValue >>= n;
671 				OutStream->writeShort( n );
672 			}
673 			else if ( rType == ::getCppuType((const sal_uInt32*)0) )
674 			{
675 				sal_uInt32 n = 0;
676 				rValue >>= n;
677 				OutStream->writeLong( n );
678 			}
679 			else if ( rType == ::getCppuType((const sal_Int32*)0) )
680 			{
681 				sal_Int32 n = 0;
682 				rValue >>= n;
683 				OutStream->writeLong( n );
684 			}
685 			else if ( rType == ::getCppuType((const double*)0) )
686 			{
687 				double n = 0;
688 				rValue >>= n;
689 				OutStream->writeDouble( n );
690 			}
691 			else if ( rType == ::getCppuType((const ::com::sun::star::awt::FontDescriptor*)0) )
692 			{
693 				::com::sun::star::awt::FontDescriptor aFD;
694 				rValue >>= aFD;
695 				OutStream->writeUTF( aFD.Name );
696 				OutStream->writeShort( aFD.Height );
697 				OutStream->writeShort( aFD.Width );
698 				OutStream->writeUTF( aFD.StyleName );
699 				OutStream->writeShort( aFD.Family );
700 				OutStream->writeShort( aFD.CharSet );
701 				OutStream->writeShort( aFD.Pitch );
702 				OutStream->writeDouble( aFD.CharacterWidth );
703 				OutStream->writeDouble( aFD.Weight );
704 				OutStream->writeShort(
705                     sal::static_int_cast< sal_Int16 >(aFD.Slant) );
706 				OutStream->writeShort( aFD.Underline );
707 				OutStream->writeShort( aFD.Strikeout );
708 				OutStream->writeDouble( aFD.Orientation );
709 				OutStream->writeBoolean( aFD.Kerning );
710 				OutStream->writeBoolean( aFD.WordLineMode );
711 				OutStream->writeShort( aFD.Type );
712 			}
713 			else if ( rType == ::getCppuType((const ::com::sun::star::uno::Sequence< ::rtl::OUString>*)0 ) )
714 			{
715 				::com::sun::star::uno::Sequence< ::rtl::OUString> aSeq;
716 				rValue >>= aSeq;
717 				long nEntries = aSeq.getLength();
718 				OutStream->writeLong( nEntries );
719 				for ( long n = 0; n < nEntries; n++ )
720 					OutStream->writeUTF( aSeq.getConstArray()[n] );
721 			}
722 			else if ( rType == ::getCppuType((const ::com::sun::star::uno::Sequence<sal_uInt16>*)0 ) )
723 			{
724 				::com::sun::star::uno::Sequence<sal_uInt16> aSeq;
725 				rValue >>= aSeq;
726 				long nEntries = aSeq.getLength();
727 				OutStream->writeLong( nEntries );
728 				for ( long n = 0; n < nEntries; n++ )
729 					OutStream->writeShort( aSeq.getConstArray()[n] );
730 			}
731 			else if ( rType == ::getCppuType((const ::com::sun::star::uno::Sequence<sal_Int16>*)0 ) )
732 			{
733 				::com::sun::star::uno::Sequence<sal_Int16> aSeq;
734 				rValue >>= aSeq;
735 				long nEntries = aSeq.getLength();
736 				OutStream->writeLong( nEntries );
737 				for ( long n = 0; n < nEntries; n++ )
738 					OutStream->writeShort( aSeq.getConstArray()[n] );
739 			}
740 			else if ( rType.getTypeClass() == TypeClass_ENUM )
741             {
742                 sal_Int32 nAsInt = 0;
743                 ::cppu::enum2int( nAsInt, rValue );
744 				OutStream->writeLong( nAsInt );
745             }
746 #if OSL_DEBUG_LEVEL > 0
747             else
748 			{
749                 ::rtl::OString sMessage( "UnoControlModel::write: don't know how to handle a property of type '" );
750                 ::rtl::OUString sTypeName( rType.getTypeName() );
751                 sMessage += ::rtl::OString( sTypeName.getStr(), sTypeName.getLength(), RTL_TEXTENCODING_ASCII_US );
752                 sMessage += "'.\n(Currently handling property '";
753                 ::rtl::OUString sPropertyName( GetPropertyName( pProp->GetId() ) );
754                 sMessage += ::rtl::OString( sPropertyName.getStr(), sPropertyName.getLength(), osl_getThreadTextEncoding() );
755                 sMessage += "'.)";
756 				DBG_ERROR( sMessage );
757 			}
758 #endif
759 		}
760 
761 		sal_Int32 nPropDataLen = xMark->offsetToMark( nPropDataBeginMark );
762 		xMark->jumpToMark( nPropDataBeginMark );
763 		OutStream->writeLong( nPropDataLen );
764 		xMark->jumpToFurthest();
765 		xMark->deleteMark(nPropDataBeginMark);
766 	}
767 
768 	ImplControlProperty* pProp = aProps.Get( BASEPROPERTY_FONTDESCRIPTOR );
769 	if ( pProp )
770 	{
771 		// Solange wir keinen 5.0-Export haben, muss das alte
772 		// Format mit rausgeschrieben werden...
773 		::com::sun::star::awt::FontDescriptor aFD;
774 		pProp->GetValue() >>= aFD;
775 
776 		for ( sal_uInt16 n = BASEPROPERTY_FONT_TYPE; n <= BASEPROPERTY_FONT_ATTRIBS; n++ )
777 		{
778 			sal_Int32 nPropDataBeginMark = xMark->createMark();
779 			OutStream->writeLong( 0L );	// DataLen
780 			OutStream->writeShort( n );	// PropId
781 			OutStream->writeBoolean( sal_False );	// Void
782 
783 			if ( n == BASEPROPERTY_FONT_TYPE )
784 			{
785 				OutStream->writeUTF( aFD.Name );
786 				OutStream->writeUTF( aFD.StyleName );
787 				OutStream->writeShort( aFD.Family );
788 				OutStream->writeShort( aFD.CharSet );
789 				OutStream->writeShort( aFD.Pitch );
790 			}
791 			else if ( n == BASEPROPERTY_FONT_SIZE )
792 			{
793 				OutStream->writeLong( aFD.Width );
794 				OutStream->writeLong( aFD.Height );
795 				OutStream->writeShort(
796                     sal::static_int_cast< sal_Int16 >(
797                         VCLUnoHelper::ConvertFontWidth( aFD.CharacterWidth )) );
798 			}
799 			else if ( n == BASEPROPERTY_FONT_ATTRIBS )
800 			{
801 				OutStream->writeShort(
802                     sal::static_int_cast< sal_Int16 >(
803                         VCLUnoHelper::ConvertFontWeight( aFD.Weight )) );
804 				OutStream->writeShort(
805                     sal::static_int_cast< sal_Int16 >(aFD.Slant) );
806 				OutStream->writeShort( aFD.Underline );
807 				OutStream->writeShort( aFD.Strikeout );
808 				OutStream->writeShort( (short)(aFD.Orientation * 10) );
809 				OutStream->writeBoolean( aFD.Kerning );
810 				OutStream->writeBoolean( aFD.WordLineMode );
811 			}
812 			else
813 			{
814 				DBG_ERROR( "Property?!" );
815 			}
816 
817 			sal_Int32 nPropDataLen = xMark->offsetToMark( nPropDataBeginMark );
818 			xMark->jumpToMark( nPropDataBeginMark );
819 			OutStream->writeLong( nPropDataLen );
820 			xMark->jumpToFurthest();
821 			xMark->deleteMark(nPropDataBeginMark);
822 		}
823 	}
824 }
825 
826 void UnoControlModel::read( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectInputStream >& InStream ) throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException)
827 {
828 	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
829 
830 	::com::sun::star::uno::Reference< ::com::sun::star::io::XMarkableStream > xMark( InStream, ::com::sun::star::uno::UNO_QUERY );
831 	DBG_ASSERT( xMark.is(), "read: no ::com::sun::star::io::XMarkableStream!" );
832 
833 	short nVersion = InStream->readShort();
834 	sal_uInt32 nProps = (sal_uInt32)InStream->readLong();
835 	::com::sun::star::uno::Sequence< ::rtl::OUString> aProps( nProps );
836 	::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any> aValues( nProps );
837 	sal_Bool bInvalidEntries = sal_False;
838 
839 	// Dummerweise kein Mark fuer den gesamten Block, es koennen also
840 	// nur Properties geaendert werden, es koennen aber nicht spaeter mal Daten
841 	// fuer das Model hinter den Properties geschrieben werden.
842 
843 	// Fuer den Import der alten ::com::sun::star::awt::FontDescriptor-Teile
844 	::com::sun::star::awt::FontDescriptor* pFD = NULL;
845 
846 	sal_uInt32 i;
847 	for ( i = 0; i < nProps; i++ )
848 	{
849 		sal_Int32 nPropDataBeginMark = xMark->createMark();
850 		sal_Int32 nPropDataLen = InStream->readLong();
851 
852 		sal_uInt16 nPropId = (sal_uInt16)InStream->readShort();
853 
854 		::com::sun::star::uno::Any aValue;
855 		sal_Bool bIsVoid = InStream->readBoolean();
856 		if ( !bIsVoid )
857 		{
858 			const ::com::sun::star::uno::Type* pType = mpData->Get( nPropId ) ? GetPropertyType( nPropId ) : NULL;
859 			if ( pType )
860 			{
861 				if ( *pType == ::getBooleanCppuType() )
862 				{
863 					sal_Bool b = InStream->readBoolean();
864 					aValue <<= b;
865 				}
866 				else if ( *pType == ::getCppuType((const ::rtl::OUString*)0) )
867 				{
868 					::rtl::OUString aUTF = InStream->readUTF();
869 					aValue <<= aUTF;
870 				}
871 				else if ( *pType == ::getCppuType((const sal_uInt16*)0) )
872 				{
873 					sal_uInt16 n = InStream->readShort();
874 					aValue <<= n;
875 				}
876 				else if ( *pType == ::getCppuType((const sal_Int16*)0) )
877 				{
878 					sal_Int16 n = InStream->readShort();
879 					aValue <<= n;
880 				}
881 				else if ( *pType == ::getCppuType((const sal_uInt32*)0) )
882 				{
883 					sal_uInt32 n = InStream->readLong();
884 					aValue <<= n;
885 				}
886 				else if ( *pType == ::getCppuType((const sal_Int32*)0) )
887 				{
888 					sal_Int32 n = InStream->readLong();
889 					aValue <<= n;
890 				}
891 				else if ( *pType == ::getCppuType((const double*)0) )
892 				{
893 					double n = InStream->readDouble();
894 					aValue <<= n;
895 				}
896 				else if ( *pType == ::getCppuType((const ::com::sun::star::awt::FontDescriptor*)0) )
897 				{
898 					::com::sun::star::awt::FontDescriptor aFD;
899 					aFD.Name = InStream->readUTF();
900 					aFD.Height = InStream->readShort();
901 					aFD.Width = InStream->readShort();
902 					aFD.StyleName = InStream->readUTF();
903 					aFD.Family = InStream->readShort();
904 					aFD.CharSet = InStream->readShort();
905 					aFD.Pitch = InStream->readShort();
906 					aFD.CharacterWidth = (float)InStream->readDouble();
907 					aFD.Weight = (float)InStream->readDouble();
908 					aFD.Slant =  (::com::sun::star::awt::FontSlant)InStream->readShort();
909 					aFD.Underline = InStream->readShort();
910 					aFD.Strikeout = InStream->readShort();
911 					aFD.Orientation = (float)InStream->readDouble();
912 					aFD.Kerning = InStream->readBoolean();
913 					aFD.WordLineMode = InStream->readBoolean();
914 					aFD.Type = InStream->readShort();
915 					aValue <<= aFD;
916 				}
917 				else if ( *pType == ::getCppuType((const ::com::sun::star::uno::Sequence< ::rtl::OUString>*)0 ) )
918 				{
919 					long nEntries = InStream->readLong();
920 					::com::sun::star::uno::Sequence< ::rtl::OUString> aSeq( nEntries );
921 					for ( long n = 0; n < nEntries; n++ )
922 						aSeq.getArray()[n] = InStream->readUTF();
923 					aValue <<= aSeq;
924 
925 				}
926 				else if ( *pType == ::getCppuType((const ::com::sun::star::uno::Sequence<sal_uInt16>*)0 ) )
927 
928 				{
929 					long nEntries = InStream->readLong();
930 					::com::sun::star::uno::Sequence<sal_uInt16> aSeq( nEntries );
931 					for ( long n = 0; n < nEntries; n++ )
932 						aSeq.getArray()[n] = (sal_uInt16)InStream->readShort();
933 					aValue <<= aSeq;
934 				}
935 				else if ( *pType == ::getCppuType((const ::com::sun::star::uno::Sequence<sal_Int16>*)0 ) )
936 				{
937 					long nEntries = InStream->readLong();
938 					::com::sun::star::uno::Sequence<sal_Int16> aSeq( nEntries );
939 					for ( long n = 0; n < nEntries; n++ )
940 						aSeq.getArray()[n] = (sal_Int16)InStream->readShort();
941 					aValue <<= aSeq;
942 				}
943                 else if ( pType->getTypeClass() == TypeClass_ENUM )
944                 {
945                     sal_Int32 nAsInt = InStream->readLong();
946                     aValue = ::cppu::int2enum( nAsInt, *pType );
947                 }
948                 else
949                 {
950                     ::rtl::OString sMessage( "UnoControlModel::read: don't know how to handle a property of type '" );
951                     ::rtl::OUString sTypeName( pType->getTypeName() );
952                     sMessage += ::rtl::OString( sTypeName.getStr(), sTypeName.getLength(), RTL_TEXTENCODING_ASCII_US );
953                     sMessage += "'.\n(Currently handling property '";
954                     ::rtl::OUString sPropertyName( GetPropertyName( nPropId ) );
955                     sMessage += ::rtl::OString( sPropertyName.getStr(), sPropertyName.getLength(), osl_getThreadTextEncoding() );
956                     sMessage += "'.)";
957 				    DBG_ERROR( sMessage );
958                 }
959 			}
960 			else
961 			{
962 				// Altes Geraffel aus 5.0
963 				if ( nPropId == BASEPROPERTY_FONT_TYPE )
964 				{
965 					// Sonst ist es nur die redundante Info fuer alte Versionen
966 					// Daten werden durch MarkableStream geskippt.
967 					if ( nVersion < 2 )
968 					{
969 						if ( !pFD )
970 						{
971 							pFD = new ::com::sun::star::awt::FontDescriptor;
972 							ImplControlProperty* pProp = mpData->Get( BASEPROPERTY_FONTDESCRIPTOR );
973 							if ( pProp ) // wegen den Defaults...
974 								pProp->GetValue() >>= *pFD;
975 						}
976 						pFD->Name = InStream->readUTF();
977 						pFD->StyleName = InStream->readUTF();
978 						pFD->Family = InStream->readShort();
979 						pFD->CharSet = InStream->readShort();
980 						pFD->Pitch = InStream->readShort();
981 					}
982 				}
983 				else if ( nPropId == BASEPROPERTY_FONT_SIZE )
984 				{
985 					if ( nVersion < 2 )
986 					{
987 						if ( !pFD )
988 						{
989 							pFD = new ::com::sun::star::awt::FontDescriptor;
990 							ImplControlProperty* pProp = mpData->Get( BASEPROPERTY_FONTDESCRIPTOR );
991 							if ( pProp ) // wegen den Defaults...
992 								pProp->GetValue() >>= *pFD;
993 						}
994 						pFD->Width = (sal_Int16)InStream->readLong();
995 						pFD->Height = (sal_Int16)InStream->readLong();
996 						InStream->readShort();	// ::com::sun::star::awt::FontWidth ignorieren - wurde mal falsch geschrieben und wird nicht gebraucht.
997 						pFD->CharacterWidth = ::com::sun::star::awt::FontWidth::DONTKNOW;
998 					}
999 				}
1000 				else if ( nPropId == BASEPROPERTY_FONT_ATTRIBS )
1001 				{
1002 					if ( nVersion < 2 )
1003 					{
1004  						if ( !pFD )
1005 						{
1006 							pFD = new ::com::sun::star::awt::FontDescriptor;
1007 							ImplControlProperty* pProp = mpData->Get( BASEPROPERTY_FONTDESCRIPTOR );
1008 							if ( pProp ) // wegen den Defaults...
1009 								pProp->GetValue() >>= *pFD;
1010 						}
1011 						pFD->Weight = VCLUnoHelper::ConvertFontWeight( (FontWeight) InStream->readShort() );
1012 						pFD->Slant =  (::com::sun::star::awt::FontSlant)InStream->readShort();
1013 						pFD->Underline = InStream->readShort();
1014 						pFD->Strikeout = InStream->readShort();
1015 						pFD->Orientation = ( (float)(double)InStream->readShort() ) / 10;
1016 						pFD->Kerning = InStream->readBoolean();
1017 						pFD->WordLineMode = InStream->readBoolean();
1018 					}
1019 				}
1020 				else
1021 				{
1022 					DBG_ERROR( "read: unknown Property!" );
1023 				}
1024 			}
1025 		}
1026 		else // bVoid
1027 		{
1028 			if ( nPropId == BASEPROPERTY_FONTDESCRIPTOR )
1029 			{
1030 				EmptyFontDescriptor aFD;
1031 				aValue <<= aFD;
1032 			}
1033 		}
1034 
1035 		if ( mpData->Get( nPropId ) )
1036 		{
1037 			aProps.getArray()[i] = GetPropertyName( nPropId );
1038 			aValues.getArray()[i] = aValue;
1039 		}
1040 		else
1041 		{
1042 			bInvalidEntries = sal_True;
1043 		}
1044 
1045 		// Falls bereits mehr drinsteht als diese Version kennt:
1046 		xMark->jumpToMark( nPropDataBeginMark );
1047 		InStream->skipBytes( nPropDataLen );
1048 		xMark->deleteMark(nPropDataBeginMark);
1049 	}
1050 	if ( bInvalidEntries )
1051 	{
1052 		for ( i = 0; i < (sal_uInt32)aProps.getLength(); i++ )
1053 		{
1054 			if ( !aProps.getConstArray()[i].getLength() )
1055 			{
1056 				::comphelper::removeElementAt( aProps, i );
1057 				::comphelper::removeElementAt( aValues, i );
1058 				i--;
1059 			}
1060 		}
1061 	}
1062 
1063     try
1064     {
1065         setPropertyValues( aProps, aValues );
1066     }
1067     catch ( const Exception& )
1068     {
1069         DBG_UNHANDLED_EXCEPTION();
1070     }
1071 
1072 	if ( pFD )
1073 	{
1074 		::com::sun::star::uno::Any aValue;
1075 		aValue <<= *pFD;
1076 		setPropertyValue( GetPropertyName( BASEPROPERTY_FONTDESCRIPTOR ), aValue );
1077 		delete pFD;
1078 	}
1079 }
1080 
1081 
1082 // ::com::sun::star::lang::XServiceInfo
1083 ::rtl::OUString UnoControlModel::getImplementationName(  ) throw(::com::sun::star::uno::RuntimeException)
1084 {
1085 	DBG_ERROR( "This method should be overloaded!" );
1086 	return ::rtl::OUString();
1087 
1088 }
1089 
1090 sal_Bool UnoControlModel::supportsService( const ::rtl::OUString& rServiceName ) throw(::com::sun::star::uno::RuntimeException)
1091 {
1092 	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
1093 
1094 	::com::sun::star::uno::Sequence< ::rtl::OUString > aSNL = getSupportedServiceNames();
1095 	const ::rtl::OUString * pArray = aSNL.getConstArray();
1096 	for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
1097 		if( pArray[i] == rServiceName )
1098 			return sal_True;
1099 	return sal_False;
1100 }
1101 
1102 ::com::sun::star::uno::Sequence< ::rtl::OUString > UnoControlModel::getSupportedServiceNames(  ) throw(::com::sun::star::uno::RuntimeException)
1103 {
1104 	::rtl::OUString sName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.awt.UnoControlModel" ) );
1105 	return Sequence< ::rtl::OUString >( &sName, 1 );
1106 }
1107 
1108 // ::cppu::OPropertySetHelper
1109 ::cppu::IPropertyArrayHelper& UnoControlModel::getInfoHelper()
1110 {
1111 	DBG_ERROR( "UnoControlModel::getInfoHelper() not possible!" );
1112 	return *(::cppu::IPropertyArrayHelper*) NULL;
1113 }
1114 
1115 // ------------------------------------------------------------------
1116 template <class TYPE>
1117 sal_Bool convertType(Any& _rConvertedValue, const Any& _rNewValueTest, const TYPE* /* _pTypeDisambiguation */)
1118 {
1119 	TYPE tValue;
1120 	if (_rNewValueTest >>= tValue)
1121 	{
1122 		_rConvertedValue <<= tValue;
1123 		return sal_True;
1124 	}
1125 }
1126 
1127 // ..................................................................
1128 sal_Bool UnoControlModel::convertFastPropertyValue( Any & rConvertedValue, Any & rOldValue, sal_Int32 nPropId, const Any& rValue ) throw (IllegalArgumentException)
1129 {
1130 	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
1131 
1132 	sal_Bool bVoid = rValue.getValueType().getTypeClass() == ::com::sun::star::uno::TypeClass_VOID;
1133 	if ( bVoid )
1134 	{
1135 		rConvertedValue.clear();
1136 	}
1137 	else
1138 	{
1139 		const ::com::sun::star::uno::Type* pDestType = GetPropertyType( (sal_uInt16)nPropId );
1140 		if ( pDestType->getTypeClass() == TypeClass_ANY )
1141 		{
1142 			rConvertedValue = rValue;
1143 		}
1144 		else
1145 		{
1146 			if ( pDestType->equals( rValue.getValueType() ) )
1147             {
1148                 rConvertedValue = rValue;
1149             }
1150 			else
1151 			{
1152 				sal_Bool bConverted = sal_False;
1153 				// 13.03.2001 - 84923 - frank.schoenheit@germany.sun.com
1154 
1155 				switch (pDestType->getTypeClass())
1156 				{
1157 					case TypeClass_DOUBLE:
1158 					{
1159 						// try as double
1160 						double nAsDouble = 0;
1161                         bConverted = ( rValue >>= nAsDouble );
1162 						if ( bConverted )
1163 							rConvertedValue <<= nAsDouble;
1164 						else
1165 						{	// try as integer - 96136 - 2002-10-08 - fs@openoffice.org
1166 							sal_Int32 nAsInteger = 0;
1167                             bConverted = ( rValue >>= nAsInteger );
1168 							if ( bConverted )
1169 								rConvertedValue <<= (double)nAsInteger;
1170 						}
1171 					}
1172 					break;
1173 					case TypeClass_SHORT:
1174                     {
1175                         sal_Int16 n;
1176                         bConverted = ( rValue >>= n );
1177                         if ( bConverted )
1178                             rConvertedValue <<= n;
1179                     }
1180 					break;
1181 					case TypeClass_UNSIGNED_SHORT:
1182                     {
1183                         sal_uInt16 n;
1184                         bConverted = ( rValue >>= n );
1185                         if ( bConverted )
1186                             rConvertedValue <<= n;
1187                     }
1188 					break;
1189 					case TypeClass_LONG:
1190                     {
1191                         sal_Int32 n;
1192                         bConverted = ( rValue >>= n );
1193                         if ( bConverted )
1194                             rConvertedValue <<= n;
1195                     }
1196 					break;
1197 					case TypeClass_UNSIGNED_LONG:
1198                     {
1199                         sal_uInt32 n;
1200                         bConverted = ( rValue >>= n );
1201                         if ( bConverted )
1202                             rConvertedValue <<= n;
1203                     }
1204 					break;
1205 					case TypeClass_INTERFACE:
1206 					{
1207 						if ( rValue.getValueType().getTypeClass() == TypeClass_INTERFACE )
1208 						{
1209 							Reference< XInterface > xPure( rValue, UNO_QUERY );
1210 							if ( xPure.is() )
1211 								rConvertedValue = xPure->queryInterface( *pDestType );
1212                             else
1213                                 rConvertedValue.setValue( NULL, *pDestType );
1214 							bConverted = sal_True;
1215 						}
1216 					}
1217 					break;
1218 					case TypeClass_ENUM:
1219 					{
1220                         sal_Int32 nValue = 0;
1221                         bConverted = ( rValue >>= nValue );
1222                         if ( bConverted )
1223                             rConvertedValue = ::cppu::int2enum( nValue, *pDestType );
1224 					}
1225 					break;
1226 					default: ; // avoid compiler warning
1227 				}
1228 
1229 				if (!bConverted)
1230                 {
1231                     ::rtl::OUStringBuffer aErrorMessage;
1232                     aErrorMessage.appendAscii( "Unable to convert the given value for the property " );
1233                     aErrorMessage.append     ( GetPropertyName( (sal_uInt16)nPropId ) );
1234                     aErrorMessage.appendAscii( ".\n" );
1235                     aErrorMessage.appendAscii( "Expected type: " );
1236                     aErrorMessage.append     ( pDestType->getTypeName() );
1237                     aErrorMessage.appendAscii( "\n" );
1238                     aErrorMessage.appendAscii( "Found type: " );
1239                     aErrorMessage.append     ( rValue.getValueType().getTypeName() );
1240 					throw ::com::sun::star::lang::IllegalArgumentException(
1241                         aErrorMessage.makeStringAndClear(),
1242 						static_cast< ::com::sun::star::beans::XPropertySet* >(this),
1243 						1);
1244                 }
1245 			}
1246 		}
1247 	}
1248 
1249 	// the current value
1250 	getFastPropertyValue( rOldValue, nPropId );
1251 	return !CompareProperties( rConvertedValue, rOldValue );
1252 }
1253 
1254 void UnoControlModel::setFastPropertyValue_NoBroadcast( sal_Int32 nPropId, const ::com::sun::star::uno::Any& rValue ) throw (::com::sun::star::uno::Exception)
1255 {
1256 	// Fehlt: Die gefakten Einzelproperties des FontDescriptors...
1257 
1258 	ImplControlProperty* pProp = mpData->Get( nPropId );
1259     ENSURE_OR_RETURN_VOID( pProp, "UnoControlModel::setFastPropertyValue_NoBroadcast: invalid property id!" );
1260 
1261     DBG_ASSERT( ( rValue.getValueType().getTypeClass() != ::com::sun::star::uno::TypeClass_VOID ) || ( GetPropertyAttribs( (sal_uInt16)nPropId ) & ::com::sun::star::beans::PropertyAttribute::MAYBEVOID ), "Property darf nicht VOID sein!" );
1262 	pProp->SetValue( rValue );
1263 }
1264 
1265 void UnoControlModel::getFastPropertyValue( ::com::sun::star::uno::Any& rValue, sal_Int32 nPropId ) const
1266 {
1267 	::osl::Guard< ::osl::Mutex > aGuard( ((UnoControlModel*)this)->GetMutex() );
1268 
1269 	ImplControlProperty* pProp = mpData->Get( nPropId );
1270 
1271 	if ( pProp )
1272 		rValue = pProp->GetValue();
1273 	else if ( ( nPropId >= BASEPROPERTY_FONTDESCRIPTORPART_START ) && ( nPropId <= BASEPROPERTY_FONTDESCRIPTORPART_END ) )
1274 	{
1275 		pProp = mpData->Get( BASEPROPERTY_FONTDESCRIPTOR );
1276 		::com::sun::star::awt::FontDescriptor aFD;
1277 		pProp->GetValue() >>= aFD;
1278 		switch ( nPropId )
1279 		{
1280 			case BASEPROPERTY_FONTDESCRIPTORPART_NAME: 			rValue <<= aFD.Name;
1281 																break;
1282 			case BASEPROPERTY_FONTDESCRIPTORPART_STYLENAME:		rValue <<= aFD.StyleName;
1283 																break;
1284 			case BASEPROPERTY_FONTDESCRIPTORPART_FAMILY: 		rValue <<= aFD.Family;
1285 																break;
1286 			case BASEPROPERTY_FONTDESCRIPTORPART_CHARSET: 		rValue <<= aFD.CharSet;
1287 																break;
1288 			case BASEPROPERTY_FONTDESCRIPTORPART_HEIGHT: 		rValue <<= (float)aFD.Height;
1289 																break;
1290 			case BASEPROPERTY_FONTDESCRIPTORPART_WEIGHT: 		rValue <<= aFD.Weight;
1291 																break;
1292 			case BASEPROPERTY_FONTDESCRIPTORPART_SLANT: 		rValue <<= (sal_Int16)aFD.Slant;
1293 																break;
1294 			case BASEPROPERTY_FONTDESCRIPTORPART_UNDERLINE:		rValue <<= aFD.Underline;
1295 																break;
1296 			case BASEPROPERTY_FONTDESCRIPTORPART_STRIKEOUT:		rValue <<= aFD.Strikeout;
1297 																break;
1298 			case BASEPROPERTY_FONTDESCRIPTORPART_WIDTH:			rValue <<= aFD.Width;
1299 																break;
1300 			case BASEPROPERTY_FONTDESCRIPTORPART_PITCH:			rValue <<= aFD.Pitch;
1301 																break;
1302 			case BASEPROPERTY_FONTDESCRIPTORPART_CHARWIDTH:		rValue <<= aFD.CharacterWidth;
1303 																break;
1304 			case BASEPROPERTY_FONTDESCRIPTORPART_ORIENTATION:	rValue <<= aFD.Orientation;
1305 																break;
1306 			case BASEPROPERTY_FONTDESCRIPTORPART_KERNING:		rValue <<= aFD.Kerning;
1307 																break;
1308 			case BASEPROPERTY_FONTDESCRIPTORPART_WORDLINEMODE:	rValue <<= aFD.WordLineMode;
1309 																break;
1310 			case BASEPROPERTY_FONTDESCRIPTORPART_TYPE:			rValue <<= aFD.Type;
1311 																break;
1312 			default: DBG_ERROR( "FontProperty?!" );
1313 		}
1314 	}
1315 	else
1316 	{
1317 		DBG_ERROR( "getFastPropertyValue - invalid Property!" );
1318 	}
1319 }
1320 
1321 // ::com::sun::star::beans::XPropertySet
1322 void UnoControlModel::setPropertyValue( const ::rtl::OUString& rPropertyName, const ::com::sun::star::uno::Any& rValue ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException)
1323 {
1324     sal_Int32 nPropId = 0;
1325     {
1326 	    ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
1327 	    nPropId = (sal_Int32) GetPropertyId( rPropertyName );
1328 	    DBG_ASSERT( nPropId, "Invalid ID in UnoControlModel::setPropertyValue" );
1329     }
1330 	if( nPropId )
1331 		setFastPropertyValue( nPropId, rValue );
1332 	else
1333 		throw ::com::sun::star::beans::UnknownPropertyException();
1334 }
1335 
1336 // ::com::sun::star::beans::XFastPropertySet
1337 void UnoControlModel::setFastPropertyValue( sal_Int32 nPropId, const ::com::sun::star::uno::Any& rValue ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException)
1338 {
1339 	if ( ( nPropId >= BASEPROPERTY_FONTDESCRIPTORPART_START ) && ( nPropId <= BASEPROPERTY_FONTDESCRIPTORPART_END ) )
1340 	{
1341 		::osl::ClearableMutexGuard aGuard( GetMutex() );
1342 
1343         Any aOldSingleValue;
1344         getFastPropertyValue( aOldSingleValue, BASEPROPERTY_FONTDESCRIPTORPART_START );
1345 
1346         ImplControlProperty* pProp = mpData->Get( BASEPROPERTY_FONTDESCRIPTOR );
1347 		FontDescriptor aOldFontDescriptor;
1348 		pProp->GetValue() >>= aOldFontDescriptor;
1349 
1350         FontDescriptor aNewFontDescriptor( aOldFontDescriptor );
1351 		lcl_ImplMergeFontProperty( aNewFontDescriptor, (sal_uInt16)nPropId, rValue );
1352 
1353 		Any aNewValue;
1354 		aNewValue <<= aNewFontDescriptor;
1355         sal_Int32 nDescriptorId( BASEPROPERTY_FONTDESCRIPTOR );
1356 		nDescriptorId = BASEPROPERTY_FONTDESCRIPTOR;
1357 
1358         // also, we need  fire a propertyChange event for the single property, since with
1359         // the above line, only an event for the FontDescriptor property will be fired
1360         Any aNewSingleValue;
1361         getFastPropertyValue( aNewSingleValue, BASEPROPERTY_FONTDESCRIPTORPART_START );
1362 
1363         aGuard.clear();
1364 		setFastPropertyValues( 1, &nDescriptorId, &aNewValue, 1 );
1365         fire( &nPropId, &aNewSingleValue, &aOldSingleValue, 1, sal_False );
1366    	}
1367     else
1368 		setFastPropertyValues( 1, &nPropId, &rValue, 1 );
1369 }
1370 
1371 // ::com::sun::star::beans::XMultiPropertySet
1372 ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > UnoControlModel::getPropertySetInfo(  ) throw(::com::sun::star::uno::RuntimeException)
1373 {
1374 	DBG_ERROR( "UnoControlModel::getPropertySetInfo() not possible!" );
1375 	return ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo >();
1376 }
1377 
1378 void UnoControlModel::setPropertyValues( const ::com::sun::star::uno::Sequence< ::rtl::OUString >& rPropertyNames, const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& Values ) throw(::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException)
1379 {
1380 	::osl::ClearableMutexGuard aGuard( GetMutex() );
1381 
1382 	sal_Int32 nProps = rPropertyNames.getLength();
1383 
1384 //	sal_Int32* pHandles = new sal_Int32[nProps];
1385         // don't do this - it leaks in case of an exception
1386     Sequence< sal_Int32 > aHandles( nProps );
1387 	sal_Int32* pHandles = aHandles.getArray();
1388 
1389 	// may need to change the order in the sequence, for this we need a non-const value sequence
1390 	// 15.05.2002 - 99314 - fs@openoffice.org
1391 	uno::Sequence< uno::Any > aValues( Values );
1392 	uno::Any* pValues = aValues.getArray();
1393 
1394 	sal_Int32 nValidHandles = getInfoHelper().fillHandles( pHandles, rPropertyNames );
1395 
1396 	if ( nValidHandles )
1397 	{
1398 		// if somebody sets properties which are single aspects of a font descriptor,
1399         // remove them, and build a font descriptor instead
1400         ::std::auto_ptr< awt::FontDescriptor > pFD;
1401 		for ( sal_uInt16 n = 0; n < nProps; ++n )
1402 		{
1403 			if ( ( pHandles[n] >= BASEPROPERTY_FONTDESCRIPTORPART_START ) && ( pHandles[n] <= BASEPROPERTY_FONTDESCRIPTORPART_END ) )
1404 			{
1405 				if ( !pFD.get() )
1406 				{
1407 					ImplControlProperty* pProp = mpData->Get( BASEPROPERTY_FONTDESCRIPTOR );
1408 					pFD.reset( new awt::FontDescriptor );
1409 					pProp->GetValue() >>= *pFD;
1410 				}
1411 				lcl_ImplMergeFontProperty( *pFD, (sal_uInt16)pHandles[n], pValues[n] );
1412 				pHandles[n] = -1;
1413 				nValidHandles--;
1414 			}
1415 		}
1416 
1417 		if ( nValidHandles )
1418 		{
1419 			ImplNormalizePropertySequence( nProps, pHandles, pValues, &nValidHandles );
1420             aGuard.clear();
1421                 // clear our guard before calling into setFastPropertyValues - this method
1422                 // will implicitly call property listeners, and this should not happen with
1423                 // our mutex locked
1424                 // #i23451# - 2004-03-18 - fs@openoffice.org
1425  			setFastPropertyValues( nProps, pHandles, pValues, nValidHandles );
1426 		}
1427         else
1428             aGuard.clear();
1429             // same as a few lines above
1430 
1431 		// FD-Propertie nicht in das Array mergen, weil sortiert...
1432 		if ( pFD.get() )
1433 		{
1434 			::com::sun::star::uno::Any aValue;
1435 			aValue <<= *pFD;
1436 			sal_Int32 nHandle = BASEPROPERTY_FONTDESCRIPTOR;
1437 			setFastPropertyValues( 1, &nHandle, &aValue, 1 );
1438 		}
1439 	}
1440 }
1441 
1442 
1443 
1444 void UnoControlModel::ImplNormalizePropertySequence( const sal_Int32, sal_Int32*,
1445 	uno::Any*, sal_Int32* ) const SAL_THROW(())
1446 {
1447 	// nothing to do here
1448 }
1449 
1450 void UnoControlModel::ImplEnsureHandleOrder( const sal_Int32 _nCount, sal_Int32* _pHandles,
1451         uno::Any* _pValues, sal_Int32 _nFirstHandle, sal_Int32 _nSecondHandle ) const
1452 {
1453 	for ( sal_Int32 i=0; i < _nCount; ++_pHandles, ++_pValues, ++i )
1454 	{
1455 		if ( _nSecondHandle  == *_pHandles )
1456 		{
1457 			sal_Int32* pLaterHandles = _pHandles + 1;
1458 			uno::Any* pLaterValues = _pValues + 1;
1459 			for ( sal_Int32 j = i + 1; j < _nCount; ++j, ++pLaterHandles, ++pLaterValues )
1460 			{
1461 				if ( _nFirstHandle == *pLaterHandles )
1462 				{
1463 					// indeed it is -> exchange the both places in the sequences
1464 					sal_Int32 nHandle( *_pHandles );
1465 					*_pHandles = *pLaterHandles;
1466 					*pLaterHandles = nHandle;
1467 
1468 					uno::Any aValue( *_pValues );
1469 					*_pValues = *pLaterValues;
1470 					*pLaterValues = aValue;
1471 
1472 					break;
1473 					// this will leave the inner loop, and continue with the outer loop.
1474 					// Note that this means we will encounter the _nSecondHandle handle, again, once we reached
1475 					// (in the outer loop) the place where we just put it.
1476 				}
1477 			}
1478 		}
1479 	}
1480 }
1481