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