Coverage Report

Created: 2026-08-14 10:22

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/sc/source/ui/unoobj/fmtuno.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 <sal/config.h>
21
22
#include <o3tl/safeint.hxx>
23
#include <osl/diagnose.h>
24
#include <svl/style.hxx>
25
#include <utility>
26
#include <vcl/svapp.hxx>
27
#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
28
#include <com/sun/star/sheet/ConditionOperator2.hpp>
29
#include <com/sun/star/sheet/ValidationAlertStyle.hpp>
30
#include <com/sun/star/sheet/ValidationType.hpp>
31
#include <com/sun/star/sheet/TableValidationVisibility.hpp>
32
33
#include <fmtuno.hxx>
34
#include <miscuno.hxx>
35
#include <validat.hxx>
36
#include <document.hxx>
37
#include <unonames.hxx>
38
#include <tokenarray.hxx>
39
#include <tokenuno.hxx>
40
#include <stylehelper.hxx>
41
42
using namespace ::com::sun::star;
43
using namespace ::formula;
44
45
//  map only for PropertySetInfo
46
47
static std::span<const SfxItemPropertyMapEntry> lcl_GetValidatePropertyMap()
48
754
{
49
754
    static const SfxItemPropertyMapEntry aValidatePropertyMap_Impl[] =
50
754
    {
51
754
        { SC_UNONAME_ERRALSTY, 0,  cppu::UnoType<sheet::ValidationAlertStyle>::get(),  0, 0},
52
754
        { SC_UNONAME_ERRMESS,  0,  cppu::UnoType<OUString>::get(),                0, 0},
53
754
        { SC_UNONAME_ERRTITLE, 0,  cppu::UnoType<OUString>::get(),                0, 0},
54
754
        { SC_UNONAME_IGNOREBL, 0,  cppu::UnoType<bool>::get(),                          0, 0},
55
754
        { SC_UNONAME_ISCASE,   0,  cppu::UnoType<bool>::get(),                          0, 0},
56
754
        { SC_UNONAME_INPMESS,  0,  cppu::UnoType<OUString>::get(),                0, 0},
57
754
        { SC_UNONAME_INPTITLE, 0,  cppu::UnoType<OUString>::get(),                0, 0},
58
754
        { SC_UNONAME_SHOWERR,  0,  cppu::UnoType<bool>::get(),                          0, 0},
59
754
        { SC_UNONAME_SHOWINP,  0,  cppu::UnoType<bool>::get(),                          0, 0},
60
754
        { SC_UNONAME_SHOWLIST, 0,  cppu::UnoType<sal_Int16>::get(),                    0, 0},
61
754
        { SC_UNONAME_TYPE,     0,  cppu::UnoType<sheet::ValidationType>::get(),        0, 0},
62
754
    };
63
754
    return aValidatePropertyMap_Impl;
64
754
}
65
66
SC_SIMPLE_SERVICE_INFO( ScTableConditionalEntry, u"ScTableConditionalEntry"_ustr, u"com.sun.star.sheet.TableConditionalEntry"_ustr )
67
SC_SIMPLE_SERVICE_INFO( ScTableConditionalFormat, u"ScTableConditionalFormat"_ustr, u"com.sun.star.sheet.TableConditionalFormat"_ustr )
68
SC_SIMPLE_SERVICE_INFO( ScTableValidationObj, u"ScTableValidationObj"_ustr, u"com.sun.star.sheet.TableValidation"_ustr )
69
70
static sal_Int32 lcl_ConditionModeToOperatorNew( ScConditionMode eMode )
71
0
{
72
0
    sal_Int32 eOper = sheet::ConditionOperator2::NONE;
73
0
    switch (eMode)
74
0
    {
75
0
        case ScConditionMode::Equal:         eOper = sheet::ConditionOperator2::EQUAL;           break;
76
0
        case ScConditionMode::Less:          eOper = sheet::ConditionOperator2::LESS;            break;
77
0
        case ScConditionMode::Greater:       eOper = sheet::ConditionOperator2::GREATER;         break;
78
0
        case ScConditionMode::EqLess:        eOper = sheet::ConditionOperator2::LESS_EQUAL;      break;
79
0
        case ScConditionMode::EqGreater:     eOper = sheet::ConditionOperator2::GREATER_EQUAL;   break;
80
0
        case ScConditionMode::NotEqual:      eOper = sheet::ConditionOperator2::NOT_EQUAL;       break;
81
0
        case ScConditionMode::Between:       eOper = sheet::ConditionOperator2::BETWEEN;         break;
82
0
        case ScConditionMode::NotBetween:    eOper = sheet::ConditionOperator2::NOT_BETWEEN;     break;
83
0
        case ScConditionMode::Direct:        eOper = sheet::ConditionOperator2::FORMULA;         break;
84
0
        case ScConditionMode::Duplicate:     eOper = sheet::ConditionOperator2::DUPLICATE;       break;
85
0
        default:
86
0
        {
87
            // added to avoid warnings
88
0
        }
89
0
    }
90
0
    return eOper;
91
0
}
92
93
static sheet::ConditionOperator lcl_ConditionModeToOperator( ScConditionMode eMode )
94
0
{
95
0
    sheet::ConditionOperator eOper = sheet::ConditionOperator_NONE;
96
0
    switch (eMode)
97
0
    {
98
0
        case ScConditionMode::Equal:         eOper = sheet::ConditionOperator_EQUAL;         break;
99
0
        case ScConditionMode::Less:          eOper = sheet::ConditionOperator_LESS;          break;
100
0
        case ScConditionMode::Greater:       eOper = sheet::ConditionOperator_GREATER;       break;
101
0
        case ScConditionMode::EqLess:        eOper = sheet::ConditionOperator_LESS_EQUAL;    break;
102
0
        case ScConditionMode::EqGreater:     eOper = sheet::ConditionOperator_GREATER_EQUAL; break;
103
0
        case ScConditionMode::NotEqual:      eOper = sheet::ConditionOperator_NOT_EQUAL;     break;
104
0
        case ScConditionMode::Between:       eOper = sheet::ConditionOperator_BETWEEN;       break;
105
0
        case ScConditionMode::NotBetween:    eOper = sheet::ConditionOperator_NOT_BETWEEN;   break;
106
0
        case ScConditionMode::Direct:        eOper = sheet::ConditionOperator_FORMULA;       break;
107
0
        default:
108
0
        {
109
            // added to avoid warnings
110
0
        }
111
0
    }
112
0
    return eOper;
113
0
}
114
115
static ScConditionMode lcl_ConditionOperatorToMode( sheet::ConditionOperator eOper )
116
0
{
117
0
    ScConditionMode eMode = ScConditionMode::NONE;
118
0
    switch (eOper)
119
0
    {
120
0
        case sheet::ConditionOperator_EQUAL:            eMode = ScConditionMode::Equal;      break;
121
0
        case sheet::ConditionOperator_LESS:             eMode = ScConditionMode::Less;       break;
122
0
        case sheet::ConditionOperator_GREATER:          eMode = ScConditionMode::Greater;    break;
123
0
        case sheet::ConditionOperator_LESS_EQUAL:       eMode = ScConditionMode::EqLess;     break;
124
0
        case sheet::ConditionOperator_GREATER_EQUAL:    eMode = ScConditionMode::EqGreater;  break;
125
0
        case sheet::ConditionOperator_NOT_EQUAL:        eMode = ScConditionMode::NotEqual;   break;
126
0
        case sheet::ConditionOperator_BETWEEN:          eMode = ScConditionMode::Between;    break;
127
0
        case sheet::ConditionOperator_NOT_BETWEEN:      eMode = ScConditionMode::NotBetween; break;
128
0
        case sheet::ConditionOperator_FORMULA:          eMode = ScConditionMode::Direct;     break;
129
0
        default:
130
0
        {
131
            // added to avoid warnings
132
0
        }
133
0
    }
134
0
    return eMode;
135
0
}
136
137
ScCondFormatEntryItem::ScCondFormatEntryItem() :
138
0
    meGrammar1( FormulaGrammar::GRAM_UNSPECIFIED ),
