Avoid potential negative array index access to cached text.
[LibreOffice.git] / toolkit / source / controls / unocontrolmodel.cxx
blob0868fc2f6a26c405fae8bd770b3e932c356931b9
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/FontSlant.hpp>
25 #include <com/sun/star/awt/MouseWheelBehavior.hpp>
26 #include <com/sun/star/graphic/XGraphic.hpp>
27 #include <com/sun/star/awt/XDevice.hpp>
28 #include <com/sun/star/text/WritingMode2.hpp>
29 #include <com/sun/star/io/XMarkableStream.hpp>
30 #include <com/sun/star/i18n/Currency2.hpp>
31 #include <com/sun/star/util/Date.hpp>
32 #include <com/sun/star/util/Time.hpp>
33 #include <toolkit/controls/unocontrolmodel.hxx>
34 #include <cppuhelper/supportsservice.hxx>
35 #include <sal/log.hxx>
36 #include <comphelper/diagnose_ex.hxx>
37 #include <tools/debug.hxx>
38 #include <tools/long.hxx>
39 #include <helper/property.hxx>
40 #include <toolkit/helper/emptyfontdescriptor.hxx>
41 #include <unotools/localedatawrapper.hxx>
42 #include <unotools/configmgr.hxx>
43 #include <comphelper/sequence.hxx>
44 #include <comphelper/extract.hxx>
45 #include <comphelper/servicehelper.hxx>
46 #include <vcl/unohelp.hxx>
48 #include <memory>
49 #include <o3tl/sorted_vector.hxx>
51 using namespace ::com::sun::star;
52 using namespace ::com::sun::star::uno;
53 using namespace ::com::sun::star::lang;
54 using namespace ::com::sun::star::i18n;
55 using ::com::sun::star::awt::FontDescriptor;
58 #define UNOCONTROL_STREAMVERSION short(2)
60 static void lcl_ImplMergeFontProperty( FontDescriptor& rFD, sal_uInt16 nPropId, const Any& rValue )
62 // some props are defined with other types than the matching FontDescriptor members have
63 // (e.g. FontWidth, FontSlant)
64 // 78474 - 09/19/2000 - FS
65 float nExtractFloat = 0;
66 sal_Int16 nExtractShort = 0;
68 switch ( nPropId )
70 case BASEPROPERTY_FONTDESCRIPTORPART_NAME: rValue >>= rFD.Name;
71 break;
72 case BASEPROPERTY_FONTDESCRIPTORPART_STYLENAME: rValue >>= rFD.StyleName;
73 break;
74 case BASEPROPERTY_FONTDESCRIPTORPART_FAMILY: rValue >>= rFD.Family;
75 break;
76 case BASEPROPERTY_FONTDESCRIPTORPART_CHARSET: rValue >>= rFD.CharSet;
77 break;
78 case BASEPROPERTY_FONTDESCRIPTORPART_HEIGHT: rValue >>= nExtractFloat; rFD.Height = static_cast<sal_Int16>(nExtractFloat);
79 break;
80 case BASEPROPERTY_FONTDESCRIPTORPART_WEIGHT: rValue >>= rFD.Weight;
81 break;
82 case BASEPROPERTY_FONTDESCRIPTORPART_SLANT: if ( rValue >>= nExtractShort )
83 rFD.Slant = static_cast<css::awt::FontSlant>(nExtractShort);
84 else
85 rValue >>= rFD.Slant;
86 break;
87 case BASEPROPERTY_FONTDESCRIPTORPART_UNDERLINE: rValue >>= rFD.Underline;
88 break;
89 case BASEPROPERTY_FONTDESCRIPTORPART_STRIKEOUT: rValue >>= rFD.Strikeout;
90 break;
91 case BASEPROPERTY_FONTDESCRIPTORPART_WIDTH: rValue >>= rFD.Width;
92 break;
93 case BASEPROPERTY_FONTDESCRIPTORPART_PITCH: rValue >>= rFD.Pitch;
94 break;
95 case BASEPROPERTY_FONTDESCRIPTORPART_CHARWIDTH: rValue >>= rFD.CharacterWidth;
96 break;
97 case BASEPROPERTY_FONTDESCRIPTORPART_ORIENTATION: rValue >>= rFD.Orientation;
98 break;
99 case BASEPROPERTY_FONTDESCRIPTORPART_KERNING: rValue >>= rFD.Kerning;
100 break;
101 case BASEPROPERTY_FONTDESCRIPTORPART_WORDLINEMODE: rValue >>= rFD.WordLineMode;
102 break;
103 case BASEPROPERTY_FONTDESCRIPTORPART_TYPE: rValue >>= rFD.Type;
104 break;
105 default: OSL_FAIL( "FontProperty?!" );
111 UnoControlModel::UnoControlModel( const Reference< XComponentContext >& rxContext )
112 :UnoControlModel_Base()
113 ,maDisposeListeners( *this )
114 ,m_xContext( rxContext )
116 // Insert properties from Model into table,
117 // only existing properties are valid, even if they're VOID
120 UnoControlModel::UnoControlModel( const UnoControlModel& rModel )
121 : UnoControlModel_Base(), OPropertySetHelper()
122 , maData( rModel.maData )
123 , maDisposeListeners( *this )
124 , m_xContext( rModel.m_xContext )
128 css::uno::Sequence<sal_Int32> UnoControlModel::ImplGetPropertyIds() const
130 sal_uInt32 nIDs = maData.size();
131 css::uno::Sequence<sal_Int32> aIDs( nIDs );
132 sal_Int32* pIDs = aIDs.getArray();
133 sal_uInt32 n = 0;
134 for ( const auto& rData : maData )
135 pIDs[n++] = rData.first;
136 return aIDs;
139 bool UnoControlModel::ImplHasProperty( sal_uInt16 nPropId ) const
141 if ( ( nPropId >= BASEPROPERTY_FONTDESCRIPTORPART_START ) && ( nPropId <= BASEPROPERTY_FONTDESCRIPTORPART_END ) )
142 nPropId = BASEPROPERTY_FONTDESCRIPTOR;
144 return maData.find( nPropId ) != maData.end();
147 css::uno::Any UnoControlModel::ImplGetDefaultValue( sal_uInt16 nPropId ) const
149 css::uno::Any aDefault;
151 if (
152 (nPropId == BASEPROPERTY_FONTDESCRIPTOR) ||
154 (nPropId >= BASEPROPERTY_FONTDESCRIPTORPART_START) &&
155 (nPropId <= BASEPROPERTY_FONTDESCRIPTORPART_END)
159 EmptyFontDescriptor aFD;
160 switch ( nPropId )
162 case BASEPROPERTY_FONTDESCRIPTOR: aDefault <<= aFD; break;
163 case BASEPROPERTY_FONTDESCRIPTORPART_NAME: aDefault <<= aFD.Name; break;
164 case BASEPROPERTY_FONTDESCRIPTORPART_STYLENAME: aDefault <<= aFD.StyleName; break;
165 case BASEPROPERTY_FONTDESCRIPTORPART_FAMILY: aDefault <<= aFD.Family; break;
166 case BASEPROPERTY_FONTDESCRIPTORPART_CHARSET: aDefault <<= aFD.CharSet; break;
167 case BASEPROPERTY_FONTDESCRIPTORPART_HEIGHT: aDefault <<= static_cast<float>(aFD.Height); break;
168 case BASEPROPERTY_FONTDESCRIPTORPART_WEIGHT: aDefault <<= aFD.Weight; break;
169 case BASEPROPERTY_FONTDESCRIPTORPART_SLANT: aDefault <<= static_cast<sal_Int16>(aFD.Slant); break;
170 case BASEPROPERTY_FONTDESCRIPTORPART_UNDERLINE: aDefault <<= aFD.Underline; break;
171 case BASEPROPERTY_FONTDESCRIPTORPART_STRIKEOUT: aDefault <<= aFD.Strikeout; break;
172 case BASEPROPERTY_FONTDESCRIPTORPART_WIDTH: aDefault <<= aFD.Width; break;
173 case BASEPROPERTY_FONTDESCRIPTORPART_PITCH: aDefault <<= aFD.Pitch; break;
174 case BASEPROPERTY_FONTDESCRIPTORPART_CHARWIDTH: aDefault <<= aFD.CharacterWidth; break;
175 case BASEPROPERTY_FONTDESCRIPTORPART_ORIENTATION: aDefault <<= aFD.Orientation; break;
176 case BASEPROPERTY_FONTDESCRIPTORPART_KERNING: aDefault <<= aFD.Kerning; break;
177 case BASEPROPERTY_FONTDESCRIPTORPART_WORDLINEMODE: aDefault <<= aFD.WordLineMode; break;
178 case BASEPROPERTY_FONTDESCRIPTORPART_TYPE: aDefault <<= aFD.Type; break;
179 default: OSL_FAIL( "FontProperty?!" );
182 else
184 switch ( nPropId )
186 case BASEPROPERTY_GRAPHIC:
187 aDefault <<= Reference< graphic::XGraphic >();
188 break;
190 case BASEPROPERTY_REFERENCE_DEVICE:
191 aDefault <<= Reference< awt::XDevice >();
192 break;
194 case BASEPROPERTY_ITEM_SEPARATOR_POS:
195 case BASEPROPERTY_VERTICALALIGN:
196 case BASEPROPERTY_BORDERCOLOR:
197 case BASEPROPERTY_SYMBOL_COLOR:
198 case BASEPROPERTY_TABSTOP:
199 case BASEPROPERTY_TEXTCOLOR:
200 case BASEPROPERTY_TEXTLINECOLOR:
201 case BASEPROPERTY_DATE:
202 case BASEPROPERTY_DATESHOWCENTURY:
203 case BASEPROPERTY_TIME:
204 case BASEPROPERTY_VALUE_DOUBLE:
205 case BASEPROPERTY_PROGRESSVALUE:
206 case BASEPROPERTY_SCROLLVALUE:
207 case BASEPROPERTY_VISIBLESIZE:
208 case BASEPROPERTY_BACKGROUNDCOLOR:
209 case BASEPROPERTY_FILLCOLOR:
210 case BASEPROPERTY_HIGHLIGHT_COLOR:
211 case BASEPROPERTY_HIGHLIGHT_TEXT_COLOR: break; // Void
213 case BASEPROPERTY_FONTRELIEF:
214 case BASEPROPERTY_FONTEMPHASISMARK:
215 case BASEPROPERTY_MAXTEXTLEN:
216 case BASEPROPERTY_STATE:
217 case BASEPROPERTY_EXTDATEFORMAT:
218 case BASEPROPERTY_EXTTIMEFORMAT:
219 case BASEPROPERTY_ECHOCHAR: aDefault <<= sal_Int16(0); break;
220 case BASEPROPERTY_BORDER: aDefault <<= sal_Int16(1); break;
221 case BASEPROPERTY_DECIMALACCURACY: aDefault <<= sal_Int16(2); break;
222 case BASEPROPERTY_LINECOUNT: aDefault <<= sal_Int16(5); break;
223 case BASEPROPERTY_ALIGN: aDefault <<= sal_Int16(PROPERTY_ALIGN_LEFT); break;
224 case BASEPROPERTY_IMAGEALIGN: aDefault <<= sal_Int16(1) /*ImageAlign::Top*/; break;
225 case BASEPROPERTY_IMAGEPOSITION: aDefault <<= sal_Int16(12) /*ImagePosition::Centered*/; break;
226 case BASEPROPERTY_PUSHBUTTONTYPE: aDefault <<= sal_Int16(0) /*PushButtonType::STANDARD*/; break;
227 case BASEPROPERTY_MOUSE_WHEEL_BEHAVIOUR:aDefault <<= sal_Int16(awt::MouseWheelBehavior::SCROLL_FOCUS_ONLY); break;
229 case BASEPROPERTY_DATEMAX: aDefault <<= util::Date( 31, 12, 2200 ); break;
230 case BASEPROPERTY_DATEMIN: aDefault <<= util::Date( 1, 1, 1900 ); break;
231 case BASEPROPERTY_TIMEMAX: aDefault <<= util::Time(0, 0, 59, 23, false); break;
232 case BASEPROPERTY_TIMEMIN: aDefault <<= util::Time(); break;
233 case BASEPROPERTY_VALUEMAX_DOUBLE: aDefault <<= double(1000000); break;
234 case BASEPROPERTY_VALUEMIN_DOUBLE: aDefault <<= double(-1000000); break;
235 case BASEPROPERTY_VALUESTEP_DOUBLE: aDefault <<= double(1); break;
236 case BASEPROPERTY_PROGRESSVALUE_MAX: aDefault <<= sal_Int32(100); break;
237 case BASEPROPERTY_PROGRESSVALUE_MIN: aDefault <<= sal_Int32(0); break;
238 case BASEPROPERTY_SCROLLVALUE_MAX: aDefault <<= sal_Int32(100); break;
239 case BASEPROPERTY_SCROLLVALUE_MIN: aDefault <<= sal_Int32(0); break;
240 case BASEPROPERTY_LINEINCREMENT: aDefault <<= sal_Int32(1); break;
241 case BASEPROPERTY_BLOCKINCREMENT: aDefault <<= sal_Int32(10); break;
242 case BASEPROPERTY_ORIENTATION: aDefault <<= sal_Int32(0); break;
243 case BASEPROPERTY_SPINVALUE: aDefault <<= sal_Int32(0); break;
244 case BASEPROPERTY_SPININCREMENT: aDefault <<= sal_Int32(1); break;
245 case BASEPROPERTY_SPINVALUE_MIN: aDefault <<= sal_Int32(0); break;
246 case BASEPROPERTY_SPINVALUE_MAX: aDefault <<= sal_Int32(100); break;
247 case BASEPROPERTY_REPEAT_DELAY: aDefault <<= sal_Int32(50); break; // 50 milliseconds
248 case BASEPROPERTY_DEFAULTCONTROL: aDefault <<= const_cast<UnoControlModel*>(this)->getServiceName(); break;
250 case BASEPROPERTY_AUTOHSCROLL:
251 case BASEPROPERTY_AUTOVSCROLL:
252 case BASEPROPERTY_MOVEABLE:
253 case BASEPROPERTY_CLOSEABLE:
254 case BASEPROPERTY_SIZEABLE:
255 case BASEPROPERTY_HSCROLL:
256 case BASEPROPERTY_DEFAULTBUTTON:
257 case BASEPROPERTY_MULTILINE:
258 case BASEPROPERTY_MULTISELECTION:
259 case BASEPROPERTY_TRISTATE:
260 case BASEPROPERTY_DROPDOWN:
261 case BASEPROPERTY_SPIN:
262 case BASEPROPERTY_READONLY:
263 case BASEPROPERTY_VSCROLL:
264 case BASEPROPERTY_NUMSHOWTHOUSANDSEP:
265 case BASEPROPERTY_STRICTFORMAT:
266 case BASEPROPERTY_REPEAT:
267 case BASEPROPERTY_PAINTTRANSPARENT:
268 case BASEPROPERTY_DESKTOP_AS_PARENT:
269 case BASEPROPERTY_HARDLINEBREAKS:
270 case BASEPROPERTY_NOLABEL: aDefault <<= false; break;
272 case BASEPROPERTY_MULTISELECTION_SIMPLEMODE:
273 case BASEPROPERTY_HIDEINACTIVESELECTION:
274 case BASEPROPERTY_ENFORCE_FORMAT:
275 case BASEPROPERTY_AUTOCOMPLETE:
276 case BASEPROPERTY_SCALEIMAGE:
277 case BASEPROPERTY_ENABLED:
278 case BASEPROPERTY_PRINTABLE:
279 case BASEPROPERTY_ENABLEVISIBLE:
280 case BASEPROPERTY_DECORATION: aDefault <<= true; break;
282 case BASEPROPERTY_GROUPNAME:
283 case BASEPROPERTY_HELPTEXT:
284 case BASEPROPERTY_HELPURL:
285 case BASEPROPERTY_IMAGEURL:
286 case BASEPROPERTY_DIALOGSOURCEURL:
287 case BASEPROPERTY_EDITMASK:
288 case BASEPROPERTY_LITERALMASK:
289 case BASEPROPERTY_LABEL:
290 case BASEPROPERTY_TITLE:
291 case BASEPROPERTY_TEXT: aDefault <<= OUString(); break;
293 case BASEPROPERTY_WRITING_MODE:
294 case BASEPROPERTY_CONTEXT_WRITING_MODE:
295 aDefault <<= text::WritingMode2::CONTEXT;
296 break;
298 case BASEPROPERTY_STRINGITEMLIST:
300 css::uno::Sequence< OUString> aStringSeq;
301 aDefault <<= aStringSeq;
304 break;
305 case BASEPROPERTY_TYPEDITEMLIST:
307 css::uno::Sequence< css::uno::Any > aAnySeq;
308 aDefault <<= aAnySeq;
311 break;
312 case BASEPROPERTY_SELECTEDITEMS:
314 css::uno::Sequence<sal_Int16> aINT16Seq;
315 aDefault <<= aINT16Seq;
317 break;
318 case BASEPROPERTY_CURRENCYSYMBOL:
320 OUString sDefaultCurrency(
321 utl::ConfigManager::getDefaultCurrency() );
323 // extract the bank symbol
324 sal_Int32 nSepPos = sDefaultCurrency.indexOf( '-' );
325 OUString sBankSymbol;
326 if ( nSepPos >= 0 )
328 sBankSymbol = sDefaultCurrency.copy( 0, nSepPos );
329 sDefaultCurrency = sDefaultCurrency.copy( nSepPos + 1 );
332 // the remaining is the locale
333 LocaleDataWrapper aLocaleInfo( m_xContext, LanguageTag(sDefaultCurrency) );
334 if ( sBankSymbol.isEmpty() )
335 sBankSymbol = aLocaleInfo.getCurrBankSymbol();
337 // look for the currency entry (for this language) which has the given bank symbol
338 const Sequence< Currency2 > aAllCurrencies = aLocaleInfo.getAllCurrencies();
340 OUString sCurrencySymbol = aLocaleInfo.getCurrSymbol();
341 if ( sBankSymbol.isEmpty() )
343 DBG_ASSERT( aAllCurrencies.hasElements(), "UnoControlModel::ImplGetDefaultValue: no currencies at all!" );
344 if ( aAllCurrencies.hasElements() )
346 sBankSymbol = aAllCurrencies[0].BankSymbol;
347 sCurrencySymbol = aAllCurrencies[0].Symbol;
351 if ( !sBankSymbol.isEmpty() )
353 bool bLegacy = false;
354 bool bFound = false;
355 for ( const Currency2& rCurrency : aAllCurrencies )
356 if ( rCurrency.BankSymbol == sBankSymbol )
358 sCurrencySymbol = rCurrency.Symbol;
359 if ( rCurrency.LegacyOnly )
360 bLegacy = true;
361 else
363 bFound = true;
364 break;
367 DBG_ASSERT( bLegacy || bFound, "UnoControlModel::ImplGetDefaultValue: did not find the given bank symbol!" );
370 aDefault <<= sCurrencySymbol;
372 break;
374 default: OSL_FAIL( "ImplGetDefaultValue - unknown Property" );
378 return aDefault;
381 void UnoControlModel::ImplRegisterProperty( sal_uInt16 nPropId, const css::uno::Any& rDefault )
383 maData[ nPropId ] = rDefault;
386 void UnoControlModel::ImplRegisterProperty( sal_uInt16 nPropId )
388 ImplRegisterProperty( nPropId, ImplGetDefaultValue( nPropId ) );
390 if ( nPropId == BASEPROPERTY_FONTDESCRIPTOR )
392 // some properties are not included in the FontDescriptor, but every time
393 // when we have a FontDescriptor we want to have these properties too.
394 // => Easier to register the here, instead everywhere where I register the FontDescriptor...
396 ImplRegisterProperty( BASEPROPERTY_TEXTCOLOR );
397 ImplRegisterProperty( BASEPROPERTY_TEXTLINECOLOR );
398 ImplRegisterProperty( BASEPROPERTY_FONTRELIEF );
399 ImplRegisterProperty( BASEPROPERTY_FONTEMPHASISMARK );
403 void UnoControlModel::ImplRegisterProperties( const std::vector< sal_uInt16 > &rIds )
405 for (const auto& rId : rIds)
407 if( !ImplHasProperty( rId ) )
408 ImplRegisterProperty( rId, ImplGetDefaultValue( rId ) );
412 // css::uno::XInterface
413 css::uno::Any UnoControlModel::queryAggregation( const css::uno::Type & rType )
415 Any aRet = UnoControlModel_Base::queryAggregation( rType );
416 if ( !aRet.hasValue() )
417 aRet = ::comphelper::OPropertySetHelper::queryInterface( rType );
418 return aRet;
421 // XInterface
422 IMPLEMENT_FORWARD_REFCOUNT( UnoControlModel, UnoControlModel_Base )
424 // css::lang::XTypeProvider
425 IMPLEMENT_FORWARD_XTYPEPROVIDER2( UnoControlModel, UnoControlModel_Base, ::comphelper::OPropertySetHelper )
428 uno::Reference< util::XCloneable > UnoControlModel::createClone()
430 rtl::Reference<UnoControlModel> pClone = Clone();
431 return pClone;
434 // css::lang::XComponent
435 void UnoControlModel::dispose( )
437 std::unique_lock aGuard( m_aMutex );
439 css::lang::EventObject aEvt;
440 aEvt.Source = static_cast<css::uno::XAggregation*>(static_cast<cppu::OWeakAggObject*>(this));
441 maDisposeListeners.disposeAndClear( aGuard, aEvt );
443 // let the property set helper notify our property listeners
444 OPropertySetHelper::disposing(aGuard);
447 void UnoControlModel::addEventListener( const css::uno::Reference< css::lang::XEventListener >& rxListener )
449 std::unique_lock aGuard( m_aMutex );
451 maDisposeListeners.addInterface( rxListener );
454 void UnoControlModel::removeEventListener( const css::uno::Reference< css::lang::XEventListener >& rxListener )
456 std::unique_lock aGuard( m_aMutex );
458 maDisposeListeners.removeInterface( rxListener );
462 // css::beans::XPropertyState
463 css::beans::PropertyState UnoControlModel::getPropertyState( const OUString& PropertyName )
465 std::unique_lock aGuard( m_aMutex );
466 return getPropertyStateImpl(aGuard, PropertyName);
469 css::beans::PropertyState UnoControlModel::getPropertyStateImpl( std::unique_lock<std::mutex>& rGuard, const OUString& PropertyName )
471 sal_uInt16 nPropId = GetPropertyId( PropertyName );
473 css::uno::Any aValue = getPropertyValueImpl( rGuard, PropertyName );
474 css::uno::Any aDefault = ImplGetDefaultValue( nPropId );
476 return CompareProperties( aValue, aDefault ) ? css::beans::PropertyState_DEFAULT_VALUE : css::beans::PropertyState_DIRECT_VALUE;
479 css::uno::Sequence< css::beans::PropertyState > UnoControlModel::getPropertyStates( const css::uno::Sequence< OUString >& PropertyNames )
481 std::unique_lock aGuard( m_aMutex );
483 sal_Int32 nNames = PropertyNames.getLength();
485 css::uno::Sequence< css::beans::PropertyState > aStates( nNames );
487 std::transform(PropertyNames.begin(), PropertyNames.end(), aStates.getArray(),
488 [this, &aGuard](const OUString& rName) -> css::beans::PropertyState
489 { return getPropertyStateImpl(aGuard, rName); });
491 return aStates;
494 void UnoControlModel::setPropertyToDefault( const OUString& PropertyName )
496 Any aDefaultValue;
498 std::unique_lock aGuard( m_aMutex );
499 aDefaultValue = ImplGetDefaultValue( GetPropertyId( PropertyName ) );
501 setPropertyValue( PropertyName, aDefaultValue );
504 css::uno::Any UnoControlModel::getPropertyDefault( const OUString& rPropertyName )
506 std::unique_lock aGuard( m_aMutex );
508 return ImplGetDefaultValue( GetPropertyId( rPropertyName ) );
512 // css::io::XPersistObjec
513 OUString UnoControlModel::getServiceName( )
515 OSL_FAIL( "ServiceName of UnoControlModel ?!" );
516 return OUString();
519 void UnoControlModel::write( const css::uno::Reference< css::io::XObjectOutputStream >& OutStream )
521 std::unique_lock aGuard( m_aMutex );
523 css::uno::Reference< css::io::XMarkableStream > xMark( OutStream, css::uno::UNO_QUERY );
524 DBG_ASSERT( xMark.is(), "write: no css::io::XMarkableStream!" );
526 OutStream->writeShort( UNOCONTROL_STREAMVERSION );
528 o3tl::sorted_vector<sal_uInt16> aProps;
530 for (const auto& rData : maData)
532 if ( ( ( GetPropertyAttribs( rData.first ) & css::beans::PropertyAttribute::TRANSIENT ) == 0 )
533 && ( getPropertyStateImpl( aGuard, GetPropertyName( rData.first ) ) != css::beans::PropertyState_DEFAULT_VALUE ) )
535 aProps.insert( rData.first );
539 sal_uInt32 nProps = aProps.size();
541 // Save FontProperty always in the old format (due to missing distinction
542 // between 5.0 and 5.1)
543 OutStream->writeLong( ( aProps.find( BASEPROPERTY_FONTDESCRIPTOR ) != aProps.end() ) ? ( nProps + 3 ) : nProps );
544 for ( const auto& rProp : aProps )
546 sal_Int32 nPropDataBeginMark = xMark->createMark();
547 OutStream->writeLong( 0 ); // DataLen
549 const css::uno::Any* pProp = &(maData[rProp]);
550 OutStream->writeShort( rProp );
552 bool bVoid = pProp->getValueType().getTypeClass() == css::uno::TypeClass_VOID;
554 OutStream->writeBoolean( bVoid );
556 if ( !bVoid )
558 const css::uno::Any& rValue = *pProp;
559 const css::uno::Type& rType = rValue.getValueType();
561 if ( rType == cppu::UnoType< bool >::get() )
563 bool b = false;
564 rValue >>= b;
565 OutStream->writeBoolean( b );
567 else if ( rType == ::cppu::UnoType< OUString >::get() )
569 OUString aUString;
570 rValue >>= aUString;
571 OutStream->writeUTF( aUString );
573 else if ( rType == ::cppu::UnoType< ::cppu::UnoUnsignedShortType >::get() )
575 sal_uInt16 n = 0;
576 rValue >>= n;
577 OutStream->writeShort( n );
579 else if ( rType == cppu::UnoType<sal_Int16>::get() )
581 sal_Int16 n = 0;
582 rValue >>= n;
583 OutStream->writeShort( n );
585 else if ( rType == cppu::UnoType<sal_uInt32>::get() )
587 sal_uInt32 n = 0;
588 rValue >>= n;
589 OutStream->writeLong( n );
591 else if ( rType == cppu::UnoType<sal_Int32>::get() )
593 sal_Int32 n = 0;
594 rValue >>= n;
595 OutStream->writeLong( n );
597 else if ( rType == cppu::UnoType<double>::get() )
599 double n = 0;
600 rValue >>= n;
601 OutStream->writeDouble( n );
603 else if ( rType == cppu::UnoType< css::awt::FontDescriptor >::get() )
605 css::awt::FontDescriptor aFD;
606 rValue >>= aFD;
607 OutStream->writeUTF( aFD.Name );
608 OutStream->writeShort( aFD.Height );
609 OutStream->writeShort( aFD.Width );
610 OutStream->writeUTF( aFD.StyleName );
611 OutStream->writeShort( aFD.Family );
612 OutStream->writeShort( aFD.CharSet );
613 OutStream->writeShort( aFD.Pitch );
614 OutStream->writeDouble( aFD.CharacterWidth );
615 OutStream->writeDouble( aFD.Weight );
616 OutStream->writeShort(
617 sal::static_int_cast< sal_Int16 >(aFD.Slant) );
618 OutStream->writeShort( aFD.Underline );
619 OutStream->writeShort( aFD.Strikeout );
620 OutStream->writeDouble( aFD.Orientation );
621 OutStream->writeBoolean( aFD.Kerning );
622 OutStream->writeBoolean( aFD.WordLineMode );
623 OutStream->writeShort( aFD.Type );
625 else if ( rType == cppu::UnoType<css::util::Date>::get() )
627 css::util::Date d;
628 rValue >>= d;
629 OutStream->writeLong(d.Day + 100 * d.Month + 10000 * d.Year);
630 // YYYYMMDD
632 else if ( rType == cppu::UnoType<css::util::Time>::get() )
634 css::util::Time t;
635 rValue >>= t;
636 OutStream->writeLong(
637 t.NanoSeconds / 1000000 + 100 * t.Seconds
638 + 10000 * t.Minutes + 1000000 * t.Hours); // HHMMSShh
640 else if ( rType == cppu::UnoType< css::uno::Sequence< OUString> >::get() )
642 css::uno::Sequence< OUString> aSeq;
643 rValue >>= aSeq;
644 tools::Long nEntries = aSeq.getLength();
645 OutStream->writeLong( nEntries );
646 for ( const auto& rVal : std::as_const(aSeq) )
647 OutStream->writeUTF( rVal );
649 else if ( rType == cppu::UnoType< cppu::UnoSequenceType<cppu::UnoUnsignedShortType> >::get() )
651 css::uno::Sequence<sal_uInt16> aSeq;
652 rValue >>= aSeq;
653 tools::Long nEntries = aSeq.getLength();
654 OutStream->writeLong( nEntries );
655 for ( const auto nVal : std::as_const(aSeq) )
656 OutStream->writeShort( nVal );
658 else if ( rType == cppu::UnoType< css::uno::Sequence<sal_Int16> >::get() )
660 css::uno::Sequence<sal_Int16> aSeq;
661 rValue >>= aSeq;
662 tools::Long nEntries = aSeq.getLength();
663 OutStream->writeLong( nEntries );
664 for ( const auto nVal : std::as_const(aSeq) )
665 OutStream->writeShort( nVal );
667 else if ( rType.getTypeClass() == TypeClass_ENUM )
669 sal_Int32 nAsInt = 0;
670 ::cppu::enum2int( nAsInt, rValue );
671 OutStream->writeLong( nAsInt );
673 #if OSL_DEBUG_LEVEL > 0
674 else
676 SAL_WARN( "toolkit", "UnoControlModel::write: don't know how to handle a property of type '"
677 << rType.getTypeName()
678 << "'.\n(Currently handling property '"
679 << GetPropertyName( rProp )
680 << "'.)");
682 #endif
685 sal_Int32 nPropDataLen = xMark->offsetToMark( nPropDataBeginMark );
686 xMark->jumpToMark( nPropDataBeginMark );
687 OutStream->writeLong( nPropDataLen );
688 xMark->jumpToFurthest();
689 xMark->deleteMark(nPropDataBeginMark);
692 if ( aProps.find( BASEPROPERTY_FONTDESCRIPTOR ) == aProps.end() )
693 return;
695 const css::uno::Any* pProp = &maData[ BASEPROPERTY_FONTDESCRIPTOR ];
696 // Until 5.0 export arrives, write old format...
697 css::awt::FontDescriptor aFD;
698 (*pProp) >>= aFD;
700 for ( sal_uInt16 n = BASEPROPERTY_FONT_TYPE; n <= BASEPROPERTY_FONT_ATTRIBS; n++ )
702 sal_Int32 nPropDataBeginMark = xMark->createMark();
703 OutStream->writeLong( 0 ); // DataLen
704 OutStream->writeShort( n ); // PropId
705 OutStream->writeBoolean( false ); // Void
707 if ( n == BASEPROPERTY_FONT_TYPE )
709 OutStream->writeUTF( aFD.Name );
710 OutStream->writeUTF( aFD.StyleName );
711 OutStream->writeShort( aFD.Family );
712 OutStream->writeShort( aFD.CharSet );
713 OutStream->writeShort( aFD.Pitch );
715 else if ( n == BASEPROPERTY_FONT_SIZE )
717 OutStream->writeLong( aFD.Width );
718 OutStream->writeLong( aFD.Height );
719 OutStream->writeShort(
720 sal::static_int_cast< sal_Int16 >(
721 vcl::unohelper::ConvertFontWidth(aFD.CharacterWidth)) );
723 else if ( n == BASEPROPERTY_FONT_ATTRIBS )
725 OutStream->writeShort(
726 sal::static_int_cast< sal_Int16 >(
727 vcl::unohelper::ConvertFontWeight(aFD.Weight)) );
728 OutStream->writeShort(
729 sal::static_int_cast< sal_Int16 >(aFD.Slant) );
730 OutStream->writeShort( aFD.Underline );
731 OutStream->writeShort( aFD.Strikeout );
732 OutStream->writeShort( static_cast<short>(aFD.Orientation * 10) );
733 OutStream->writeBoolean( aFD.Kerning );
734 OutStream->writeBoolean( aFD.WordLineMode );
736 else
738 OSL_FAIL( "Property?!" );
741 sal_Int32 nPropDataLen = xMark->offsetToMark( nPropDataBeginMark );
742 xMark->jumpToMark( nPropDataBeginMark );
743 OutStream->writeLong( nPropDataLen );
744 xMark->jumpToFurthest();
745 xMark->deleteMark(nPropDataBeginMark);
749 void UnoControlModel::read( const css::uno::Reference< css::io::XObjectInputStream >& InStream )
751 std::unique_lock aGuard( m_aMutex );
753 css::uno::Reference< css::io::XMarkableStream > xMark( InStream, css::uno::UNO_QUERY );
754 DBG_ASSERT( xMark.is(), "read: no css::io::XMarkableStream!" );
756 short nVersion = InStream->readShort();
757 sal_uInt32 nProps = static_cast<sal_uInt32>(InStream->readLong());
758 css::uno::Sequence< OUString> aProps( nProps );
759 css::uno::Sequence< css::uno::Any> aValues( nProps );
760 bool bInvalidEntries = false;
762 // Unfortunately, there's no mark for the whole block, thus only properties may be changed.
763 // No data for the model may be added following the properties
765 // Used for import of old parts in css::awt::FontDescriptor
766 std::unique_ptr<css::awt::FontDescriptor> pFD;
768 for ( sal_uInt32 i = 0; i < nProps; i++ )
770 sal_Int32 nPropDataBeginMark = xMark->createMark();
771 sal_Int32 nPropDataLen = InStream->readLong();
773 sal_uInt16 nPropId = static_cast<sal_uInt16>(InStream->readShort());
775 css::uno::Any aValue;
776 bool bIsVoid = InStream->readBoolean();
777 if ( !bIsVoid )
779 if ( maData.find( nPropId ) != maData.end() )
781 const css::uno::Type* pType = GetPropertyType( nPropId );
782 if ( *pType == cppu::UnoType<bool>::get() )
784 bool b = InStream->readBoolean();
785 aValue <<= b;
787 else if ( *pType == cppu::UnoType<OUString>::get() )
789 OUString aUTF = InStream->readUTF();
790 aValue <<= aUTF;
792 else if ( *pType == ::cppu::UnoType< ::cppu::UnoUnsignedShortType >::get() )
794 sal_uInt16 n = InStream->readShort();
795 aValue <<= n;
797 else if ( *pType == cppu::UnoType<sal_Int16>::get() )
799 sal_Int16 n = InStream->readShort();
800 aValue <<= n;
802 else if ( *pType == cppu::UnoType<sal_uInt32>::get() )
804 sal_uInt32 n = InStream->readLong();
805 aValue <<= n;
807 else if ( *pType == cppu::UnoType<sal_Int32>::get() )
809 sal_Int32 n = InStream->readLong();
810 aValue <<= n;
812 else if ( *pType == cppu::UnoType<double>::get() )
814 double n = InStream->readDouble();
815 aValue <<= n;
817 else if ( *pType == cppu::UnoType< css::awt::FontDescriptor >::get() )
819 css::awt::FontDescriptor aFD;
820 aFD.Name = InStream->readUTF();
821 aFD.Height = InStream->readShort();
822 aFD.Width = InStream->readShort();
823 aFD.StyleName = InStream->readUTF();
824 aFD.Family = InStream->readShort();
825 aFD.CharSet = InStream->readShort();
826 aFD.Pitch = InStream->readShort();
827 aFD.CharacterWidth = static_cast<float>(InStream->readDouble());
828 aFD.Weight = static_cast<float>(InStream->readDouble());
829 aFD.Slant = static_cast<css::awt::FontSlant>(InStream->readShort());
830 aFD.Underline = InStream->readShort();
831 aFD.Strikeout = InStream->readShort();
832 aFD.Orientation = static_cast<float>(InStream->readDouble());
833 aFD.Kerning = InStream->readBoolean() != 0;
834 aFD.WordLineMode = InStream->readBoolean() != 0;
835 aFD.Type = InStream->readShort();
836 aValue <<= aFD;
838 else if ( *pType == cppu::UnoType<css::util::Date>::get() )
840 sal_Int32 n = InStream->readLong(); // YYYYMMDD
841 aValue <<= css::util::Date(
842 n % 100, (n / 100) % 100, n / 10000);
844 else if ( *pType == cppu::UnoType<css::util::Time>::get() )
846 sal_Int32 n = InStream->readLong(); // HHMMSShh
847 aValue <<= css::util::Time(
848 (n % 100) * 1000000, (n / 100) % 100, (n / 10000) % 100,
849 n / 1000000, false);
851 else if ( *pType == cppu::UnoType< css::uno::Sequence< OUString> >::get() )
853 tools::Long nEntries = InStream->readLong();
854 css::uno::Sequence< OUString> aSeq( nEntries );
855 for ( tools::Long n = 0; n < nEntries; n++ )
856 aSeq.getArray()[n] = InStream->readUTF();
857 aValue <<= aSeq;
860 else if ( *pType == cppu::UnoType< cppu::UnoSequenceType<cppu::UnoUnsignedShortType> >::get() )
863 tools::Long nEntries = InStream->readLong();
864 css::uno::Sequence<sal_uInt16> aSeq( nEntries );
865 for ( tools::Long n = 0; n < nEntries; n++ )
866 aSeq.getArray()[n] = static_cast<sal_uInt16>(InStream->readShort());
867 aValue <<= aSeq;
869 else if ( *pType == cppu::UnoType< css::uno::Sequence<sal_Int16> >::get() )
871 tools::Long nEntries = InStream->readLong();
872 css::uno::Sequence<sal_Int16> aSeq( nEntries );
873 for ( tools::Long n = 0; n < nEntries; n++ )
874 aSeq.getArray()[n] = InStream->readShort();
875 aValue <<= aSeq;
877 else if ( pType->getTypeClass() == TypeClass_ENUM )
879 sal_Int32 nAsInt = InStream->readLong();
880 aValue = ::cppu::int2enum( nAsInt, *pType );
882 else
884 SAL_WARN( "toolkit", "UnoControlModel::read: don't know how to handle a property of type '"
885 << pType->getTypeName()
886 << "'.\n(Currently handling property '"
887 << GetPropertyName( nPropId )
888 << "'.)");
891 else
893 // Old trash from 5.0
894 if ( nPropId == BASEPROPERTY_FONT_TYPE )
896 // Redundant information for older versions
897 // is skipped by MarkableStream
898 if ( nVersion < 2 )
900 if ( !pFD )
902 pFD.reset(new css::awt::FontDescriptor);
903 auto it = maData.find( BASEPROPERTY_FONTDESCRIPTOR );
904 if ( it != maData.end() ) // due to defaults...
905 it->second >>= *pFD;
907 pFD->Name = InStream->readUTF();
908 pFD->StyleName = InStream->readUTF();
909 pFD->Family = InStream->readShort();
910 pFD->CharSet = InStream->readShort();
911 pFD->Pitch = InStream->readShort();
914 else if ( nPropId == BASEPROPERTY_FONT_SIZE )
916 if ( nVersion < 2 )
918 if ( !pFD )
920 pFD.reset(new css::awt::FontDescriptor);
921 auto it = maData.find(BASEPROPERTY_FONTDESCRIPTOR);
922 if ( it != maData.end() ) // due to defaults...
923 it->second >>= *pFD;
925 pFD->Width = static_cast<sal_Int16>(InStream->readLong());
926 pFD->Height = static_cast<sal_Int16>(InStream->readLong());
927 InStream->readShort(); // ignore css::awt::FontWidth - it was
928 // misspelled and is no longer needed
929 pFD->CharacterWidth = css::awt::FontWidth::DONTKNOW;
932 else if ( nPropId == BASEPROPERTY_FONT_ATTRIBS )
934 if ( nVersion < 2 )
936 if ( !pFD )
938 pFD.reset(new css::awt::FontDescriptor);
939 auto it = maData.find(BASEPROPERTY_FONTDESCRIPTOR);
940 if ( it != maData.end() ) // due to defaults...
941 it->second >>= *pFD;
943 pFD->Weight = vcl::unohelper::ConvertFontWeight(static_cast<FontWeight>(InStream->readShort()));
944 pFD->Slant = static_cast<css::awt::FontSlant>(InStream->readShort());
945 pFD->Underline = InStream->readShort();
946 pFD->Strikeout = InStream->readShort();
947 pFD->Orientation = static_cast<float>(static_cast<double>(InStream->readShort())) / 10;
948 pFD->Kerning = InStream->readBoolean() != 0;
949 pFD->WordLineMode = InStream->readBoolean() != 0;
952 else
954 OSL_FAIL( "read: unknown Property!" );
958 else // bVoid
960 if ( nPropId == BASEPROPERTY_FONTDESCRIPTOR )
962 EmptyFontDescriptor aFD;
963 aValue <<= aFD;
967 if ( maData.find( nPropId ) != maData.end() )
969 aProps.getArray()[i] = GetPropertyName( nPropId );
970 aValues.getArray()[i] = aValue;
972 else
974 bInvalidEntries = true;
977 // Skip rest of input if there is more data in stream than this version can handle
978 xMark->jumpToMark( nPropDataBeginMark );
979 InStream->skipBytes( nPropDataLen );
980 xMark->deleteMark(nPropDataBeginMark);
982 if ( bInvalidEntries )
984 for ( sal_Int32 i = 0; i < aProps.getLength(); i++ )
986 if ( aProps.getConstArray()[i].isEmpty() )
988 ::comphelper::removeElementAt( aProps, i );
989 ::comphelper::removeElementAt( aValues, i );
990 i--;
997 setPropertyValuesImpl( aGuard, aProps, aValues );
999 catch ( const Exception& )
1001 DBG_UNHANDLED_EXCEPTION("toolkit.controls");
1004 if ( pFD )
1006 css::uno::Any aValue;
1007 aValue <<= *pFD;
1008 setFastPropertyValueImpl( aGuard, BASEPROPERTY_FONTDESCRIPTOR, aValue );
1013 // css::lang::XServiceInfo
1014 OUString UnoControlModel::getImplementationName( )
1016 OSL_FAIL( "This method should be overridden!" );
1017 return OUString();
1021 sal_Bool UnoControlModel::supportsService( const OUString& rServiceName )
1023 return cppu::supportsService(this, rServiceName);
1026 css::uno::Sequence< OUString > UnoControlModel::getSupportedServiceNames( )
1028 return { "com.sun.star.awt.UnoControlModel" };
1031 bool UnoControlModel::convertFastPropertyValue( std::unique_lock<std::mutex>& rGuard, Any & rConvertedValue, Any & rOldValue, sal_Int32 nPropId, const Any& rValue )
1033 bool bVoid = rValue.getValueType().getTypeClass() == css::uno::TypeClass_VOID;
1034 if ( bVoid )
1036 rConvertedValue.clear();
1038 else
1040 const css::uno::Type* pDestType = GetPropertyType( static_cast<sal_uInt16>(nPropId) );
1041 if ( pDestType->getTypeClass() == TypeClass_ANY )
1043 rConvertedValue = rValue;
1045 else
1047 if ( pDestType->equals( rValue.getValueType() ) )
1049 rConvertedValue = rValue;
1051 else
1053 bool bConverted = false;
1054 // 13.03.2001 - 84923 - frank.schoenheit@germany.sun.com
1056 switch (pDestType->getTypeClass())
1058 case TypeClass_DOUBLE:
1060 // try as double
1061 double nAsDouble = 0;
1062 bConverted = ( rValue >>= nAsDouble );
1063 if ( bConverted )
1064 rConvertedValue <<= nAsDouble;
1065 else
1066 { // try as integer
1067 sal_Int32 nAsInteger = 0;
1068 bConverted = ( rValue >>= nAsInteger );
1069 if ( bConverted )
1070 rConvertedValue <<= static_cast<double>(nAsInteger);
1073 break;
1074 case TypeClass_SHORT:
1076 sal_Int16 n;
1077 bConverted = ( rValue >>= n );
1078 if ( bConverted )
1079 rConvertedValue <<= n;
1081 break;
1082 case TypeClass_UNSIGNED_SHORT:
1084 sal_uInt16 n;
1085 bConverted = ( rValue >>= n );
1086 if ( bConverted )
1087 rConvertedValue <<= n;
1089 break;
1090 case TypeClass_LONG:
1092 sal_Int32 n;
1093 bConverted = ( rValue >>= n );
1094 if ( bConverted )
1095 rConvertedValue <<= n;
1097 break;
1098 case TypeClass_UNSIGNED_LONG:
1100 sal_uInt32 n;
1101 bConverted = ( rValue >>= n );
1102 if ( bConverted )
1103 rConvertedValue <<= n;
1105 break;
1106 case TypeClass_INTERFACE:
1108 if ( rValue.getValueType().getTypeClass() == TypeClass_INTERFACE )
1110 Reference< XInterface > xPure( rValue, UNO_QUERY );
1111 if ( xPure.is() )
1112 rConvertedValue = xPure->queryInterface( *pDestType );
1113 else
1114 rConvertedValue.setValue( nullptr, *pDestType );
1115 bConverted = true;
1118 break;
1119 case TypeClass_ENUM:
1121 sal_Int32 nValue = 0;
1122 bConverted = ( rValue >>= nValue );
1123 if ( bConverted )
1124 rConvertedValue = ::cppu::int2enum( nValue, *pDestType );
1126 break;
1127 default: ; // avoid compiler warning
1130 if (!bConverted)
1132 throw css::lang::IllegalArgumentException(
1133 "Unable to convert the given value for the property "
1134 + GetPropertyName( static_cast<sal_uInt16>(nPropId) )
1135 + ".\nExpected type: " + pDestType->getTypeName()
1136 + "\nFound type: " + rValue.getValueType().getTypeName(),
1137 static_cast< css::beans::XPropertySet* >(this),
1144 // the current value
1145 getFastPropertyValue( rGuard, rOldValue, nPropId );
1146 return !CompareProperties( rConvertedValue, rOldValue );
1149 void UnoControlModel::setFastPropertyValue_NoBroadcast( std::unique_lock<std::mutex>& /*rGuard*/, sal_Int32 nPropId, const css::uno::Any& rValue )
1151 // Missing: the fake solo properties of the FontDescriptor
1153 ImplPropertyTable::const_iterator it = maData.find( nPropId );
1154 const css::uno::Any* pProp = it == maData.end() ? nullptr : &(it->second);
1155 ENSURE_OR_RETURN_VOID( pProp, "UnoControlModel::setFastPropertyValue_NoBroadcast: invalid property id!" );
1157 DBG_ASSERT( ( rValue.getValueType().getTypeClass() != css::uno::TypeClass_VOID ) || ( GetPropertyAttribs( static_cast<sal_uInt16>(nPropId) ) & css::beans::PropertyAttribute::MAYBEVOID ), "Property should not be VOID!" );
1158 maData[ nPropId ] = rValue;
1161 void UnoControlModel::getFastPropertyValue( std::unique_lock<std::mutex>& /*rGuard*/, css::uno::Any& rValue, sal_Int32 nPropId ) const
1163 ImplPropertyTable::const_iterator it = maData.find( nPropId );
1164 const css::uno::Any* pProp = it == maData.end() ? nullptr : &(it->second);
1166 if ( pProp )
1167 rValue = *pProp;
1168 else if ( ( nPropId >= BASEPROPERTY_FONTDESCRIPTORPART_START ) && ( nPropId <= BASEPROPERTY_FONTDESCRIPTORPART_END ) )
1170 const auto iter = maData.find( BASEPROPERTY_FONTDESCRIPTOR );
1171 assert(iter != maData.end());
1172 pProp = &(iter->second);
1173 css::awt::FontDescriptor aFD;
1174 (*pProp) >>= aFD;
1175 switch ( nPropId )
1177 case BASEPROPERTY_FONTDESCRIPTORPART_NAME: rValue <<= aFD.Name;
1178 break;
1179 case BASEPROPERTY_FONTDESCRIPTORPART_STYLENAME: rValue <<= aFD.StyleName;
1180 break;
1181 case BASEPROPERTY_FONTDESCRIPTORPART_FAMILY: rValue <<= aFD.Family;
1182 break;
1183 case BASEPROPERTY_FONTDESCRIPTORPART_CHARSET: rValue <<= aFD.CharSet;
1184 break;
1185 case BASEPROPERTY_FONTDESCRIPTORPART_HEIGHT: rValue <<= static_cast<float>(aFD.Height);
1186 break;
1187 case BASEPROPERTY_FONTDESCRIPTORPART_WEIGHT: rValue <<= aFD.Weight;
1188 break;
1189 case BASEPROPERTY_FONTDESCRIPTORPART_SLANT: rValue <<= static_cast<sal_Int16>(aFD.Slant);
1190 break;
1191 case BASEPROPERTY_FONTDESCRIPTORPART_UNDERLINE: rValue <<= aFD.Underline;
1192 break;
1193 case BASEPROPERTY_FONTDESCRIPTORPART_STRIKEOUT: rValue <<= aFD.Strikeout;
1194 break;
1195 case BASEPROPERTY_FONTDESCRIPTORPART_WIDTH: rValue <<= aFD.Width;
1196 break;
1197 case BASEPROPERTY_FONTDESCRIPTORPART_PITCH: rValue <<= aFD.Pitch;
1198 break;
1199 case BASEPROPERTY_FONTDESCRIPTORPART_CHARWIDTH: rValue <<= aFD.CharacterWidth;
1200 break;
1201 case BASEPROPERTY_FONTDESCRIPTORPART_ORIENTATION: rValue <<= aFD.Orientation;
1202 break;
1203 case BASEPROPERTY_FONTDESCRIPTORPART_KERNING: rValue <<= aFD.Kerning;
1204 break;
1205 case BASEPROPERTY_FONTDESCRIPTORPART_WORDLINEMODE: rValue <<= aFD.WordLineMode;
1206 break;
1207 case BASEPROPERTY_FONTDESCRIPTORPART_TYPE: rValue <<= aFD.Type;
1208 break;
1209 default: OSL_FAIL( "FontProperty?!" );
1212 else
1214 OSL_FAIL( "getFastPropertyValue - invalid Property!" );
1218 // css::beans::XFastPropertySet
1219 void UnoControlModel::setFastPropertyValueImpl( std::unique_lock<std::mutex>& rGuard, sal_Int32 nPropId, const css::uno::Any& rValue )
1221 if ( ( nPropId >= BASEPROPERTY_FONTDESCRIPTORPART_START ) && ( nPropId <= BASEPROPERTY_FONTDESCRIPTORPART_END ) )
1223 Any aOldSingleValue;
1224 getFastPropertyValue( rGuard, aOldSingleValue, BASEPROPERTY_FONTDESCRIPTORPART_START );
1226 css::uno::Any* pProp = &maData[ BASEPROPERTY_FONTDESCRIPTOR ];
1227 FontDescriptor aOldFontDescriptor;
1228 (*pProp) >>= aOldFontDescriptor;
1230 FontDescriptor aNewFontDescriptor( aOldFontDescriptor );
1231 lcl_ImplMergeFontProperty( aNewFontDescriptor, static_cast<sal_uInt16>(nPropId), rValue );
1233 Any aNewValue;
1234 aNewValue <<= aNewFontDescriptor;
1235 sal_Int32 nDescriptorId = BASEPROPERTY_FONTDESCRIPTOR;
1237 // also, we need fire a propertyChange event for the single property, since with
1238 // the above line, only an event for the FontDescriptor property will be fired
1239 Any aNewSingleValue;
1240 getFastPropertyValue( rGuard, aNewSingleValue, BASEPROPERTY_FONTDESCRIPTORPART_START );
1242 setFastPropertyValues( rGuard, 1, &nDescriptorId, &aNewValue, 1 );
1243 fire( rGuard, &nPropId, &aNewSingleValue, &aOldSingleValue, 1, false );
1245 else
1246 setFastPropertyValues( rGuard, 1, &nPropId, &rValue, 1 );
1249 // css::beans::XMultiPropertySet
1250 css::uno::Reference< css::beans::XPropertySetInfo > UnoControlModel::getPropertySetInfo( )
1252 OSL_FAIL( "UnoControlModel::getPropertySetInfo() not possible!" );
1253 return css::uno::Reference< css::beans::XPropertySetInfo >();
1256 void UnoControlModel::setPropertyValues( const css::uno::Sequence< OUString >& rPropertyNames, const css::uno::Sequence< css::uno::Any >& Values )
1258 std::unique_lock aGuard( m_aMutex );
1259 setPropertyValuesImpl(aGuard, rPropertyNames, Values);
1262 void UnoControlModel::setPropertyValuesImpl( std::unique_lock<std::mutex>& rGuard, const css::uno::Sequence< OUString >& rPropertyNames, const css::uno::Sequence< css::uno::Any >& Values )
1264 sal_Int32 nProps = rPropertyNames.getLength();
1265 if (nProps != Values.getLength())
1266 throw css::lang::IllegalArgumentException("lengths do not match",
1267 getXWeak(), -1);
1269 // sal_Int32* pHandles = new sal_Int32[nProps];
1270 // don't do this - it leaks in case of an exception
1271 Sequence< sal_Int32 > aHandles( nProps );
1272 sal_Int32* pHandles = aHandles.getArray();
1274 // may need to change the order in the sequence, for this we need a non-const value sequence
1275 uno::Sequence< uno::Any > aValues( Values );
1276 uno::Any* pValues = aValues.getArray();
1278 sal_Int32 nValidHandles = getInfoHelper().fillHandles( pHandles, rPropertyNames );
1280 if ( !nValidHandles )
1281 return;
1283 // if somebody sets properties which are single aspects of a font descriptor,
1284 // remove them, and build a font descriptor instead
1285 std::unique_ptr< awt::FontDescriptor > pFD;
1286 for ( sal_Int32 n = 0; n < nProps; ++n )
1288 if ( ( pHandles[n] >= BASEPROPERTY_FONTDESCRIPTORPART_START ) && ( pHandles[n] <= BASEPROPERTY_FONTDESCRIPTORPART_END ) )
1290 if (!pFD)
1292 css::uno::Any* pProp = &maData[ BASEPROPERTY_FONTDESCRIPTOR ];
1293 pFD.reset( new awt::FontDescriptor );
1294 (*pProp) >>= *pFD;
1296 lcl_ImplMergeFontProperty( *pFD, static_cast<sal_uInt16>(pHandles[n]), pValues[n] );
1297 pHandles[n] = -1;
1298 nValidHandles--;
1302 if ( nValidHandles )
1304 ImplNormalizePropertySequence( nProps, pHandles, pValues, &nValidHandles );
1305 setFastPropertyValues( rGuard, nProps, pHandles, pValues, nValidHandles );
1308 // Don't merge FD property into array, as it is sorted
1309 if (pFD)
1311 css::uno::Any aValue;
1312 aValue <<= *pFD;
1313 sal_Int32 nHandle = BASEPROPERTY_FONTDESCRIPTOR;
1314 setFastPropertyValues( rGuard, 1, &nHandle, &aValue, 1 );
1319 void UnoControlModel::ImplNormalizePropertySequence( const sal_Int32, sal_Int32*,
1320 uno::Any*, sal_Int32* ) const
1322 // nothing to do here
1325 void UnoControlModel::ImplEnsureHandleOrder( const sal_Int32 _nCount, sal_Int32* _pHandles,
1326 uno::Any* _pValues, sal_Int32 _nFirstHandle, sal_Int32 _nSecondHandle )
1328 for ( sal_Int32 i=0; i < _nCount; ++_pHandles, ++_pValues, ++i )
1330 if ( _nSecondHandle == *_pHandles )
1332 sal_Int32* pLaterHandles = _pHandles + 1;
1333 uno::Any* pLaterValues = _pValues + 1;
1334 for ( sal_Int32 j = i + 1; j < _nCount; ++j, ++pLaterHandles, ++pLaterValues )
1336 if ( _nFirstHandle == *pLaterHandles )
1338 // indeed it is -> exchange the both places in the sequences
1339 sal_Int32 nHandle( *_pHandles );
1340 *_pHandles = *pLaterHandles;
1341 *pLaterHandles = nHandle;
1343 uno::Any aValue( *_pValues );
1344 *_pValues = *pLaterValues;
1345 *pLaterValues = aValue;
1347 break;
1348 // this will leave the inner loop, and continue with the outer loop.
1349 // Note that this means we will encounter the _nSecondHandle handle, again, once we reached
1350 // (in the outer loop) the place where we just put it.
1357 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */