Coverage Report

Created: 2025-07-07 10:01

/src/libreoffice/toolkit/source/controls/unocontrolmodel.cxx
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
/*
3
 * This file is part of the LibreOffice project.
4
 *
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/.
8
 *
9
 * This file incorporates work covered by the following license notice:
10
 *
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 .
18
 */
19
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>
47
48
#include <memory>
49
#include <o3tl/sorted_vector.hxx>
50
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;
56
57
58
0
#define UNOCONTROL_STREAMVERSION    short(2)
59
60
static void lcl_ImplMergeFontProperty( FontDescriptor& rFD, sal_uInt16 nPropId, const Any& rValue )
61
0
{
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
0
    float       nExtractFloat = 0;
66
0
    sal_Int16   nExtractShort = 0;
67
68
0
    switch ( nPropId )
69
0
    {
70
0
        case BASEPROPERTY_FONTDESCRIPTORPART_NAME:          rValue >>= rFD.Name;
71
0
                                                            break;
72
0
        case BASEPROPERTY_FONTDESCRIPTORPART_STYLENAME:     rValue >>= rFD.StyleName;
73
0
                                                            break;
74
0
        case BASEPROPERTY_FONTDESCRIPTORPART_FAMILY:        rValue >>= rFD.Family;
75
0
                                                            break;
76
0
        case BASEPROPERTY_FONTDESCRIPTORPART_CHARSET:       rValue >>= rFD.CharSet;
77
0
                                                            break;
78
0
        case BASEPROPERTY_FONTDESCRIPTORPART_HEIGHT:        rValue >>= nExtractFloat; rFD.Height = static_cast<sal_Int16>(nExtractFloat);
79
0
                                                            break;
80
0
        case BASEPROPERTY_FONTDESCRIPTORPART_WEIGHT:        rValue >>= rFD.Weight;
81
0
                                                            break;
82
0
        case BASEPROPERTY_FONTDESCRIPTORPART_SLANT:         if ( rValue >>= nExtractShort )
83
0
                                                                rFD.Slant = static_cast<css::awt::FontSlant>(nExtractShort);
84
0
                                                            else
85
0
                                                                rValue >>= rFD.Slant;
86
0
                                                            break;
87
0
        case BASEPROPERTY_FONTDESCRIPTORPART_UNDERLINE:     rValue >>= rFD.Underline;
88
0
                                                            break;
89
0
        case BASEPROPERTY_FONTDESCRIPTORPART_STRIKEOUT:     rValue >>= rFD.Strikeout;
90
0
                                                            break;
91
0
        case BASEPROPERTY_FONTDESCRIPTORPART_WIDTH:         rValue >>= rFD.Width;
92
0
                                                            break;
93
0
        case BASEPROPERTY_FONTDESCRIPTORPART_PITCH:         rValue >>= rFD.Pitch;
94
0
                                                            break;
95
0
        case BASEPROPERTY_FONTDESCRIPTORPART_CHARWIDTH:     rValue >>= rFD.CharacterWidth;
96
0
                                                            break;
97
0
        case BASEPROPERTY_FONTDESCRIPTORPART_ORIENTATION:   rValue >>= rFD.Orientation;
98
0
                                                            break;
99
0
        case BASEPROPERTY_FONTDESCRIPTORPART_KERNING:       rValue >>= rFD.Kerning;
100
0
                                                            break;
101
0
        case BASEPROPERTY_FONTDESCRIPTORPART_WORDLINEMODE:  rValue >>= rFD.WordLineMode;
102
0
                                                            break;
103
0
        case BASEPROPERTY_FONTDESCRIPTORPART_TYPE:          rValue >>= rFD.Type;
104
0
                                                            break;
105
0
        default:                                            OSL_FAIL( "FontProperty?!" );
106
0
    }
107
0
}
108
109
110
111
UnoControlModel::UnoControlModel( const Reference< XComponentContext >& rxContext )
112
0
    :UnoControlModel_Base()
113
0
    ,maDisposeListeners( *this )
114
0
    ,m_xContext( rxContext )
115
0
{
116
    // Insert properties from Model into table,
117
    // only existing properties are valid, even if they're VOID
118
0
}
119
120
UnoControlModel::UnoControlModel( const UnoControlModel& rModel )
121
0
    : UnoControlModel_Base(), OPropertySetHelper()
122
0
    , maData( rModel.maData )
123
0
    , maDisposeListeners( *this )
124
0
    , m_xContext( rModel.m_xContext )