139
0
    meGrammar2( FormulaGrammar::GRAM_UNSPECIFIED ),
140
0
    meMode( ScConditionMode::NONE )
141
0
{
142
0
}
143
144
ScTableConditionalFormat::ScTableConditionalFormat(
145
        const ScDocument& rDoc, sal_uLong nKey, SCTAB nTab, FormulaGrammar::Grammar eGrammar)
146
0
{
147
    //  read the entry from the document...
148
149
0
    if ( !nKey )
150
0
        return;
151
152
0
    ScConditionalFormatList* pList = rDoc.GetCondFormList(nTab);
153
0
    if (!pList)
154
0
        return;
155
156
0
    const ScConditionalFormat* pFormat = pList->GetFormat( nKey );
157
0
    if (!pFormat)
158
0
        return;
159
160
    // During save to XML.
161
0
    if (rDoc.IsInExternalReferenceMarking())
162
0
        pFormat->MarkUsedExternalReferences();
163
164
0
    size_t nEntryCount = pFormat->size();
165
0
    for (size_t i=0; i<nEntryCount; i++)
166
0
    {
167
0
        ScCondFormatEntryItem aItem;
168
0
        const ScFormatEntry* pFrmtEntry = pFormat->GetEntry(i);
169
0
        if(pFrmtEntry->GetType() != ScFormatEntry::Type::Condition &&
170
0
           pFrmtEntry->GetType() != ScFormatEntry::Type::ExtCondition)
171
0
            continue;
172
173
0
        const ScCondFormatEntry* pFormatEntry = static_cast<const ScCondFormatEntry*>(pFrmtEntry);
174
0
        aItem.meMode = pFormatEntry->GetOperation();
175
0
        aItem.maPos = pFormatEntry->GetValidSrcPos();
176
0
        aItem.maExpr1 = pFormatEntry->GetExpression(aItem.maPos, 0, 0, eGrammar);
177
0
        aItem.maExpr2 = pFormatEntry->GetExpression(aItem.maPos, 1, 0, eGrammar);
178
0
        aItem.meGrammar1 = aItem.meGrammar2 = eGrammar;
179
0
        aItem.maStyle = pFormatEntry->GetStyle();
180
181
0
        AddEntry_Impl(aItem);
182
0
    }
183
0
}
184
185
namespace {
186
187
FormulaGrammar::Grammar lclResolveGrammar( FormulaGrammar::Grammar eExtGrammar, FormulaGrammar::Grammar eIntGrammar )
188
1.50k
{
189
1.50k
    if( eExtGrammar != FormulaGrammar::GRAM_UNSPECIFIED )
190
1.50k
        return eExtGrammar;
191
0
    OSL_ENSURE( eIntGrammar != FormulaGrammar::GRAM_UNSPECIFIED, "lclResolveGrammar - unspecified grammar, using GRAM_API" );
192
0
    return (eIntGrammar == FormulaGrammar::GRAM_UNSPECIFIED) ? FormulaGrammar::GRAM_API : eIntGrammar;
193
1.50k
}
194
195
} // namespace
196
197
void ScTableConditionalFormat::FillFormat( ScConditionalFormat& rFormat,
198
        ScDocument& rDoc, FormulaGrammar::Grammar eGrammar) const
199
0
{
200
    //  ScConditionalFormat = Core-Struktur, has to be empty
201
202
0
    OSL_ENSURE( rFormat.IsEmpty(), "FillFormat: format not empty" );
203
204
0
    for (const auto & i : maEntries)
205
0
    {
206
0
        ScCondFormatEntryItem aData;
207
0
        i->GetData(aData);
208
209
0
        FormulaGrammar::Grammar eGrammar1 = lclResolveGrammar( eGrammar, aData.meGrammar1 );
210
0
        FormulaGrammar::Grammar eGrammar2 = lclResolveGrammar( eGrammar, aData.meGrammar2 );
211
212
0
        ScCondFormatEntry* pCoreEntry = new ScCondFormatEntry( aData.meMode, aData.maExpr1, aData.maExpr2,
213
0
            rDoc, aData.maPos, aData.maStyle, aData.maExprNmsp1, aData.maExprNmsp2, eGrammar1, eGrammar2 );
214
215
0
        if ( !aData.maPosStr.isEmpty() )
216
0
            pCoreEntry->SetSrcString( aData.maPosStr );
217
218
0
        if ( aData.maTokens1.hasElements() )
219
0
        {
220
0
            ScTokenArray aTokenArray(rDoc);
221
0
            if ( ScTokenConversion::ConvertToTokenArray(rDoc, aTokenArray, aData.maTokens1) )
222
0
                pCoreEntry->SetFormula1(aTokenArray);
223
0
        }
224
225
0
        if ( aData.maTokens2.hasElements() )
226
0
        {
227
0
            ScTokenArray aTokenArray(rDoc);
228
0
            if ( ScTokenConversion::ConvertToTokenArray(rDoc, aTokenArray, aData.maTokens2) )
229
0
                pCoreEntry->SetFormula2(aTokenArray);
230
0
        }
231
0
        rFormat.AddEntry( pCoreEntry );
232
0
    }
233
0
}
234
235
ScTableConditionalFormat::~ScTableConditionalFormat()
236
0
{
237
0
}
238
239
void ScTableConditionalFormat::AddEntry_Impl(const ScCondFormatEntryItem& aEntry)
240
0
{
241
0
    rtl::Reference<ScTableConditionalEntry> pNew = new ScTableConditionalEntry(aEntry);
242
0
    maEntries.emplace_back(pNew);
243
0
}
244
245
// XSheetConditionalFormat
246
247
ScTableConditionalEntry* ScTableConditionalFormat::GetObjectByIndex_Impl(sal_uInt16 nIndex) const
248
0
{
249
0
    return nIndex < maEntries.size() ? maEntries[nIndex].get() : nullptr;
250
0
}
251
252
void SAL_CALL ScTableConditionalFormat::addNew(
253
                    const uno::Sequence<beans::PropertyValue >& aConditionalEntry )
254
0
{
255
0
    SolarMutexGuard aGuard;
256
0
    ScCondFormatEntryItem aEntry;
257
0
    aEntry.meMode = ScConditionMode::NONE;
258
259
0
    for (const beans::PropertyValue& rProp : aConditionalEntry)
260
0
    {
261
0
        if ( rProp.Name == SC_UNONAME_OPERATOR )
262
0
        {
263
0
            sal_Int32 eOper = ScUnoHelpFunctions::GetEnumFromAny( rProp.Value );
264
0
            aEntry.meMode = ScConditionEntry::GetModeFromApi( static_cast<sheet::ConditionOperator>(eOper) );
265
0
        }
266
0
        else if ( rProp.Name == SC_UNONAME_FORMULA1 )
267
0
        {
268
0
            OUString aStrVal;
269
0
            uno::Sequence<sheet::FormulaToken> aTokens;
270
0
            if ( rProp.Value >>= aStrVal )
271
0
                aEntry.maExpr1 = aStrVal;
272
0
            else if ( rProp.Value >>= aTokens )
273
0
            {
274
0
                aEntry.maExpr1.clear();
275
0
                aEntry.maTokens1 = std::move(aTokens);
276
0
            }
277
0
        }
278
0
        else if ( rProp.Name == SC_UNONAME_FORMULA2 )
279
0
        {
280
0
            OUString aStrVal;
281
0
            uno::Sequence<sheet::FormulaToken> aTokens;
282
0
            if ( rProp.Value >>= aStrVal )
283
0
                aEntry.maExpr2 = aStrVal;
284
0
            else if ( rProp.Value >>= aTokens )
285
0
            {
286
0
                aEntry.maExpr2.clear();
287
0
                aEntry.maTokens2 = std::move(aTokens);
288
0
            }
289
0
        }
290
0
        else if ( rProp.Name == SC_UNONAME_SOURCEPOS )
291
0
        {
292
0
            table::CellAddress aAddress;
293
0
            if ( rProp.Value >>= aAddress )
294
0
                aEntry.maPos = ScAddress( static_cast<SCCOL>(aAddress.Column), static_cast<SCROW>(aAddress.Row), aAddress.Sheet );
295
0
        }
296
0
        else if ( rProp.Name == SC_UNONAME_SOURCESTR )
297
0
        {
298
0
            OUString aStrVal;
299
0
            if ( rProp.Value >>= aStrVal )
300
0
                aEntry.maPosStr = aStrVal;
301
0
        }
302
0
        else if ( rProp.Name == SC_UNONAME_STYLENAME )
303
0
        {
304
0
            OUString aStrVal;
305
0
            if ( rProp.Value >>= aStrVal )
306
0
                aEntry.maStyle = ScStyleNameConversion::ProgrammaticToDisplayName(
307
0
                                                aStrVal, SfxStyleFamily::Para );
308
0
        }
309
0
        else if ( rProp.Name == SC_UNONAME_FORMULANMSP1 )
310
0
        {
311
0
            OUString aStrVal;
312
0
            if ( rProp.Value >>= aStrVal )
313
0
                aEntry.maExprNmsp1 = aStrVal;
314
0
        }
315
0
        else if ( rProp.Name == SC_UNONAME_FORMULANMSP2 )
316
0
        {
317
0
            OUString aStrVal;
318
0
            if ( rProp.Value >>= aStrVal )
319
0
                aEntry.maExprNmsp2 = aStrVal;
320
0
        }
321
0
        else if ( rProp.Name == SC_UNONAME_GRAMMAR1 )
322
0
        {
323
0
            sal_Int32 nVal = 0;
324
0
            if ( rProp.Value >>= nVal )
325
0
                aEntry.meGrammar1 = static_cast< FormulaGrammar::Grammar >( nVal );
326
0
        }
327
0
        else if ( rProp.Name == SC_UNONAME_GRAMMAR2 )
328
0
        {
329
0
            sal_Int32 nVal = 0;
330
0
            if ( rProp.Value >>= nVal )
331
0
                aEntry.meGrammar2 = static_cast< FormulaGrammar::Grammar >( nVal );
332
0
        }
333
0
        else
334
0
        {
335
0
            OSL_FAIL("wrong property");
336
            //! Exception...
337
0
        }
338
0
    }
339
340
0
    AddEntry_Impl(aEntry);
341
0
}
342
343
void SAL_CALL ScTableConditionalFormat::removeByIndex( sal_Int32 nIndex )
344
0
{
345
0
    SolarMutexGuard aGuard;
346
347
0
    if (nIndex >= 0 && o3tl::make_unsigned(nIndex) < maEntries.size())
348
0
    {
349
0
        maEntries.erase(maEntries.begin()+nIndex);
350
0
    }
351
0
}
352
353
void SAL_CALL ScTableConditionalFormat::clear()
354
0
{
355
0
    SolarMutexGuard aGuard;
356
0
    maEntries.clear();
357
0
}
358
359
// XEnumerationAccess
360
361
uno::Reference<container::XEnumeration> SAL_CALL ScTableConditionalFormat::createEnumeration()
362
0
{
363
0
    SolarMutexGuard aGuard;
364
0
    return new ScIndexEnumeration(this, u"com.sun.star.sheet.TableConditionalEntryEnumeration"_ustr);
365
0
}
366
367
// XIndexAccess
368
369
sal_Int32 SAL_CALL ScTableConditionalFormat::getCount()
370
0
{
371
0
    SolarMutexGuard aGuard;
372
0
    return maEntries.size();
373
0
}
374
375
uno::Any SAL_CALL ScTableConditionalFormat::getByIndex( sal_Int32 nIndex )
376
0
{
377
0
    SolarMutexGuard aGuard;
378
0
    uno::Reference<sheet::XSheetConditionalEntry> xEntry(GetObjectByIndex_Impl(static_cast<sal_uInt16>(nIndex)));
379
0
    if (!xEntry.is())
380
0
        throw lang::IndexOutOfBoundsException();
381
382
0
    return uno::Any(xEntry);
383
0
}
384
385
uno::Type SAL_CALL ScTableConditionalFormat::getElementType()
386
0
{
387
0
    return cppu::UnoType<sheet::XSheetConditionalEntry>::get();
388
0
}
389
390
sal_Bool SAL_CALL ScTableConditionalFormat::hasElements()
391
0
{
392
0
    SolarMutexGuard aGuard;
393
0
    return ( getCount() != 0 );
394
0
}
395
396
//  conditional format entries have no real names
397
//  -> generate name from index
398
399
static OUString lcl_GetEntryNameFromIndex( sal_Int32 nIndex )
400
0
{
401
0
    OUString aRet = "Entry" + OUString::number( nIndex );
402
0
    return aRet;
403
0
}
404
405
uno::Any SAL_CALL ScTableConditionalFormat::getByName( const OUString& aName )
406
0
{
407
0
    SolarMutexGuard aGuard;
408
409
0
    uno::Reference<sheet::XSheetConditionalEntry> xEntry;
410
0
    tools::Long nCount = maEntries.size();
411
0
    for (tools::Long i=0; i<nCount; i++)
412
0
        if ( aName == lcl_GetEntryNameFromIndex(i) )
413
0
        {
414
0
            xEntry.set(GetObjectByIndex_Impl(static_cast<sal_uInt16>(i)));
415
0
            break;
416
0
        }
417
418
0
    if (!xEntry.is())
419
0
        throw container::NoSuchElementException();
420
421
0
    return uno::Any(xEntry);
422
0
}
423
424
uno::Sequence<OUString> SAL_CALL ScTableConditionalFormat::getElementNames()
425
0
{
426
0
    SolarMutexGuard aGuard;
427
428
0
    tools::Long nCount = maEntries.size();
429
0
    uno::Sequence<OUString> aNames(nCount);
430
0
    OUString* pArray = aNames.getArray();
431
0
    for (tools::Long i=0; i<nCount; i++)
432
0
        pArray[i] = lcl_GetEntryNameFromIndex(i);
433
434
0
    return aNames;
435
0
}
436
437
sal_Bool SAL_CALL ScTableConditionalFormat::hasByName( const OUString& aName )
438
0
{
439
0
    SolarMutexGuard aGuard;
440
441
0
    tools::Long nCount = maEntries.size();
442
0
    for (tools::Long i=0; i<nCount; i++)
443
0
        if ( aName == lcl_GetEntryNameFromIndex(i) )
444
0
            return true;
445
446
0
    return false;
447
0
}
448
449
ScTableConditionalEntry::ScTableConditionalEntry(ScCondFormatEntryItem  aItem) :
450
0
    aData(std::move( aItem ))
451
0
{
452
    // #i113668# only store the settings, keep no reference to parent object
453
0
}
454
455
ScTableConditionalEntry::~ScTableConditionalEntry()
456
0
{
457
0
}
458
459
void ScTableConditionalEntry::GetData(ScCondFormatEntryItem& rData) const
460
0
{
461
0
    rData = aData;
462
0
}
463
464
// XSheetCondition
465
466
sheet::ConditionOperator SAL_CALL ScTableConditionalEntry::getOperator()
467
0
{
468
0
    SolarMutexGuard aGuard;
469
0
    return lcl_ConditionModeToOperator( aData.meMode );
470
0
}
471
472
void SAL_CALL ScTableConditionalEntry::setOperator( sheet::ConditionOperator nOperator )
473
0
{
474
0
    SolarMutexGuard aGuard;
475
0
    aData.meMode = lcl_ConditionOperatorToMode( nOperator );
476
0
}
477
478
sal_Int32 SAL_CALL ScTableConditionalEntry::getConditionOperator()
479
0
{
480
0
    SolarMutexGuard aGuard;
481
0
    return lcl_ConditionModeToOperatorNew( aData.meMode );
482
0
}
483
484
void SAL_CALL ScTableConditionalEntry::setConditionOperator( sal_Int32 nOperator )
485
0
{
486
0
    SolarMutexGuard aGuard;
487
0
    aData.meMode = ScConditionEntry::GetModeFromApi( static_cast<sheet::ConditionOperator>(nOperator) );
488
0
}
489
490
OUString SAL_CALL ScTableConditionalEntry::getFormula1()
491
0
{
492
0
    SolarMutexGuard aGuard;
493
0
    return aData.maExpr1;
494
0
}
495
496
void SAL_CALL ScTableConditionalEntry::setFormula1( const OUString& aFormula1 )
497
0
{
498
0
    SolarMutexGuard aGuard;
499
0
    aData.maExpr1 = aFormula1;
500
0
}
501
502
OUString SAL_CALL ScTableConditionalEntry::getFormula2()
503
0
{
504
0
    SolarMutexGuard aGuard;
505
0
    return aData.maExpr2;
506
0
}
507
508
void SAL_CALL ScTableConditionalEntry::setFormula2( const OUString& aFormula2 )
509
0
{
510
0
    SolarMutexGuard aGuard;
511
0
    aData.maExpr2 = aFormula2;
512
0
}
513
514
table::CellAddress SAL_CALL ScTableConditionalEntry::getSourcePosition()
515
0
{
516
0
    SolarMutexGuard aGuard;
517
0
    table::CellAddress aRet;
518
0
    aRet.Column = aData.maPos.Col();
519
0
    aRet.Row    = aData.maPos.Row();
520
0
    aRet.Sheet  = aData.maPos.Tab();
521
0
    return aRet;
522
0
}
523
524
void SAL_CALL ScTableConditionalEntry::setSourcePosition( const table::CellAddress& aSourcePosition )
525
0
{
526
0
    SolarMutexGuard aGuard;
527
0
    aData.maPos.Set( static_cast<SCCOL>(aSourcePosition.Column), static_cast<SCROW>(aSourcePosition.Row), aSourcePosition.Sheet );
528
0
}
529
530
// XSheetConditionalEntry
531
532
OUString SAL_CALL ScTableConditionalEntry::getStyleName()
533
0
{
534
0
    SolarMutexGuard aGuard;
535
0
    return ScStyleNameConversion::DisplayToProgrammaticName( aData.maStyle, SfxStyleFamily::Para );
536
0
}
537
538
void SAL_CALL ScTableConditionalEntry::setStyleName( const OUString& aStyleName )
539
0
{
540
0
    SolarMutexGuard aGuard;
541
0
    aData.maStyle = ScStyleNameConversion::ProgrammaticToDisplayName( aStyleName, SfxStyleFamily::Para );
542
0
}
543
544
ScTableValidationObj::ScTableValidationObj(const ScDocument& rDoc, sal_uInt32 nKey,
545
                                           const formula::FormulaGrammar::Grammar eGrammar) :
546
754
    aPropSet( lcl_GetValidatePropertyMap() )
547
754
{
548
    //  read the entry from the document...
549
550
754
    bool bFound = false;
551
754
    if (nKey)
552
0
    {
553
0
        const ScValidationData* pData = rDoc.GetValidationEntry( nKey );
554
0
        if (pData)
555
0
        {
556
0
            nMode = pData->GetOperation();
557
0
            aSrcPos = pData->GetValidSrcPos();  // valid pos for expressions
558
0
            aExpr1 = pData->GetExpression( aSrcPos, 0, 0, eGrammar );
559
0
            aExpr2 = pData->GetExpression( aSrcPos, 1, 0, eGrammar );
560
0
            meGrammar1 = meGrammar2 = eGrammar;
561
0
            nValMode = sal::static_int_cast<sal_uInt16>( pData->GetDataMode() );
562
0
            bIgnoreBlank = pData->IsIgnoreBlank();
563
0
            bCaseSensitive = pData->IsCaseSensitive();
564
0
            nShowList = pData->GetListType();
565
0
            bShowInput = pData->GetInput( aInputTitle, aInputMessage );
566
0
            ScValidErrorStyle eStyle;
567
0
            bShowError = pData->GetErrMsg( aErrorTitle, aErrorMessage, eStyle );
568
0
            nErrorStyle = sal::static_int_cast<sal_uInt16>( eStyle );
569
570
            // During save to XML, sheet::ValidationType_ANY formulas are not
571
            // saved, even if in the list, see
572
            // ScMyValidationsContainer::GetCondition(), so shall not mark
573
            // anything in use.
574
0
            if (nValMode != SC_VALID_ANY && rDoc.IsInExternalReferenceMarking())
575
0
                pData->MarkUsedExternalReferences();
576
577
0
            bFound = true;
578
0
        }
579
0
    }
580
754
    if (!bFound)
581
754
        ClearData_Impl();       // Defaults
582
754
}
583
584
ScValidationData* ScTableValidationObj::CreateValidationData( ScDocument& rDoc,
585
                                            formula::FormulaGrammar::Grammar eGrammar ) const
