Coverage Report

Created: 2026-07-10 11:04

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