125
0
{
126
0
}
127
128
css::uno::Sequence<sal_Int32> UnoControlModel::ImplGetPropertyIds() const
129
0
{
130
0
    sal_uInt32 nIDs = maData.size();
131
0
    css::uno::Sequence<sal_Int32>  aIDs( nIDs );
132
0
    sal_Int32* pIDs = aIDs.getArray();
133
0
    sal_uInt32 n = 0;
134
0
    for ( const auto& rData : maData )
135
0
        pIDs[n++] = rData.first;
136
0
    return aIDs;
137
0
}
138
139
bool UnoControlModel::ImplHasProperty( sal_uInt16 nPropId ) const
140
0
{
141
0
    if ( ( nPropId >= BASEPROPERTY_FONTDESCRIPTORPART_START ) && ( nPropId <= BASEPROPERTY_FONTDESCRIPTORPART_END ) )
142
0
        nPropId = BASEPROPERTY_FONTDESCRIPTOR;
143
144
0
    return maData.find( nPropId ) != maData.end();
145
0
}
146
147
css::uno::Any UnoControlModel::ImplGetDefaultValue( sal_uInt16 nPropId ) const
148
0
{
149
0
    css::uno::Any aDefault;
150
151
0
    if (
152
0
        (nPropId == BASEPROPERTY_FONTDESCRIPTOR) ||
153
0
        (
154
0
         (nPropId >= BASEPROPERTY_FONTDESCRIPTORPART_START) &&
155
0
         (nPropId <= BASEPROPERTY_FONTDESCRIPTORPART_END)
156
0
        )
157
0
       )
158
0
    {
159
0
        EmptyFontDescriptor aFD;
160
0
        switch ( nPropId )
161
0
        {
162
0
            case BASEPROPERTY_FONTDESCRIPTOR:                   aDefault <<= aFD;                   break;
163
0
            case BASEPROPERTY_FONTDESCRIPTORPART_NAME:          aDefault <<= aFD.Name;              break;
164
0
            case BASEPROPERTY_FONTDESCRIPTORPART_STYLENAME:     aDefault <<= aFD.StyleName;         break;
165
0
            case BASEPROPERTY_FONTDESCRIPTORPART_FAMILY:        aDefault <<= aFD.Family;            break;
166
0
            case BASEPROPERTY_FONTDESCRIPTORPART_CHARSET:       aDefault <<= aFD.CharSet;           break;
167
0
            case BASEPROPERTY_FONTDESCRIPTORPART_HEIGHT:        aDefault <<= static_cast<float>(aFD.Height);     break;
168
0
            case BASEPROPERTY_FONTDESCRIPTORPART_WEIGHT:        aDefault <<= aFD.Weight;            break;
169
0
            case BASEPROPERTY_FONTDESCRIPTORPART_SLANT:         aDefault <<= static_cast<sal_Int16>(aFD.Slant);  break;
170
0
            case BASEPROPERTY_FONTDESCRIPTORPART_UNDERLINE:     aDefault <<= aFD.Underline;         break;
171
0
            case BASEPROPERTY_FONTDESCRIPTORPART_STRIKEOUT:     aDefault <<= aFD.Strikeout;         break;
172
0
            case BASEPROPERTY_FONTDESCRIPTORPART_WIDTH:         aDefault <<= aFD.Width;             break;
173
0
            case BASEPROPERTY_FONTDESCRIPTORPART_PITCH:         aDefault <<= aFD.Pitch;             break;
174
0
            case BASEPROPERTY_FONTDESCRIPTORPART_CHARWIDTH:     aDefault <<= aFD.CharacterWidth;    break;
175
0
            case BASEPROPERTY_FONTDESCRIPTORPART_ORIENTATION:   aDefault <<= aFD.Orientation;       break;
176
0
            case BASEPROPERTY_FONTDESCRIPTORPART_KERNING:       aDefault <<= aFD.Kerning;           break;
177
0
            case BASEPROPERTY_FONTDESCRIPTORPART_WORDLINEMODE:  aDefault <<= aFD.WordLineMode;      break;
178
0
            case BASEPROPERTY_FONTDESCRIPTORPART_TYPE:          aDefault <<= aFD.Type;              break;
179
0
            default: OSL_FAIL( "FontProperty?!" );
180
0
        }
181
0
    }
182
0
    else
183
0
    {
184
0
        switch ( nPropId )
185
0
        {
186
0
            case BASEPROPERTY_GRAPHIC:
187
0
                aDefault <<= Reference< graphic::XGraphic >();
188
0
                break;
189
190
0
            case BASEPROPERTY_REFERENCE_DEVICE:
191
0
                aDefault <<= Reference< awt::XDevice >();
192
0
                break;
193
194
0
            case BASEPROPERTY_ITEM_SEPARATOR_POS:
195
0
            case BASEPROPERTY_VERTICALALIGN:
196
0
            case BASEPROPERTY_BORDERCOLOR:
197
0
            case BASEPROPERTY_SYMBOL_COLOR:
198
0
            case BASEPROPERTY_TABSTOP:
199
0
            case BASEPROPERTY_TEXTCOLOR:
200
0
            case BASEPROPERTY_TEXTLINECOLOR:
201
0
            case BASEPROPERTY_DATE:
202
0
            case BASEPROPERTY_DATESHOWCENTURY:
203
0
            case BASEPROPERTY_TIME:
204
0
            case BASEPROPERTY_VALUE_DOUBLE:
205
0
            case BASEPROPERTY_PROGRESSVALUE:
206
0
            case BASEPROPERTY_SCROLLVALUE:
207
0
            case BASEPROPERTY_VISIBLESIZE:
208
0
            case BASEPROPERTY_BACKGROUNDCOLOR:
209
0
            case BASEPROPERTY_FILLCOLOR:
210
0
            case BASEPROPERTY_HIGHLIGHT_COLOR:
211
0
            case BASEPROPERTY_HIGHLIGHT_TEXT_COLOR:            break;  // Void
212
213
0
            case BASEPROPERTY_FONTRELIEF:
214
0
            case BASEPROPERTY_FONTEMPHASISMARK:
215
0
            case BASEPROPERTY_MAXTEXTLEN:
216
0
            case BASEPROPERTY_STATE:
217
0
            case BASEPROPERTY_EXTDATEFORMAT:
218
0
            case BASEPROPERTY_EXTTIMEFORMAT:
219
0
            case BASEPROPERTY_ECHOCHAR:             aDefault <<= sal_Int16(0); break;
220
0
            case BASEPROPERTY_BORDER:               aDefault <<= sal_Int16(1); break;
221
0
            case BASEPROPERTY_DECIMALACCURACY:      aDefault <<= sal_Int16(2); break;
222
0
            case BASEPROPERTY_LINECOUNT:            aDefault <<= sal_Int16(5); break;
223
0
            case BASEPROPERTY_ALIGN:                aDefault <<= sal_Int16(PROPERTY_ALIGN_LEFT); break;
224
0
            case BASEPROPERTY_IMAGEALIGN:           aDefault <<= sal_Int16(1) /*ImageAlign::Top*/; break;
225
0
            case BASEPROPERTY_IMAGEPOSITION:        aDefault <<= sal_Int16(12) /*ImagePosition::Centered*/; break;
226
0
            case BASEPROPERTY_PUSHBUTTONTYPE:       aDefault <<= sal_Int16(0) /*PushButtonType::STANDARD*/; break;
227
0
            case BASEPROPERTY_MOUSE_WHEEL_BEHAVIOUR:aDefault <<= sal_Int16(awt::MouseWheelBehavior::SCROLL_FOCUS_ONLY); break;
228
229
0
            case BASEPROPERTY_DATEMAX:              aDefault <<= util::Date( 31, 12, 2200 );    break;
230
0
            case BASEPROPERTY_DATEMIN:              aDefault <<= util::Date( 1, 1, 1900 );  break;
231
0
            case BASEPROPERTY_TIMEMAX:              aDefault <<= util::Time(0, 0, 59, 23, false);  break;
232
0
            case BASEPROPERTY_TIMEMIN:              aDefault <<= util::Time();      break;
233
0
            case BASEPROPERTY_VALUEMAX_DOUBLE:      aDefault <<= double(1000000);  break;
234
0
            case BASEPROPERTY_VALUEMIN_DOUBLE:      aDefault <<= double(-1000000); break;
235
0
            case BASEPROPERTY_VALUESTEP_DOUBLE:     aDefault <<= double(1);       break;
236
0
            case BASEPROPERTY_PROGRESSVALUE_MAX:    aDefault <<= sal_Int32(100);   break;
237
0
            case BASEPROPERTY_PROGRESSVALUE_MIN:    aDefault <<= sal_Int32(0);   break;
238
0
            case BASEPROPERTY_SCROLLVALUE_MAX:      aDefault <<= sal_Int32(100);   break;
239
0
            case BASEPROPERTY_SCROLLVALUE_MIN:      aDefault <<= sal_Int32(0);   break;
240
0
            case BASEPROPERTY_LINEINCREMENT:        aDefault <<= sal_Int32(1);   break;
241
0
            case BASEPROPERTY_BLOCKINCREMENT:       aDefault <<= sal_Int32(10);   break;
242
0
            case BASEPROPERTY_ORIENTATION:          aDefault <<= sal_Int32(0);   break;
243
0
            case BASEPROPERTY_SPINVALUE:            aDefault <<= sal_Int32(0);   break;
244
0
            case BASEPROPERTY_SPININCREMENT:        aDefault <<= sal_Int32(1);   break;
245
0
            case BASEPROPERTY_SPINVALUE_MIN:        aDefault <<= sal_Int32(0);   break;
246
0
            case BASEPROPERTY_SPINVALUE_MAX:        aDefault <<= sal_Int32(100);   break;
247
0
            case BASEPROPERTY_REPEAT_DELAY:         aDefault <<= sal_Int32(50);   break;    // 50 milliseconds
248
0
            case BASEPROPERTY_DEFAULTCONTROL:       aDefault <<= const_cast<UnoControlModel*>(this)->getServiceName();    break;
249
250
0
            case BASEPROPERTY_AUTOHSCROLL:
251
0
            case BASEPROPERTY_AUTOVSCROLL:
252
0
            case BASEPROPERTY_MOVEABLE:
253
0
            case BASEPROPERTY_CLOSEABLE:
254
0
            case BASEPROPERTY_SIZEABLE:
255
0
            case BASEPROPERTY_HSCROLL:
256
0
            case BASEPROPERTY_DEFAULTBUTTON:
257
0
            case BASEPROPERTY_MULTILINE:
258
0
            case BASEPROPERTY_MULTISELECTION:
259
0
            case BASEPROPERTY_TRISTATE:
260
0
            case BASEPROPERTY_DROPDOWN:
261
0
            case BASEPROPERTY_SPIN:
262
0
            case BASEPROPERTY_READONLY:
263
0
            case BASEPROPERTY_VSCROLL:
264
0
            case BASEPROPERTY_NUMSHOWTHOUSANDSEP:
265
0
            case BASEPROPERTY_STRICTFORMAT:
266
0
            case BASEPROPERTY_REPEAT:
267
0
            case BASEPROPERTY_PAINTTRANSPARENT:
268
0
            case BASEPROPERTY_DESKTOP_AS_PARENT:
269
0
            case BASEPROPERTY_HARDLINEBREAKS:
270
0
            case BASEPROPERTY_NOLABEL:              aDefault <<= false; break;
271
272
0
            case BASEPROPERTY_MULTISELECTION_SIMPLEMODE:
273
0
            case BASEPROPERTY_HIDEINACTIVESELECTION:
274
0
            case BASEPROPERTY_ENFORCE_FORMAT:
275
0
            case BASEPROPERTY_AUTOCOMPLETE:
276
0
            case BASEPROPERTY_SCALEIMAGE:
277
0
            case BASEPROPERTY_ENABLED:
278
0
            case BASEPROPERTY_PRINTABLE:
279
0
            case BASEPROPERTY_ENABLEVISIBLE:
280
0
            case BASEPROPERTY_DECORATION:           aDefault <<= true; break;
281
282
0
            case BASEPROPERTY_GROUPNAME:
283
0
            case BASEPROPERTY_HELPTEXT:
284
0
            case BASEPROPERTY_HELPURL:
285
0
            case BASEPROPERTY_IMAGEURL:
286
0
            case BASEPROPERTY_DIALOGSOURCEURL:
287
0
            case BASEPROPERTY_EDITMASK:
288
0
            case BASEPROPERTY_LITERALMASK:
289
0
            case BASEPROPERTY_LABEL:
290
0
            case BASEPROPERTY_TITLE:
291
0
            case BASEPROPERTY_TEXT:                 aDefault <<= OUString(); break;
292
293
0
            case BASEPROPERTY_WRITING_MODE:
294
0
            case BASEPROPERTY_CONTEXT_WRITING_MODE:
295
0
                aDefault <<= text::WritingMode2::CONTEXT;
296
0
                break;
297
298
0
            case BASEPROPERTY_STRINGITEMLIST:
299
0
            {
300
0
                css::uno::Sequence< OUString> aStringSeq;
301
0
                aDefault <<= aStringSeq;
302
303
0
            }
304
0
            break;
305
0
            case BASEPROPERTY_TYPEDITEMLIST:
306
0
            {
307
0
                css::uno::Sequence< css::uno::Any > aAnySeq;
308
0
                aDefault <<= aAnySeq;
309
310
0
            }
311
0
            break;
312
0
            case BASEPROPERTY_SELECTEDITEMS:
313
0
            {
314
0
                css::uno::Sequence<sal_Int16> aINT16Seq;
315
0
                aDefault <<= aINT16Seq;
316
0
            }
317
0
            break;
318
0
            case BASEPROPERTY_CURRENCYSYMBOL:
319
0
            {
320
0
                OUString sDefaultCurrency(
321
0
                    utl::ConfigManager::getDefaultCurrency() );
322
323
                // extract the bank symbol
324
0
                sal_Int32 nSepPos = sDefaultCurrency.indexOf( '-' );
325
0
                OUString sBankSymbol;
326
0
                if ( nSepPos >= 0 )
327
0
                {
328
0
                    sBankSymbol = sDefaultCurrency.copy( 0, nSepPos );
329
0
                    sDefaultCurrency = sDefaultCurrency.copy( nSepPos + 1 );
330
0
                }
331
332
                // the remaining is the locale
333
0
                const LocaleDataWrapper* pLocaleInfo = LocaleDataWrapper::get( LanguageTag(sDefaultCurrency) );
334
0
                if ( sBankSymbol.isEmpty() )
335
0
                    sBankSymbol = pLocaleInfo->getCurrBankSymbol();
336
337
                // look for the currency entry (for this language) which has the given bank symbol
338
0
                const Sequence< Currency2 > aAllCurrencies = pLocaleInfo->getAllCurrencies();
339
340
0
                OUString sCurrencySymbol = pLocaleInfo->getCurrSymbol();
341
0
                if ( sBankSymbol.isEmpty() )
342
0
                {
343
0
                    DBG_ASSERT( aAllCurrencies.hasElements(), "UnoControlModel::ImplGetDefaultValue: no currencies at all!" );
344
0
                    if ( aAllCurrencies.hasElements() )
345
0
                    {
346
0
                        sBankSymbol = aAllCurrencies[0].BankSymbol;
347
0
                        sCurrencySymbol = aAllCurrencies[0].Symbol;
348
0
                    }
349
0
                }
350
351
0
                if ( !sBankSymbol.isEmpty() )
352
0
                {
353
0
                    bool bLegacy = false;
354
0
                    bool bFound = false;
355
0
                    for ( const Currency2& rCurrency : aAllCurrencies )
356
0
                        if ( rCurrency.BankSymbol == sBankSymbol )
357
0
                        {
358
0
                            sCurrencySymbol = rCurrency.Symbol;
359
0
                            if ( rCurrency.LegacyOnly )
360
0
                                bLegacy = true;
361
0
                            else
362
0
                            {
363
0
                                bFound = true;
364
0
                                break;
365
0
                            }
366
0
                        }
367
0
                    DBG_ASSERT( bLegacy || bFound, "UnoControlModel::ImplGetDefaultValue: did not find the given bank symbol!" );
368
0
                }
369
370
0
                aDefault <<= sCurrencySymbol;
371
0
            }
372
0
            break;
373
374
0
            default:    OSL_FAIL( "ImplGetDefaultValue - unknown Property" );
375
0
        }
376
0
    }
377
378
0
    return aDefault;
379
0
}
380
381
void UnoControlModel::ImplRegisterProperty( sal_uInt16 nPropId, const css::uno::Any& rDefault )
382
0
{
383
0
    maData[ nPropId ] = rDefault;
384
0
}
385
386
void UnoControlModel::ImplRegisterProperty( sal_uInt16 nPropId )
387
0
{
388
0
    ImplRegisterProperty( nPropId, ImplGetDefaultValue( nPropId ) );
389
390
0
    if ( nPropId == BASEPROPERTY_FONTDESCRIPTOR )
391
0
    {
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...
395
396
0
        ImplRegisterProperty( BASEPROPERTY_TEXTCOLOR );
397
0
        ImplRegisterProperty( BASEPROPERTY_TEXTLINECOLOR );
398
0
        ImplRegisterProperty( BASEPROPERTY_FONTRELIEF );
399
0
        ImplRegisterProperty( BASEPROPERTY_FONTEMPHASISMARK );
400
0
    }
401
0
}
402
403
void UnoControlModel::ImplRegisterProperties( const std::vector< sal_uInt16 > &rIds )
404
0
{
405
0
    for (const auto& rId : rIds)
406
0
    {
407
0
        if( !ImplHasProperty( rId ) )
408
0
            ImplRegisterProperty( rId, ImplGetDefaultValue( rId ) );
409
0
    }
410
0
}
411
412
// css::uno::XInterface
413
css::uno::Any UnoControlModel::queryAggregation( const css::uno::Type & rType )
414
0
{
415
0
    Any aRet = UnoControlModel_Base::queryAggregation( rType );
416
0
    if ( !aRet.hasValue() )
417
0
        aRet = ::comphelper::OPropertySetHelper::queryInterface( rType );
418
0
    return aRet;
419
0
}
420
421
// XInterface
422
IMPLEMENT_FORWARD_REFCOUNT( UnoControlModel, UnoControlModel_Base )
423
424
// css::lang::XTypeProvider
425
IMPLEMENT_FORWARD_XTYPEPROVIDER2( UnoControlModel, UnoControlModel_Base, ::comphelper::OPropertySetHelper )
426
427
428
uno::Reference< util::XCloneable > UnoControlModel::createClone()
429
0
{
430
0
    rtl::Reference<UnoControlModel> pClone = Clone();
431
0
    return pClone;
432
0
}
433
434
// css::lang::XComponent
435
void UnoControlModel::dispose(  )
436
0
{
437
0
    std::unique_lock aGuard( m_aMutex );
438
439
0
    css::lang::EventObject aEvt;
440
0
    aEvt.Source = static_cast<css::uno::XAggregation*>(static_cast<cppu::OWeakAggObject*>(this));
441
0
    maDisposeListeners.disposeAndClear( aGuard, aEvt );
442
443
    // let the property set helper notify our property listeners
444
0
    OPropertySetHelper::disposing(aGuard);
445
0
}
446
447
void UnoControlModel::addEventListener( const css::uno::Reference< css::lang::XEventListener >& rxListener )
448
0
{
449
0
    std::unique_lock aGuard( m_aMutex );
450
451
0
    maDisposeListeners.addInterface( rxListener );
452
0
}
453
454
void UnoControlModel::removeEventListener( const css::uno::Reference< css::lang::XEventListener >& rxListener )
455
0
{
456
0
    std::unique_lock aGuard( m_aMutex );
457
458
0
    maDisposeListeners.removeInterface( rxListener );
459
0
}
460
461
462
// css::beans::XPropertyState
463
css::beans::PropertyState UnoControlModel::getPropertyState( const OUString& PropertyName )
464
0
{
465
0
    std::unique_lock aGuard( m_aMutex );
466
0
    return getPropertyStateImpl(aGuard, PropertyName);
467
0
}
468
469
css::beans::PropertyState UnoControlModel::getPropertyStateImpl( std::unique_lock<std::mutex>& rGuard, const OUString& PropertyName )
470
0
{
471
0
    sal_uInt16 nPropId = GetPropertyId( PropertyName );
472
473
0
    css::uno::Any aValue = getPropertyValueImpl( rGuard, PropertyName );
474
0
    css::uno::Any aDefault = ImplGetDefaultValue( nPropId );
475
476
0
    return CompareProperties( aValue, aDefault ) ? css::beans::PropertyState_DEFAULT_VALUE : css::beans::PropertyState_DIRECT_VALUE;
477
0
}
478
479
css::uno::Sequence< css::beans::PropertyState > UnoControlModel::getPropertyStates( const css::uno::Sequence< OUString >& PropertyNames )
480
0
{
481
0
    std::unique_lock aGuard( m_aMutex );
482
483
0
    sal_Int32 nNames = PropertyNames.getLength();
484
485
0
    css::uno::Sequence< css::beans::PropertyState > aStates( nNames );
486
487
0
    std::transform(PropertyNames.begin(), PropertyNames.end(), aStates.getArray(),
488
0
        [this, &aGuard](const OUString& rName) -> css::beans::PropertyState
489
0
        { return getPropertyStateImpl(aGuard, rName); });
490
491
0
    return aStates;
492
0
}
493
494
void UnoControlModel::setPropertyToDefault( const OUString& PropertyName )
495
0
{
496
0
    Any aDefaultValue;
497
0
    {
498
0
        std::unique_lock aGuard( m_aMutex );
499
0
        aDefaultValue = ImplGetDefaultValue( GetPropertyId( PropertyName ) );
500
0
    }
501
0
    setPropertyValue( PropertyName, aDefaultValue );
502
0
}
503
504
css::uno::Any UnoControlModel::getPropertyDefault( const OUString& rPropertyName )
505
0
{
506
0
    std::unique_lock aGuard( m_aMutex );
507
508
0
    return ImplGetDefaultValue( GetPropertyId( rPropertyName ) );
509
0
}
510
511
512
// css::io::XPersistObjec
513
OUString UnoControlModel::getServiceName(  )
514
0
{
515
0
    OSL_FAIL( "ServiceName of UnoControlModel ?!" );
516
0
    return OUString();
517
0
}
518
519
void UnoControlModel::write( const css::uno::Reference< css::io::XObjectOutputStream >& OutStream )
520
0
{
521
0
    std::unique_lock aGuard( m_aMutex );
522
523
0
    css::uno::Reference< css::io::XMarkableStream > xMark( OutStream, css::uno::UNO_QUERY );
524
0
    DBG_ASSERT( xMark.is(), "write: no css::io::XMarkableStream!" );
525
526
0
    OutStream->writeShort( UNOCONTROL_STREAMVERSION );
527
528
0
    o3tl::sorted_vector<sal_uInt16> aProps;
529
530
0
    for (const auto& rData : maData)
531
0
    {
532
0
        if ( ( ( GetPropertyAttribs( rData.first ) & css::beans::PropertyAttribute::TRANSIENT ) == 0 )
533
0
            && ( getPropertyStateImpl( aGuard, GetPropertyName( rData.first ) ) != css::beans::PropertyState_DEFAULT_VALUE ) )
534
0
        {
535
0
            aProps.insert( rData.first );
536
0
        }
537
0
    }
538
539
0
    sal_uInt32 nProps = aProps.size();
540
541
    // Save FontProperty always in the old format (due to missing distinction
542
    // between 5.0 and 5.1)
543
0
    OutStream->writeLong( ( aProps.find( BASEPROPERTY_FONTDESCRIPTOR ) != aProps.end() ) ? ( nProps + 3 ) : nProps );
544
0
    for ( const auto& rProp : aProps )
545
0
    {
546
0
        sal_Int32 nPropDataBeginMark = xMark->createMark();
547
0
        OutStream->writeLong( 0 ); // DataLen
548
549
0
        const css::uno::Any* pProp = &(maData[rProp]);
550
0
        OutStream->writeShort( rProp );
551
552
0
        bool bVoid = pProp->getValueTypeClass() == css::uno::TypeClass_VOID;
553
554
0
        OutStream->writeBoolean( bVoid );
555
556
0
        if ( !bVoid )
557
0
        {
558
0
            const css::uno::Any& rValue = *pProp;
559
0
            const css::uno::Type& rType = rValue.getValueType();
560
561
0
            if ( rType == cppu::UnoType< bool >::get() )
562
0
            {
563
0
                bool b = false;
564
0
                rValue >>= b;
565
0
                OutStream->writeBoolean( b );
566
0
            }
567
0
            else if ( rType == ::cppu::UnoType< OUString >::get() )
568
0
            {
569
0
                OUString aUString;
570
0
                rValue >>= aUString;
571
0
                OutStream->writeUTF( aUString );
572
0
            }
573
0
            else if ( rType == ::cppu::UnoType< ::cppu::UnoUnsignedShortType >::get() )
574
0
            {
575
0
                sal_uInt16 n = 0;
576
0
                rValue >>= n;
577
0
                OutStream->writeShort( n );
578
0
            }
579
0
            else if ( rType == cppu::UnoType<sal_Int16>::get() )
580
0
            {
581
0
                sal_Int16 n = 0;
582
0
                rValue >>= n;
583
0
                OutStream->writeShort( n );
584
0
            }
585
0
            else if ( rType == cppu::UnoType<sal_uInt32>::get() )
586
0
            {
587
0
                sal_uInt32 n = 0;
588
0
                rValue >>= n;
589
0
                OutStream->writeLong( n );
590
0
            }
591
0
            else if ( rType == cppu::UnoType<sal_Int32>::get() )
592
0
            {
593
0
                sal_Int32 n = 0;
594
0
                rValue >>= n;
595
0
                OutStream->writeLong( n );
596
0
            }
597
0
            else if ( rType == cppu::UnoType<double>::get() )
598
0
            {
599
0
                double n = 0;
600
0
                rValue >>= n;
601
0
                OutStream->writeDouble( n );
602
0
            }
603
0
            else if ( rType == cppu::UnoType< css::awt::FontDescriptor >::get() )
604
0
            {
605
0
                css::awt::FontDescriptor aFD;
606
0
                rValue >>= aFD;
607
0
                OutStream->writeUTF( aFD.Name );
608
0
                OutStream->writeShort( aFD.Height );
609
0
                OutStream->writeShort( aFD.Width );
610
0
                OutStream->writeUTF( aFD.StyleName );
611
0
                OutStream->writeShort( aFD.Family );
612
0
                OutStream->writeShort( aFD.CharSet );
613
0
                OutStream->writeShort( aFD.Pitch );
614
0
                OutStream->writeDouble( aFD.CharacterWidth );
615
0
                OutStream->writeDouble( aFD.Weight );
616
0
                OutStream->writeShort(
617
0
                    sal::static_int_cast< sal_Int16 >(aFD.Slant) );
618
0
                OutStream->writeShort( aFD.Underline );
619
0
                OutStream->writeShort( aFD.Strikeout );
620
0
                OutStream->writeDouble( aFD.Orientation );
621
0
                OutStream->writeBoolean( aFD.Kerning );
622
0
                OutStream->writeBoolean( aFD.WordLineMode );
623
0
                OutStream->writeShort( aFD.Type );
624
0
            }
625
0
            else if ( rType == cppu::UnoType<css::util::Date>::get() )
626
0
            {
627
0
                css::util::Date d;
628
0
                rValue >>= d;
629
0
                OutStream->writeLong(d.Day + 100 * d.Month + 10000 * d.Year);
630
                    // YYYYMMDD
631
0
            }
632
0
            else if ( rType == cppu::UnoType<css::util::Time>::get() )
633
0
            {
634
0
                css::util::Time t;
635
0
                rValue >>= t;
636
0
                OutStream->writeLong(
637
0
                    t.NanoSeconds / 1000000 + 100 * t.Seconds
638
0
                    + 10000 * t.Minutes + 1000000 * t.Hours); // HHMMSShh
639
0
            }
640
0
            else if ( rType == cppu::UnoType< css::uno::Sequence< OUString> >::get() )
641
0
            {
642
0
                css::uno::Sequence< OUString> aSeq;
643
0
                rValue >>= aSeq;
644
0
                tools::Long nEntries = aSeq.getLength();
645
0
                OutStream->writeLong( nEntries );
646
0
                for (const auto& rVal : aSeq)
647
0
                    OutStream->writeUTF( rVal );
648
0
            }
649
0
            else if ( rType == cppu::UnoType< cppu::UnoSequenceType<cppu::UnoUnsignedShortType> >::get() )
650
0
            {
651
0
                css::uno::Sequence<sal_uInt16> aSeq;
652
0
                rValue >>= aSeq;
653
0
                tools::Long nEntries = aSeq.getLength();
654
0
                OutStream->writeLong( nEntries );
655
0
                for (const auto nVal : aSeq)
656
0
                    OutStream->writeShort( nVal );
657
0
            }
658
0
            else if ( rType == cppu::UnoType< css::uno::Sequence<sal_Int16> >::get() )
659
0
            {
660
0
                css::uno::Sequence<sal_Int16> aSeq;
661
0
                rValue >>= aSeq;
662
0
                tools::Long nEntries = aSeq.getLength();
663
0
                OutStream->writeLong( nEntries );
664
0
                for (const auto nVal : aSeq)
665
0
                    OutStream->writeShort( nVal );
666
0
            }
667
0
            else if ( rType.getTypeClass() == TypeClass_ENUM )
668
0
            {
669
0
                sal_Int32 nAsInt = 0;
670
0
                ::cppu::enum2int( nAsInt, rValue );
671
0
                OutStream->writeLong( nAsInt );
672
0
            }
673
#if OSL_DEBUG_LEVEL > 0
674
            else
675
            {
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
                          << "'.)");
681
            }
682
#endif
683
0
        }
684
685
0
        sal_Int32 nPropDataLen = xMark->offsetToMark( nPropDataBeginMark );
686
0
        xMark->jumpToMark( nPropDataBeginMark );
687
0
        OutStream->writeLong( nPropDataLen );
688
0
        xMark->jumpToFurthest();
689
0
        xMark->deleteMark(nPropDataBeginMark);
690
0
    }
691
692
0
    if ( aProps.find( BASEPROPERTY_FONTDESCRIPTOR ) == aProps.end() )
693
0
        return;
694
695
0
    const css::uno::Any* pProp = &maData[ BASEPROPERTY_FONTDESCRIPTOR ];
696
    // Until 5.0 export arrives, write old format...
697
0
    css::awt::FontDescriptor aFD;
698
0
    (*pProp) >>= aFD;
699
700
0
    for ( sal_uInt16 n = BASEPROPERTY_FONT_TYPE; n <= BASEPROPERTY_FONT_ATTRIBS; n++ )
701
0
    {
702
0
        sal_Int32 nPropDataBeginMark = xMark->createMark();
703
0
        OutStream->writeLong( 0 ); // DataLen
704
0
        OutStream->writeShort( n ); // PropId
705
0
        OutStream->writeBoolean( false );   // Void
706
707
0
        if ( n == BASEPROPERTY_FONT_TYPE )
708
0
        {
709
0
            OutStream->writeUTF( aFD.Name );
710
0
            OutStream->writeUTF( aFD.StyleName );
711
0
            OutStream->writeShort( aFD.Family );
712
0
            OutStream->writeShort( aFD.CharSet );
713
0
            OutStream->writeShort( aFD.Pitch );
714
0
        }
715
0
        else if ( n == BASEPROPERTY_FONT_SIZE )
716
0
        {
717
0
            OutStream->writeLong( aFD.Width );
718
0
            OutStream->writeLong( aFD.Height );
719
0
            OutStream->writeShort(
720
0
                sal::static_int_cast< sal_Int16 >(
721
0
                    vcl::unohelper::ConvertFontWidth(aFD.CharacterWidth)) );
722
0
        }
723
0
        else if ( n == BASEPROPERTY_FONT_ATTRIBS )
724
0
        {
725
0
            OutStream->writeShort(
726
0
                sal::static_int_cast< sal_Int16 >(
727
0
                    vcl::unohelper::ConvertFontWeight(aFD.Weight)) );
728
0
            OutStream->writeShort(
729
0
                sal::static_int_cast< sal_Int16 >(aFD.Slant) );
730
0
            OutStream->writeShort( aFD.Underline );
731
0
            OutStream->writeShort( aFD.Strikeout );
732
0
            OutStream->writeShort( static_cast<short>(aFD.Orientation * 10) );
733
0
            OutStream->writeBoolean( aFD.Kerning );
734
0
            OutStream->writeBoolean( aFD.WordLineMode );
735
0
        }
736
0
        else
737
0
        {
738
0
            OSL_FAIL( "Property?!" );
739
0
        }
740
741
0
        sal_Int32 nPropDataLen = xMark->offsetToMark( nPropDataBeginMark );
742
0
        xMark->jumpToMark( nPropDataBeginMark );
743
0
        OutStream->writeLong( nPropDataLen );
744
0
        xMark->jumpToFurthest();
745
0
        xMark->deleteMark(nPropDataBeginMark);
746
0
    }