586
754
{
587
    //  ScValidationData = Core-Struktur
588
589
754
    FormulaGrammar::Grammar eGrammar1 = lclResolveGrammar( eGrammar, meGrammar1 );
590
754
    FormulaGrammar::Grammar eGrammar2 = lclResolveGrammar( eGrammar, meGrammar2 );
591
592
754
    ScValidationData* pRet = new ScValidationData( static_cast<ScValidationMode>(nValMode),
593
754
                                                   nMode,
594
754
                                                   aExpr1, aExpr2, rDoc, aSrcPos,
595
754
                                                   maExprNmsp1, maExprNmsp2,
596
754
                                                   eGrammar1, eGrammar2 );
597
754
    pRet->SetIgnoreBlank(bIgnoreBlank);
598
754
    pRet->SetCaseSensitive(bCaseSensitive);
599
754
    pRet->SetListType(nShowList);
600
601
754
    if ( aTokens1.hasElements() )
602
752
    {
603
752
        ScTokenArray aTokenArray(rDoc);
604
752
        if ( ScTokenConversion::ConvertToTokenArray(rDoc, aTokenArray, aTokens1) )
605
752
            pRet->SetFormula1(aTokenArray);
606
752
    }
607
608
754
    if ( aTokens2.hasElements() )
609
487
    {
610
487
        ScTokenArray aTokenArray(rDoc);
611
487
        if ( ScTokenConversion::ConvertToTokenArray(rDoc, aTokenArray, aTokens2) )
612
487
            pRet->SetFormula2(aTokenArray);
613
487
    }
614
615
    // set strings for error / input even if disabled (and disable afterwards)
616
754
    pRet->SetInput( aInputTitle, aInputMessage );
617
754
    if (!bShowInput)
618
457
        pRet->ResetInput();
619
754
    pRet->SetError( aErrorTitle, aErrorMessage, static_cast<ScValidErrorStyle>(nErrorStyle) );
620
754
    if (!bShowError)
621
82
        pRet->ResetError();
622
623
754
    if ( !aPosString.isEmpty() )
624
0
        pRet->SetSrcString( aPosString );
625
626
754
    return pRet;
627
754
}
628
629
void ScTableValidationObj::ClearData_Impl()
630
754
{
631
754
    nMode        = ScConditionMode::NONE;
632
754
    nValMode     = SC_VALID_ANY;
633
754
    bIgnoreBlank = true;
634
754
    bCaseSensitive = false;
635
754
    nShowList    = sheet::TableValidationVisibility::UNSORTED;
636
754
    bShowInput   = false;
637
754
    bShowError   = false;
638
754
    nErrorStyle  = SC_VALERR_STOP;
639
754
    aSrcPos.Set(0,0,0);
640
754
    aExpr1.clear();
641
754
    aExpr2.clear();
642
754
    maExprNmsp1.clear();
643
754
    maExprNmsp2.clear();
644
754
    meGrammar1 = meGrammar2 = FormulaGrammar::GRAM_UNSPECIFIED;  // will be overridden when needed
645
754
    aInputTitle.clear();
646
754
    aInputMessage.clear();
647
754
    aErrorTitle.clear();
648
754
    aErrorMessage.clear();
649
754
}
650
651
ScTableValidationObj::~ScTableValidationObj()
652
754
{
653
754
}
654
655
// XSheetCondition
656
657
sheet::ConditionOperator SAL_CALL ScTableValidationObj::getOperator()
658
0
{
659
0
    SolarMutexGuard aGuard;
660
0
    return lcl_ConditionModeToOperator( nMode );
661
0
}
662
663
void SAL_CALL ScTableValidationObj::setOperator( sheet::ConditionOperator nOperator )
664
0
{
665
0
    SolarMutexGuard aGuard;
666
0
    nMode = lcl_ConditionOperatorToMode( nOperator );
667
0
}
668
669
sal_Int32 SAL_CALL ScTableValidationObj::getConditionOperator()
670
0
{
671
0
    SolarMutexGuard aGuard;
672
0
    return lcl_ConditionModeToOperatorNew( nMode );
673
0
}
674
675
void SAL_CALL ScTableValidationObj::setConditionOperator( sal_Int32 nOperator )
676
754
{
677
754
    SolarMutexGuard aGuard;
678
754
    nMode = ScConditionEntry::GetModeFromApi( static_cast<css::sheet::ConditionOperator>(nOperator) );
679
754
}
680
681
OUString SAL_CALL ScTableValidationObj::getFormula1()
682
0
{
683
0
    SolarMutexGuard aGuard;
684
0
    return aExpr1;
685
0
}
686
687
void SAL_CALL ScTableValidationObj::setFormula1( const OUString& aFormula1 )
688
0
{
689
0
    SolarMutexGuard aGuard;
690
0
    aExpr1 = aFormula1;
691
0
}
692
693
OUString SAL_CALL ScTableValidationObj::getFormula2()
694
0
{
695
0
    SolarMutexGuard aGuard;
696
0
    return aExpr2;
697
0
}
698
699
void SAL_CALL ScTableValidationObj::setFormula2( const OUString& aFormula2 )
700
0
{
701
0
    SolarMutexGuard aGuard;
702
0
    aExpr2 = aFormula2;
703
0
}
704
705
table::CellAddress SAL_CALL ScTableValidationObj::getSourcePosition()
706
0
{
707
0
    SolarMutexGuard aGuard;
708
0
    table::CellAddress aRet;
709
0
    aRet.Column = aSrcPos.Col();
710
0
    aRet.Row    = aSrcPos.Row();
711
0
    aRet.Sheet  = aSrcPos.Tab();
712
0
    return aRet;
713
0
}
714
715
void SAL_CALL ScTableValidationObj::setSourcePosition( const table::CellAddress& aSourcePosition )
716
754
{
717
754
    SolarMutexGuard aGuard;
718
754
    aSrcPos.Set( static_cast<SCCOL>(aSourcePosition.Column), static_cast<SCROW>(aSourcePosition.Row), aSourcePosition.Sheet );
719
754
}
720
721
uno::Sequence<sheet::FormulaToken> SAL_CALL ScTableValidationObj::getTokens( sal_Int32 nIndex )
722
0
{
723
0
    SolarMutexGuard aGuard;
724
0
    if (nIndex >= 2 || nIndex < 0)
725
0
        throw lang::IndexOutOfBoundsException();
726
727
0
    return nIndex == 0 ? aTokens1 : aTokens2;
728
0
}
729
730
void SAL_CALL ScTableValidationObj::setTokens( sal_Int32 nIndex, const uno::Sequence<sheet::FormulaToken>& aTokens )
731
1.50k
{
732
1.50k
    SolarMutexGuard aGuard;
733
1.50k
    if (nIndex >= 2 || nIndex < 0)
734
0
        throw lang::IndexOutOfBoundsException();
735
736
1.50k
    if (nIndex == 0)
737
754
    {
738
754
        aTokens1 = aTokens;
739
754
        aExpr1.clear();
740
754
    }
741
754
    else if (nIndex == 1)
742
754
    {
743
754
        aTokens2 = aTokens;
744
754
        aExpr2.clear();
745
754
    }
746
1.50k
}
747
748
sal_Int32 SAL_CALL ScTableValidationObj::getCount()
749
0
{
750
0
    return 2;
751
0
}
752
753
uno::Reference<beans::XPropertySetInfo> SAL_CALL ScTableValidationObj::getPropertySetInfo()
754
754
{
755
754
    SolarMutexGuard aGuard;
756
754
    static uno::Reference<beans::XPropertySetInfo> aRef(
757
754
        new SfxItemPropertySetInfo( aPropSet.getPropertyMap() ));
758
754
    return aRef;
759
754
}
760
761
void SAL_CALL ScTableValidationObj::setPropertyValue(
762
                        const OUString& aPropertyName, const uno::Any& aValue )
763
7.54k
{
764
7.54k
    SolarMutexGuard aGuard;
765
766
7.54k
    if ( aPropertyName == SC_UNONAME_SHOWINP )       bShowInput = ScUnoHelpFunctions::GetBoolFromAny( aValue );
767
6.78k
    else if ( aPropertyName == SC_UNONAME_SHOWERR )  bShowError = ScUnoHelpFunctions::GetBoolFromAny( aValue );
768
6.03k
    else if ( aPropertyName == SC_UNONAME_IGNOREBL ) bIgnoreBlank = ScUnoHelpFunctions::GetBoolFromAny( aValue );
769
5.27k
    else if ( aPropertyName == SC_UNONAME_ISCASE )   bCaseSensitive = ScUnoHelpFunctions::GetBoolFromAny( aValue );
770
5.27k
    else if ( aPropertyName == SC_UNONAME_SHOWLIST ) aValue >>= nShowList;
771
4.52k
    else if ( aPropertyName == SC_UNONAME_INPTITLE )
772
754
    {
773
754
        OUString aStrVal;
774
754
        if ( aValue >>= aStrVal )
775
754
            aInputTitle = aStrVal;
776
754
    }
777
3.77k
    else if ( aPropertyName == SC_UNONAME_INPMESS )
778
754
    {
779
754
        OUString aStrVal;
780
754
        if ( aValue >>= aStrVal )
781
754
            aInputMessage = aStrVal;
782
754
    }
783
3.01k
    else if ( aPropertyName == SC_UNONAME_ERRTITLE )
784
754
    {
785
754
        OUString aStrVal;
786
754
        if ( aValue >>= aStrVal )
787
754
            aErrorTitle = aStrVal;
788
754
    }
789
2.26k
    else if ( aPropertyName == SC_UNONAME_ERRMESS )
790
754
    {
791
754
        OUString aStrVal;
792
754
        if ( aValue >>= aStrVal )
793
754
            aErrorMessage = aStrVal;
794
754
    }
795
1.50k
    else if ( aPropertyName == SC_UNONAME_TYPE )
796
754
    {
797
754
        sheet::ValidationType eType = static_cast<sheet::ValidationType>(ScUnoHelpFunctions::GetEnumFromAny( aValue ));
798
754
        switch (eType)
799
754
        {
800
12
            case sheet::ValidationType_ANY:      nValMode = SC_VALID_ANY;     break;
801
39
            case sheet::ValidationType_WHOLE:    nValMode = SC_VALID_WHOLE;   break;
802
3
            case sheet::ValidationType_DECIMAL:  nValMode = SC_VALID_DECIMAL; break;
803
16
            case sheet::ValidationType_DATE:     nValMode = SC_VALID_DATE;    break;
804
0
            case sheet::ValidationType_TIME:     nValMode = SC_VALID_TIME;    break;
805
20
            case sheet::ValidationType_TEXT_LEN: nValMode = SC_VALID_TEXTLEN; break;
806
656
            case sheet::ValidationType_LIST:     nValMode = SC_VALID_LIST;    break;
807
8
            case sheet::ValidationType_CUSTOM:   nValMode = SC_VALID_CUSTOM;  break;
808
0
            default:
809
0
            {
810
                // added to avoid warnings
811
0
            }
812
754
        }
813
754
    }
814
754
    else if ( aPropertyName == SC_UNONAME_ERRALSTY )
815
754
    {
816
754
        sheet::ValidationAlertStyle eStyle = static_cast<sheet::ValidationAlertStyle>(ScUnoHelpFunctions::GetEnumFromAny( aValue ));
817
754
        switch (eStyle)
818
754
        {
819
754
            case sheet::ValidationAlertStyle_STOP:    nErrorStyle = SC_VALERR_STOP;    break;
820
0
            case sheet::ValidationAlertStyle_WARNING: nErrorStyle = SC_VALERR_WARNING; break;
821
0
            case sheet::ValidationAlertStyle_INFO:    nErrorStyle = SC_VALERR_INFO;    break;
822
0
            case sheet::ValidationAlertStyle_MACRO:   nErrorStyle = SC_VALERR_MACRO;   break;
823
0
            case sheet::ValidationAlertStyle_NONE:    nErrorStyle = SC_VALERR_NONE;    break;
824
0
            default:
825
0
            {
826
                // added to avoid warnings
827
0
            }
828
754
        }
829
754
    }
830
0
    else if ( aPropertyName == SC_UNONAME_SOURCESTR )
831
0
    {
832
        // internal - only for XML filter, not in PropertySetInfo, only set
833
834
0
        OUString aStrVal;
835
0
        if ( aValue >>= aStrVal )
836
0
            aPosString =  aStrVal;
837
0
    }
838
0
    else if ( aPropertyName == SC_UNONAME_FORMULANMSP1 )
839
0
    {
840
        // internal - only for XML filter, not in PropertySetInfo, only set
841
842
0
        OUString aStrVal;
843
0
        if ( aValue >>= aStrVal )
844
0
            maExprNmsp1 = aStrVal;
845
0
    }
846
0
    else if ( aPropertyName == SC_UNONAME_FORMULANMSP2 )
847
0
    {
848
        // internal - only for XML filter, not in PropertySetInfo, only set
849
850
0
        OUString aStrVal;
851
0
        if ( aValue >>= aStrVal )
852
0
            maExprNmsp2 = aStrVal;
853
0
    }
854
0
    else if ( aPropertyName == SC_UNONAME_GRAMMAR1 )
855
0
    {
856
        // internal - only for XML filter, not in PropertySetInfo, only set
857
858
0
        sal_Int32 nVal = 0;
859
0
        if ( aValue >>= nVal )
860
0
            meGrammar1 = static_cast< FormulaGrammar::Grammar >(nVal);
861
0
    }
862
0
    else if ( aPropertyName == SC_UNONAME_GRAMMAR2 )
863
0
    {
864
        // internal - only for XML filter, not in PropertySetInfo, only set
865
866
0
        sal_Int32 nVal = 0;
867
0
        if ( aValue >>= nVal )
868
0
            meGrammar2 = static_cast< FormulaGrammar::Grammar >(nVal);
869
0
    }
870
7.54k
}
871
872
uno::Any SAL_CALL ScTableValidationObj::getPropertyValue( const OUString& aPropertyName )
873
0
{
874
0
    SolarMutexGuard aGuard;
875
0
    uno::Any aRet;
876
877
0
    if ( aPropertyName == SC_UNONAME_SHOWINP )       aRet <<= bShowInput;
878
0
    else if ( aPropertyName == SC_UNONAME_SHOWERR )  aRet <<= bShowError;
879
0
    else if ( aPropertyName == SC_UNONAME_IGNOREBL ) aRet <<= bIgnoreBlank;
880
0
    else if ( aPropertyName == SC_UNONAME_ISCASE )   aRet <<= bCaseSensitive;
881
0
    else if ( aPropertyName == SC_UNONAME_SHOWLIST ) aRet <<= nShowList;
882
0
    else if ( aPropertyName == SC_UNONAME_INPTITLE ) aRet <<= aInputTitle;
883
0
    else if ( aPropertyName == SC_UNONAME_INPMESS )  aRet <<= aInputMessage;
884
0
    else if ( aPropertyName == SC_UNONAME_ERRTITLE ) aRet <<= aErrorTitle;
885
0
    else if ( aPropertyName == SC_UNONAME_ERRMESS )  aRet <<= aErrorMessage;
886
0
    else if ( aPropertyName == SC_UNONAME_TYPE )
887
0
    {
888
0
        sheet::ValidationType eType = sheet::ValidationType_ANY;
889
0
        switch (nValMode)
890
0
        {
891
0
            case SC_VALID_ANY:      eType = sheet::ValidationType_ANY;      break;
892
0
            case SC_VALID_WHOLE:    eType = sheet::ValidationType_WHOLE;    break;
893
0
            case SC_VALID_DECIMAL:  eType = sheet::ValidationType_DECIMAL;  break;
894
0
            case SC_VALID_DATE:     eType = sheet::ValidationType_DATE;     break;
895
0
            case SC_VALID_TIME:     eType = sheet::ValidationType_TIME;     break;
896
0
            case SC_VALID_TEXTLEN:  eType = sheet::ValidationType_TEXT_LEN; break;
897
0
            case SC_VALID_LIST:     eType = sheet::ValidationType_LIST;     break;
898
0
            case SC_VALID_CUSTOM:   eType = sheet::ValidationType_CUSTOM;   break;
899
0
        }
900
0
        aRet <<= eType;
901
0
    }
902
0
    else if ( aPropertyName == SC_UNONAME_ERRALSTY )
903
0
    {
904
0
        sheet::ValidationAlertStyle eStyle = sheet::ValidationAlertStyle_STOP;
905
0
        switch (nErrorStyle)
906
0
        {
907
0
            case SC_VALERR_STOP:    eStyle = sheet::ValidationAlertStyle_STOP;    break;
908
0
            case SC_VALERR_WARNING: eStyle = sheet::ValidationAlertStyle_WARNING; break;
909
0
            case SC_VALERR_INFO:    eStyle = sheet::ValidationAlertStyle_INFO;    break;
910
0
            case SC_VALERR_MACRO:   eStyle = sheet::ValidationAlertStyle_MACRO;   break;
911
0
            case SC_VALERR_NONE:    eStyle = sheet::ValidationAlertStyle_NONE;    break;
912
0
        }
913
0
        aRet <<= eStyle;
914
0
    }
915
916
0
    return aRet;
917
0
}
918
919
SC_IMPL_DUMMY_PROPERTY_LISTENER( ScTableValidationObj )
920
921
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */