Version 6.1.4.1, tag libreoffice-6.1.4.1
[LibreOffice.git] / toolkit / source / controls / unocontrolmodel.cxx
blob2e7b75ddd0e1944258cedca46d58219a2b631f75
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <com/sun/star/beans/PropertyState.hpp>
21 #include <com/sun/star/beans/PropertyAttribute.hpp>
22 #include <com/sun/star/awt/FontDescriptor.hpp>
23 #include <com/sun/star/awt/FontWidth.hpp>
24 #include <com/sun/star/awt/FontWeight.hpp>
25 #include <com/sun/star/awt/FontSlant.hpp>
26 #include <com/sun/star/awt/MouseWheelBehavior.hpp>
27 #include <com/sun/star/graphic/XGraphicProvider.hpp>
28 #include <com/sun/star/awt/XDevice.hpp>
29 #include <com/sun/star/text/WritingMode2.hpp>
30 #include <com/sun/star/io/XMarkableStream.hpp>
31 #include <toolkit/controls/unocontrolmodel.hxx>
32 #include <toolkit/helper/macros.hxx>
33 #include <cppuhelper/supportsservice.hxx>
34 #include <cppuhelper/typeprovider.hxx>
35 #include <rtl/uuid.h>
36 #include <tools/diagnose_ex.h>
37 #include <tools/date.hxx>
38 #include <tools/time.hxx>
39 #include <tools/debug.hxx>
40 #include <toolkit/helper/property.hxx>
41 #include <toolkit/helper/emptyfontdescriptor.hxx>
42 #include <com/sun/star/lang/Locale.hpp>
43 #include <unotools/localedatawrapper.hxx>
44 #include <unotools/configmgr.hxx>
45 #include <comphelper/sequence.hxx>
46 #include <comphelper/extract.hxx>
47 #include <vcl/svapp.hxx>
48 #include <vcl/unohelp.hxx>
49 #include <uno/data.h>
51 #include <memory>
52 #include <set>
54 using namespace ::com::sun::star;
55 using namespace ::com::sun::star::uno;
56 using namespace ::com::sun::star::lang;
57 using namespace ::com::sun::star::i18n;
58 using ::com::sun::star::awt::FontDescriptor;
61 #define UNOCONTROL_STREAMVERSION short(2)
63 static void lcl_ImplMergeFontProperty( FontDescriptor& rFD, sal_uInt16 nPropId, const Any& rValue )
65 // some props are defined with other types than the matching FontDescriptor members have
66 // (e.g. FontWidth, FontSlant)
67 // 78474 - 09/19/2000 - FS
68 float nExtractFloat = 0;
69 sal_Int16 nExtractShort = 0;
71 switch ( nPropId )
73 case BASEPROPERTY_FONTDESCRIPTORPART_NAME: rValue >>= rFD.Name;
74 break;
75 case BASEPROPERTY_FONTDESCRIPTORPART_STYLENAME: rValue >>= rFD.StyleName;
76 break;
77 case BASEPROPERTY_FONTDESCRIPTORPART_FAMILY: rValue >>= rFD.Family;
78 break;
79 case BASEPROPERTY_FONTDESCRIPTORPART_CHARSET: rValue >>= rFD.CharSet;
80 break;
81 case BASEPROPERTY_FONTDESCRIPTORPART_HEIGHT: rValue >>= nExtractFloat; rFD.Height = static_cast<sal_Int16>(nExtractFloat);
82 break;
83 case BASEPROPERTY_FONTDESCRIPTORPART_WEIGHT: rValue >>= rFD.Weight;
84 break;
85 case BASEPROPERTY_FONTDESCRIPTORPART_SLANT: if ( rValue >>= nExtractShort )
86 rFD.Slant = static_cast<css::awt::FontSlant>(nExtractShort);
87 else
88 rValue >>= rFD.Slant;
89 break;
90 case BASEPROPERTY_FONTDESCRIPTORPART_UNDERLINE: rValue >>= rFD.Underline;
91 break;
92 case BASEPROPERTY_FONTDESCRIPTORPART_STRIKEOUT: rValue >>= rFD.Strikeout;
93 break;
94 case BASEPROPERTY_FONTDESCRIPTORPART_WIDTH: rValue >>= rFD.Width;
95 break;
96 case BASEPROPERTY_FONTDESCRIPTORPART_PITCH: rValue >>= rFD.Pitch;
97 break;
98 case BASEPROPERTY_FONTDESCRIPTORPART_CHARWIDTH: rValue >>= rFD.CharacterWidth;
99 break;
100 case BASEPROPERTY_FONTDESCRIPTORPART_ORIENTATION: rValue >>= rFD.Orientation;
101 break;
102 case BASEPROPERTY_FONTDESCRIPTORPART_KERNING: rValue >>= rFD.Kerning;
103 break;
104 case BASEPROPERTY_FONTDESCRIPTORPART_WORDLINEMODE: rValue >>= rFD.WordLineMode;
105 break;
106 case BASEPROPERTY_FONTDESCRIPTORPART_TYPE: rValue >>= rFD.Type;
107 break;
108 default: OSL_FAIL( "FontProperty?!" );
113 // class UnoControlModel
115 UnoControlModel::UnoControlModel( const Reference< XComponentContext >& rxContext )
116 :UnoControlModel_Base()
117 ,MutexAndBroadcastHelper()
118 ,OPropertySetHelper( BrdcstHelper )
119 ,maDisposeListeners( *this )
120 ,m_xContext( rxContext )
122 // Insert properties from Model into table,
123 // only existing properties are valid, even if they're VOID
126 UnoControlModel::UnoControlModel( const UnoControlModel& rModel )
127 : UnoControlModel_Base()
128 , MutexAndBroadcastHelper()
129 , OPropertySetHelper( BrdcstHelper )
130 , maData( rModel.maData )
131 , maDisposeListeners( *this )
132 , m_xContext( rModel.m_xContext )
136 css::uno::Sequence<sal_Int32> UnoControlModel::ImplGetPropertyIds() const
138 sal_uInt32 nIDs = maData.size();
139 css::uno::Sequence<sal_Int32> aIDs( nIDs );
140 sal_Int32* pIDs = aIDs.getArray();
141 sal_uInt32 n = 0;
142 for ( ImplPropertyTable::const_iterator it = maData.begin(); it != maData.end(); ++it )
143 pIDs[n++] = it->first;
144 return aIDs;
147 bool UnoControlModel::ImplHasProperty( sal_uInt16 nPropId ) const
149 if ( ( nPropId >= BASEPROPERTY_FONTDESCRIPTORPART_START ) && ( nPropId <= BASEPROPERTY_FONTDESCRIPTORPART_END ) )
150 nPropId = BASEPROPERTY_FONTDESCRIPTOR;
152 return maData.find( nPropId ) != maData.end();
155 css::uno::Any UnoControlModel::ImplGetDefaultValue( sal_uInt16 nPropId ) const
157 css::uno::Any aDefault;
159 if (
160 (nPropId == BASEPROPERTY_FONTDESCRIPTOR) ||
162 (nPropId >= BASEPROPERTY_FONTDESCRIPTORPART_START) &&
163 (nPropId <= BASEPROPERTY_FONTDESCRIPTORPART_END)
167 EmptyFontDescriptor aFD;
168 switch ( nPropId )
170 case BASEPROPERTY_FONTDESCRIPTOR: aDefault <<= aFD; break;
171 case BASEPROPERTY_FONTDESCRIPTORPART_NAME: aDefault <<= aFD.Name; break;
172 case BASEPROPERTY_FONTDESCRIPTORPART_STYLENAME: aDefault <<= aFD.StyleName; break;
173 case BASEPROPERTY_FONTDESCRIPTORPART_FAMILY: aDefault <<= aFD.Family; break;
174 case BASEPROPERTY_FONTDESCRIPTORPART_CHARSET: aDefault <<= aFD.CharSet; break;
175 case BASEPROPERTY_FONTDESCRIPTORPART_HEIGHT: aDefault <<= static_cast<float>(aFD.Height); break;
176 case BASEPROPERTY_FONTDESCRIPTORPART_WEIGHT: aDefault <<= aFD.Weight; break;
177 case BASEPROPERTY_FONTDESCRIPTORPART_SLANT: aDefault <<= static_cast<sal_Int16>(aFD.Slant); break;
178 case BASEPROPERTY_FONTDESCRIPTORPART_UNDERLINE: aDefault <<= aFD.Underline; break;
179 case BASEPROPERTY_FONTDESCRIPTORPART_STRIKEOUT: aDefault <<= aFD.Strikeout; break;
180 case BASEPROPERTY_FONTDESCRIPTORPART_WIDTH: aDefault <<= aFD.Width; break;
181 case BASEPROPERTY_FONTDESCRIPTORPART_PITCH: aDefault <<= aFD.Pitch; break;
182 case BASEPROPERTY_FONTDESCRIPTORPART_CHARWIDTH: aDefault <<= aFD.CharacterWidth; break;
183 case BASEPROPERTY_FONTDESCRIPTORPART_ORIENTATION: aDefault <<= aFD.Orientation; break;
184 case BASEPROPERTY_FONTDESCRIPTORPART_KERNING: aDefault <<= aFD.Kerning; break;
185 case BASEPROPERTY_FONTDESCRIPTORPART_WORDLINEMODE: aDefault <<= aFD.WordLineMode; break;
186 case BASEPROPERTY_FONTDESCRIPTORPART_TYPE: aDefault <<= aFD.Type; break;
187 default: OSL_FAIL( "FontProperty?!" );
190 else
192 switch ( nPropId )
194 case BASEPROPERTY_GRAPHIC:
195 aDefault <<= Reference< graphic::XGraphic >();
196 break;
198 case BASEPROPERTY_REFERENCE_DEVICE:
199 aDefault <<= Reference< awt::XDevice >();
200 break;
202 case BASEPROPERTY_ITEM_SEPARATOR_POS:
203 case BASEPROPERTY_VERTICALALIGN:
204 case BASEPROPERTY_BORDERCOLOR:
205 case BASEPROPERTY_SYMBOL_COLOR:
206 case BASEPROPERTY_TABSTOP:
207 case BASEPROPERTY_TEXTCOLOR:
208 case BASEPROPERTY_TEXTLINECOLOR:
209 case BASEPROPERTY_DATE:
210 case BASEPROPERTY_DATESHOWCENTURY:
211 case BASEPROPERTY_TIME:
212 case BASEPROPERTY_VALUE_DOUBLE:
213 case BASEPROPERTY_PROGRESSVALUE:
214 case BASEPROPERTY_SCROLLVALUE:
215 case BASEPROPERTY_VISIBLESIZE:
216 case BASEPROPERTY_BACKGROUNDCOLOR:
217 case BASEPROPERTY_FILLCOLOR: break; // Void
219 case BASEPROPERTY_FONTRELIEF:
220 case BASEPROPERTY_FONTEMPHASISMARK:
221 case BASEPROPERTY_MAXTEXTLEN:
222 case BASEPROPERTY_STATE:
223 case BASEPROPERTY_EXTDATEFORMAT:
224 case BASEPROPERTY_EXTTIMEFORMAT:
225 case BASEPROPERTY_ECHOCHAR: aDefault <<= sal_Int16(0); break;
226 case BASEPROPERTY_BORDER: aDefault <<= sal_Int16(1); break;
227 case BASEPROPERTY_DECIMALACCURACY: aDefault <<= sal_Int16(2); break;
228 case BASEPROPERTY_LINECOUNT: aDefault <<= sal_Int16(5); break;
229 case BASEPROPERTY_ALIGN: aDefault <<= sal_Int16(PROPERTY_ALIGN_LEFT); break;
230 case BASEPROPERTY_IMAGEALIGN: aDefault <<= sal_Int16(1) /*ImageAlign::Top*/; break;
231 case BASEPROPERTY_IMAGEPOSITION: aDefault <<= sal_Int16(12) /*ImagePosition::Centered*/; break;
232 case BASEPROPERTY_PUSHBUTTONTYPE: aDefault <<= sal_Int16(0) /*PushButtonType::STANDARD*/; break;
233 case BASEPROPERTY_MOUSE_WHEEL_BEHAVIOUR:aDefault <<= sal_Int16(awt::MouseWheelBehavior::SCROLL_FOCUS_ONLY); break;
235 case BASEPROPERTY_DATEMAX: aDefault <<= util::Date( 31, 12, 2200 ); break;
236 case BASEPROPERTY_DATEMIN: aDefault <<= util::Date( 1, 1, 1900 ); break;
237 case BASEPROPERTY_TIMEMAX: aDefault <<= util::Time(0, 0, 59, 23, false); break;
238 case BASEPROPERTY_TIMEMIN: aDefault <<= util::Time(); break;
239 case BASEPROPERTY_VALUEMAX_DOUBLE: aDefault <<= double(1000000); break;
240 case BASEPROPERTY_VALUEMIN_DOUBLE: aDefault <<= double(-1000000); break;
241 case BASEPROPERTY_VALUESTEP_DOUBLE: aDefault <<= double(1); break;
242 case BASEPROPERTY_PROGRESSVALUE_MAX: aDefault <<= sal_Int32(100); break;
243 case BASEPROPERTY_PROGRESSVALUE_MIN: aDefault <<= sal_Int32(0); break;
244 case BASEPROPERTY_SCROLLVALUE_MAX: aDefault <<= sal_Int32(100); break;
245 case BASEPROPERTY_SCROLLVALUE_MIN: aDefault <<= sal_Int32(0); break;
246 case BASEPROPERTY_LINEINCREMENT: aDefault <<= sal_Int32(1); break;
247 case BASEPROPERTY_BLOCKINCREMENT: aDefault <<= sal_Int32(10); break;
248 case BASEPROPERTY_ORIENTATION: aDefault <<= sal_Int32(0); break;
249 case BASEPROPERTY_SPINVALUE: aDefault <<= sal_Int32(0); break;
250 case BASEPROPERTY_SPININCREMENT: aDefault <<= sal_Int32(1); break;
251 case BASEPROPERTY_SPINVALUE_MIN: aDefault <<= sal_Int32(0); break;
252 case BASEPROPERTY_SPINVALUE_MAX: aDefault <<= sal_Int32(100); break;
253 case BASEPROPERTY_REPEAT_DELAY: aDefault <<= sal_Int32(50); break; // 50 milliseconds
254 case BASEPROPERTY_DEFAULTCONTROL: aDefault <<= const_cast<UnoControlModel*>(this)->getServiceName(); break;
256 case BASEPROPERTY_AUTOHSCROLL:
257 case BASEPROPERTY_AUTOVSCROLL:
258 case BASEPROPERTY_MOVEABLE:
259 case BASEPROPERTY_CLOSEABLE:
260 case BASEPROPERTY_SIZEABLE:
261 case BASEPROPERTY_HSCROLL:
262 case BASEPROPERTY_DEFAULTBUTTON:
263 case BASEPROPERTY_MULTILINE:
264 case BASEPROPERTY_MULTISELECTION:
265 case BASEPROPERTY_TRISTATE:
266 case BASEPROPERTY_DROPDOWN:
267 case BASEPROPERTY_SPIN:
268 case BASEPROPERTY_READONLY:
269 case BASEPROPERTY_VSCROLL:
270 case BASEPROPERTY_NUMSHOWTHOUSANDSEP:
271 case BASEPROPERTY_STRICTFORMAT:
272 case BASEPROPERTY_REPEAT:
273 case BASEPROPERTY_PAINTTRANSPARENT:
274 case BASEPROPERTY_DESKTOP_AS_PARENT:
275 case BASEPROPERTY_HARDLINEBREAKS:
276 case BASEPROPERTY_NOLABEL: aDefault <<= false; break;
278 case BASEPROPERTY_MULTISELECTION_SIMPLEMODE:
279 case BASEPROPERTY_HIDEINACTIVESELECTION:
280 case BASEPROPERTY_ENFORCE_FORMAT:
281 case BASEPROPERTY_AUTOCOMPLETE:
282 case BASEPROPERTY_SCALEIMAGE:
283 case BASEPROPERTY_ENABLED:
284 case BASEPROPERTY_PRINTABLE:
285 case BASEPROPERTY_ENABLEVISIBLE:
286 case BASEPROPERTY_DECORATION: aDefault <<= true; break;
288 case BASEPROPERTY_GROUPNAME:
289 case BASEPROPERTY_HELPTEXT:
290 case BASEPROPERTY_HELPURL:
291 case BASEPROPERTY_IMAGEURL:
292 case BASEPROPERTY_DIALOGSOURCEURL:
293 case BASEPROPERTY_EDITMASK:
294 case BASEPROPERTY_LITERALMASK:
295 case BASEPROPERTY_LABEL:
296 case BASEPROPERTY_TITLE:
297 case BASEPROPERTY_TEXT: aDefault <<= OUString(); break;
299 case BASEPROPERTY_WRITING_MODE:
300 case BASEPROPERTY_CONTEXT_WRITING_MODE:
301 aDefault <<= text::WritingMode2::CONTEXT;
302 break;
304 case BASEPROPERTY_STRINGITEMLIST:
306 css::uno::Sequence< OUString> aStringSeq;
307 aDefault <<= aStringSeq;
310 break;
311 case BASEPROPERTY_TYPEDITEMLIST:
313 css::uno::Sequence< css::uno::Any > aAnySeq;
314 aDefault <<= aAnySeq;
317 break;
318 case BASEPROPERTY_SELECTEDITEMS:
320 css::uno::Sequence<sal_Int16> aINT16Seq;
321 aDefault <<= aINT16Seq;
323 break;
324 case BASEPROPERTY_CURRENCYSYMBOL:
326 OUString sDefaultCurrency(
327 utl::ConfigManager::getDefaultCurrency() );
329 // extract the bank symbol
330 sal_Int32 nSepPos = sDefaultCurrency.indexOf( '-' );
331 OUString sBankSymbol;
332 if ( nSepPos >= 0 )
334 sBankSymbol = sDefaultCurrency.copy( 0, nSepPos );
335 sDefaultCurrency = sDefaultCurrency.copy( nSepPos + 1 );
338 // the remaining is the locale
339 LanguageTag aLanguageTag( sDefaultCurrency);
340 LocaleDataWrapper aLocaleInfo( m_xContext, aLanguageTag );
341 if ( sBankSymbol.isEmpty() )
342 sBankSymbol = aLocaleInfo.getCurrBankSymbol();
344 // look for the currency entry (for this language) which has the given bank symbol
345 Sequence< Currency2 > aAllCurrencies = aLocaleInfo.getAllCurrencies();
346 const Currency2* pAllCurrencies = aAllCurrencies.getConstArray();
347 const Currency2* pAllCurrenciesEnd = pAllCurrencies + aAllCurrencies.getLength();
349 OUString sCurrencySymbol = aLocaleInfo.getCurrSymbol();
350 if ( sBankSymbol.isEmpty() )
352 DBG_ASSERT( pAllCurrencies != pAllCurrenciesEnd, "UnoControlModel::ImplGetDefaultValue: no currencies at all!" );
353 if ( pAllCurrencies != pAllCurrenciesEnd )
355 sBankSymbol = pAllCurrencies->BankSymbol;
356 sCurrencySymbol = pAllCurrencies->Symbol;
360 if ( !sBankSymbol.isEmpty() )
362 bool bLegacy = false;
363 for ( ;pAllCurrencies != pAllCurrenciesEnd; ++pAllCurrencies )
364 if ( pAllCurrencies->BankSymbol == sBankSymbol )
366 sCurrencySymbol = pAllCurrencies->Symbol;
367 if ( pAllCurrencies->LegacyOnly )
368 bLegacy = true;
369 else
370 break;
372 DBG_ASSERT( bLegacy || pAllCurrencies != pAllCurrenciesEnd, "UnoControlModel::ImplGetDefaultValue: did not find the given bank symbol!" );
375 aDefault <<= sCurrencySymbol;
377 break;
379 default: OSL_FAIL( "ImplGetDefaultValue - unknown Property" );
383 return aDefault;
386 void UnoControlModel::ImplRegisterProperty( sal_uInt16 nPropId, const css::uno::Any& rDefault )
388 maData[ nPropId ] = rDefault;
391 void UnoControlModel::ImplRegisterProperty( sal_uInt16 nPropId )
393 ImplRegisterProperty( nPropId, ImplGetDefaultValue( nPropId ) );
395 if ( nPropId == BASEPROPERTY_FONTDESCRIPTOR )
397 // some properties are not included in the FontDescriptor, but every time
398 // when we have a FontDescriptor we want to have these properties too.
399 // => Easier to register the here, instead everywhere where I register the FontDescriptor...
401 ImplRegisterProperty( BASEPROPERTY_TEXTCOLOR );
402 ImplRegisterProperty( BASEPROPERTY_TEXTLINECOLOR );
403 ImplRegisterProperty( BASEPROPERTY_FONTRELIEF );
404 ImplRegisterProperty( BASEPROPERTY_FONTEMPHASISMARK );
408 void UnoControlModel::ImplRegisterProperties( const std::vector< sal_uInt16 > &rIds )
410 std::vector< sal_uInt16 >::const_iterator iter;
411 for( iter = rIds.begin(); iter != rIds.end(); ++iter)
413 if( !ImplHasProperty( *iter ) )
414 ImplRegisterProperty( *iter, ImplGetDefaultValue( *iter ) );
418 // css::uno::XInterface
419 css::uno::Any UnoControlModel::queryAggregation( const css::uno::Type & rType )
421 Any aRet = UnoControlModel_Base::queryAggregation( rType );
422 if ( !aRet.hasValue() )
423 aRet = ::cppu::OPropertySetHelper::queryInterface( rType );
424 return aRet;
427 // css::lang::XUnoTunnel
428 IMPL_XUNOTUNNEL_MINIMAL( UnoControlModel )
430 // XInterface
431 IMPLEMENT_FORWARD_REFCOUNT( UnoControlModel, UnoControlModel_Base )
433 // css::lang::XTypeProvider
434 IMPLEMENT_FORWARD_XTYPEPROVIDER2( UnoControlModel, UnoControlModel_Base, ::cppu::OPropertySetHelper )
437 uno::Reference< util::XCloneable > UnoControlModel::createClone()
439 rtl::Reference<UnoControlModel> pClone = Clone();
440 return pClone.get();
443 // css::lang::XComponent
444 void UnoControlModel::dispose( )
446 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
448 css::lang::EventObject aEvt;
449 aEvt.Source = static_cast<css::uno::XAggregation*>(static_cast<cppu::OWeakAggObject*>(this));
450 maDisposeListeners.disposeAndClear( aEvt );
452 BrdcstHelper.aLC.disposeAndClear( aEvt );
454 // let the property set helper notify our property listeners
455 OPropertySetHelper::disposing();
458 void UnoControlModel::addEventListener( const css::uno::Reference< css::lang::XEventListener >& rxListener )
460 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
462 maDisposeListeners.addInterface( rxListener );
465 void UnoControlModel::removeEventListener( const css::uno::Reference< css::lang::XEventListener >& rxListener )
467 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
469 maDisposeListeners.removeInterface( rxListener );
473 // css::beans::XPropertyState
474 css::beans::PropertyState UnoControlModel::getPropertyState( const OUString& PropertyName )
476 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
478 sal_uInt16 nPropId = GetPropertyId( PropertyName );
480 css::uno::Any aValue = getPropertyValue( PropertyName );
481 css::uno::Any aDefault = ImplGetDefaultValue( nPropId );
483 return CompareProperties( aValue, aDefault ) ? css::beans::PropertyState_DEFAULT_VALUE : css::beans::PropertyState_DIRECT_VALUE;
486 css::uno::Sequence< css::beans::PropertyState > UnoControlModel::getPropertyStates( const css::uno::Sequence< OUString >& PropertyNames )
488 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
490 sal_uInt32 nNames = PropertyNames.getLength();
491 const OUString* pNames = PropertyNames.getConstArray();
493 css::uno::Sequence< css::beans::PropertyState > aStates( nNames );
494 css::beans::PropertyState* pStates = aStates.getArray();
496 for ( sal_uInt32 n = 0; n < nNames; n++ )
497 pStates[n] = getPropertyState( pNames[n] );
499 return aStates;
502 void UnoControlModel::setPropertyToDefault( const OUString& PropertyName )
504 Any aDefaultValue;
506 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
507 aDefaultValue = ImplGetDefaultValue( GetPropertyId( PropertyName ) );
509 setPropertyValue( PropertyName, aDefaultValue );
512 css::uno::Any UnoControlModel::getPropertyDefault( const OUString& rPropertyName )
514 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
516 return ImplGetDefaultValue( GetPropertyId( rPropertyName ) );
520 // css::io::XPersistObjec
521 OUString UnoControlModel::getServiceName( )
523 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
525 OSL_FAIL( "ServiceName of UnoControlModel ?!" );
526 return OUString();
529 void UnoControlModel::write( const css::uno::Reference< css::io::XObjectOutputStream >& OutStream )
531 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
533 css::uno::Reference< css::io::XMarkableStream > xMark( OutStream, css::uno::UNO_QUERY );
534 DBG_ASSERT( xMark.is(), "write: no css::io::XMarkableStream!" );
536 OutStream->writeShort( UNOCONTROL_STREAMVERSION );
538 std::set<sal_uInt16> aProps;
540 for (ImplPropertyTable::const_iterator it = maData.begin(); it != maData.end(); ++it )
542 if ( ( ( GetPropertyAttribs( it->first ) & css::beans::PropertyAttribute::TRANSIENT ) == 0 )
543 && ( getPropertyState( GetPropertyName( it->first ) ) != css::beans::PropertyState_DEFAULT_VALUE ) )
545 aProps.insert( it->first );
549 sal_uInt32 nProps = aProps.size();
551 // Save FontProperty always in the old format (due to missing distinction
552 // between 5.0 and 5.1)
553 OutStream->writeLong( ( aProps.find( BASEPROPERTY_FONTDESCRIPTOR ) != aProps.end() ) ? ( nProps + 3 ) : nProps );
554 for ( std::set<sal_uInt16>::const_iterator it = aProps.begin(); it != aProps.end(); ++it )
556 sal_Int32 nPropDataBeginMark = xMark->createMark();
557 OutStream->writeLong( 0 ); // DataLen
559 const css::uno::Any* pProp = &(maData[*it]);
560 OutStream->writeShort( *it );
562 bool bVoid = pProp->getValueType().getTypeClass() == css::uno::TypeClass_VOID;
564 OutStream->writeBoolean( bVoid );
566 if ( !bVoid )
568 const css::uno::Any& rValue = *pProp;
569 const css::uno::Type& rType = rValue.getValueType();
571 if ( rType == cppu::UnoType< bool >::get() )
573 bool b = false;
574 rValue >>= b;
575 OutStream->writeBoolean( b );
577 else if ( rType == ::cppu::UnoType< OUString >::get() )
579 OUString aUString;
580 rValue >>= aUString;
581 OutStream->writeUTF( aUString );
583 else if ( rType == ::cppu::UnoType< ::cppu::UnoUnsignedShortType >::get() )
585 sal_uInt16 n = 0;
586 rValue >>= n;
587 OutStream->writeShort( n );
589 else if ( rType == cppu::UnoType<sal_Int16>::get() )
591 sal_Int16 n = 0;
592 rValue >>= n;
593 OutStream->writeShort( n );
595 else if ( rType == cppu::UnoType<sal_uInt32>::get() )
597 sal_uInt32 n = 0;
598 rValue >>= n;
599 OutStream->writeLong( n );
601 else if ( rType == cppu::UnoType<sal_Int32>::get() )
603 sal_Int32 n = 0;
604 rValue >>= n;
605 OutStream->writeLong( n );
607 else if ( rType == cppu::UnoType<double>::get() )
609 double n = 0;
610 rValue >>= n;
611 OutStream->writeDouble( n );
613 else if ( rType == cppu::UnoType< css::awt::FontDescriptor >::get() )
615 css::awt::FontDescriptor aFD;
616 rValue >>= aFD;
617 OutStream->writeUTF( aFD.Name );
618 OutStream->writeShort( aFD.Height );
619 OutStream->writeShort( aFD.Width );
620 OutStream->writeUTF( aFD.StyleName );
621 OutStream->writeShort( aFD.Family );
622 OutStream->writeShort( aFD.CharSet );
623 OutStream->writeShort( aFD.Pitch );
624 OutStream->writeDouble( aFD.CharacterWidth );
625 OutStream->writeDouble( aFD.Weight );
626 OutStream->writeShort(
627 sal::static_int_cast< sal_Int16 >(aFD.Slant) );
628 OutStream->writeShort( aFD.Underline );
629 OutStream->writeShort( aFD.Strikeout );
630 OutStream->writeDouble( aFD.Orientation );
631 OutStream->writeBoolean( aFD.Kerning );
632 OutStream->writeBoolean( aFD.WordLineMode );
633 OutStream->writeShort( aFD.Type );
635 else if ( rType == cppu::UnoType<css::util::Date>::get() )
637 css::util::Date d;
638 rValue >>= d;
639 OutStream->writeLong(d.Day + 100 * d.Month + 10000 * d.Year);
640 // YYYYMMDD
642 else if ( rType == cppu::UnoType<css::util::Time>::get() )
644 css::util::Time t;
645 rValue >>= t;
646 OutStream->writeLong(
647 t.NanoSeconds / 1000000 + 100 * t.Seconds
648 + 10000 * t.Minutes + 1000000 * t.Hours); // HHMMSShh
650 else if ( rType == cppu::UnoType< css::uno::Sequence< OUString> >::get() )
652 css::uno::Sequence< OUString> aSeq;
653 rValue >>= aSeq;
654 long nEntries = aSeq.getLength();
655 OutStream->writeLong( nEntries );
656 for ( long n = 0; n < nEntries; n++ )
657 OutStream->writeUTF( aSeq.getConstArray()[n] );
659 else if ( rType == cppu::UnoType< cppu::UnoSequenceType<cppu::UnoUnsignedShortType> >::get() )
661 css::uno::Sequence<sal_uInt16> aSeq;
662 rValue >>= aSeq;
663 long nEntries = aSeq.getLength();
664 OutStream->writeLong( nEntries );
665 for ( long n = 0; n < nEntries; n++ )
666 OutStream->writeShort( aSeq.getConstArray()[n] );
668 else if ( rType == cppu::UnoType< css::uno::Sequence<sal_Int16> >::get() )
670 css::uno::Sequence<sal_Int16> aSeq;
671 rValue >>= aSeq;
672 long nEntries = aSeq.getLength();
673 OutStream->writeLong( nEntries );
674 for ( long n = 0; n < nEntries; n++ )
675 OutStream->writeShort( aSeq.getConstArray()[n] );
677 else if ( rType.getTypeClass() == TypeClass_ENUM )
679 sal_Int32 nAsInt = 0;
680 ::cppu::enum2int( nAsInt, rValue );
681 OutStream->writeLong( nAsInt );
683 #if OSL_DEBUG_LEVEL > 0
684 else
686 SAL_WARN( "toolkit", "UnoControlModel::write: don't know how to handle a property of type '"
687 << rType.getTypeName()
688 << "'.\n(Currently handling property '"
689 << GetPropertyName( *it )
690 << "'.)");
692 #endif
695 sal_Int32 nPropDataLen = xMark->offsetToMark( nPropDataBeginMark );
696 xMark->jumpToMark( nPropDataBeginMark );
697 OutStream->writeLong( nPropDataLen );
698 xMark->jumpToFurthest();
699 xMark->deleteMark(nPropDataBeginMark);
702 if ( aProps.find( BASEPROPERTY_FONTDESCRIPTOR ) != aProps.end() )
704 const css::uno::Any* pProp = &maData[ BASEPROPERTY_FONTDESCRIPTOR ];
705 // Until 5.0 export arrives, write old format..
706 css::awt::FontDescriptor aFD;
707 (*pProp) >>= aFD;
709 for ( sal_uInt16 n = BASEPROPERTY_FONT_TYPE; n <= BASEPROPERTY_FONT_ATTRIBS; n++ )
711 sal_Int32 nPropDataBeginMark = xMark->createMark();
712 OutStream->writeLong( 0 ); // DataLen
713 OutStream->writeShort( n ); // PropId
714 OutStream->writeBoolean( false ); // Void
716 if ( n == BASEPROPERTY_FONT_TYPE )
718 OutStream->writeUTF( aFD.Name );
719 OutStream->writeUTF( aFD.StyleName );
720 OutStream->writeShort( aFD.Family );
721 OutStream->writeShort( aFD.CharSet );
722 OutStream->writeShort( aFD.Pitch );
724 else if ( n == BASEPROPERTY_FONT_SIZE )
726 OutStream->writeLong( aFD.Width );
727 OutStream->writeLong( aFD.Height );
728 OutStream->writeShort(
729 sal::static_int_cast< sal_Int16 >(
730 vcl::unohelper::ConvertFontWidth(aFD.CharacterWidth)) );
732 else if ( n == BASEPROPERTY_FONT_ATTRIBS )
734 OutStream->writeShort(
735 sal::static_int_cast< sal_Int16 >(
736 vcl::unohelper::ConvertFontWeight(aFD.Weight)) );
737 OutStream->writeShort(
738 sal::static_int_cast< sal_Int16 >(aFD.Slant) );
739 OutStream->writeShort( aFD.Underline );
740 OutStream->writeShort( aFD.Strikeout );
741 OutStream->writeShort( static_cast<short>(aFD.Orientation * 10) );
742 OutStream->writeBoolean( aFD.Kerning );
743 OutStream->writeBoolean( aFD.WordLineMode );
745 else
747 OSL_FAIL( "Property?!" );
750 sal_Int32 nPropDataLen = xMark->offsetToMark( nPropDataBeginMark );
751 xMark->jumpToMark( nPropDataBeginMark );
752 OutStream->writeLong( nPropDataLen );
753 xMark->jumpToFurthest();
754 xMark->deleteMark(nPropDataBeginMark);
759 void UnoControlModel::read( const css::uno::Reference< css::io::XObjectInputStream >& InStream )
761 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
763 css::uno::Reference< css::io::XMarkableStream > xMark( InStream, css::uno::UNO_QUERY );
764 DBG_ASSERT( xMark.is(), "read: no css::io::XMarkableStream!" );
766 short nVersion = InStream->readShort();
767 sal_uInt32 nProps = static_cast<sal_uInt32>(InStream->readLong());
768 css::uno::Sequence< OUString> aProps( nProps );
769 css::uno::Sequence< css::uno::Any> aValues( nProps );
770 bool bInvalidEntries = false;
772 // Unfortunately, there's no mark for the whole block, thus only properties may be changed.
773 // No data for the model may be added following the properties
775 // Used for import of old parts in css::awt::FontDescriptor
776 css::awt::FontDescriptor* pFD = nullptr;
778 sal_uInt32 i;
779 for ( i = 0; i < nProps; i++ )
781 sal_Int32 nPropDataBeginMark = xMark->createMark();
782 sal_Int32 nPropDataLen = InStream->readLong();
784 sal_uInt16 nPropId = static_cast<sal_uInt16>(InStream->readShort());
786 css::uno::Any aValue;
787 bool bIsVoid = InStream->readBoolean();
788 if ( !bIsVoid )
790 if ( maData.find( nPropId ) != maData.end() )
792 const css::uno::Type* pType = GetPropertyType( nPropId );
793 if ( *pType == cppu::UnoType<bool>::get() )
795 bool b = InStream->readBoolean();
796 aValue <<= b;
798 else if ( *pType == cppu::UnoType<OUString>::get() )
800 OUString aUTF = InStream->readUTF();
801 aValue <<= aUTF;
803 else if ( *pType == ::cppu::UnoType< ::cppu::UnoUnsignedShortType >::get() )
805 sal_uInt16 n = InStream->readShort();
806 aValue <<= n;
808 else if ( *pType == cppu::UnoType<sal_Int16>::get() )
810 sal_Int16 n = InStream->readShort();
811 aValue <<= n;
813 else if ( *pType == cppu::UnoType<sal_uInt32>::get() )
815 sal_uInt32 n = InStream->readLong();
816 aValue <<= n;
818 else if ( *pType == cppu::UnoType<sal_Int32>::get() )
820 sal_Int32 n = InStream->readLong();
821 aValue <<= n;
823 else if ( *pType == cppu::UnoType<double>::get() )
825 double n = InStream->readDouble();
826 aValue <<= n;
828 else if ( *pType == cppu::UnoType< css::awt::FontDescriptor >::get() )
830 css::awt::FontDescriptor aFD;
831 aFD.Name = InStream->readUTF();
832 aFD.Height = InStream->readShort();
833 aFD.Width = InStream->readShort();
834 aFD.StyleName = InStream->readUTF();
835 aFD.Family = InStream->readShort();
836 aFD.CharSet = InStream->readShort();
837 aFD.Pitch = InStream->readShort();
838 aFD.CharacterWidth = static_cast<float>(InStream->readDouble());
839 aFD.Weight = static_cast<float>(InStream->readDouble());
840 aFD.Slant = static_cast<css::awt::FontSlant>(InStream->readShort());
841 aFD.Underline = InStream->readShort();
842 aFD.Strikeout = InStream->readShort();
843 aFD.Orientation = static_cast<float>(InStream->readDouble());
844 aFD.Kerning = InStream->readBoolean() != 0;
845 aFD.WordLineMode = InStream->readBoolean() != 0;
846 aFD.Type = InStream->readShort();
847 aValue <<= aFD;
849 else if ( *pType == cppu::UnoType<css::util::Date>::get() )
851 sal_Int32 n = InStream->readLong(); // YYYYMMDD
852 aValue <<= css::util::Date(
853 n % 100, (n / 100) % 100, n / 10000);
855 else if ( *pType == cppu::UnoType<css::util::Time>::get() )
857 sal_Int32 n = InStream->readLong(); // HHMMSShh
858 aValue <<= css::util::Time(
859 (n % 100) * 1000000, (n / 100) % 100, (n / 10000) % 100,
860 n / 1000000, false);
862 else if ( *pType == cppu::UnoType< css::uno::Sequence< OUString> >::get() )
864 long nEntries = InStream->readLong();
865 css::uno::Sequence< OUString> aSeq( nEntries );
866 for ( long n = 0; n < nEntries; n++ )
867 aSeq.getArray()[n] = InStream->readUTF();
868 aValue <<= aSeq;
871 else if ( *pType == cppu::UnoType< cppu::UnoSequenceType<cppu::UnoUnsignedShortType> >::get() )
874 long nEntries = InStream->readLong();
875 css::uno::Sequence<sal_uInt16> aSeq( nEntries );
876 for ( long n = 0; n < nEntries; n++ )
877 aSeq.getArray()[n] = static_cast<sal_uInt16>(InStream->readShort());
878 aValue <<= aSeq;
880 else if ( *pType == cppu::UnoType< css::uno::Sequence<sal_Int16> >::get() )
882 long nEntries = InStream->readLong();
883 css::uno::Sequence<sal_Int16> aSeq( nEntries );
884 for ( long n = 0; n < nEntries; n++ )
885 aSeq.getArray()[n] = static_cast<sal_Int16>(InStream->readShort());
886 aValue <<= aSeq;
888 else if ( pType->getTypeClass() == TypeClass_ENUM )
890 sal_Int32 nAsInt = InStream->readLong();
891 aValue = ::cppu::int2enum( nAsInt, *pType );
893 else
895 SAL_WARN( "toolkit", "UnoControlModel::read: don't know how to handle a property of type '"
896 << pType->getTypeName()
897 << "'.\n(Currently handling property '"
898 << GetPropertyName( nPropId )
899 << "'.)");
902 else
904 // Old trash from 5.0
905 if ( nPropId == BASEPROPERTY_FONT_TYPE )
907 // Redundant information for older versions
908 // is skipped by MarkableStream
909 if ( nVersion < 2 )
911 if ( !pFD )
913 pFD = new css::awt::FontDescriptor;
914 if ( maData.find( BASEPROPERTY_FONTDESCRIPTOR ) != maData.end() ) // due to defaults...
915 maData[ BASEPROPERTY_FONTDESCRIPTOR ] >>= *pFD;
917 pFD->Name = InStream->readUTF();
918 pFD->StyleName = InStream->readUTF();
919 pFD->Family = InStream->readShort();
920 pFD->CharSet = InStream->readShort();
921 pFD->Pitch = InStream->readShort();
924 else if ( nPropId == BASEPROPERTY_FONT_SIZE )
926 if ( nVersion < 2 )
928 if ( !pFD )
930 pFD = new css::awt::FontDescriptor;
931 if ( maData.find(BASEPROPERTY_FONTDESCRIPTOR) != maData.end() ) // due to defaults...
932 maData[BASEPROPERTY_FONTDESCRIPTOR] >>= *pFD;
934 pFD->Width = static_cast<sal_Int16>(InStream->readLong());
935 pFD->Height = static_cast<sal_Int16>(InStream->readLong());
936 InStream->readShort(); // ignore css::awt::FontWidth - it was
937 // misspelled and is no longer needed
938 pFD->CharacterWidth = css::awt::FontWidth::DONTKNOW;
941 else if ( nPropId == BASEPROPERTY_FONT_ATTRIBS )
943 if ( nVersion < 2 )
945 if ( !pFD )
947 pFD = new css::awt::FontDescriptor;
948 if ( maData.find(BASEPROPERTY_FONTDESCRIPTOR) != maData.end() ) // due to defaults...
949 maData[BASEPROPERTY_FONTDESCRIPTOR] >>= *pFD;
951 pFD->Weight = vcl::unohelper::ConvertFontWeight(static_cast<FontWeight>(InStream->readShort()));
952 pFD->Slant = static_cast<css::awt::FontSlant>(InStream->readShort());
953 pFD->Underline = InStream->readShort();
954 pFD->Strikeout = InStream->readShort();
955 pFD->Orientation = static_cast<float>(static_cast<double>(InStream->readShort())) / 10;
956 pFD->Kerning = InStream->readBoolean() != 0;
957 pFD->WordLineMode = InStream->readBoolean() != 0;
960 else
962 OSL_FAIL( "read: unknown Property!" );
966 else // bVoid
968 if ( nPropId == BASEPROPERTY_FONTDESCRIPTOR )
970 EmptyFontDescriptor aFD;
971 aValue <<= aFD;
975 if ( maData.find( nPropId ) != maData.end() )
977 aProps.getArray()[i] = GetPropertyName( nPropId );
978 aValues.getArray()[i] = aValue;
980 else
982 bInvalidEntries = true;
985 // Skip rest of input if there is more data in stream than this version can handle
986 xMark->jumpToMark( nPropDataBeginMark );
987 InStream->skipBytes( nPropDataLen );
988 xMark->deleteMark(nPropDataBeginMark);
990 if ( bInvalidEntries )
992 for ( i = 0; i < static_cast<sal_uInt32>(aProps.getLength()); i++ )
994 if ( aProps.getConstArray()[i].isEmpty() )
996 ::comphelper::removeElementAt( aProps, i );
997 ::comphelper::removeElementAt( aValues, i );
998 i--;
1005 setPropertyValues( aProps, aValues );
1007 catch ( const Exception& )
1009 DBG_UNHANDLED_EXCEPTION("toolkit.controls");
1012 if ( pFD )
1014 css::uno::Any aValue;
1015 aValue <<= *pFD;
1016 setPropertyValue( GetPropertyName( BASEPROPERTY_FONTDESCRIPTOR ), aValue );
1017 delete pFD;
1022 // css::lang::XServiceInfo
1023 OUString UnoControlModel::getImplementationName( )
1025 OSL_FAIL( "This method should be overridden!" );
1026 return OUString();
1030 sal_Bool UnoControlModel::supportsService( const OUString& rServiceName )
1032 return cppu::supportsService(this, rServiceName);
1035 css::uno::Sequence< OUString > UnoControlModel::getSupportedServiceNames( )
1037 OUString sName( "com.sun.star.awt.UnoControlModel" );
1038 return Sequence< OUString >( &sName, 1 );
1041 sal_Bool UnoControlModel::convertFastPropertyValue( Any & rConvertedValue, Any & rOldValue, sal_Int32 nPropId, const Any& rValue )
1043 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
1045 bool bVoid = rValue.getValueType().getTypeClass() == css::uno::TypeClass_VOID;
1046 if ( bVoid )
1048 rConvertedValue.clear();
1050 else
1052 const css::uno::Type* pDestType = GetPropertyType( static_cast<sal_uInt16>(nPropId) );
1053 if ( pDestType->getTypeClass() == TypeClass_ANY )
1055 rConvertedValue = rValue;
1057 else
1059 if ( pDestType->equals( rValue.getValueType() ) )
1061 rConvertedValue = rValue;
1063 else
1065 bool bConverted = false;
1066 // 13.03.2001 - 84923 - frank.schoenheit@germany.sun.com
1068 switch (pDestType->getTypeClass())
1070 case TypeClass_DOUBLE:
1072 // try as double
1073 double nAsDouble = 0;
1074 bConverted = ( rValue >>= nAsDouble );
1075 if ( bConverted )
1076 rConvertedValue <<= nAsDouble;
1077 else
1078 { // try as integer
1079 sal_Int32 nAsInteger = 0;
1080 bConverted = ( rValue >>= nAsInteger );
1081 if ( bConverted )
1082 rConvertedValue <<= static_cast<double>(nAsInteger);
1085 break;
1086 case TypeClass_SHORT:
1088 sal_Int16 n;
1089 bConverted = ( rValue >>= n );
1090 if ( bConverted )
1091 rConvertedValue <<= n;
1093 break;
1094 case TypeClass_UNSIGNED_SHORT:
1096 sal_uInt16 n;
1097 bConverted = ( rValue >>= n );
1098 if ( bConverted )
1099 rConvertedValue <<= n;
1101 break;
1102 case TypeClass_LONG:
1104 sal_Int32 n;
1105 bConverted = ( rValue >>= n );
1106 if ( bConverted )
1107 rConvertedValue <<= n;
1109 break;
1110 case TypeClass_UNSIGNED_LONG:
1112 sal_uInt32 n;
1113 bConverted = ( rValue >>= n );
1114 if ( bConverted )
1115 rConvertedValue <<= n;
1117 break;
1118 case TypeClass_INTERFACE:
1120 if ( rValue.getValueType().getTypeClass() == TypeClass_INTERFACE )
1122 Reference< XInterface > xPure( rValue, UNO_QUERY );
1123 if ( xPure.is() )
1124 rConvertedValue = xPure->queryInterface( *pDestType );
1125 else
1126 rConvertedValue.setValue( nullptr, *pDestType );
1127 bConverted = true;
1130 break;
1131 case TypeClass_ENUM:
1133 sal_Int32 nValue = 0;
1134 bConverted = ( rValue >>= nValue );
1135 if ( bConverted )
1136 rConvertedValue = ::cppu::int2enum( nValue, *pDestType );
1138 break;
1139 default: ; // avoid compiler warning
1142 if (!bConverted)
1144 throw css::lang::IllegalArgumentException(
1145 "Unable to convert the given value for the property "
1146 + GetPropertyName( static_cast<sal_uInt16>(nPropId) )
1147 + ".\nExpected type: " + pDestType->getTypeName()
1148 + "\nFound type: " + rValue.getValueType().getTypeName(),
1149 static_cast< css::beans::XPropertySet* >(this),
1156 // the current value
1157 getFastPropertyValue( rOldValue, nPropId );
1158 return !CompareProperties( rConvertedValue, rOldValue );
1161 void UnoControlModel::setFastPropertyValue_NoBroadcast( sal_Int32 nPropId, const css::uno::Any& rValue )
1163 // Missing: the fake solo properties of the FontDescriptor
1165 ImplPropertyTable::const_iterator it = maData.find( nPropId );
1166 const css::uno::Any* pProp = it == maData.end() ? nullptr : &(it->second);
1167 ENSURE_OR_RETURN_VOID( pProp, "UnoControlModel::setFastPropertyValue_NoBroadcast: invalid property id!" );
1169 DBG_ASSERT( ( rValue.getValueType().getTypeClass() != css::uno::TypeClass_VOID ) || ( GetPropertyAttribs( static_cast<sal_uInt16>(nPropId) ) & css::beans::PropertyAttribute::MAYBEVOID ), "Property should not be VOID!" );
1170 maData[ nPropId ] = rValue;
1173 void UnoControlModel::getFastPropertyValue( css::uno::Any& rValue, sal_Int32 nPropId ) const
1175 ::osl::Guard< ::osl::Mutex > aGuard( const_cast<UnoControlModel*>(this)->GetMutex() );
1177 ImplPropertyTable::const_iterator it = maData.find( nPropId );
1178 const css::uno::Any* pProp = it == maData.end() ? nullptr : &(it->second);
1180 if ( pProp )
1181 rValue = *pProp;
1182 else if ( ( nPropId >= BASEPROPERTY_FONTDESCRIPTORPART_START ) && ( nPropId <= BASEPROPERTY_FONTDESCRIPTORPART_END ) )
1184 pProp = &( maData.find( BASEPROPERTY_FONTDESCRIPTOR )->second );
1185 css::awt::FontDescriptor aFD;
1186 (*pProp) >>= aFD;
1187 switch ( nPropId )
1189 case BASEPROPERTY_FONTDESCRIPTORPART_NAME: rValue <<= aFD.Name;
1190 break;
1191 case BASEPROPERTY_FONTDESCRIPTORPART_STYLENAME: rValue <<= aFD.StyleName;
1192 break;
1193 case BASEPROPERTY_FONTDESCRIPTORPART_FAMILY: rValue <<= aFD.Family;
1194 break;
1195 case BASEPROPERTY_FONTDESCRIPTORPART_CHARSET: rValue <<= aFD.CharSet;
1196 break;
1197 case BASEPROPERTY_FONTDESCRIPTORPART_HEIGHT: rValue <<= static_cast<float>(aFD.Height);
1198 break;
1199 case BASEPROPERTY_FONTDESCRIPTORPART_WEIGHT: rValue <<= aFD.Weight;
1200 break;
1201 case BASEPROPERTY_FONTDESCRIPTORPART_SLANT: rValue <<= static_cast<sal_Int16>(aFD.Slant);
1202 break;
1203 case BASEPROPERTY_FONTDESCRIPTORPART_UNDERLINE: rValue <<= aFD.Underline;
1204 break;
1205 case BASEPROPERTY_FONTDESCRIPTORPART_STRIKEOUT: rValue <<= aFD.Strikeout;
1206 break;
1207 case BASEPROPERTY_FONTDESCRIPTORPART_WIDTH: rValue <<= aFD.Width;
1208 break;
1209 case BASEPROPERTY_FONTDESCRIPTORPART_PITCH: rValue <<= aFD.Pitch;
1210 break;
1211 case BASEPROPERTY_FONTDESCRIPTORPART_CHARWIDTH: rValue <<= aFD.CharacterWidth;
1212 break;
1213 case BASEPROPERTY_FONTDESCRIPTORPART_ORIENTATION: rValue <<= aFD.Orientation;
1214 break;
1215 case BASEPROPERTY_FONTDESCRIPTORPART_KERNING: rValue <<= aFD.Kerning;
1216 break;
1217 case BASEPROPERTY_FONTDESCRIPTORPART_WORDLINEMODE: rValue <<= aFD.WordLineMode;
1218 break;
1219 case BASEPROPERTY_FONTDESCRIPTORPART_TYPE: rValue <<= aFD.Type;
1220 break;
1221 default: OSL_FAIL( "FontProperty?!" );
1224 else
1226 OSL_FAIL( "getFastPropertyValue - invalid Property!" );
1230 // css::beans::XPropertySet
1231 void UnoControlModel::setPropertyValue( const OUString& rPropertyName, const css::uno::Any& rValue )
1233 sal_Int32 nPropId = 0;
1235 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
1236 nPropId = static_cast<sal_Int32>(GetPropertyId( rPropertyName ));
1237 DBG_ASSERT( nPropId, "Invalid ID in UnoControlModel::setPropertyValue" );
1239 if( !nPropId )
1240 throw css::beans::UnknownPropertyException();
1242 setFastPropertyValue( nPropId, rValue );
1246 // css::beans::XFastPropertySet
1247 void UnoControlModel::setFastPropertyValue( sal_Int32 nPropId, const css::uno::Any& rValue )
1249 if ( ( nPropId >= BASEPROPERTY_FONTDESCRIPTORPART_START ) && ( nPropId <= BASEPROPERTY_FONTDESCRIPTORPART_END ) )
1251 ::osl::ClearableMutexGuard aGuard( GetMutex() );
1253 Any aOldSingleValue;
1254 getFastPropertyValue( aOldSingleValue, BASEPROPERTY_FONTDESCRIPTORPART_START );
1256 css::uno::Any* pProp = &maData[ BASEPROPERTY_FONTDESCRIPTOR ];
1257 FontDescriptor aOldFontDescriptor;
1258 (*pProp) >>= aOldFontDescriptor;
1260 FontDescriptor aNewFontDescriptor( aOldFontDescriptor );
1261 lcl_ImplMergeFontProperty( aNewFontDescriptor, static_cast<sal_uInt16>(nPropId), rValue );
1263 Any aNewValue;
1264 aNewValue <<= aNewFontDescriptor;
1265 sal_Int32 nDescriptorId( BASEPROPERTY_FONTDESCRIPTOR );
1266 nDescriptorId = BASEPROPERTY_FONTDESCRIPTOR;
1268 // also, we need fire a propertyChange event for the single property, since with
1269 // the above line, only an event for the FontDescriptor property will be fired
1270 Any aNewSingleValue;
1271 getFastPropertyValue( aNewSingleValue, BASEPROPERTY_FONTDESCRIPTORPART_START );
1273 aGuard.clear();
1274 setFastPropertyValues( 1, &nDescriptorId, &aNewValue, 1 );
1275 fire( &nPropId, &aNewSingleValue, &aOldSingleValue, 1, false );
1277 else
1278 setFastPropertyValues( 1, &nPropId, &rValue, 1 );
1281 // css::beans::XMultiPropertySet
1282 css::uno::Reference< css::beans::XPropertySetInfo > UnoControlModel::getPropertySetInfo( )
1284 OSL_FAIL( "UnoControlModel::getPropertySetInfo() not possible!" );
1285 return css::uno::Reference< css::beans::XPropertySetInfo >();
1288 void UnoControlModel::setPropertyValues( const css::uno::Sequence< OUString >& rPropertyNames, const css::uno::Sequence< css::uno::Any >& Values )
1290 ::osl::ClearableMutexGuard aGuard( GetMutex() );
1292 sal_Int32 nProps = rPropertyNames.getLength();
1294 // sal_Int32* pHandles = new sal_Int32[nProps];
1295 // don't do this - it leaks in case of an exception
1296 Sequence< sal_Int32 > aHandles( nProps );
1297 sal_Int32* pHandles = aHandles.getArray();
1299 // may need to change the order in the sequence, for this we need a non-const value sequence
1300 uno::Sequence< uno::Any > aValues( Values );
1301 uno::Any* pValues = aValues.getArray();
1303 sal_Int32 nValidHandles = getInfoHelper().fillHandles( pHandles, rPropertyNames );
1305 if ( nValidHandles )
1307 // if somebody sets properties which are single aspects of a font descriptor,
1308 // remove them, and build a font descriptor instead
1309 std::unique_ptr< awt::FontDescriptor > pFD;
1310 for ( sal_Int32 n = 0; n < nProps; ++n )
1312 if ( ( pHandles[n] >= BASEPROPERTY_FONTDESCRIPTORPART_START ) && ( pHandles[n] <= BASEPROPERTY_FONTDESCRIPTORPART_END ) )
1314 if ( !pFD.get() )
1316 css::uno::Any* pProp = &maData[ BASEPROPERTY_FONTDESCRIPTOR ];
1317 pFD.reset( new awt::FontDescriptor );
1318 (*pProp) >>= *pFD;
1320 lcl_ImplMergeFontProperty( *pFD, static_cast<sal_uInt16>(pHandles[n]), pValues[n] );
1321 pHandles[n] = -1;
1322 nValidHandles--;
1326 if ( nValidHandles )
1328 ImplNormalizePropertySequence( nProps, pHandles, pValues, &nValidHandles );
1329 aGuard.clear();
1330 // clear our guard before calling into setFastPropertyValues - this method
1331 // will implicitly call property listeners, and this should not happen with
1332 // our mutex locked
1333 // #i23451#
1334 setFastPropertyValues( nProps, pHandles, pValues, nValidHandles );
1336 else
1337 aGuard.clear();
1338 // same as a few lines above
1340 // Don't merge FD property into array, as it is sorted
1341 if ( pFD.get() )
1343 css::uno::Any aValue;
1344 aValue <<= *pFD;
1345 sal_Int32 nHandle = BASEPROPERTY_FONTDESCRIPTOR;
1346 setFastPropertyValues( 1, &nHandle, &aValue, 1 );
1352 void UnoControlModel::ImplNormalizePropertySequence( const sal_Int32, sal_Int32*,
1353 uno::Any*, sal_Int32* ) const
1355 // nothing to do here
1358 void UnoControlModel::ImplEnsureHandleOrder( const sal_Int32 _nCount, sal_Int32* _pHandles,
1359 uno::Any* _pValues, sal_Int32 _nFirstHandle, sal_Int32 _nSecondHandle )
1361 for ( sal_Int32 i=0; i < _nCount; ++_pHandles, ++_pValues, ++i )
1363 if ( _nSecondHandle == *_pHandles )
1365 sal_Int32* pLaterHandles = _pHandles + 1;
1366 uno::Any* pLaterValues = _pValues + 1;
1367 for ( sal_Int32 j = i + 1; j < _nCount; ++j, ++pLaterHandles, ++pLaterValues )
1369 if ( _nFirstHandle == *pLaterHandles )
1371 // indeed it is -> exchange the both places in the sequences
1372 sal_Int32 nHandle( *_pHandles );
1373 *_pHandles = *pLaterHandles;
1374 *pLaterHandles = nHandle;
1376 uno::Any aValue( *_pValues );
1377 *_pValues = *pLaterValues;
1378 *pLaterValues = aValue;
1380 break;
1381 // this will leave the inner loop, and continue with the outer loop.
1382 // Note that this means we will encounter the _nSecondHandle handle, again, once we reached
1383 // (in the outer loop) the place where we just put it.
1390 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */