xref: /AOO41X/main/toolkit/source/controls/unocontrolmodel.cxx (revision b0724fc6948542b2496e16ea247f985ee5987cfe)
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 everytime
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