747
0
}
748
749
void UnoControlModel::read( const css::uno::Reference< css::io::XObjectInputStream >& InStream )
750
0
{
751
0
    std::unique_lock aGuard( m_aMutex );
752
753
0
    css::uno::Reference< css::io::XMarkableStream > xMark( InStream, css::uno::UNO_QUERY );
754
0
    DBG_ASSERT( xMark.is(), "read: no css::io::XMarkableStream!" );
755
756
0
    short nVersion = InStream->readShort();
757
0
    sal_uInt32 nProps = static_cast<sal_uInt32>(InStream->readLong());
758
0
    css::uno::Sequence< OUString> aProps( nProps );
759
0
    css::uno::Sequence< css::uno::Any> aValues( nProps );
760
0
    bool bInvalidEntries = false;
761
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
764
765
    // Used for import of old parts in css::awt::FontDescriptor
766
0
    std::unique_ptr<css::awt::FontDescriptor> pFD;
767
768
0
    for ( sal_uInt32 i = 0; i < nProps; i++ )
769
0
    {
770
0
        sal_Int32 nPropDataBeginMark = xMark->createMark();
771
0
        sal_Int32 nPropDataLen = InStream->readLong();
772
773
0
        sal_uInt16 nPropId = static_cast<sal_uInt16>(InStream->readShort());
774
775
0
        css::uno::Any aValue;
776
0
        bool bIsVoid = InStream->readBoolean();
777
0
        if ( !bIsVoid )
778
0
        {
779
0
            if ( maData.find( nPropId ) != maData.end() )
780
0
            {
781
0
                const css::uno::Type* pType = GetPropertyType( nPropId );
782
0
                if ( *pType == cppu::UnoType<bool>::get() )
783
0
                {
784
0
                    bool b = InStream->readBoolean();
785
0
                    aValue <<= b;
786
0
                }
787
0
                else if ( *pType == cppu::UnoType<OUString>::get() )
788
0
                {
789
0
                    OUString aUTF = InStream->readUTF();
790
0
                    aValue <<= aUTF;
791
0
                }
792
0
                else if ( *pType == ::cppu::UnoType< ::cppu::UnoUnsignedShortType >::get() )
793
0
                {
794
0
                    sal_uInt16 n = InStream->readShort();
795
0
                    aValue <<= n;
796
0
                }
797
0
                else if ( *pType == cppu::UnoType<sal_Int16>::get() )
798
0
                {
799
0
                    sal_Int16 n = InStream->readShort();
800
0
                    aValue <<= n;
801
0
                }
802
0
                else if ( *pType == cppu::UnoType<sal_uInt32>::get() )
803
0
                {
804
0
                    sal_uInt32 n = InStream->readLong();
805
0
                    aValue <<= n;
806
0
                }
807
0
                else if ( *pType == cppu::UnoType<sal_Int32>::get() )
808
0
                {
809
0
                    sal_Int32 n = InStream->readLong();
810
0
                    aValue <<= n;
811
0
                }
812
0
                else if ( *pType == cppu::UnoType<double>::get() )
813
0
                {
814
0
                    double n = InStream->readDouble();
815
0
                    aValue <<= n;
816
0
                }
817
0
                else if ( *pType == cppu::UnoType< css::awt::FontDescriptor >::get() )
818
0
                {
819
0
                    css::awt::FontDescriptor aFD;
820
0
                    aFD.Name = InStream->readUTF();
821
0
                    aFD.Height = InStream->readShort();
822
0
                    aFD.Width = InStream->readShort();
823
0
                    aFD.StyleName = InStream->readUTF();
824
0
                    aFD.Family = InStream->readShort();
825
0
                    aFD.CharSet = InStream->readShort();
826
0
                    aFD.Pitch = InStream->readShort();
827
0
                    aFD.CharacterWidth = static_cast<float>(InStream->readDouble());
828
0
                    aFD.Weight = static_cast<float>(InStream->readDouble());
829
0
                    aFD.Slant =  static_cast<css::awt::FontSlant>(InStream->readShort());
830
0
                    aFD.Underline = InStream->readShort();
831
0
                    aFD.Strikeout = InStream->readShort();
832
0
                    aFD.Orientation = static_cast<float>(InStream->readDouble());
833
0
                    aFD.Kerning = InStream->readBoolean() != 0;
834
0
                    aFD.WordLineMode = InStream->readBoolean() != 0;
835
0
                    aFD.Type = InStream->readShort();
836
0
                    aValue <<= aFD;
837
0
                }
838
0
                else if ( *pType == cppu::UnoType<css::util::Date>::get() )
839
0
                {
840
0
                    sal_Int32 n = InStream->readLong(); // YYYYMMDD
841
0
                    aValue <<= css::util::Date(
842
0
                        n % 100, (n / 100) % 100, n / 10000);
843
0
                }
844
0
                else if ( *pType == cppu::UnoType<css::util::Time>::get() )
845
0
                {
846
0
                    sal_Int32 n = InStream->readLong(); // HHMMSShh
847
0
                    aValue <<= css::util::Time(
848
0
                        (n % 100) * 1000000, (n / 100) % 100, (n / 10000) % 100,
849
0
                        n / 1000000, false);
850
0
                }
851
0
                else if ( *pType == cppu::UnoType< css::uno::Sequence< OUString> >::get() )
852
0
                {
853
0
                    tools::Long nEntries = InStream->readLong();
854
0
                    css::uno::Sequence< OUString> aSeq( nEntries );
855
0
                    for ( tools::Long n = 0; n < nEntries; n++ )
856
0
                        aSeq.getArray()[n] = InStream->readUTF();
857
0
                    aValue <<= aSeq;
858
859
0
                }
860
0
                else if ( *pType == cppu::UnoType< cppu::UnoSequenceType<cppu::UnoUnsignedShortType> >::get() )
861
862
0
                {
863
0
                    tools::Long nEntries = InStream->readLong();
864
0
                    css::uno::Sequence<sal_uInt16> aSeq( nEntries );
865
0
                    for ( tools::Long n = 0; n < nEntries; n++ )
866
0
                        aSeq.getArray()[n] = static_cast<sal_uInt16>(InStream->readShort());
867
0
                    aValue <<= aSeq;
868
0
                }
869
0
                else if ( *pType == cppu::UnoType< css::uno::Sequence<sal_Int16> >::get() )
870
0
                {
871
0
                    tools::Long nEntries = InStream->readLong();
872
0
                    css::uno::Sequence<sal_Int16> aSeq( nEntries );
873
0
                    for ( tools::Long n = 0; n < nEntries; n++ )
874
0
                        aSeq.getArray()[n] = InStream->readShort();
875
0
                    aValue <<= aSeq;
876
0
                }
877
0
                else if ( pType->getTypeClass() == TypeClass_ENUM )
878
0
                {
879
0
                    sal_Int32 nAsInt = InStream->readLong();
880
0
                    aValue = ::cppu::int2enum( nAsInt, *pType );
881
0
                }
882
0
                else
883
0
                {
884
0
                    SAL_WARN( "toolkit", "UnoControlModel::read: don't know how to handle a property of type '"
885
0
                                << pType->getTypeName()
886
0
                                << "'.\n(Currently handling property '"
887
0
                                << GetPropertyName( nPropId )
888
0
                                << "'.)");
889
0
                }
890
0
            }
891
0
            else
892
0
            {
893
                // Old trash from 5.0
894
0
                if ( nPropId == BASEPROPERTY_FONT_TYPE )
895
0
                {
896
                    // Redundant information for older versions
897
                    // is skipped by MarkableStream
898
0
                    if ( nVersion < 2 )
899
0
                    {
900
0
                        if ( !pFD )
901
0
                        {
902
0
                            pFD.reset(new css::awt::FontDescriptor);
903
0
                            auto it = maData.find( BASEPROPERTY_FONTDESCRIPTOR );
904
0
                            if ( it != maData.end() ) // due to defaults...
905
0
                                it->second >>= *pFD;
906
0
                        }
907
0
                        pFD->Name = InStream->readUTF();
908
0
                        pFD->StyleName = InStream->readUTF();
909
0
                        pFD->Family = InStream->readShort();
910
0
                        pFD->CharSet = InStream->readShort();
911
0
                        pFD->Pitch = InStream->readShort();
912
0
                    }
913
0
                }
914
0
                else if ( nPropId == BASEPROPERTY_FONT_SIZE )
915
0
                {
916
0
                    if ( nVersion < 2 )
917
0
                    {
918
0
                        if ( !pFD )
919
0
                        {
920
0
                            pFD.reset(new css::awt::FontDescriptor);
921
0
                            auto it = maData.find(BASEPROPERTY_FONTDESCRIPTOR);
922
0
                            if ( it != maData.end() ) // due to defaults...
923
0
                                it->second >>= *pFD;
924
0
                        }
925
0
                        pFD->Width = static_cast<sal_Int16>(InStream->readLong());
926
0
                        pFD->Height = static_cast<sal_Int16>(InStream->readLong());
927
0
                        InStream->readShort(); // ignore css::awt::FontWidth - it was
928
                                               // misspelled and is no longer needed
929
0
                        pFD->CharacterWidth = css::awt::FontWidth::DONTKNOW;
930
0
                    }
931
0
                }
932
0
                else if ( nPropId == BASEPROPERTY_FONT_ATTRIBS )
933
0
                {
934
0
                    if ( nVersion < 2 )
935
0
                    {
936
0
                        if ( !pFD )
937
0
                        {
938
0
                            pFD.reset(new css::awt::FontDescriptor);
939
0
                            auto it = maData.find(BASEPROPERTY_FONTDESCRIPTOR);
940
0
                            if ( it != maData.end() ) // due to defaults...
941
0
                                it->second >>= *pFD;
942
0
                        }
943
0
                        pFD->Weight = vcl::unohelper::ConvertFontWeight(static_cast<FontWeight>(InStream->readShort()));
944
0
                        pFD->Slant =  static_cast<css::awt::FontSlant>(InStream->readShort());
945
0
                        pFD->Underline = InStream->readShort();
946
0
                        pFD->Strikeout = InStream->readShort();
947
0
                        pFD->Orientation = static_cast<float>(static_cast<double>(InStream->readShort())) / 10;
948
0
                        pFD->Kerning = InStream->readBoolean() != 0;
949
0
                        pFD->WordLineMode = InStream->readBoolean() != 0;
950
0
                    }
951
0
                }
952
0
                else
953
0
                {
954
0
                    OSL_FAIL( "read: unknown Property!" );
955
0
                }
956
0
            }
957
0
        }
958
0
        else // bVoid
959
0
        {
960
0
            if ( nPropId == BASEPROPERTY_FONTDESCRIPTOR )
961
0
            {
962
0
                EmptyFontDescriptor aFD;
963
0
                aValue <<= aFD;
964
0
            }
965
0
        }
966
967
0
        if ( maData.find( nPropId ) != maData.end() )
968
0
        {
969
0
            aProps.getArray()[i] = GetPropertyName( nPropId );
970
0
            aValues.getArray()[i] = std::move(aValue);
971
0
        }
972
0
        else
973
0
        {
974
0
            bInvalidEntries = true;
975
0
        }
976
977
        // Skip rest of input if there is more data in stream than this version can handle
978
0
        xMark->jumpToMark( nPropDataBeginMark );
979
0
        InStream->skipBytes( nPropDataLen );
980
0
        xMark->deleteMark(nPropDataBeginMark);
981
0
    }
982
0
    if ( bInvalidEntries )
983
0
    {
984
0
        for ( sal_Int32 i = 0; i < aProps.getLength(); i++ )
985
0
        {
986
0
            if ( aProps.getConstArray()[i].isEmpty() )
987
0
            {
988
0
                ::comphelper::removeElementAt( aProps, i );
989
0
                ::comphelper::removeElementAt( aValues, i );
990
0
                i--;
991
0
            }
992
0
        }
993
0
    }
994
995
0
    try
996
0
    {
997
0
        setPropertyValuesImpl( aGuard, aProps, aValues );
998
0
    }
999
0
    catch ( const Exception& )
1000
0
    {
1001
0
        DBG_UNHANDLED_EXCEPTION("toolkit.controls");
1002
0
    }
1003
1004
0
    if ( pFD )
1005
0
    {
1006
0
        css::uno::Any aValue;
1007
0
        aValue <<= *pFD;
1008
0
        setFastPropertyValueImpl( aGuard, BASEPROPERTY_FONTDESCRIPTOR, aValue );
1009
0
    }
1010
0
}
1011
1012
1013
// css::lang::XServiceInfo
1014
OUString UnoControlModel::getImplementationName(  )
1015
0
{
1016
0
    OSL_FAIL( "This method should be overridden!" );
1017
0
    return OUString();
1018
1019
0
}
1020
1021
sal_Bool UnoControlModel::supportsService( const OUString& rServiceName )
1022
0
{
1023
0
    return cppu::supportsService(this, rServiceName);
1024
0
}
1025
1026
css::uno::Sequence< OUString > UnoControlModel::getSupportedServiceNames(  )
1027
0
{
1028
0
    return { u"com.sun.star.awt.UnoControlModel"_ustr };
1029
0
}
1030
1031
bool UnoControlModel::convertFastPropertyValue( std::unique_lock<std::mutex>& rGuard, Any & rConvertedValue, Any & rOldValue, sal_Int32 nPropId, const Any& rValue )
1032
0
{
1033
0
    bool bVoid = rValue.getValueTypeClass() == css::uno::TypeClass_VOID;
1034
0
    if ( bVoid )
1035
0
    {
1036
0
        rConvertedValue.clear();
1037
0
    }
1038
0
    else
1039
0
    {
1040
0
        const css::uno::Type* pDestType = GetPropertyType( static_cast<sal_uInt16>(nPropId) );
1041
0
        if ( pDestType->getTypeClass() == TypeClass_ANY )
1042
0
        {
1043
0
            rConvertedValue = rValue;
1044
0
        }
1045
0
        else
1046
0
        {
1047
0
            if ( pDestType->equals( rValue.getValueType() ) )
1048
0
            {
1049
0
                rConvertedValue = rValue;
1050
0
            }
1051
0
            else
1052
0
            {
1053
0
                bool bConverted = false;
1054
                // 13.03.2001 - 84923 - frank.schoenheit@germany.sun.com
1055
1056
0
                switch (pDestType->getTypeClass())
1057
0
                {
1058
0
                    case TypeClass_DOUBLE:
1059
0
                    {
1060
                        // try as double
1061
0
                        double nAsDouble = 0;
1062
0
                        bConverted = ( rValue >>= nAsDouble );
1063
0
                        if ( bConverted )
1064
0
                            rConvertedValue <<= nAsDouble;
1065
0
                        else
1066
0
                        {   // try as integer
1067
0
                            sal_Int32 nAsInteger = 0;
1068
0
                            bConverted = ( rValue >>= nAsInteger );
1069
0
                            if ( bConverted )
1070
0
                                rConvertedValue <<= static_cast<double>(nAsInteger);
1071
0
                        }
1072
0
                    }
1073
0
                    break;
1074
0
                    case TypeClass_SHORT:
1075
0
                    {
1076
0
                        sal_Int16 n;
1077
0
                        bConverted = ( rValue >>= n );
1078
0
                        if ( bConverted )
1079
0
                            rConvertedValue <<= n;
1080
0
                    }
1081
0
                    break;
1082
0
                    case TypeClass_UNSIGNED_SHORT:
1083
0
                    {
1084
0
                        sal_uInt16 n;
1085
0
                        bConverted = ( rValue >>= n );
1086
0
                        if ( bConverted )
1087
0
                            rConvertedValue <<= n;
1088
0
                    }
1089
0
                    break;
1090
0
                    case TypeClass_LONG:
1091
0
                    {
1092
0
                        sal_Int32 n;
1093
0
                        bConverted = ( rValue >>= n );
1094
0
                        if ( bConverted )
1095
0
                            rConvertedValue <<= n;
1096
0
                    }
1097
0
                    break;
1098
0
                    case TypeClass_UNSIGNED_LONG:
1099
0
                    {
1100
0
                        sal_uInt32 n;
1101
0
                        bConverted = ( rValue >>= n );
1102
0
                        if ( bConverted )
1103
0
                            rConvertedValue <<= n;
1104
0
                    }
1105
0
                    break;
1106
0
                    case TypeClass_INTERFACE:
1107
0
                    {
1108
0
                        if ( rValue.getValueTypeClass() == TypeClass_INTERFACE )
1109
0
                        {
1110
0
                            Reference< XInterface > xPure( rValue, UNO_QUERY );
1111
0
                            if ( xPure.is() )
1112
0
                                rConvertedValue = xPure->queryInterface( *pDestType );
1113
0
                            else
1114
0
                                rConvertedValue.setValue( nullptr, *pDestType );
1115
0
                            bConverted = true;
1116
0
                        }
1117
0
                    }
1118
0
                    break;
1119
0
                    case TypeClass_ENUM:
1120
0
                    {
1121
0
                        sal_Int32 nValue = 0;
1122
0
                        bConverted = ( rValue >>= nValue );
1123
0
                        if ( bConverted )
1124
0
                            rConvertedValue = ::cppu::int2enum( nValue, *pDestType );
1125
0
                    }
1126
0
                    break;
1127
0
                    default: ; // avoid compiler warning
1128
0
                }
1129
1130
0
                if (!bConverted)
1131
0
                {
1132
0
                    throw css::lang::IllegalArgumentException(
1133
0
                        "Unable to convert the given value for the property "
1134
0
                        + GetPropertyName( static_cast<sal_uInt16>(nPropId) )
1135
0
                        + ".\nExpected type: " + pDestType->getTypeName()
1136
0
                        + "\nFound type: " + rValue.getValueTypeName(),
1137
0
                        static_cast< css::beans::XPropertySet* >(this),
1138
0
                        1);
1139
0
                }
1140
0
            }
1141
0
        }
1142
0
    }
1143
1144
    // the current value
1145
0
    getFastPropertyValue( rGuard, rOldValue, nPropId );
1146
0
    return !CompareProperties( rConvertedValue, rOldValue );
1147
0
}
1148
1149
void UnoControlModel::setFastPropertyValue_NoBroadcast( std::unique_lock<std::mutex>& /*rGuard*/, sal_Int32 nPropId, const css::uno::Any& rValue )
1150
0
{
1151
    // Missing: the fake solo properties of the FontDescriptor
1152
1153
0
    ImplPropertyTable::const_iterator it = maData.find( nPropId );
1154
0
    const css::uno::Any* pProp = it == maData.end() ? nullptr : &(it->second);
1155
0
    ENSURE_OR_RETURN_VOID( pProp, "UnoControlModel::setFastPropertyValue_NoBroadcast: invalid property id!" );
1156
1157
0
    DBG_ASSERT( ( rValue.getValueTypeClass() != css::uno::TypeClass_VOID ) || ( GetPropertyAttribs( static_cast<sal_uInt16>(nPropId) ) & css::beans::PropertyAttribute::MAYBEVOID ), "Property should not be VOID!" );
1158
0
    maData[ nPropId ] = rValue;
1159
0
}
1160
1161
void UnoControlModel::getFastPropertyValue( std::unique_lock<std::mutex>& /*rGuard*/, css::uno::Any& rValue, sal_Int32 nPropId ) const
1162
0
{
1163
0
    ImplPropertyTable::const_iterator it = maData.find( nPropId );
1164
0
    const css::uno::Any* pProp = it == maData.end() ? nullptr : &(it->second);
1165
1166
0
    if ( pProp )
1167
0
        rValue = *pProp;
1168
0
    else if ( ( nPropId >= BASEPROPERTY_FONTDESCRIPTORPART_START ) && ( nPropId <= BASEPROPERTY_FONTDESCRIPTORPART_END ) )
1169
0
    {
1170
0
        const auto iter = maData.find( BASEPROPERTY_FONTDESCRIPTOR );
1171
0
        assert(iter != maData.end());
1172
0
        pProp = &(iter->second);
1173
0
        css::awt::FontDescriptor aFD;
1174
0
        (*pProp) >>= aFD;
1175
0
        switch ( nPropId )
1176
0
        {
1177
0
            case BASEPROPERTY_FONTDESCRIPTORPART_NAME:          rValue <<= aFD.Name;
1178
0
                                                                break;
1179
0
            case BASEPROPERTY_FONTDESCRIPTORPART_STYLENAME:     rValue <<= aFD.StyleName;
1180
0
                                                                break;
1181
0
            case BASEPROPERTY_FONTDESCRIPTORPART_FAMILY:        rValue <<= aFD.Family;
1182
0
                                                                break;
1183
0
            case BASEPROPERTY_FONTDESCRIPTORPART_CHARSET:       rValue <<= aFD.CharSet;
1184
0
                                                                break;
1185
0
            case BASEPROPERTY_FONTDESCRIPTORPART_HEIGHT:        rValue <<= static_cast<float>(aFD.Height);
1186
0
                                                                break;
1187
0
            case BASEPROPERTY_FONTDESCRIPTORPART_WEIGHT:        rValue <<= aFD.Weight;
1188
0
                                                                break;
1189
0
            case BASEPROPERTY_FONTDESCRIPTORPART_SLANT:         rValue <<= static_cast<sal_Int16>(aFD.Slant);
1190
0
                                                                break;
1191
0
            case BASEPROPERTY_FONTDESCRIPTORPART_UNDERLINE:     rValue <<= aFD.Underline;
1192
0
                                                                break;
1193
0
            case BASEPROPERTY_FONTDESCRIPTORPART_STRIKEOUT:     rValue <<= aFD.Strikeout;
1194
0
                                                                break;
1195
0
            case BASEPROPERTY_FONTDESCRIPTORPART_WIDTH:         rValue <<= aFD.Width;
1196
0
                                                                break;
1197
0
            case BASEPROPERTY_FONTDESCRIPTORPART_PITCH:         rValue <<= aFD.Pitch;
1198
0
                                                                break;
1199
0
            case BASEPROPERTY_FONTDESCRIPTORPART_CHARWIDTH:     rValue <<= aFD.CharacterWidth;
1200
0
                                                                break;
1201
0
            case BASEPROPERTY_FONTDESCRIPTORPART_ORIENTATION:   rValue <<= aFD.Orientation;
1202
0
                                                                break;
1203
0
            case BASEPROPERTY_FONTDESCRIPTORPART_KERNING:       rValue <<= aFD.Kerning;
1204
0
                                                                break;
1205
0
            case BASEPROPERTY_FONTDESCRIPTORPART_WORDLINEMODE:  rValue <<= aFD.WordLineMode;
1206
0
                                                                break;
1207
0
            case BASEPROPERTY_FONTDESCRIPTORPART_TYPE:          rValue <<= aFD.Type;
1208
0
                                                                break;
1209
0
            default: OSL_FAIL( "FontProperty?!" );
1210
0
        }
1211
0
    }
1212
0
    else
1213
0
    {
1214
0
        OSL_FAIL( "getFastPropertyValue - invalid Property!" );
1215
0
    }
1216
0
}
1217
1218
// css::beans::XFastPropertySet
1219
void UnoControlModel::setFastPropertyValueImpl( std::unique_lock<std::mutex>& rGuard, sal_Int32 nPropId, const css::uno::Any& rValue )
1220
0
{
1221
0
    if ( ( nPropId >= BASEPROPERTY_FONTDESCRIPTORPART_START ) && ( nPropId <= BASEPROPERTY_FONTDESCRIPTORPART_END ) )
1222
0
    {
1223
0
        Any aOldSingleValue;
1224
0
        getFastPropertyValue( rGuard, aOldSingleValue, BASEPROPERTY_FONTDESCRIPTORPART_START );
1225
1226
0
        css::uno::Any* pProp = &maData[ BASEPROPERTY_FONTDESCRIPTOR ];
1227
0
        FontDescriptor aFontDescriptor;
1228
0
        (*pProp) >>= aFontDescriptor;
1229
1230
0
        lcl_ImplMergeFontProperty(aFontDescriptor, static_cast<sal_uInt16>(nPropId), rValue);
1231
1232
0
        Any aNewValue;
1233
0
        aNewValue <<= aFontDescriptor;
1234
0
        sal_Int32 nDescriptorId = BASEPROPERTY_FONTDESCRIPTOR;
1235
1236
        // also, we need  fire a propertyChange event for the single property, since with
1237
        // the above line, only an event for the FontDescriptor property will be fired
1238
0
        Any aNewSingleValue;
1239
0
        getFastPropertyValue( rGuard, aNewSingleValue, BASEPROPERTY_FONTDESCRIPTORPART_START );
1240
1241
0
        setFastPropertyValues( rGuard, 1, &nDescriptorId, &aNewValue, 1 );
1242
0
        fire( rGuard, &nPropId, &aNewSingleValue, &aOldSingleValue, 1, false );
1243
0
    }
1244
0
    else
1245
0
        setFastPropertyValues( rGuard, 1, &nPropId, &rValue, 1 );
1246
0
}
1247
1248
// css::beans::XMultiPropertySet
1249
css::uno::Reference< css::beans::XPropertySetInfo > UnoControlModel::getPropertySetInfo(  )
1250
0
{
1251
0
    OSL_FAIL( "UnoControlModel::getPropertySetInfo() not possible!" );
1252
0
    return css::uno::Reference< css::beans::XPropertySetInfo >();
1253
0
}
1254
1255
void UnoControlModel::setPropertyValues( const css::uno::Sequence< OUString >& rPropertyNames, const css::uno::Sequence< css::uno::Any >& Values )
1256
0
{
1257
0
    std::unique_lock aGuard( m_aMutex );
1258
0
    setPropertyValuesImpl(aGuard, rPropertyNames, Values);
1259
0
}
1260
1261
void UnoControlModel::setPropertyValuesImpl( std::unique_lock<std::mutex>& rGuard, const css::uno::Sequence< OUString >& rPropertyNames, const css::uno::Sequence< css::uno::Any >& Values )
1262
0
{
1263
0
    sal_Int32 nProps = rPropertyNames.getLength();
1264
0
    if (nProps != Values.getLength())
1265
0
        throw css::lang::IllegalArgumentException(u"lengths do not match"_ustr,
1266
0
                                                  getXWeak(), -1);
1267
1268
//  sal_Int32* pHandles = new sal_Int32[nProps];
1269
        // don't do this - it leaks in case of an exception
1270
0
    Sequence< sal_Int32 > aHandles( nProps );
1271
0
    sal_Int32* pHandles = aHandles.getArray();
1272
1273
    // may need to change the order in the sequence, for this we need a non-const value sequence
1274
0
    uno::Sequence< uno::Any > aValues( Values );
1275
0
    uno::Any* pValues = aValues.getArray();
1276
1277
0
    sal_Int32 nValidHandles = getInfoHelper().fillHandles( pHandles, rPropertyNames );
1278
1279
0
    if ( !nValidHandles )
1280
0
        return;
1281
1282
    // if somebody sets properties which are single aspects of a font descriptor,
1283
    // remove them, and build a font descriptor instead
1284
0
    std::unique_ptr< awt::FontDescriptor > pFD;
1285
0
    for ( sal_Int32 n = 0; n < nProps; ++n )
1286
0
    {
1287
0
        if ( ( pHandles[n] >= BASEPROPERTY_FONTDESCRIPTORPART_START ) && ( pHandles[n] <= BASEPROPERTY_FONTDESCRIPTORPART_END ) )
1288
0
        {
1289
0
            if (!pFD)
1290
0
            {
1291
0
                css::uno::Any* pProp = &maData[ BASEPROPERTY_FONTDESCRIPTOR ];
1292
0
                pFD.reset( new awt::FontDescriptor );
1293
0
                (*pProp) >>= *pFD;
1294
0
            }
1295
0
            lcl_ImplMergeFontProperty( *pFD, static_cast<sal_uInt16>(pHandles[n]), pValues[n] );
1296
0
            pHandles[n] = -1;
1297
0
            nValidHandles--;
1298
0
        }
1299
0
    }
1300
1301
0
    if ( nValidHandles )
1302
0
    {
1303
0
        ImplNormalizePropertySequence( nProps, pHandles, pValues, &nValidHandles );
1304
0
        setFastPropertyValues( rGuard, nProps, pHandles, pValues, nValidHandles );
1305
0
    }
1306
1307
    // Don't merge FD property into array, as it is sorted
1308
0
    if (pFD)
1309
0
    {
1310
0
        css::uno::Any aValue;
1311
0
        aValue <<= *pFD;
1312
0
        sal_Int32 nHandle = BASEPROPERTY_FONTDESCRIPTOR;
1313
0
        setFastPropertyValues( rGuard, 1, &nHandle, &aValue, 1 );
1314
0
    }
1315
0
}
1316
1317
1318
void UnoControlModel::ImplNormalizePropertySequence( const sal_Int32, sal_Int32*,
1319
    uno::Any*, sal_Int32* ) const
1320
0
{
1321
    // nothing to do here
1322
0
}
1323
1324
void UnoControlModel::ImplEnsureHandleOrder( const sal_Int32 _nCount, sal_Int32* _pHandles,
1325
        uno::Any* _pValues, sal_Int32 _nFirstHandle, sal_Int32 _nSecondHandle )
1326
0
{
1327
0
    for ( sal_Int32 i=0; i < _nCount; ++_pHandles, ++_pValues, ++i )
1328
0
    {
1329
0
        if ( _nSecondHandle  == *_pHandles )
1330
0
        {
1331
0
            sal_Int32* pLaterHandles = _pHandles + 1;
1332
0
            uno::Any* pLaterValues = _pValues + 1;
1333
0
            for ( sal_Int32 j = i + 1; j < _nCount; ++j, ++pLaterHandles, ++pLaterValues )
1334
0
            {
1335
0
                if ( _nFirstHandle == *pLaterHandles )
1336
0
                {
1337
                    // indeed it is -> exchange the both places in the sequences
1338
0
                    std::swap(*_pHandles, *pLaterHandles);
1339
0
                    std::swap(*_pValues, *pLaterValues);
1340
0
                    break;
1341
                    // this will leave the inner loop, and continue with the outer loop.
1342
                    // Note that this means we will encounter the _nSecondHandle handle, again, once we reached
1343
                    // (in the outer loop) the place where we just put it.
1344
0
                }
1345
0
            }
1346
0
        }
1347
0
    }
1348
0
}
1349
1350
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */