Coverage Report

Created: 2026-11-06 11:29

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/sc/source/ui/unoobj/datauno.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 <datauno.hxx>
21
22
#include <svl/hint.hxx>
23
#include <svl/numformat.hxx>
24
#include <svl/sharedstringpool.hxx>
25
#include <utility>
26
#include <vcl/svapp.hxx>
27
#include <unotools/charclass.hxx>
28
#include <osl/diagnose.h>
29
30
#include <com/sun/star/awt/XBitmap.hpp>
31
#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
32
#include <com/sun/star/util/SortField.hpp>
33
#include <com/sun/star/table/TableSortField.hpp>
34
#include <com/sun/star/beans/PropertyAttribute.hpp>
35
#include <com/sun/star/table/TableOrientation.hpp>
36
#include <com/sun/star/table/CellRangeAddress.hpp>
37
#include <com/sun/star/sheet/DataImportMode.hpp>
38
#include <com/sun/star/sheet/FilterFieldType.hpp>
39
#include <com/sun/star/sheet/FilterOperator2.hpp>
40
#include <com/sun/star/sheet/TableFilterField2.hpp>
41
#include <com/sun/star/sheet/SortNumberBehavior.hpp>
42
43
#include <dapiuno.hxx>
44
#include <cellsuno.hxx>
45
#include <miscuno.hxx>
46
#include <targuno.hxx>
47
#include <rangeutl.hxx>
48
#include <dbdata.hxx>
49
#include <docsh.hxx>
50
#include <dbdocfun.hxx>
51
#include <unonames.hxx>
52
#include <globalnames.hxx>
53
#include <convuno.hxx>
54
#include <hints.hxx>
55
#include <attrib.hxx>
56
#include <dpshttab.hxx>
57
#include <queryentry.hxx>
58
#include <dputil.hxx>
59
#include <sortparam.hxx>
60
#include <dpobject.hxx>
61
#include <filterentries.hxx>
62
63
#include <comphelper/extract.hxx>
64
#include <cppuhelper/supportsservice.hxx>
65
#include <svx/dataaccessdescriptor.hxx>
66
67
#include <memory>
68
69
using namespace com::sun::star;
70
using namespace css::sheet;
71
72
//  everything without Which-ID, map only for PropertySetInfo
73
74
static std::span<const SfxItemPropertyMapEntry> lcl_GetSubTotalPropertyMap()
75
0
{
76
    // some old property names are for 5.2 compatibility
77
78
0
    static const SfxItemPropertyMapEntry aSubTotalPropertyMap_Impl[] =
79
0
    {
80
0
        { SC_UNONAME_BINDFMT,  0,  cppu::UnoType<bool>::get(),       0, 0},
81
0
        { SC_UNONAME_CASE,     0,  cppu::UnoType<bool>::get(),       0, 0},
82
0
        { SC_UNONAME_ENABSORT, 0,  cppu::UnoType<bool>::get(),       0, 0},
83
0
        { SC_UNONAME_ENUSLIST, 0,  cppu::UnoType<bool>::get(),       0, 0},
84
0
        { SC_UNONAME_FORMATS,  0,  cppu::UnoType<bool>::get(),       0, 0},
85
0
        { SC_UNONAME_INSBRK,   0,  cppu::UnoType<bool>::get(),       0, 0},
86
0
        { SC_UNONAME_ISCASE,   0,  cppu::UnoType<bool>::get(),       0, 0},
87
0
        { SC_UNONAME_MAXFLD,   0,  cppu::UnoType<sal_Int32>::get(), beans::PropertyAttribute::READONLY, 0},
88
0
        { SC_UNONAME_SORTASC,  0,  cppu::UnoType<bool>::get(),       0, 0},
89
0
        { SC_UNONAME_ULIST,    0,  cppu::UnoType<bool>::get(),       0, 0},
90
0
        { SC_UNONAME_UINDEX,   0,  cppu::UnoType<sal_Int32>::get(), 0, 0},
91
0
        { SC_UNONAME_USINDEX,  0,  cppu::UnoType<sal_Int32>::get(), 0, 0},
92
0
    };
93
0
    return aSubTotalPropertyMap_Impl;
94
0
}
95
96
static std::span<const SfxItemPropertyMapEntry> lcl_GetFilterPropertyMap()
97
525
{
98
525
    static const SfxItemPropertyMapEntry aFilterPropertyMap_Impl[] =
99
525
    {
100
525
        { SC_UNONAME_CONTHDR,  0,  cppu::UnoType<bool>::get(),                      0, 0},
101
525
        { SC_UNONAME_COPYOUT,  0,  cppu::UnoType<bool>::get(),                      0, 0},
102
525
        { SC_UNONAME_ISCASE,   0,  cppu::UnoType<bool>::get(),                      0, 0},
103
525
        { SC_UNONAME_MAXFLD,   0,  cppu::UnoType<sal_Int32>::get(),                beans::PropertyAttribute::READONLY, 0},
104
525
        { SC_UNONAME_ORIENT,   0,  cppu::UnoType<table::TableOrientation>::get(),  0, 0},
105
525
        { SC_UNONAME_OUTPOS,   0,  cppu::UnoType<table::CellAddress>::get(),       0, 0},
106
525
        { SC_UNONAME_SAVEOUT,  0,  cppu::UnoType<bool>::get(),                      0, 0},
107
525
        { SC_UNONAME_SKIPDUP,  0,  cppu::UnoType<bool>::get(),                      0, 0},
108
525
        { SC_UNONAME_USEREGEX, 0,  cppu::UnoType<bool>::get(),                      0, 0},
109
525
    };
110
525
    return aFilterPropertyMap_Impl;
111
525
}
112
113
static std::span<const SfxItemPropertyMapEntry> lcl_GetDBRangePropertyMap()
114
841
{
115
841
    static const SfxItemPropertyMapEntry aDBRangePropertyMap_Impl[] =
116
841
    {
117
841
        { SC_UNONAME_AUTOFLT,  0,  cppu::UnoType<bool>::get(),                      0, 0},
118
841
        { SC_UNONAME_FLTCRT,   0,  cppu::UnoType<table::CellRangeAddress>::get(),  0, 0},
119
841
        { SC_UNONAME_FROMSELECT,0, cppu::UnoType<bool>::get(),                      0, 0},
120
841
        { SC_UNONAME_ISUSER,   0,  cppu::UnoType<bool>::get(),           beans::PropertyAttribute::READONLY, 0 },
121
841
        { SC_UNONAME_KEEPFORM, 0,  cppu::UnoType<bool>::get(),                      0, 0},
122
841
        { SC_UNO_LINKDISPBIT,  0,  cppu::UnoType<awt::XBitmap>::get(), beans::PropertyAttribute::READONLY, 0 },
123
841
        { SC_UNO_LINKDISPNAME, 0,  cppu::UnoType<OUString>::get(), beans::PropertyAttribute::READONLY, 0 },
124
841
        { SC_UNONAME_MOVCELLS, 0,  cppu::UnoType<bool>::get(),                      0, 0},
125
841
        { SC_UNONAME_REFPERIOD, 0, cppu::UnoType<sal_Int32>::get(),                0, 0},
126
841
        { SC_UNONAME_STRIPDAT, 0,  cppu::UnoType<bool>::get(),                      0, 0},
127
841
        { SC_UNONAME_TOKENINDEX,0, cppu::UnoType<sal_Int32>::get(),     beans::PropertyAttribute::READONLY, 0 },
128
841
        { SC_UNONAME_USEFLTCRT,0,  cppu::UnoType<bool>::get(),                      0, 0},
129
841
        { SC_UNONAME_TOTALSROW,0,  cppu::UnoType<bool>::get(),                      0, 0},
130
841
        { SC_UNONAME_CONTHDR  ,0,  cppu::UnoType<bool>::get(),                      0, 0},
131
841
        { SC_UNONAME_TABLE_STYLENAME,0,  cppu::UnoType<OUString>::get(),            0, 0},
132
841
        { SC_UNONAME_ROW_STRIPES,0,  cppu::UnoType<bool>::get(),                    0, 0},
133
841
        { SC_UNONAME_COL_STRIPES,0,  cppu::UnoType<bool>::get(),                    0, 0},
134
841
        { SC_UNONAME_FIRST_COL,0,  cppu::UnoType<bool>::get(),                      0, 0},
135
841
        { SC_UNONAME_LAST_COL,0,  cppu::UnoType<bool>::get(),                       0, 0},
136
841
    };
137
841
    return aDBRangePropertyMap_Impl;
138
841
}
139
140
SC_SIMPLE_SERVICE_INFO( ScConsolidationDescriptor, u"ScConsolidationDescriptor"_ustr, u"com.sun.star.sheet.ConsolidationDescriptor"_ustr )
141
SC_SIMPLE_SERVICE_INFO( ScDatabaseRangesObj, u"ScDatabaseRangesObj"_ustr, u"com.sun.star.sheet.DatabaseRanges"_ustr )
142
SC_SIMPLE_SERVICE_INFO( ScFilterDescriptorBase, u"ScFilterDescriptorBase"_ustr, u"com.sun.star.sheet.SheetFilterDescriptor"_ustr )
143
SC_SIMPLE_SERVICE_INFO( ScSubTotalDescriptorBase, u"ScSubTotalDescriptorBase"_ustr, u"com.sun.star.sheet.SubTotalDescriptor"_ustr )
144
SC_SIMPLE_SERVICE_INFO( ScSubTotalFieldObj, u"ScSubTotalFieldObj"_ustr, u"com.sun.star.sheet.SubTotalField"_ustr )
145
146
sheet::GeneralFunction  ScDataUnoConversion::SubTotalToGeneral( ScSubTotalFunc eSubTotal )
147
0
{
148
0
    sheet::GeneralFunction eGeneral;
149
0
    switch (eSubTotal)
150
0
    {
151
0
        case SUBTOTAL_FUNC_NONE: eGeneral = sheet::GeneralFunction_NONE;      break;
152
0
        case SUBTOTAL_FUNC_AVE:  eGeneral = sheet::GeneralFunction_AVERAGE;   break;
153
0
        case SUBTOTAL_FUNC_CNT:  eGeneral = sheet::GeneralFunction_COUNTNUMS; break;
154
0
        case SUBTOTAL_FUNC_CNT2: eGeneral = sheet::GeneralFunction_COUNT;     break;
155
0
        case SUBTOTAL_FUNC_MAX:  eGeneral = sheet::GeneralFunction_MAX;       break;
156
0
        case SUBTOTAL_FUNC_MIN:  eGeneral = sheet::GeneralFunction_MIN;       break;
157
0
        case SUBTOTAL_FUNC_PROD: eGeneral = sheet::GeneralFunction_PRODUCT;   break;
158
0
        case SUBTOTAL_FUNC_STD:  eGeneral = sheet::GeneralFunction_STDEV;     break;
159
0
        case SUBTOTAL_FUNC_STDP: eGeneral = sheet::GeneralFunction_STDEVP;    break;
160
0
        case SUBTOTAL_FUNC_SUM:  eGeneral = sheet::GeneralFunction_SUM;       break;
161
0
        case SUBTOTAL_FUNC_VAR:  eGeneral = sheet::GeneralFunction_VAR;       break;
162
0
        case SUBTOTAL_FUNC_VARP: eGeneral = sheet::GeneralFunction_VARP;      break;
163
0
        default:
164
0
            OSL_FAIL("SubTotalToGeneral: wrong enum");
165
0
            eGeneral = sheet::GeneralFunction_NONE;
166
0
            break;
167
0
    }
168
0
    return eGeneral;
169
0
}
170
171
void ScImportDescriptor::FillProperties( uno::Sequence<beans::PropertyValue>& rSeq, const ScImportParam& rParam )
172
0
{
173
0
    OSL_ENSURE( rSeq.getLength() == GetPropertyCount(), "wrong Count" );
174
175
0
    beans::PropertyValue* pArray = rSeq.getArray();
176
177
0
    sheet::DataImportMode eMode = sheet::DataImportMode_NONE;
178
0
    if ( rParam.bImport )
179
0
    {
180
0
        if ( rParam.bSql )
181
0
            eMode = sheet::DataImportMode_SQL;
182
0
        else if ( rParam.nType == ScDbQuery )
183
0
            eMode = sheet::DataImportMode_QUERY;
184
0
        else
185
0
            eMode = sheet::DataImportMode_TABLE;        // type always ScDbQuery or ScDbTable
186
0
    }
187
188
0
    svx::ODataAccessDescriptor aDescriptor;
189
0
    aDescriptor.setDataSource(rParam.aDBName);
190
0
    if (aDescriptor.has( svx::DataAccessDescriptorProperty::DataSource ) ||
191
0
        aDescriptor.has( svx::DataAccessDescriptorProperty::DatabaseLocation ))
192
0
    {
193
0
        pArray[0].Name = SC_UNONAME_DBNAME;
194
0
        pArray[0].Value <<= aDescriptor.getDataSource();
195
0
    }
196
0
    else if (aDescriptor.has( svx::DataAccessDescriptorProperty::ConnectionResource ))
197
0
    {
198
0
        pArray[0].Name = SC_UNONAME_CONRES;
199
0
        pArray[0].Value <<= rParam.aDBName;
200
0
    }
201
202
0
    pArray[1].Name = SC_UNONAME_SRCTYPE;
203
0
    pArray[1].Value <<= eMode;
204
205
0
    pArray[2].Name = SC_UNONAME_SRCOBJ;
206
0
    pArray[2].Value <<= rParam.aStatement;
207
208
0
    pArray[3].Name = SC_UNONAME_ISNATIVE;
209
0
    pArray[3].Value <<= rParam.bNative;
210
0
}
211
212
void ScImportDescriptor::FillImportParam( ScImportParam& rParam, const uno::Sequence<beans::PropertyValue>& rSeq )
213
0
{
214
0
    OUString aStrVal;
215
0
    for (const beans::PropertyValue& rProp : rSeq)
216
0
    {
217
0
        OUString aPropName(rProp.Name);
218
219
0
        if (aPropName == SC_UNONAME_ISNATIVE)
220
0
            rParam.bNative = ScUnoHelpFunctions::GetBoolFromAny( rProp.Value );
221
0
        else if (aPropName == SC_UNONAME_DBNAME)
222
0
        {
223
0
            if ( rProp.Value >>= aStrVal )
224
0
                rParam.aDBName = aStrVal;
225
0
        }
226
0
        else if (aPropName == SC_UNONAME_CONRES)
227
0
        {
228
0
            if ( rProp.Value >>= aStrVal )
229
0
                rParam.aDBName = aStrVal;
230
0
        }
231
0
        else if (aPropName == SC_UNONAME_SRCOBJ)
232
0
        {
233
0
            if ( rProp.Value >>= aStrVal )
234
0
                rParam.aStatement = aStrVal;
235
0
        }
236
0
        else if (aPropName == SC_UNONAME_SRCTYPE)
237
0
        {
238
            //! test for correct enum type?
239
0
            sheet::DataImportMode eMode = static_cast<sheet::DataImportMode>(ScUnoHelpFunctions::GetEnumFromAny( rProp.Value ));
240
0
            switch (eMode)
241
0
            {
242
0
                case sheet::DataImportMode_NONE:
243
0
                    rParam.bImport = false;
244
0
                    break;
245
0
                case sheet::DataImportMode_SQL:
246
0
                    rParam.bImport = true;
247
0
                    rParam.bSql    = true;
248
0
                    break;
249
0
                case sheet::DataImportMode_TABLE:
250
0
                    rParam.bImport = true;
251
0
                    rParam.bSql    = false;
252
0
                    rParam.nType   = ScDbTable;
253
0
                    break;
254
0
                case sheet::DataImportMode_QUERY:
255
0
                    rParam.bImport = true;
256
0
                    rParam.bSql    = false;
257
0
                    rParam.nType   = ScDbQuery;
258
0
                    break;
259
0
                default:
260
0
                    OSL_FAIL("wrong mode");
261
0
                    rParam.bImport = false;
262
0
            }
263
0
        }
264
0
    }
265
0
}
266
267
void ScSortDescriptor::FillProperties( uno::Sequence<beans::PropertyValue>& rSeq, const ScSortParam& rParam )
268
0
{
269
0
    OSL_ENSURE( rSeq.getLength() == GetPropertyCount(), "wrong count" );
270
271
0
    beans::PropertyValue* pArray = rSeq.getArray();
272
273
    //  gather Uno values together
274
275
0
    table::CellAddress aOutPos;
276
0
    aOutPos.Sheet  = rParam.nDestTab;
277
0
    aOutPos.Column = rParam.nDestCol;
278
0
    aOutPos.Row    = rParam.nDestRow;
279
280
0
    sal_uInt16 nSortCount = 0;
281
0
    while ( nSortCount < rParam.GetSortKeyCount() && rParam.maKeyState[nSortCount].bDoSort )
282
0
        ++nSortCount;
283
284
0
    uno::Sequence<table::TableSortField> aFields(nSortCount);
285
0
    if (nSortCount)
286
0
    {
287
0
        table::TableSortField* pFieldArray = aFields.getArray();
288
0
        for (sal_uInt16 i=0; i<nSortCount; i++)
289
0
        {
290
0
            pFieldArray[i].Field         = rParam.maKeyState[i].nField;
291
0
            pFieldArray[i].IsAscending   = rParam.maKeyState[i].bAscending;
292
0
            pFieldArray[i].FieldType     = table::TableSortFieldType_AUTOMATIC;     // always automatic
293
0
            pFieldArray[i].IsCaseSensitive = rParam.bCaseSens;
294
0
            pFieldArray[i].CollatorLocale = rParam.aCollatorLocale;
295
0
            pFieldArray[i].CollatorAlgorithm = rParam.aCollatorAlgorithm;
296
0
        }
297
0
    }
298
299
    //  fill the sequence
300
301
0
    pArray[0].Name = SC_UNONAME_ISSORTCOLUMNS;
302
0
    pArray[0].Value <<= !rParam.bByRow;
303
304
0
    pArray[1].Name = SC_UNONAME_CONTHDR;
305
0
    pArray[1].Value <<= rParam.bHasHeader;
306
307
0
    pArray[2].Name = SC_UNONAME_MAXFLD;
308
0
    pArray[2].Value <<= static_cast<sal_Int32>( rParam.GetSortKeyCount() );
309
310
0
    pArray[3].Name = SC_UNONAME_SORTFLD;
311
0
    pArray[3].Value <<= aFields;
312
313
0
    pArray[4].Name = SC_UNONAME_BINDFMT;
314
0
    pArray[4].Value <<= rParam.aDataAreaExtras.mbCellFormats;
315
316
0
    pArray[5].Name = SC_UNONAME_COPYOUT;
317
0
    pArray[5].Value <<= !rParam.bInplace;
318
319
0
    pArray[6].Name = SC_UNONAME_OUTPOS;
320
0
    pArray[6].Value <<= aOutPos;
321
322
0
    pArray[7].Name = SC_UNONAME_ISULIST;
323
0
    pArray[7].Value <<= rParam.bUserDef;
324
325
0
    pArray[8].Name = SC_UNONAME_UINDEX;
326
0
    pArray[8].Value <<= static_cast<sal_Int32>( rParam.nUserIndex );
327
328
0
    pArray[9].Name = SC_UNONAME_NUMBERBEHAVIOR;
329
0
    pArray[9].Value <<= static_cast<sal_Int32>(rParam.eSortNumberBehavior);
330
0
}
331
332
void ScSortDescriptor::FillSortParam( ScSortParam& rParam, const uno::Sequence<beans::PropertyValue>& rSeq )
333
0
{
334
0
    sal_Int32 nSortSize = static_cast<sal_Int32>(rParam.GetSortKeyCount());
335
    // default if optional SC_UNONAME_NUMBERBEHAVIOR does not exist
336
0
    rParam.eSortNumberBehavior = ScSortNumberBehavior::ALPHA_NUMERIC;
337
338
0
    for (const beans::PropertyValue& rProp : rSeq)
339
0
    {
340
0
        OUString aPropName(rProp.Name);
341
342
0
        if (aPropName == SC_UNONAME_ORIENT)
343
0
        {
344
            //! test for correct enum type?
345
0
            table::TableOrientation eOrient = static_cast<table::TableOrientation>(ScUnoHelpFunctions::GetEnumFromAny( rProp.Value ));
346
0
            rParam.bByRow = ( eOrient != table::TableOrientation_COLUMNS );
347
0
        }
348
0
        else if (aPropName == SC_UNONAME_ISSORTCOLUMNS)
349
0
        {
350
0
            rParam.bByRow = !::cppu::any2bool(rProp.Value);
351
0
        }
352
0
        else if (aPropName == SC_UNONAME_CONTHDR)
353
0
            rParam.bHasHeader = ScUnoHelpFunctions::GetBoolFromAny( rProp.Value );
354
0
        else if (aPropName == SC_UNONAME_MAXFLD)
355
0
        {
356
0
            sal_Int32 nVal;
357
0
            if ( (rProp.Value >>= nVal) && nVal > nSortSize )
358
0
            {
359
                //! specify exceptions
360
                //! throw lang::IllegalArgumentException();
361
0
            }
362
0
        }
363
0
        else if (aPropName == SC_UNONAME_SORTFLD)
364
0
        {
365
0
            uno::Sequence<util::SortField> aSeq;
366
0
            uno::Sequence<table::TableSortField> aNewSeq;
367
0
            if ( rProp.Value >>= aSeq )
368
0
            {
369
0
                sal_Int32 nCount = aSeq.getLength();
370
0
                sal_Int32 i;
371
0
                if ( nCount > static_cast<sal_Int32>( rParam.GetSortKeyCount() ) )
372
0
                {
373
                    // tdf#105301 - increase the size of the sorting keys
374
0
                    nSortSize = nCount;
375
0
                    rParam.maKeyState.resize(nCount);
376
0
                }
377
0
                const util::SortField* pFieldArray = aSeq.getConstArray();
378
0
                for (i=0; i<nCount; i++)
379
0
                {
380
0
                    rParam.maKeyState[i].nField     = static_cast<SCCOLROW>( pFieldArray[i].Field );
381
0
                    rParam.maKeyState[i].bAscending = pFieldArray[i].SortAscending;
382
383
                    // FieldType is ignored
384
0
                    rParam.maKeyState[i].bDoSort = true;
385
0
                }
386
0
                for (i=nCount; i<nSortSize; i++)
387
0
                    rParam.maKeyState[i].bDoSort = false;
388
0
            }
389
0
            else if ( rProp.Value >>= aNewSeq )
390
0
            {
391
0
                sal_Int32 nCount = aNewSeq.getLength();
392
0
                sal_Int32 i;
393
0
                if ( nCount > nSortSize )
394
0
                {
395
0
                    nSortSize = nCount;
396
0
                    rParam.maKeyState.resize(nCount);
397
0
                }
398
0
                const table::TableSortField* pFieldArray = aNewSeq.getConstArray();
399
0
                for (i=0; i<nCount; i++)
400
0
                {
401
0
                    rParam.maKeyState[i].nField     = static_cast<SCCOLROW>( pFieldArray[i].Field );
402
0
                    rParam.maKeyState[i].bAscending = pFieldArray[i].IsAscending;
403
404
                    // only one is possible, sometime we should make it possible to have different for every entry
405
0
                    rParam.bCaseSens = pFieldArray[i].IsCaseSensitive;
406
0
                    rParam.aCollatorLocale = pFieldArray[i].CollatorLocale;
407
0
                    rParam.aCollatorAlgorithm = pFieldArray[i].CollatorAlgorithm;
408
409
                    // FieldType is ignored
410
0
                    rParam.maKeyState[i].bDoSort = true;
411
0
                }
412
0
                for (i=nCount; i<nSortSize; i++)
413
0
                    rParam.maKeyState[i].bDoSort = false;
414
0
            }
415
0
        }
416
0
        else if (aPropName == SC_UNONAME_ISCASE)
417
0
        {
418
0
            rParam.bCaseSens = ScUnoHelpFunctions::GetBoolFromAny( rProp.Value );
419
0
        }
420
0
        else if (aPropName == SC_UNONAME_BINDFMT)
421
0
            rParam.aDataAreaExtras.mbCellFormats = ScUnoHelpFunctions::GetBoolFromAny( rProp.Value );
422
0
        else if (aPropName == SC_UNONAME_COPYOUT)
423
0
            rParam.bInplace = !ScUnoHelpFunctions::GetBoolFromAny( rProp.Value );
424
0
        else if (aPropName == SC_UNONAME_OUTPOS)
425
0
        {
426
0
            table::CellAddress aAddress;
427
0
            if ( rProp.Value >>= aAddress )
428
0
            {
429
0
                rParam.nDestTab = aAddress.Sheet;
430
0
                rParam.nDestCol = static_cast<SCCOL>(aAddress.Column);
431
0
                rParam.nDestRow = static_cast<SCROW>(aAddress.Row);
432
0
            }
433
0
        }
434
0
        else if (aPropName == SC_UNONAME_ISULIST)
435
0
            rParam.bUserDef = ScUnoHelpFunctions::GetBoolFromAny( rProp.Value );
436
0
        else if (aPropName == SC_UNONAME_UINDEX)
437
0
        {
438
0
            sal_Int32 nVal = 0;
439
0
            if ( rProp.Value >>= nVal )
440
0
                rParam.nUserIndex = static_cast<sal_uInt16>(nVal);
441
0
        }
442
0
        else if (aPropName == SC_UNONAME_COLLLOC)
443
0
        {
444
0
            rProp.Value >>= rParam.aCollatorLocale;
445
0
        }
446
0
        else if (aPropName == SC_UNONAME_COLLALG)
447
0
        {
448
0
            OUString sStr;
449
0
            if ( rProp.Value >>= sStr )
450
0
                rParam.aCollatorAlgorithm = sStr;
451
0
        }
452
0
        else if (aPropName == SC_UNONAME_NUMBERBEHAVIOR)
453
0
        {
454
0
            sal_Int32 nVal = css::sheet::SortNumberBehavior::ALPHA_NUMERIC;
455
0
            if (rProp.Value >>= nVal)
456
0
            {
457
0
                rParam.eSortNumberBehavior = static_cast<ScSortNumberBehavior>(nVal <= 0 || nVal > 2 ? 0 : nVal);
458
0
            }
459
0
        }
460
0
    }
461
0
}
462
463
ScSubTotalFieldObj::ScSubTotalFieldObj( ScSubTotalDescriptorBase* pDesc, sal_uInt16 nP ) :
464
0
    xParent( pDesc ),
465
0
    nPos( nP )
466
0
{
467
0
    OSL_ENSURE(pDesc, "ScSubTotalFieldObj: Parent is 0");
468
0
}
469
470
ScSubTotalFieldObj::~ScSubTotalFieldObj()
471
0
{
472
0
}
473
474
// XSubTotalField
475
476
sal_Int32 SAL_CALL ScSubTotalFieldObj::getGroupColumn()
477
0
{
478
0
    SolarMutexGuard aGuard;
479
0
    ScSubTotalParam aParam;
480
0
    xParent->GetData(aParam);
481
482
0
    return aParam.aGroups[nPos].nField;
483
0
}
484
485
void SAL_CALL ScSubTotalFieldObj::setGroupColumn( sal_Int32 nGroupColumn )
486
0
{
487
0
    SolarMutexGuard aGuard;
488
0
    ScSubTotalParam aParam;
489
0
    xParent->GetData(aParam);
490
491
0
    aParam.aGroups[nPos].nField = static_cast<SCCOL>(nGroupColumn);
492
493
0
    xParent->PutData(aParam);
494
0
}
495
496
uno::Sequence<sheet::SubTotalColumn> SAL_CALL ScSubTotalFieldObj::getSubTotalColumns()
497
0
{
498
0
    SolarMutexGuard aGuard;
499
0
    ScSubTotalParam aParam;
500
0
    xParent->GetData(aParam);
501
502
0
    SCCOL nCount = aParam.aGroups[nPos].nSubTotals;
503
0
    uno::Sequence<sheet::SubTotalColumn> aSeq(nCount);
504
0
    sheet::SubTotalColumn* pAry = aSeq.getArray();
505
0
    for (SCCOL i=0; i<nCount; i++)
506
0
    {
507
0
        pAry[i].Column = aParam.aGroups[nPos].col(i);
508
0
        pAry[i].Function = ScDataUnoConversion::SubTotalToGeneral(aParam.aGroups[nPos].func(i));
509
0
    }
510
0
    return aSeq;
511
0
}
512
513
void SAL_CALL ScSubTotalFieldObj::setSubTotalColumns(
514
                            const uno::Sequence<sheet::SubTotalColumn>& aSubTotalColumns )
515
0
{
516
0
    SolarMutexGuard aGuard;
517
0
    ScSubTotalParam aParam;
518
0
    xParent->GetData(aParam);
519
520
0
    if (aSubTotalColumns.getLength() <= SCCOL_MAX)
521
0
        aParam.aGroups[nPos].SetSubtotals(aSubTotalColumns);
522
    //! otherwise exception or so? (too many columns)
523
524
0
    xParent->PutData(aParam);
525
0
}
526
527
ScSubTotalDescriptorBase::ScSubTotalDescriptorBase() :
528
0
    aPropSet( lcl_GetSubTotalPropertyMap() )
529
0
{
530
0
}
531
532
ScSubTotalDescriptorBase::~ScSubTotalDescriptorBase()
533
0
{
534
0
}
535
536
// XSubTotalDescriptor
537
538
rtl::Reference<ScSubTotalFieldObj> ScSubTotalDescriptorBase::GetObjectByIndex_Impl(sal_uInt16 nIndex)
539
0
{
540
0
    if ( nIndex < getCount() )
541
0
        return new ScSubTotalFieldObj( this, nIndex );
542
0
    return nullptr;
543
0
}
544
545
void SAL_CALL ScSubTotalDescriptorBase::clear()
546
0
{
547
0
    SolarMutexGuard aGuard;
548
0
    ScSubTotalParam aParam;
549
0
    GetData(aParam);
550
551
0
    for (auto& group : aParam.aGroups)
552
0
        group.bActive = false;
553
554
    //! notify the field objects???
555
556
0
    PutData(aParam);
557
0
}
558
559
void SAL_CALL ScSubTotalDescriptorBase::addNew(
560
                        const uno::Sequence<sheet::SubTotalColumn>& aSubTotalColumns,
561
                        sal_Int32 nGroupColumn )
562
0
{
563
0
    SolarMutexGuard aGuard;
564
0
    ScSubTotalParam aParam;
565
0
    GetData(aParam);
566
567
0
    sal_uInt16 nPos = 0;
568
0
    while (nPos < MAXSUBTOTAL && aParam.aGroups[nPos].bActive)
569
0
        ++nPos;
570
571
0
    if (nPos >= MAXSUBTOTAL || aSubTotalColumns.getLength() > SCCOL_MAX)
572
        // too many fields / columns
573
0
        throw uno::RuntimeException();      // no other exceptions specified
574
0
    auto& group = aParam.aGroups[nPos];
575
576
0
    group.bActive = true;
577
0
    group.nField = static_cast<SCCOL>(nGroupColumn);
578
0
    group.SetSubtotals(aSubTotalColumns);
579
580
0
    PutData(aParam);
581
0
}
582
583
//  flags/settings as properties
584
585
// XEnumerationAccess
586
587
uno::Reference<container::XEnumeration> SAL_CALL ScSubTotalDescriptorBase::createEnumeration()
588
0
{
589
0
    SolarMutexGuard aGuard;
590
0
    return new ScIndexEnumeration(this, u"com.sun.star.sheet.SubTotalFieldsEnumeration"_ustr);
591
0
}
592
593
// XIndexAccess
594
595
sal_Int32 SAL_CALL ScSubTotalDescriptorBase::getCount()
596
0
{
597
0
    SolarMutexGuard aGuard;
598
0
    ScSubTotalParam aParam;
599
0
    GetData(aParam);
600
601
0
    sal_uInt16 nCount = 0;
602
0
    while ( nCount < MAXSUBTOTAL && aParam.aGroups[nCount].bActive )
603
0
        ++nCount;
604
0
    return nCount;
605
0
}
606
607
uno::Any SAL_CALL ScSubTotalDescriptorBase::getByIndex( sal_Int32 nIndex )
608
0
{
609
0
    SolarMutexGuard aGuard;
610
0
    rtl::Reference<ScSubTotalFieldObj> xField(GetObjectByIndex_Impl(static_cast<sal_uInt16>(nIndex)));
611
0
    if (!xField.is())
612
0
        throw lang::IndexOutOfBoundsException();
613
614
0
    return uno::Any(uno::Reference<sheet::XSubTotalField>(xField));
615
0
}
616
617
uno::Type SAL_CALL ScSubTotalDescriptorBase::getElementType()
618
0
{
619
0
    return cppu::UnoType<sheet::XSubTotalField>::get();
620
0
}
621
622
sal_Bool SAL_CALL ScSubTotalDescriptorBase::hasElements()
623
0
{
624
0
    SolarMutexGuard aGuard;
625
0
    return ( getCount() != 0 );
626
0
}
627
628
// XPropertySet
629
630
uno::Reference<beans::XPropertySetInfo> SAL_CALL ScSubTotalDescriptorBase::getPropertySetInfo()
631
0
{
632
0
    SolarMutexGuard aGuard;
633
0
    static uno::Reference<beans::XPropertySetInfo> aRef(
634
0
        new SfxItemPropertySetInfo( aPropSet.getPropertyMap() ));
635
0
    return aRef;
636
0
}
637
638
void SAL_CALL ScSubTotalDescriptorBase::setPropertyValue(
639
                        const OUString& aPropertyName, const uno::Any& aValue )
640
0
{
641
0
    SolarMutexGuard aGuard;
642
0
    ScSubTotalParam aParam;
643
0
    GetData(aParam);
644
645
    // some old property names are for 5.2 compatibility
646
647
0
    if (aPropertyName == SC_UNONAME_CASE || aPropertyName == SC_UNONAME_ISCASE )
648
0
        aParam.bCaseSens = ScUnoHelpFunctions::GetBoolFromAny( aValue );
649
0
    else if (aPropertyName == SC_UNONAME_FORMATS || aPropertyName == SC_UNONAME_BINDFMT )
650
0
        aParam.bIncludePattern = ScUnoHelpFunctions::GetBoolFromAny( aValue );
651
0
    else if (aPropertyName == SC_UNONAME_ENABSORT )
652
0
        aParam.bDoSort = ScUnoHelpFunctions::GetBoolFromAny( aValue );
653
0
    else if (aPropertyName == SC_UNONAME_SORTASC )
654
0
        aParam.bAscending = ScUnoHelpFunctions::GetBoolFromAny( aValue );
655
0
    else if (aPropertyName == SC_UNONAME_INSBRK )
656
0
        aParam.bPagebreak = ScUnoHelpFunctions::GetBoolFromAny( aValue );
657
0
    else if (aPropertyName == SC_UNONAME_ULIST || aPropertyName == SC_UNONAME_ENUSLIST )
658
0
        aParam.bUserDef = ScUnoHelpFunctions::GetBoolFromAny( aValue );
659
0
    else if (aPropertyName == SC_UNONAME_UINDEX || aPropertyName == SC_UNONAME_USINDEX )
660
0
    {
661
0
        sal_Int32 nVal = 0;
662
0
        if ( aValue >>= nVal )
663
0
            aParam.nUserIndex = static_cast<sal_uInt16>(nVal);
664
0
    }
665
0
    else if (aPropertyName == SC_UNONAME_MAXFLD )
666
0
    {
667
0
        sal_Int32 nVal = 0;
668
0
        if ( (aValue >>= nVal) && nVal > sal::static_int_cast<sal_Int32>(MAXSUBTOTAL) )
669
0
        {
670
0
            throw lang::IllegalArgumentException();
671
0
        }
672
0
    }
673
674
0
    PutData(aParam);
675
0
}
676
677
uno::Any SAL_CALL ScSubTotalDescriptorBase::getPropertyValue( const OUString& aPropertyName )
678
0
{
679
0
    SolarMutexGuard aGuard;
680
0
    ScSubTotalParam aParam;
681
0
    GetData(aParam);
682
683
0
    uno::Any aRet;
684
685
    // some old property names are for 5.2 compatibility
686
687
0
    if (aPropertyName == SC_UNONAME_CASE || aPropertyName == SC_UNONAME_ISCASE )
688
0
        aRet <<= aParam.bCaseSens;
689
0
    else if (aPropertyName == SC_UNONAME_FORMATS || aPropertyName == SC_UNONAME_BINDFMT )
690
0
        aRet <<= aParam.bIncludePattern;
691
0
    else if (aPropertyName == SC_UNONAME_ENABSORT )
692
0
        aRet <<= aParam.bDoSort;
693
0
    else if (aPropertyName == SC_UNONAME_SORTASC )
694
0
        aRet <<= aParam.bAscending;
695
0
    else if (aPropertyName == SC_UNONAME_INSBRK )
696
0
        aRet <<= aParam.bPagebreak;
697
0
    else if (aPropertyName == SC_UNONAME_ULIST || aPropertyName == SC_UNONAME_ENUSLIST )
698
0
        aRet <<= aParam.bUserDef;
699
0
    else if (aPropertyName == SC_UNONAME_UINDEX || aPropertyName == SC_UNONAME_USINDEX )
700
0
        aRet <<= static_cast<sal_Int32>(aParam.nUserIndex);
701
0
    else if (aPropertyName == SC_UNONAME_MAXFLD )
702
0
        aRet <<= sal_Int32(MAXSUBTOTAL);
703
704
0
    return aRet;
705
0
}
706
707
SC_IMPL_DUMMY_PROPERTY_LISTENER( ScSubTotalDescriptorBase )
708
709
ScSubTotalDescriptor::ScSubTotalDescriptor()
710
0
{
711
0
}
712
713
ScSubTotalDescriptor::~ScSubTotalDescriptor()
714
0
{
715
0
}
716
717
void ScSubTotalDescriptor::GetData( ScSubTotalParam& rParam ) const
718
0
{
719
0
    rParam = aStoredParam;          // query for interface
720
0
}
721
722
void ScSubTotalDescriptor::PutData( const ScSubTotalParam& rParam )
723
0
{
724
0
    aStoredParam = rParam;          // set by the interface
725
0
}
726
727
void ScSubTotalDescriptor::SetParam( const ScSubTotalParam& rNew )
728
0
{
729
0
    aStoredParam = rNew;            // set from outside
730
0
}
731
732
ScRangeSubTotalDescriptor::ScRangeSubTotalDescriptor(ScDatabaseRangeObj* pPar) :
733
0
    mxParent(pPar)
734
0
{
735
0
}
736
737
ScRangeSubTotalDescriptor::~ScRangeSubTotalDescriptor()
738
0
{
739
0
}
740
741
void ScRangeSubTotalDescriptor::GetData( ScSubTotalParam& rParam ) const
742
0
{
743
0
    if (mxParent.is())
744
0
        mxParent->GetSubTotalParam( rParam );
745
0
}
746
747
void ScRangeSubTotalDescriptor::PutData( const ScSubTotalParam& rParam )
748
0
{
749
0
    if (mxParent.is())
750
0
        mxParent->SetSubTotalParam( rParam );
751
0
}
752
753
ScConsolidationDescriptor::ScConsolidationDescriptor()
754
0
{
755
0
}
756
757
ScConsolidationDescriptor::~ScConsolidationDescriptor()
758
0
{
759
0
}
760
761
void ScConsolidationDescriptor::SetParam( const ScConsolidateParam& rNew )
762
0
{
763
0
    aParam = rNew;
764
0
}
765
766
// XConsolidationDescriptor
767
768
sheet::GeneralFunction SAL_CALL ScConsolidationDescriptor::getFunction()
769
0
{
770
0
    SolarMutexGuard aGuard;
771
0
    return ScDataUnoConversion::SubTotalToGeneral(aParam.eFunction);
772
0
}
773
774
void SAL_CALL ScConsolidationDescriptor::setFunction( sheet::GeneralFunction nFunction )
775
0
{
776
0
    SolarMutexGuard aGuard;
777
0
    aParam.eFunction = ScDPUtil::toSubTotalFunc(static_cast<ScGeneralFunction>(nFunction));
778
0
}
779
780
uno::Sequence<table::CellRangeAddress> SAL_CALL ScConsolidationDescriptor::getSources()
781
0
{
782
0
    SolarMutexGuard aGuard;
783
0
    sal_uInt16 nCount = aParam.nDataAreaCount;
784
0
    if (!aParam.pDataAreas)
785
0
        nCount = 0;
786
0
    table::CellRangeAddress aRange;
787
0
    uno::Sequence<table::CellRangeAddress> aSeq(nCount);
788
0
    table::CellRangeAddress* pAry = aSeq.getArray();
789
0
    for (sal_uInt16 i=0; i<nCount; i++)
790
0
    {
791
0
        ScArea const & rArea = aParam.pDataAreas[i];
792
0
        aRange.Sheet        = rArea.nTab;
793
0
        aRange.StartColumn  = rArea.nColStart;
794
0
        aRange.StartRow     = rArea.nRowStart;
795
0
        aRange.EndColumn    = rArea.nColEnd;
796
0
        aRange.EndRow       = rArea.nRowEnd;
797
0
        pAry[i] = aRange;
798
0
    }
799
0
    return aSeq;
800
0
}
801
802
void SAL_CALL ScConsolidationDescriptor::setSources(
803
                    const uno::Sequence<table::CellRangeAddress>& aSources )
804
0
{
805
0
    SolarMutexGuard aGuard;
806
0
    sal_uInt16 nCount = static_cast<sal_uInt16>(aSources.getLength());
807
0
    if (nCount)
808
0
    {
809
0
        const table::CellRangeAddress* pAry = aSources.getConstArray();
810
0
        std::unique_ptr<ScArea[]> pNew(new ScArea[nCount]);
811
0
        sal_uInt16 i;
812
0
        for (i=0; i<nCount; i++)
813
0
            pNew[i] = ScArea( pAry[i].Sheet,
814
0
                    static_cast<SCCOL>(pAry[i].StartColumn), pAry[i].StartRow,
815
0
                    static_cast<SCCOL>(pAry[i].EndColumn),   pAry[i].EndRow );
816
817
0
        aParam.SetAreas( std::move(pNew), nCount );    // copy everything
818
0
    }
819
0
    else
820
0
        aParam.ClearDataAreas();
821
0
}
822
823
table::CellAddress SAL_CALL ScConsolidationDescriptor::getStartOutputPosition()
824
0
{
825
0
    SolarMutexGuard aGuard;
826
0
    table::CellAddress aPos;
827
0
    aPos.Column = aParam.nCol;
828
0
    aPos.Row    = aParam.nRow;
829
0
    aPos.Sheet  = aParam.nTab;
830
0
    return aPos;
831
0
}
832
833
void SAL_CALL ScConsolidationDescriptor::setStartOutputPosition(
834
                                const table::CellAddress& aStartOutputPosition )
835
0
{
836
0
    SolarMutexGuard aGuard;
837
0
    aParam.nCol = static_cast<SCCOL>(aStartOutputPosition.Column);
838
0
    aParam.nRow = static_cast<SCROW>(aStartOutputPosition.Row);
839
0
    aParam.nTab = aStartOutputPosition.Sheet;
840
0
}
841
842
sal_Bool SAL_CALL ScConsolidationDescriptor::getUseColumnHeaders()
843
0
{
844
0
    SolarMutexGuard aGuard;
845
0
    return aParam.bByCol;
846
0
}
847
848
void SAL_CALL ScConsolidationDescriptor::setUseColumnHeaders( sal_Bool bUseColumnHeaders )
849
0
{
850
0
    SolarMutexGuard aGuard;
851
0
    aParam.bByCol = bUseColumnHeaders;
852
0
}
853
854
sal_Bool SAL_CALL ScConsolidationDescriptor::getUseRowHeaders()
855
0
{
856
0
    SolarMutexGuard aGuard;
857
0
    return aParam.bByRow;
858
0
}
859
860
void SAL_CALL ScConsolidationDescriptor::setUseRowHeaders( sal_Bool bUseRowHeaders )
861
0
{
862
0
    SolarMutexGuard aGuard;
863
0
    aParam.bByRow = bUseRowHeaders;
864
0
}
865
866
sal_Bool SAL_CALL ScConsolidationDescriptor::getInsertLinks()
867
0
{
868
0
    SolarMutexGuard aGuard;
869
0
    return aParam.bReferenceData;
870
0
}
871
872
void SAL_CALL ScConsolidationDescriptor::setInsertLinks( sal_Bool bInsertLinks )
873
0
{
874
0
    SolarMutexGuard aGuard;
875
0
    aParam.bReferenceData = bInsertLinks;
876
0
}
877
878
ScFilterDescriptorBase::ScFilterDescriptorBase(ScDocShell* pDocShell) :
879
525
    aPropSet( lcl_GetFilterPropertyMap() ),
880
525
    pDocSh(pDocShell)
881
525
{
882
525
    if (pDocSh)
883
525
        pDocSh->GetDocument().AddUnoObject(*this);
884
525
}
885
886
ScFilterDescriptorBase::~ScFilterDescriptorBase()
887
525
{
888
525
    SolarMutexGuard g;
889
890
525
    if (pDocSh)
891
525
        pDocSh->GetDocument().RemoveUnoObject(*this);
892
525
}
893
894
void ScFilterDescriptorBase::Notify( SfxBroadcaster&, const SfxHint& rHint )
895
1.19k
{
896
1.19k
    if ( rHint.GetId() == SfxHintId::Dying )
897
0
    {
898
0
        pDocSh = nullptr;          // invalid
899
0
    }
900
1.19k
}
901
902
// XSheetFilterDescriptor and XSheetFilterDescriptor2
903
904
uno::Sequence<sheet::TableFilterField> SAL_CALL ScFilterDescriptorBase::getFilterFields()
905
0
{
906
0
    SolarMutexGuard aGuard;
907
0
    ScQueryParam aParam;
908
0
    GetData(aParam);
909
910
0
    SCSIZE nEntries = aParam.GetEntryCount();   // allocated entries in Param
911
0
    SCSIZE nCount = 0;                          // active
912
0
    while ( nCount < nEntries &&
913
0
            aParam.GetEntry(nCount).bDoQuery )
914
0
        ++nCount;
915
916
0
    sheet::TableFilterField aField;
917
0
    uno::Sequence<sheet::TableFilterField> aSeq(static_cast<sal_Int32>(nCount));
918
0
    sheet::TableFilterField* pAry = aSeq.getArray();
919
0
    for (SCSIZE i=0; i<nCount; i++)
920
0
    {
921
0
        const ScQueryEntry& rEntry = aParam.GetEntry(i);
922
0
        if (rEntry.GetQueryItems().empty())
923
0
            continue;
924
925
0
        const ScQueryEntry::Item& rItem = rEntry.GetQueryItems().front();
926
927
0
        aField.Connection    = (rEntry.eConnect == SC_AND) ? sheet::FilterConnection_AND :
928
0
                                                             sheet::FilterConnection_OR;
929
0
        aField.Field         = rEntry.nField;
930
0
        aField.IsNumeric     = rItem.meType != ScQueryEntry::ByString;
931
0
        aField.StringValue   = rItem.maString.getString();
932
0
        aField.NumericValue  = rItem.mfVal;
933
934
0
        switch (rEntry.eOp)             // ScQueryOp
935
0
        {
936
0
            case SC_EQUAL:
937
0
                {
938
0
                    aField.Operator = sheet::FilterOperator_EQUAL;
939
0
                    if (rEntry.IsQueryByEmpty())
940
0
                    {
941
0
                        aField.Operator = sheet::FilterOperator_EMPTY;
942
0
                        aField.NumericValue = 0;
943
0
                    }
944
0
                    else if (rEntry.IsQueryByNonEmpty())
945
0
                    {
946
0
                        aField.Operator = sheet::FilterOperator_NOT_EMPTY;
947
0
                        aField.NumericValue = 0;
948
0
                    }
949
0
                }
950
0
                break;
951
0
            case SC_LESS:           aField.Operator = sheet::FilterOperator_LESS;             break;
952
0
            case SC_GREATER:        aField.Operator = sheet::FilterOperator_GREATER;          break;
953
0
            case SC_LESS_EQUAL:     aField.Operator = sheet::FilterOperator_LESS_EQUAL;   break;
954
0
            case SC_GREATER_EQUAL:  aField.Operator = sheet::FilterOperator_GREATER_EQUAL;  break;
955
0
            case SC_NOT_EQUAL:      aField.Operator = sheet::FilterOperator_NOT_EQUAL;    break;
956
0
            case SC_TOPVAL:         aField.Operator = sheet::FilterOperator_TOP_VALUES;   break;
957
0
            case SC_BOTVAL:         aField.Operator = sheet::FilterOperator_BOTTOM_VALUES;  break;
958
0
            case SC_TOPPERC:        aField.Operator = sheet::FilterOperator_TOP_PERCENT;      break;
959
0
            case SC_BOTPERC:        aField.Operator = sheet::FilterOperator_BOTTOM_PERCENT; break;
960
0
            default:
961
0
                OSL_FAIL("wrong filter enum");
962
0
                aField.Operator = sheet::FilterOperator_EMPTY;
963
0
        }
964
0
        pAry[i] = aField;
965
0
    }
966
0
    return aSeq;
967
0
}
968
969
namespace {
970
971
template<typename T>
972
void convertQueryEntryToUno(const ScQueryEntry& rEntry, T& rField)
973
0
{
974
0
    rField.Connection = (rEntry.eConnect == SC_AND) ? sheet::FilterConnection_AND : sheet::FilterConnection_OR;
975
0
    rField.Field = rEntry.nField;
976
977
0
    switch (rEntry.eOp)             // ScQueryOp
978
0
    {
979
0
    case SC_EQUAL:                  rField.Operator = sheet::FilterOperator2::EQUAL;                break;
980
0
    case SC_LESS:                   rField.Operator = sheet::FilterOperator2::LESS;                 break;
981
0
    case SC_GREATER:                rField.Operator = sheet::FilterOperator2::GREATER;              break;
982
0
    case SC_LESS_EQUAL:             rField.Operator = sheet::FilterOperator2::LESS_EQUAL;           break;
983
0
    case SC_GREATER_EQUAL:          rField.Operator = sheet::FilterOperator2::GREATER_EQUAL;        break;
984
0
    case SC_NOT_EQUAL:              rField.Operator = sheet::FilterOperator2::NOT_EQUAL;            break;
985
0
    case SC_TOPVAL:                 rField.Operator = sheet::FilterOperator2::TOP_VALUES;           break;
986
0
    case SC_BOTVAL:                 rField.Operator = sheet::FilterOperator2::BOTTOM_VALUES;        break;
987
0
    case SC_TOPPERC:                rField.Operator = sheet::FilterOperator2::TOP_PERCENT;          break;
988
0
    case SC_BOTPERC:                rField.Operator = sheet::FilterOperator2::BOTTOM_PERCENT;       break;
989
0
    case SC_CONTAINS:               rField.Operator = sheet::FilterOperator2::CONTAINS;             break;
990
0
    case SC_DOES_NOT_CONTAIN:       rField.Operator = sheet::FilterOperator2::DOES_NOT_CONTAIN;     break;
991
0
    case SC_BEGINS_WITH:            rField.Operator = sheet::FilterOperator2::BEGINS_WITH;          break;
992
0
    case SC_DOES_NOT_BEGIN_WITH:    rField.Operator = sheet::FilterOperator2::DOES_NOT_BEGIN_WITH;  break;
993
0
    case SC_ENDS_WITH:              rField.Operator = sheet::FilterOperator2::ENDS_WITH;            break;
994
0
    case SC_DOES_NOT_END_WITH:      rField.Operator = sheet::FilterOperator2::DOES_NOT_END_WITH;    break;
995
0
    default:
996
0
        OSL_FAIL("Unknown filter operator value.");
997
0
        rField.Operator = sheet::FilterOperator2::EMPTY;
998
0
    }
999
0
}
Unexecuted instantiation: datauno.cxx:void (anonymous namespace)::convertQueryEntryToUno<com::sun::star::sheet::TableFilterField2>(ScQueryEntry const&, com::sun::star::sheet::TableFilterField2&)
Unexecuted instantiation: datauno.cxx:void (anonymous namespace)::convertQueryEntryToUno<com::sun::star::sheet::TableFilterField3>(ScQueryEntry const&, com::sun::star::sheet::TableFilterField3&)
1000
1001
template<typename T>
1002
void convertUnoToQueryEntry(const T& rField, ScQueryEntry& rEntry)
1003
264
{
1004
264
    rEntry.bDoQuery = true;
1005
264
    rEntry.eConnect = (rField.Connection == sheet::FilterConnection_AND) ? SC_AND : SC_OR;
1006
264
    rEntry.nField   = rField.Field;
1007
1008
264
    switch (rField.Operator)           // FilterOperator
1009
264
    {
1010
127
    case sheet::FilterOperator2::EQUAL:                 rEntry.eOp = SC_EQUAL;              break;
1011
0
    case sheet::FilterOperator2::LESS:                  rEntry.eOp = SC_LESS;               break;
1012
9
    case sheet::FilterOperator2::GREATER:               rEntry.eOp = SC_GREATER;            break;
1013
9
    case sheet::FilterOperator2::LESS_EQUAL:            rEntry.eOp = SC_LESS_EQUAL;         break;
1014
0
    case sheet::FilterOperator2::GREATER_EQUAL:         rEntry.eOp = SC_GREATER_EQUAL;      break;
1015
0
    case sheet::FilterOperator2::NOT_EQUAL:             rEntry.eOp = SC_NOT_EQUAL;          break;
1016
25
    case sheet::FilterOperator2::TOP_VALUES:            rEntry.eOp = SC_TOPVAL;             break;
1017
13
    case sheet::FilterOperator2::BOTTOM_VALUES:         rEntry.eOp = SC_BOTVAL;             break;
1018
13
    case sheet::FilterOperator2::TOP_PERCENT:           rEntry.eOp = SC_TOPPERC;            break;
1019
16
    case sheet::FilterOperator2::BOTTOM_PERCENT:        rEntry.eOp = SC_BOTPERC;            break;
1020
11
    case sheet::FilterOperator2::CONTAINS:              rEntry.eOp = SC_CONTAINS;           break;
1021
0
    case sheet::FilterOperator2::DOES_NOT_CONTAIN:      rEntry.eOp = SC_DOES_NOT_CONTAIN;   break;
1022
11
    case sheet::FilterOperator2::BEGINS_WITH:           rEntry.eOp = SC_BEGINS_WITH;        break;
1023
0
    case sheet::FilterOperator2::DOES_NOT_BEGIN_WITH:   rEntry.eOp = SC_DOES_NOT_BEGIN_WITH;break;
1024
0
    case sheet::FilterOperator2::ENDS_WITH:             rEntry.eOp = SC_ENDS_WITH;          break;
1025
0
    case sheet::FilterOperator2::DOES_NOT_END_WITH:     rEntry.eOp = SC_DOES_NOT_END_WITH;  break;
1026
19
    case sheet::FilterOperator2::EMPTY:
1027
19
        rEntry.SetQueryByEmpty();
1028
19
        break;
1029
11
    case sheet::FilterOperator2::NOT_EMPTY:
1030
11
        rEntry.SetQueryByNonEmpty();
1031
11
        break;
1032
0
    default:
1033
0
        OSL_FAIL("Unknown filter operator type.");
1034
0
        rEntry.eOp = SC_EQUAL;
1035
264
    }
1036
264
}
Unexecuted instantiation: datauno.cxx:void (anonymous namespace)::convertUnoToQueryEntry<com::sun::star::sheet::TableFilterField2>(com::sun::star::sheet::TableFilterField2 const&, ScQueryEntry&)
datauno.cxx:void (anonymous namespace)::convertUnoToQueryEntry<com::sun::star::sheet::TableFilterField3>(com::sun::star::sheet::TableFilterField3 const&, ScQueryEntry&)
Line
Count
Source
1003
264
{
1004
264
    rEntry.bDoQuery = true;
1005
264
    rEntry.eConnect = (rField.Connection == sheet::FilterConnection_AND) ? SC_AND : SC_OR;
1006
264
    rEntry.nField   = rField.Field;
1007
1008
264
    switch (rField.Operator)           // FilterOperator
1009
264
    {
1010
127
    case sheet::FilterOperator2::EQUAL:                 rEntry.eOp = SC_EQUAL;              break;
1011
0
    case sheet::FilterOperator2::LESS:                  rEntry.eOp = SC_LESS;               break;
1012
9
    case sheet::FilterOperator2::GREATER:               rEntry.eOp = SC_GREATER;            break;
1013
9
    case sheet::FilterOperator2::LESS_EQUAL:            rEntry.eOp = SC_LESS_EQUAL;         break;
1014
0
    case sheet::FilterOperator2::GREATER_EQUAL:         rEntry.eOp = SC_GREATER_EQUAL;      break;
1015
0
    case sheet::FilterOperator2::NOT_EQUAL:             rEntry.eOp = SC_NOT_EQUAL;          break;
1016
25
    case sheet::FilterOperator2::TOP_VALUES:            rEntry.eOp = SC_TOPVAL;             break;
1017
13
    case sheet::FilterOperator2::BOTTOM_VALUES:         rEntry.eOp = SC_BOTVAL;             break;
1018
13
    case sheet::FilterOperator2::TOP_PERCENT:           rEntry.eOp = SC_TOPPERC;            break;
1019
16
    case sheet::FilterOperator2::BOTTOM_PERCENT:        rEntry.eOp = SC_BOTPERC;            break;
1020
11
    case sheet::FilterOperator2::CONTAINS:              rEntry.eOp = SC_CONTAINS;           break;
1021
0
    case sheet::FilterOperator2::DOES_NOT_CONTAIN:      rEntry.eOp = SC_DOES_NOT_CONTAIN;   break;
1022
11
    case sheet::FilterOperator2::BEGINS_WITH:           rEntry.eOp = SC_BEGINS_WITH;        break;
1023
0
    case sheet::FilterOperator2::DOES_NOT_BEGIN_WITH:   rEntry.eOp = SC_DOES_NOT_BEGIN_WITH;break;
1024
0
    case sheet::FilterOperator2::ENDS_WITH:             rEntry.eOp = SC_ENDS_WITH;          break;
1025
0
    case sheet::FilterOperator2::DOES_NOT_END_WITH:     rEntry.eOp = SC_DOES_NOT_END_WITH;  break;
1026
19
    case sheet::FilterOperator2::EMPTY:
1027
19
        rEntry.SetQueryByEmpty();
1028
19
        break;
1029
11
    case sheet::FilterOperator2::NOT_EMPTY:
1030
11
        rEntry.SetQueryByNonEmpty();
1031
11
        break;
1032
0
    default:
1033
0
        OSL_FAIL("Unknown filter operator type.");
1034
0
        rEntry.eOp = SC_EQUAL;
1035
264
    }
1036
264
}
1037
1038
void fillQueryParam(
1039
    ScQueryParam& rParam, ScDocument* pDoc,
1040
    const uno::Sequence<sheet::TableFilterField2>& aFilterFields)
1041
0
{
1042
0
    size_t nCount = static_cast<size_t>(aFilterFields.getLength());
1043
0
    rParam.Resize(nCount);
1044
1045
0
    const sheet::TableFilterField2* pAry = aFilterFields.getConstArray();
1046
0
    svl::SharedStringPool& rPool = pDoc->GetSharedStringPool();
1047
0
    for (size_t i = 0; i < nCount; ++i)
1048
0
    {
1049
0
        ScQueryEntry& rEntry = rParam.GetEntry(i);
1050
0
        convertUnoToQueryEntry(pAry[i], rEntry);
1051
1052
0
        if (pAry[i].Operator != sheet::FilterOperator2::EMPTY && pAry[i].Operator != sheet::FilterOperator2::NOT_EMPTY)
1053
0
        {
1054
0
            ScQueryEntry::QueryItemsType& rItems = rEntry.GetQueryItems();
1055
0
            rItems.resize(1);
1056
0
            ScQueryEntry::Item& rItem = rItems.front();
1057
0
            rItem.meType    = pAry[i].IsNumeric ? ScQueryEntry::ByValue : ScQueryEntry::ByString;
1058
0
            rItem.mfVal     = pAry[i].NumericValue;
1059
0
            rItem.maString = rPool.intern(pAry[i].StringValue);
1060
1061
0
            if (rItem.meType == ScQueryEntry::ByValue)
1062
0
            {
1063
0
                OUString aStr = pDoc->GetFormatTable()->GetInputLineString(rItem.mfVal, 0);
1064
0
                rItem.maString = rPool.intern(aStr);
1065
0
            }
1066
0
        }
1067
0
    }
1068
1069
0
    size_t nParamCount = rParam.GetEntryCount();    // if below eight Param isn't resized
1070
0
    for (size_t i = nCount; i < nParamCount; ++i)
1071
0
        rParam.GetEntry(i).bDoQuery = false;        // reset surplus fields
1072
0
}
1073
1074
void fillQueryParam(
1075
    ScQueryParam& rParam, ScDocument* pDoc,
1076
    const uno::Sequence<sheet::TableFilterField3>& aFilterFields)
1077
144
{
1078
144
    size_t nCount = static_cast<size_t>(aFilterFields.getLength());
1079
144
    rParam.Resize(nCount);
1080
1081
144
    svl::SharedStringPool& rPool = pDoc->GetSharedStringPool();
1082
144
    const sheet::TableFilterField3* pAry = aFilterFields.getConstArray();
1083
408
    for (size_t i = 0; i < nCount; ++i)
1084
264
    {
1085
264
        ScQueryEntry& rEntry = rParam.GetEntry(i);
1086
264
        convertUnoToQueryEntry(pAry[i], rEntry);
1087
1088
264
        if (pAry[i].Operator != sheet::FilterOperator2::EMPTY && pAry[i].Operator != sheet::FilterOperator2::NOT_EMPTY)
1089
234
        {
1090
234
            ScQueryEntry::QueryItemsType& rItems = rEntry.GetQueryItems();
1091
234
            rItems.clear();
1092
234
            const uno::Sequence<sheet::FilterFieldValue>& rVals = pAry[i].Values;
1093
234
            for (const auto& rVal : rVals)
1094
312
            {
1095
312
                ScQueryEntry::Item aItem;
1096
312
                switch (rVal.FilterType)
1097
312
                {
1098
67
                    case FilterFieldType::NUMERIC:
1099
67
                        aItem.meType = ScQueryEntry::ByValue;
1100
67
                        break;
1101
241
                    case FilterFieldType::STRING:
1102
241
                        aItem.meType = ScQueryEntry::ByString;
1103
241
                        break;
1104
4
                    case FilterFieldType::DATE:
1105
4
                        aItem.meType = ScQueryEntry::ByDate;
1106
4
                        break;
1107
0
                    case FilterFieldType::TEXT_COLOR:
1108
0
                        aItem.meType = ScQueryEntry::ByTextColor;
1109
0
                        break;
1110
0
                    case FilterFieldType::BACKGROUND_COLOR:
1111
0
                        aItem.meType = ScQueryEntry::ByBackgroundColor;
1112
0
                        break;
1113
312
                }
1114
312
                aItem.mfVal    = rVal.NumericValue;
1115
312
                aItem.maString = rPool.intern(rVal.StringValue);
1116
1117
312
                if (aItem.meType == ScQueryEntry::ByValue)
1118
67
                {
1119
67
                    OUString aStr = pDoc->GetFormatTable()->GetInputLineString(aItem.mfVal, 0);
1120
67
                    aItem.maString = rPool.intern(aStr);
1121
67
                }
1122
245
                else if (aItem.meType == ScQueryEntry::ByTextColor
1123
245
                         || aItem.meType == ScQueryEntry::ByBackgroundColor)
1124
0
                {
1125
0
                    aItem.maColor = Color(ColorTransparency, rVal.ColorValue);
1126
0
                }
1127
1128
                // filter all dates starting with the given date filter YYYY or YYYY-MM and filter all datetimes
1129
                // starting with the given datetime filter YYYY-MM-DD, YYYY-MM-DD HH, or YYYY-MM-DD HH:MM
1130
312
                if( aItem.meType == ScQueryEntry::ByDate && aItem.maString.getLength() < 19 )
1131
4
                {
1132
4
                    ScFilterEntries aFilterEntries;
1133
4
                    pDoc->GetFilterEntries(rEntry.nField, rParam.nRow1, rParam.nTab, aFilterEntries);
1134
4
                    for( const auto& rFilter : aFilterEntries )
1135
12
                    {
1136
12
                        if( rFilter.GetString().startsWith(rVal.StringValue) )
1137
2
                        {
1138
2
                            aItem.maString = rPool.intern(rFilter.GetString());
1139
2
                            rItems.push_back(aItem);
1140
2
                        }
1141
12
                    }
1142
4
                }
1143
308
                else
1144
308
                {
1145
308
                    rItems.push_back(aItem);
1146
308
                }
1147
312
            }
1148
234
        }
1149
264
    }
1150
1151
144
    size_t nParamCount = rParam.GetEntryCount();    // if below eight Param isn't resized
1152
1.03k
    for (size_t i = nCount; i < nParamCount; ++i)
1153
888
        rParam.GetEntry(i).bDoQuery = false;        // reset surplus fields
1154
144
}
1155
1156
}
1157
1158
uno::Sequence<sheet::TableFilterField2> SAL_CALL ScFilterDescriptorBase::getFilterFields2()
1159
0
{
1160
0
    SolarMutexGuard aGuard;
1161
0
    ScQueryParam aParam;
1162
0
    GetData(aParam);
1163
1164
0
    SCSIZE nEntries = aParam.GetEntryCount();   // allocated entries in Param
1165
0
    SCSIZE nCount = 0;                          // active
1166
0
    while ( nCount < nEntries &&
1167
0
        aParam.GetEntry(nCount).bDoQuery )
1168
0
        ++nCount;
1169
1170
0
    sheet::TableFilterField2 aField;
1171
0
    uno::Sequence<sheet::TableFilterField2> aSeq(static_cast<sal_Int32>(nCount));
1172
0
    sheet::TableFilterField2* pAry = aSeq.getArray();
1173
0
    for (SCSIZE i=0; i<nCount; i++)
1174
0
    {
1175
0
        const ScQueryEntry& rEntry = aParam.GetEntry(i);
1176
0
        convertQueryEntryToUno(rEntry, aField);
1177
1178
0
        bool bByEmpty = false;
1179
0
        if (aField.Operator == sheet::FilterOperator2::EQUAL)
1180
0
        {
1181
0
            if (rEntry.IsQueryByEmpty())
1182
0
            {
1183
0
                aField.Operator = sheet::FilterOperator2::EMPTY;
1184
0
                aField.NumericValue = 0;
1185
0
                bByEmpty = true;
1186
0
            }
1187
0
            else if (rEntry.IsQueryByNonEmpty())
1188
0
            {
1189
0
                aField.Operator = sheet::FilterOperator2::NOT_EMPTY;
1190
0
                aField.NumericValue = 0;
1191
0
                bByEmpty = true;
1192
0
            }
1193
0
        }
1194
1195
0
        if (!bByEmpty && !rEntry.GetQueryItems().empty())
1196
0
        {
1197
0
            const ScQueryEntry::Item& rItem = rEntry.GetQueryItems().front();
1198
0
            aField.IsNumeric     = rItem.meType != ScQueryEntry::ByString;
1199
0
            aField.StringValue   = rItem.maString.getString();
1200
0
            aField.NumericValue  = rItem.mfVal;
1201
0
        }
1202
1203
0
        pAry[i] = aField;
1204
0
    }
1205
0
    return aSeq;
1206
0
}
1207
1208
uno::Sequence<sheet::TableFilterField3> SAL_CALL ScFilterDescriptorBase::getFilterFields3()
1209
0
{
1210
0
    SolarMutexGuard aGuard;
1211
0
    ScQueryParam aParam;
1212
0
    GetData(aParam);
1213
1214
0
    SCSIZE nEntries = aParam.GetEntryCount();   // allocated entries in Param
1215
0
    SCSIZE nCount = 0;                          // active
1216
0
    while ( nCount < nEntries &&
1217
0
        aParam.GetEntry(nCount).bDoQuery )
1218
0
        ++nCount;
1219
1220
0
    sheet::TableFilterField3 aField;
1221
0
    uno::Sequence<sheet::TableFilterField3> aSeq(static_cast<sal_Int32>(nCount));
1222
0
    sheet::TableFilterField3* pAry = aSeq.getArray();
1223
0
    for (SCSIZE i = 0; i < nCount; ++i)
1224
0
    {
1225
0
        const ScQueryEntry& rEntry = aParam.GetEntry(i);
1226
0
        convertQueryEntryToUno(rEntry, aField);
1227
1228
0
        bool bByEmpty = false;
1229
0
        if (aField.Operator == sheet::FilterOperator2::EQUAL)
1230
0
        {
1231
0
            if (rEntry.IsQueryByEmpty())
1232
0
            {
1233
0
                aField.Operator = sheet::FilterOperator2::EMPTY;
1234
0
                aField.Values.realloc(1);
1235
0
                aField.Values.getArray()[0].NumericValue = 0;
1236
0
                bByEmpty = true;
1237
0
            }
1238
0
            else if (rEntry.IsQueryByNonEmpty())
1239
0
            {
1240
0
                aField.Operator = sheet::FilterOperator2::NOT_EMPTY;
1241
0
                aField.Values.realloc(1);
1242
0
                aField.Values.getArray()[0].NumericValue = 0;
1243
0
                bByEmpty = true;
1244
0
            }
1245
0
        }
1246
1247
0
        if (!bByEmpty)
1248
0
        {
1249
0
            const ScQueryEntry::QueryItemsType& rItems = rEntry.GetQueryItems();
1250
0
            size_t nItemCount = rItems.size();
1251
0
            aField.Values.realloc(nItemCount);
1252
0
            auto pValues = aField.Values.getArray();
1253
0
            size_t j = 0;
1254
0
            for (const auto& rItem : rItems)
1255
0
            {
1256
0
                pValues[j].IsNumeric = rItem.meType != ScQueryEntry::ByString;
1257
0
                pValues[j].StringValue = rItem.maString.getString();
1258
0
                pValues[j].NumericValue = rItem.mfVal;
1259
0
                ++j;
1260
0
            }
1261
0
        }
1262
1263
0
        pAry[i] = aField;
1264
0
    }
1265
0
    return aSeq;
1266
0
}
1267
1268
void SAL_CALL ScFilterDescriptorBase::setFilterFields(
1269
                const uno::Sequence<sheet::TableFilterField>& aFilterFields )
1270
0
{
1271
0
    SolarMutexGuard aGuard;
1272
0
    ScQueryParam aParam;
1273
0
    GetData(aParam);
1274
1275
0
    SCSIZE nCount = static_cast<SCSIZE>(aFilterFields.getLength());
1276
0
    aParam.Resize( nCount );
1277
1278
0
    ScDocument& rDoc = pDocSh->GetDocument();
1279
0
    svl::SharedStringPool& rPool = rDoc.GetSharedStringPool();
1280
0
    const sheet::TableFilterField* pAry = aFilterFields.getConstArray();
1281
0
    SCSIZE i;
1282
0
    for (i=0; i<nCount; i++)
1283
0
    {
1284
0
        ScQueryEntry& rEntry = aParam.GetEntry(i);
1285
0
        ScQueryEntry::QueryItemsType& rItems = rEntry.GetQueryItems();
1286
0
        rItems.resize(1);
1287
0
        ScQueryEntry::Item& rItem = rItems.front();
1288
0
        rEntry.bDoQuery = true;
1289
0
        rEntry.eConnect = (pAry[i].Connection == sheet::FilterConnection_AND) ? SC_AND : SC_OR;
1290
0
        rEntry.nField   = pAry[i].Field;
1291
0
        rItem.meType    = pAry[i].IsNumeric ? ScQueryEntry::ByValue : ScQueryEntry::ByString;
1292
0
        rItem.mfVal     = pAry[i].NumericValue;
1293
0
        rItem.maString = rPool.intern(pAry[i].StringValue);
1294
1295
0
        if (rItem.meType != ScQueryEntry::ByString)
1296
0
        {
1297
0
            OUString aStr = rDoc.GetFormatTable()->GetInputLineString(rItem.mfVal, 0);
1298
0
            rItem.maString = rPool.intern(aStr);
1299
0
        }
1300
1301
0
        switch (pAry[i].Operator)           // FilterOperator
1302
0
        {
1303
0
            case sheet::FilterOperator_EQUAL:           rEntry.eOp = SC_EQUAL;       break;
1304
0
            case sheet::FilterOperator_LESS:            rEntry.eOp = SC_LESS;            break;
1305
0
            case sheet::FilterOperator_GREATER:         rEntry.eOp = SC_GREATER;         break;
1306
0
            case sheet::FilterOperator_LESS_EQUAL:      rEntry.eOp = SC_LESS_EQUAL;  break;
1307
0
            case sheet::FilterOperator_GREATER_EQUAL:   rEntry.eOp = SC_GREATER_EQUAL; break;
1308
0
            case sheet::FilterOperator_NOT_EQUAL:       rEntry.eOp = SC_NOT_EQUAL;   break;
1309
0
            case sheet::FilterOperator_TOP_VALUES:      rEntry.eOp = SC_TOPVAL;      break;
1310
0
            case sheet::FilterOperator_BOTTOM_VALUES:   rEntry.eOp = SC_BOTVAL;      break;
1311
0
            case sheet::FilterOperator_TOP_PERCENT:     rEntry.eOp = SC_TOPPERC;         break;
1312
0
            case sheet::FilterOperator_BOTTOM_PERCENT:  rEntry.eOp = SC_BOTPERC;         break;
1313
0
            case sheet::FilterOperator_EMPTY:
1314
0
                rEntry.SetQueryByEmpty();
1315
0
                break;
1316
0
            case sheet::FilterOperator_NOT_EMPTY:
1317
0
                rEntry.SetQueryByNonEmpty();
1318
0
                break;
1319
0
            default:
1320
0
                OSL_FAIL("Wrong query enum");
1321
0
                rEntry.eOp = SC_EQUAL;
1322
0
        }
1323
0
    }
1324
1325
0
    SCSIZE nParamCount = aParam.GetEntryCount();    // if below eight Param isn't resized
1326
0
    for (i=nCount; i<nParamCount; i++)
1327
0
        aParam.GetEntry(i).bDoQuery = false;        // reset surplus fields
1328
1329
0
    PutData(aParam);
1330
0
}
1331
1332
void SAL_CALL ScFilterDescriptorBase::setFilterFields2(
1333
    const uno::Sequence<sheet::TableFilterField2>& aFilterFields )
1334
0
{
1335
0
    SolarMutexGuard aGuard;
1336
0
    ScQueryParam aParam;
1337
0
    GetData(aParam);
1338
0
    fillQueryParam(aParam, &pDocSh->GetDocument(), aFilterFields);
1339
0
    PutData(aParam);
1340
0
}
1341
1342
void SAL_CALL ScFilterDescriptorBase::setFilterFields3(
1343
    const uno::Sequence<sheet::TableFilterField3>& aFilterFields )
1344
144
{
1345
144
    SolarMutexGuard aGuard;
1346
144
    ScQueryParam aParam;
1347
144
    GetData(aParam);
1348
144
    fillQueryParam(aParam, &pDocSh->GetDocument(), aFilterFields);
1349
144
    PutData(aParam);
1350
144
}
1351
1352
// Rest are Properties
1353
1354
// XPropertySet
1355
1356
uno::Reference<beans::XPropertySetInfo> SAL_CALL ScFilterDescriptorBase::getPropertySetInfo()
1357
0
{
1358
0
    SolarMutexGuard aGuard;
1359
0
    static uno::Reference<beans::XPropertySetInfo> aRef(
1360
0
        new SfxItemPropertySetInfo( aPropSet.getPropertyMap() ));
1361
0
    return aRef;
1362
0
}
1363
1364
void SAL_CALL ScFilterDescriptorBase::setPropertyValue(
1365
                        const OUString& aPropertyName, const uno::Any& aValue )
1366
525
{
1367
525
    SolarMutexGuard aGuard;
1368
525
    ScQueryParam aParam;
1369
525
    GetData(aParam);
1370
1371
525
    if (aPropertyName == SC_UNONAME_CONTHDR)
1372
0
        aParam.bHasHeader = ScUnoHelpFunctions::GetBoolFromAny( aValue );
1373
525
    else if (aPropertyName == SC_UNONAME_COPYOUT)
1374
0
        aParam.bInplace = !(ScUnoHelpFunctions::GetBoolFromAny( aValue ));
1375
525
    else if (aPropertyName == SC_UNONAME_ISCASE)
1376
0
        aParam.bCaseSens = ScUnoHelpFunctions::GetBoolFromAny( aValue );
1377
525
    else if (aPropertyName == SC_UNONAME_MAXFLD)
1378
0
    {
1379
        // silently ignored
1380
0
    }
1381
525
    else if (aPropertyName == SC_UNONAME_ORIENT)
1382
0
    {
1383
        //! test for correct enum type?
1384
0
        table::TableOrientation eOrient = static_cast<table::TableOrientation>(ScUnoHelpFunctions::GetEnumFromAny( aValue ));
1385
0
        aParam.bByRow = ( eOrient != table::TableOrientation_COLUMNS );
1386
0
    }
1387
525
    else if (aPropertyName == SC_UNONAME_OUTPOS)
1388
0
    {
1389
0
        table::CellAddress aAddress;
1390
0
        if ( aValue >>= aAddress )
1391
0
        {
1392
0
            aParam.nDestTab = aAddress.Sheet;
1393
0
            aParam.nDestCol = static_cast<SCCOL>(aAddress.Column);
1394
0
            aParam.nDestRow = static_cast<SCROW>(aAddress.Row);
1395
0
        }
1396
0
    }
1397
525
    else if (aPropertyName == SC_UNONAME_SAVEOUT)
1398
0
        aParam.bDestPers = ScUnoHelpFunctions::GetBoolFromAny( aValue );
1399
525
    else if (aPropertyName == SC_UNONAME_SKIPDUP)
1400
0
        aParam.bDuplicate = !(ScUnoHelpFunctions::GetBoolFromAny( aValue ));
1401
525
    else if (aPropertyName == SC_UNONAME_USEREGEX)
1402
0
        aParam.eSearchType = ScUnoHelpFunctions::GetBoolFromAny( aValue ) ? utl::SearchParam::SearchType::Regexp :
1403
0
            utl::SearchParam::SearchType::Normal;
1404
1405
525
    PutData(aParam);
1406
525
}
1407
1408
uno::Any SAL_CALL ScFilterDescriptorBase::getPropertyValue( const OUString& aPropertyName )
1409
0
{
1410
0
    SolarMutexGuard aGuard;
1411
0
    ScQueryParam aParam;
1412
0
    GetData(aParam);
1413
1414
0
    uno::Any aRet;
1415
1416
0
    if (aPropertyName == SC_UNONAME_CONTHDR )
1417
0
        aRet <<= aParam.bHasHeader;
1418
0
    else if (aPropertyName == SC_UNONAME_COPYOUT )
1419
0
        aRet <<= !(aParam.bInplace);
1420
0
    else if (aPropertyName == SC_UNONAME_ISCASE )
1421
0
        aRet <<= aParam.bCaseSens;
1422
0
    else if (aPropertyName == SC_UNONAME_MAXFLD )
1423
0
        aRet <<= static_cast<sal_Int32>(aParam.GetEntryCount());
1424
0
    else if (aPropertyName == SC_UNONAME_ORIENT )
1425
0
    {
1426
0
        table::TableOrientation eOrient = aParam.bByRow ? table::TableOrientation_ROWS :
1427
0
                                                          table::TableOrientation_COLUMNS;
1428
0
        aRet <<= eOrient;
1429
0
    }
1430
0
    else if (aPropertyName == SC_UNONAME_OUTPOS )
1431
0
    {
1432
0
        table::CellAddress aOutPos;
1433
0
        aOutPos.Sheet  = aParam.nDestTab;
1434
0
        aOutPos.Column = aParam.nDestCol;
1435
0
        aOutPos.Row    = aParam.nDestRow;
1436
0
        aRet <<= aOutPos;
1437
0
    }
1438
0
    else if (aPropertyName == SC_UNONAME_SAVEOUT )
1439
0
        aRet <<= aParam.bDestPers;
1440
0
    else if (aPropertyName == SC_UNONAME_SKIPDUP )
1441
0
        aRet <<= !(aParam.bDuplicate);
1442
0
    else if (aPropertyName == SC_UNONAME_USEREGEX )
1443
0
        aRet <<= (aParam.eSearchType == utl::SearchParam::SearchType::Regexp);
1444
1445
0
    return aRet;
1446
0
}
1447
1448
SC_IMPL_DUMMY_PROPERTY_LISTENER( ScFilterDescriptorBase )
1449
1450
ScFilterDescriptor::ScFilterDescriptor(ScDocShell* pDocShell)
1451
    :
1452
0
    ScFilterDescriptorBase(pDocShell)
1453
0
{
1454
0
}
1455
1456
ScFilterDescriptor::~ScFilterDescriptor()
1457
0
{
1458
0
}
1459
1460
void ScFilterDescriptor::GetData( ScQueryParam& rParam ) const
1461
0
{
1462
0
    rParam = aStoredParam;          // query for interface
1463
0
}
1464
1465
void ScFilterDescriptor::PutData( const ScQueryParam& rParam )
1466
0
{
1467
0
    aStoredParam = rParam;          // set by the interface
1468
0
}
1469
1470
void ScFilterDescriptor::SetParam( const ScQueryParam& rNew )
1471
0
{
1472
0
    aStoredParam = rNew;            // set from outside
1473
0
}
1474
1475
ScRangeFilterDescriptor::ScRangeFilterDescriptor(ScDocShell* pDocShell, ScDatabaseRangeObj* pPar) :
1476
525
    ScFilterDescriptorBase(pDocShell),
1477
525
    mxParent(pPar)
1478
525
{
1479
525
}
1480
1481
ScRangeFilterDescriptor::~ScRangeFilterDescriptor()
1482
525
{
1483
525
}
1484
1485
void ScRangeFilterDescriptor::GetData( ScQueryParam& rParam ) const
1486
1.19k
{
1487
1.19k
    if (mxParent.is())
1488
1.19k
        mxParent->GetQueryParam( rParam );
1489
1.19k
}
1490
1491
void ScRangeFilterDescriptor::PutData( const ScQueryParam& rParam )
1492
1.19k
{
1493
1.19k
    if (mxParent.is())
1494
1.19k
        mxParent->SetQueryParam( rParam );
1495
1.19k
}
1496
1497
ScDataPilotFilterDescriptor::ScDataPilotFilterDescriptor(ScDocShell* pDocShell, ScDataPilotDescriptorBase* pPar) :
1498
0
    ScFilterDescriptorBase(pDocShell),
1499
0
    mxParent(pPar)
1500
0
{
1501
0
}
1502
1503
ScDataPilotFilterDescriptor::~ScDataPilotFilterDescriptor()
1504
0
{
1505
0
}
1506
1507
void ScDataPilotFilterDescriptor::GetData( ScQueryParam& rParam ) const
1508
0
{
1509
0
    if (mxParent.is())
1510
0
    {
1511
0
        ScDPObject* pDPObj = mxParent->GetDPObject();
1512
0
        if (pDPObj && pDPObj->IsSheetData())
1513
0
            rParam = pDPObj->GetSheetDesc()->GetQueryParam();
1514
0
    }
1515
0
}
1516
1517
void ScDataPilotFilterDescriptor::PutData( const ScQueryParam& rParam )
1518
0
{
1519
0
    if (!mxParent.is())
1520
0
        return;
1521
1522
0
    ScDPObject* pDPObj = mxParent->GetDPObject();
1523
0
    if (pDPObj)
1524
0
    {
1525
0
        ScSheetSourceDesc aSheetDesc(&mxParent->GetDocShell()->GetDocument());
1526
0
        if (pDPObj->IsSheetData())
1527
0
            aSheetDesc = *pDPObj->GetSheetDesc();
1528
0
        aSheetDesc.SetQueryParam(rParam);
1529
0
        pDPObj->SetSheetDesc(aSheetDesc);
1530
0
        mxParent->SetDPObject(pDPObj);
1531
0
    }
1532
0
}
1533
1534
ScDatabaseRangeObj::ScDatabaseRangeObj(ScDocShell* pDocSh, OUString aNm) :
1535
586
    pDocShell( pDocSh ),
1536
586
    aName(std::move( aNm )),
1537
586
    aPropSet( lcl_GetDBRangePropertyMap() ),
1538
586
    bIsUnnamed(false),
1539
586
    aTab( 0 )
1540
586
{
1541
586
    pDocShell->GetDocument().AddUnoObject(*this);
1542
586
}
1543
1544
ScDatabaseRangeObj::ScDatabaseRangeObj(ScDocShell* pDocSh, const SCTAB nTab) :
1545
255
    pDocShell( pDocSh ),
1546
255
    aName(STR_DB_LOCAL_NONAME),
1547
255
    aPropSet( lcl_GetDBRangePropertyMap() ),
1548
255
    bIsUnnamed(true),
1549
255
    aTab( nTab )
1550
255
{
1551
255
    pDocShell->GetDocument().AddUnoObject(*this);
1552
255
}
1553
1554
ScDatabaseRangeObj::~ScDatabaseRangeObj()
1555
841
{
1556
841
    SolarMutexGuard g;
1557
1558
841
    if (pDocShell)
1559
841
        pDocShell->GetDocument().RemoveUnoObject(*this);
1560
841
}
1561
1562
void ScDatabaseRangeObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
1563
3.62k
{
1564
1565
3.62k
    if ( rHint.GetId() == SfxHintId::Dying )
1566
0
        pDocShell = nullptr;
1567
3.62k
    else if ( rHint.GetId() == SfxHintId::ScDBRangeRefreshed )
1568
0
    {
1569
0
        auto pRefreshHint = static_cast<const ScDBRangeRefreshedHint*>(&rHint);
1570
0
        ScDBData* pDBData = GetDBData_Impl();
1571
0
        ScImportParam aParam;
1572
0
        pDBData->GetImportParam(aParam);
1573
0
        if (aParam == pRefreshHint->GetImportParam())
1574
0
            Refreshed_Impl();
1575
0
    }
1576
3.62k
}
1577
1578
// Help functions
1579
1580
ScDBData* ScDatabaseRangeObj::GetDBData_Impl() const
1581
5.69k
{
1582
5.69k
    ScDBData* pRet = nullptr;
1583
5.69k
    if (pDocShell)
1584
5.69k
    {
1585
5.69k
        if (bIsUnnamed)
1586
1.40k
        {
1587
1.40k
            pRet = pDocShell->GetDocument().GetAnonymousDBData(aTab);
1588
1.40k
        }
1589
4.29k
        else
1590
4.29k
        {
1591
4.29k
            ScDBCollection* pNames = pDocShell->GetDocument().GetDBCollection();
1592
4.29k
            if (pNames)
1593
4.29k
            {
1594
4.29k
                ScDBData* p = pNames->getNamedDBs().findByUpperName(ScGlobal::getCharClass().uppercase(aName));
1595
4.29k
                if (p)
1596
4.29k
                    pRet = p;
1597
4.29k
            }
1598
4.29k
        }
1599
5.69k
    }
1600
5.69k
    return pRet;
1601
5.69k
}
1602
1603
// XNamed
1604
1605
OUString SAL_CALL ScDatabaseRangeObj::getName()
1606
0
{
1607
0
    SolarMutexGuard aGuard;
1608
0
    return aName;
1609
0
}
1610
1611
void SAL_CALL ScDatabaseRangeObj::setName( const OUString& aNewName )
1612
0
{
1613
0
    SolarMutexGuard aGuard;
1614
0
    if (pDocShell)
1615
0
    {
1616
0
        ScDBDocFunc aFunc(*pDocShell);
1617
0
        bool bOk = aFunc.RenameDBRange( aName, aNewName );
1618
0
        if (bOk)
1619
0
            aName = aNewName;
1620
0
    }
1621
0
}
1622
1623
// XDatabaseRange
1624
1625
table::CellRangeAddress SAL_CALL ScDatabaseRangeObj::getDataArea()
1626
293
{
1627
293
    SolarMutexGuard aGuard;
1628
293
    table::CellRangeAddress aAddress;
1629
293
    ScDBData* pData = GetDBData_Impl();
1630
293
    if (pData)
1631
293
    {
1632
293
        ScRange aRange;
1633
293
        pData->GetArea(aRange);
1634
293
        aAddress.Sheet       = aRange.aStart.Tab();
1635
293
        aAddress.StartColumn = aRange.aStart.Col();
1636
293
        aAddress.StartRow    = aRange.aStart.Row();
1637
293
        aAddress.EndColumn   = aRange.aEnd.Col();
1638
293
        aAddress.EndRow      = aRange.aEnd.Row();
1639
293
    }
1640
293
    return aAddress;
1641
293
}
1642
1643
void SAL_CALL ScDatabaseRangeObj::setDataArea( const table::CellRangeAddress& aDataArea )
1644
0
{
1645
0
    SolarMutexGuard aGuard;
1646
0
    ScDBData* pData = GetDBData_Impl();
1647
0
    if ( pDocShell && pData )
1648
0
    {
1649
0
        ScDBData aNewData( *pData );
1650
        //! MoveTo ???
1651
0
        aNewData.SetArea( aDataArea.Sheet, static_cast<SCCOL>(aDataArea.StartColumn), static_cast<SCROW>(aDataArea.StartRow),
1652
0
                                           static_cast<SCCOL>(aDataArea.EndColumn), static_cast<SCROW>(aDataArea.EndRow) );
1653
0
        ScDBDocFunc aFunc(*pDocShell);
1654
0
        aFunc.ModifyDBData(aNewData);
1655
0
    }
1656
0
}
1657
1658
uno::Sequence<beans::PropertyValue> SAL_CALL ScDatabaseRangeObj::getSortDescriptor()
1659
0
{
1660
0
    SolarMutexGuard aGuard;
1661
0
    ScSortParam aParam;
1662
0
    const ScDBData* pData = GetDBData_Impl();
1663
0
    if (pData)
1664
0
    {
1665
0
        pData->GetSortParam(aParam);
1666
1667
        //  SortDescriptor contains the counted fields inside the area
1668
0
        ScRange aDBRange;
1669
0
        pData->GetArea(aDBRange);
1670
0
        SCCOLROW nFieldStart = aParam.bByRow ? static_cast<SCCOLROW>(aDBRange.aStart.Col()) : static_cast<SCCOLROW>(aDBRange.aStart.Row());
1671
0
        for (sal_uInt16 i=0; i<aParam.GetSortKeyCount(); i++)
1672
0
            if ( aParam.maKeyState[i].bDoSort && aParam.maKeyState[i].nField >= nFieldStart )
1673
0
                aParam.maKeyState[i].nField -= nFieldStart;
1674
0
    }
1675
1676
0
    uno::Sequence<beans::PropertyValue> aSeq( ScSortDescriptor::GetPropertyCount() );
1677
0
    ScSortDescriptor::FillProperties( aSeq, aParam );
1678
0
    return aSeq;
1679
0
}
1680
1681
void ScDatabaseRangeObj::GetQueryParam(ScQueryParam& rQueryParam) const
1682
1.19k
{
1683
1.19k
    const ScDBData* pData = GetDBData_Impl();
1684
1.19k
    if (!pData)
1685
0
        return;
1686
1687
1.19k
    pData->GetQueryParam(rQueryParam);
1688
1689
    //  FilterDescriptor contains the counted fields inside the area
1690
1.19k
    ScRange aDBRange;
1691
1.19k
    pData->GetArea(aDBRange);
1692
1.19k
    SCCOLROW nFieldStart = rQueryParam.bByRow ? static_cast<SCCOLROW>(aDBRange.aStart.Col()) : static_cast<SCCOLROW>(aDBRange.aStart.Row());
1693
1.19k
    SCSIZE nCount = rQueryParam.GetEntryCount();
1694
10.7k
    for (SCSIZE i=0; i<nCount; i++)
1695
9.55k
    {
1696
9.55k
        ScQueryEntry& rEntry = rQueryParam.GetEntry(i);
1697
9.55k
        if (rEntry.bDoQuery && rEntry.nField >= nFieldStart)
1698
264
            rEntry.nField -= nFieldStart;
1699
9.55k
    }
1700
1.19k
}
1701
1702
void ScDatabaseRangeObj::SetQueryParam(const ScQueryParam& rQueryParam)
1703
1.19k
{
1704
1.19k
    const ScDBData* pData = GetDBData_Impl();
1705
1.19k
    if (!pData)
1706
0
        return;
1707
1708
    //  FilterDescriptor contains the counted fields inside the area
1709
1.19k
    ScQueryParam aParam(rQueryParam);
1710
1.19k
    ScRange aDBRange;
1711
1.19k
    pData->GetArea(aDBRange);
1712
1.19k
    SCCOLROW nFieldStart = aParam.bByRow ? static_cast<SCCOLROW>(aDBRange.aStart.Col()) : static_cast<SCCOLROW>(aDBRange.aStart.Row());
1713
1714
1.19k
    SCSIZE nCount = aParam.GetEntryCount();
1715
10.7k
    for (SCSIZE i=0; i<nCount; i++)
1716
9.55k
    {
1717
9.55k
           ScQueryEntry& rEntry = aParam.GetEntry(i);
1718
9.55k
           if (rEntry.bDoQuery)
1719
528
                   rEntry.nField += nFieldStart;
1720
9.55k
    }
1721
1722
1.19k
    ScDBData aNewData( *pData );
1723
1.19k
    aNewData.SetQueryParam(aParam);
1724
1.19k
    aNewData.SetHeader(aParam.bHasHeader);      // not in ScDBData::SetQueryParam
1725
1.19k
    aNewData.SetTotals(aParam.bHasTotals);      // not in ScDBData::SetQueryParam
1726
1.19k
    ScDBDocFunc aFunc(*pDocShell);
1727
1.19k
    aFunc.ModifyDBData(aNewData);
1728
1.19k
}
1729
1730
uno::Reference<sheet::XSheetFilterDescriptor> SAL_CALL ScDatabaseRangeObj::getFilterDescriptor()
1731
0
{
1732
0
    SolarMutexGuard aGuard;
1733
0
    return new ScRangeFilterDescriptor(pDocShell, this);
1734
0
}
1735
1736
void ScDatabaseRangeObj::GetSubTotalParam(ScSubTotalParam& rSubTotalParam) const
1737
0
{
1738
0
    const ScDBData* pData = GetDBData_Impl();
1739
0
    if (!pData)
1740
0
        return;
1741
1742
0
    pData->GetSubTotalParam(rSubTotalParam);
1743
1744
    //  FilterDescriptor contains the counted fields inside the area
1745
0
    ScRange aDBRange;
1746
0
    pData->GetArea(aDBRange);
1747
0
    SCCOL nFieldStart = aDBRange.aStart.Col();
1748
0
    for (auto& group : rSubTotalParam.aGroups)
1749
0
    {
1750
0
        if (group.bActive)
1751
0
        {
1752
0
            if (group.nField >= nFieldStart)
1753
0
                group.nField -= nFieldStart;
1754
0
            for (SCCOL j = 0; j < group.nSubTotals; j++)
1755
0
                if (group.col(j) >= nFieldStart)
1756
0
                    group.col(j) -= nFieldStart;
1757
0
        }
1758
0
    }
1759
0
}
1760
1761
void ScDatabaseRangeObj::SetSubTotalParam(const ScSubTotalParam& rSubTotalParam)
1762
0
{
1763
0
    const ScDBData* pData = GetDBData_Impl();
1764
0
    if (!pData)
1765
0
        return;
1766
1767
    //  FilterDescriptor contains the counted fields inside the area
1768
0
    ScSubTotalParam aParam(rSubTotalParam);
1769
0
    ScRange aDBRange;
1770
0
    pData->GetArea(aDBRange);
1771
0
    SCCOL nFieldStart = aDBRange.aStart.Col();
1772
0
    for (auto& group : aParam.aGroups)
1773
0
    {
1774
0
        if (group.bActive)
1775
0
        {
1776
0
            group.nField += nFieldStart;
1777
0
            for (SCCOL j = 0; j < group.nSubTotals; j++)
1778
0
                group.col(j) += nFieldStart;
1779
0
        }
1780
0
    }
1781
1782
0
    ScDBData aNewData( *pData );
1783
0
    aNewData.SetSubTotalParam(aParam);
1784
0
    ScDBDocFunc aFunc(*pDocShell);
1785
0
    aFunc.ModifyDBData(aNewData);
1786
0
}
1787
1788
uno::Reference<sheet::XSubTotalDescriptor> SAL_CALL ScDatabaseRangeObj::getSubTotalDescriptor()
1789
0
{
1790
0
    SolarMutexGuard aGuard;
1791
0
    return new ScRangeSubTotalDescriptor(this);
1792
0
}
1793
1794
uno::Sequence<beans::PropertyValue> SAL_CALL ScDatabaseRangeObj::getImportDescriptor()
1795
0
{
1796
0
    SolarMutexGuard aGuard;
1797
0
    ScImportParam aParam;
1798
0
    const ScDBData* pData = GetDBData_Impl();
1799
0
    if (pData)
1800
0
        pData->GetImportParam(aParam);
1801
1802
0
    uno::Sequence<beans::PropertyValue> aSeq( ScImportDescriptor::GetPropertyCount() );
1803
0
    ScImportDescriptor::FillProperties( aSeq, aParam );
1804
0
    return aSeq;
1805
0
}
1806
1807
// XRefreshable
1808
1809
void SAL_CALL ScDatabaseRangeObj::refresh()
1810
0
{
1811
0
    SolarMutexGuard aGuard;
1812
0
    ScDBData* pData = GetDBData_Impl();
1813
0
    if ( !(pDocShell && pData) )
1814
0
        return;
1815
1816
0
    ScDBDocFunc aFunc(*pDocShell);
1817
1818
    // repeat import?
1819
0
    bool bContinue = true;
1820
0
    ScImportParam aImportParam;
1821
0
    pData->GetImportParam( aImportParam );
1822
0
    if (aImportParam.bImport && !pData->HasImportSelection())
1823
0
    {
1824
0
        SCTAB nTab;
1825
0
        SCCOL nDummyCol;
1826
0
        SCROW nDummyRow;
1827
0
        pData->GetArea( nTab, nDummyCol,nDummyRow,nDummyCol,nDummyRow );
1828
0
        bContinue = aFunc.DoImport( nTab, aImportParam, nullptr );   //! Api-Flag as parameter
1829
0
    }
1830
1831
    // if no error then internal operations (sort, query, subtotal)
1832
0
    if (bContinue)
1833
0
        aFunc.RepeatDB( pData->GetName(), true, bIsUnnamed, aTab );
1834
0
}
1835
1836
void SAL_CALL ScDatabaseRangeObj::addRefreshListener(
1837
                                const uno::Reference<util::XRefreshListener >& xListener )
1838
0
{
1839
0
    SolarMutexGuard aGuard;
1840
0
    aRefreshListeners.emplace_back( xListener );
1841
1842
    //  hold one additional ref to keep this object alive as long as there are listeners
1843
0
    if ( aRefreshListeners.size() == 1 )
1844
0
        acquire();
1845
0
}
1846
1847
void SAL_CALL ScDatabaseRangeObj::removeRefreshListener(
1848
                                const uno::Reference<util::XRefreshListener >& xListener )
1849
0
{
1850
0
    SolarMutexGuard aGuard;
1851
0
    sal_uInt16 nCount = aRefreshListeners.size();
1852
0
    for ( sal_uInt16 n=nCount; n--; )
1853
0
    {
1854
0
        uno::Reference<util::XRefreshListener>& rObj = aRefreshListeners[n];
1855
0
        if ( rObj == xListener )
1856
0
        {
1857
0
            aRefreshListeners.erase( aRefreshListeners.begin() + n );
1858
0
            if ( aRefreshListeners.empty() )
1859
0
                release();                          // release ref for listeners
1860
0
            break;
1861
0
        }
1862
0
    }
1863
0
}
1864
1865
void ScDatabaseRangeObj::Refreshed_Impl()
1866
0
{
1867
0
    lang::EventObject aEvent;
1868
0
    aEvent.Source = getXWeak();
1869
0
    for (uno::Reference<util::XRefreshListener> & xRefreshListener : aRefreshListeners)
1870
0
        xRefreshListener->refreshed( aEvent );
1871
0
}
1872
1873
// XCellRangeSource
1874
1875
uno::Reference<table::XCellRange> SAL_CALL ScDatabaseRangeObj::getReferredCells()
1876
0
{
1877
0
    SolarMutexGuard aGuard;
1878
0
    ScDBData* pData = GetDBData_Impl();
1879
0
    if ( pData )
1880
0
    {
1881
        //! static function to create ScCellObj/ScCellRange on ScCellRangeObj ???
1882
0
        ScRange aRange;
1883
1884
0
        pData->GetArea(aRange);
1885
0
        if ( aRange.aStart == aRange.aEnd )
1886
0
            return new ScCellObj( pDocShell, aRange.aStart );
1887
0
        else
1888
0
            return new ScCellRangeObj( pDocShell, aRange );
1889
0
    }
1890
0
    return nullptr;
1891
0
}
1892
1893
// XPropertySet
1894
1895
uno::Reference<beans::XPropertySetInfo> SAL_CALL ScDatabaseRangeObj::getPropertySetInfo()
1896
0
{
1897
0
    SolarMutexGuard aGuard;
1898
0
    static uno::Reference<beans::XPropertySetInfo> aRef(
1899
0
        new SfxItemPropertySetInfo( aPropSet.getPropertyMap() ));
1900
0
    return aRef;
1901
0
}
1902
1903
void SAL_CALL ScDatabaseRangeObj::setPropertyValue(
1904
                        const OUString& aPropertyName, const uno::Any& aValue )
1905
2.43k
{
1906
2.43k
    SolarMutexGuard aGuard;
1907
2.43k
    ScDBData* pData = GetDBData_Impl();
1908
2.43k
    if ( !(pDocShell && pData) )
1909
0
        return;
1910
1911
2.43k
    ScDBData aNewData( *pData );
1912
2.43k
    bool bDo = true;
1913
1914
2.43k
    if ( aPropertyName == SC_UNONAME_KEEPFORM )
1915
0
        aNewData.SetKeepFmt( ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
1916
2.43k
    else if ( aPropertyName == SC_UNONAME_MOVCELLS )
1917
0
        aNewData.SetDoSize( ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
1918
2.43k
    else if ( aPropertyName == SC_UNONAME_STRIPDAT )
1919
0
        aNewData.SetStripData( ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
1920
2.43k
    else if (aPropertyName == SC_UNONAME_AUTOFLT )
1921
525
    {
1922
525
        bool bAutoFilter(ScUnoHelpFunctions::GetBoolFromAny( aValue ));
1923
525
        aNewData.SetAutoFilter(bAutoFilter);
1924
525
        ScRange aRange;
1925
525
        aNewData.GetArea(aRange);
1926
525
        ScDocument& rDoc = pDocShell->GetDocument();
1927
525
        if (bAutoFilter)
1928
525
            rDoc.ApplyFlagsTab( aRange.aStart.Col(), aRange.aStart.Row(),
1929
525
                                 aRange.aEnd.Col(), aRange.aStart.Row(),
1930
525
                                 aRange.aStart.Tab(), ScMF::Auto );
1931
0
        else if (!bAutoFilter)
1932
0
            rDoc.RemoveFlagsTab(aRange.aStart.Col(), aRange.aStart.Row(),
1933
0
                                 aRange.aEnd.Col(), aRange.aStart.Row(),
1934
0
                                 aRange.aStart.Tab(), ScMF::Auto );
1935
525
        ScRange aPaintRange(aRange.aStart, aRange.aEnd);
1936
525
        aPaintRange.aEnd.SetRow(aPaintRange.aStart.Row());
1937
525
        pDocShell->PostPaint(aPaintRange, PaintPartFlags::Grid);
1938
525
    }
1939
1.90k
    else if (aPropertyName == SC_UNONAME_USEFLTCRT )
1940
0
    {
1941
0
        if (ScUnoHelpFunctions::GetBoolFromAny( aValue ))
1942
0
        {
1943
            // only here to set bIsAdvanced in ScDBData
1944
0
            ScRange aRange;
1945
0
            (void)aNewData.GetAdvancedQuerySource(aRange);
1946
0
            aNewData.SetAdvancedQuerySource(&aRange);
1947
0
        }
1948
0
        else
1949
0
            aNewData.SetAdvancedQuerySource(nullptr);
1950
0
    }
1951
1.90k
    else if (aPropertyName == SC_UNONAME_FLTCRT )
1952
0
    {
1953
0
        table::CellRangeAddress aRange;
1954
0
        if (aValue >>= aRange)
1955
0
        {
1956
0
            ScRange aCoreRange;
1957
0
            ScUnoConversion::FillScRange(aCoreRange, aRange);
1958
1959
0
            aNewData.SetAdvancedQuerySource(&aCoreRange);
1960
0
        }
1961
0
    }
1962
1.90k
    else if (aPropertyName == SC_UNONAME_FROMSELECT )
1963
0
    {
1964
0
        aNewData.SetImportSelection(::cppu::any2bool(aValue));
1965
0
    }
1966
1.90k
    else if (aPropertyName == SC_UNONAME_REFPERIOD )
1967
0
    {
1968
0
        sal_Int32 nRefresh = 0;
1969
0
        if (aValue >>= nRefresh)
1970
0
        {
1971
0
            ScDocument& rDoc = pDocShell->GetDocument();
1972
0
            aNewData.SetRefreshDelay(nRefresh);
1973
0
            if (rDoc.GetDBCollection())
1974
0
            {
1975
0
                aNewData.SetRefreshHandler( rDoc.GetDBCollection()->GetRefreshHandler() );
1976
0
                aNewData.SetRefreshControl( &rDoc.GetRefreshTimerControlAddress() );
1977
0
            }
1978
0
        }
1979
0
    }
1980
1.90k
    else if (aPropertyName == SC_UNONAME_CONRES )
1981
0
    {
1982
0
    }
1983
1.90k
    else if ( aPropertyName == SC_UNONAME_TOTALSROW )
1984
141
        aNewData.SetTotals( ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
1985
1.76k
    else if ( aPropertyName == SC_UNONAME_CONTHDR )
1986
7
        aNewData.SetHeader( ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
1987
1.75k
    else if ( aPropertyName == SC_UNONAME_TABLETYPE )
1988
293
    {
1989
293
        OUString aStrVal;
1990
293
        aValue >>= aStrVal;
1991
293
        aNewData.SetTableType(aStrVal);
1992
293
    }
1993
1.46k
    else if (aPropertyName == SC_UNONAME_TABLE_STYLENAME)
1994
293
    {
1995
293
        OUString aStyleID;
1996
293
        aValue >>= aStyleID;
1997
293
        ScTableStyleParam aParam;
1998
293
        const ScTableStyleParam* pOldParam = pData->GetTableStyleInfo();
1999
293
        if (pOldParam)
2000
0
        {
2001
0
            aParam = *pOldParam;
2002
0
        }
2003
293
        aParam.maStyleID = aStyleID;
2004
2005
293
        aNewData.SetTableStyleInfo(aParam);
2006
293
    }
2007
1.17k
    else if (aPropertyName == SC_UNONAME_ROW_STRIPES || aPropertyName == SC_UNONAME_COL_STRIPES || aPropertyName == SC_UNONAME_FIRST_COL || aPropertyName == SC_UNONAME_LAST_COL)
2008
1.17k
    {
2009
1.17k
        bool bVal = ScUnoHelpFunctions::GetBoolFromAny(aValue);
2010
1.17k
        ScTableStyleParam aParam;
2011
1.17k
        const ScTableStyleParam* pOldParam = pData->GetTableStyleInfo();
2012
1.17k
        if (pOldParam)
2013
1.17k
        {
2014
1.17k
            aParam = *pOldParam;
2015
1.17k
        }
2016
1.17k
        if (aPropertyName == SC_UNONAME_ROW_STRIPES)
2017
293
            aParam.mbRowStripes = bVal;
2018
879
        else if (aPropertyName == SC_UNONAME_COL_STRIPES)
2019
293
            aParam.mbColumnStripes = bVal;
2020
586
        else if (aPropertyName == SC_UNONAME_FIRST_COL)
2021
293
            aParam.mbFirstColumn = bVal;
2022
293
        else if (aPropertyName == SC_UNONAME_LAST_COL)
2023
293
            aParam.mbLastColumn = bVal;
2024
2025
1.17k
        aNewData.SetTableStyleInfo(aParam);
2026
1.17k
    }
2027
0
    else
2028
0
        bDo = false;
2029
2030
2.43k
    if (bDo)
2031
2.43k
    {
2032
2.43k
        ScDBDocFunc aFunc(*pDocShell);
2033
2.43k
        aFunc.ModifyDBData(aNewData);
2034
2.43k
    }
2035
2.43k
}
2036
2037
uno::Any SAL_CALL ScDatabaseRangeObj::getPropertyValue( const OUString& aPropertyName )
2038
293
{
2039
293
    SolarMutexGuard aGuard;
2040
293
    uno::Any aRet;
2041
293
    ScDBData* pData = GetDBData_Impl();
2042
293
    if ( pData )
2043
293
    {
2044
293
        if ( aPropertyName == SC_UNONAME_KEEPFORM )
2045
0
            aRet <<= pData->IsKeepFmt();
2046
293
        else if ( aPropertyName == SC_UNONAME_MOVCELLS )
2047
0
            aRet <<= pData->IsDoSize();
2048
293
        else if ( aPropertyName == SC_UNONAME_STRIPDAT )
2049
0
            aRet <<= pData->IsStripData();
2050
293
        else if ( aPropertyName == SC_UNONAME_ISUSER )
2051
0
        {
2052
            //  all database ranges except "unnamed" are user defined
2053
0
            aRet <<= (pData->GetName() != STR_DB_LOCAL_NONAME);
2054
0
        }
2055
293
        else if ( aPropertyName == SC_UNO_LINKDISPBIT )
2056
0
        {
2057
            //  no target bitmaps for individual entries (would be all equal)
2058
            // ScLinkTargetTypeObj::SetLinkTargetBitmap( aRet, SC_LINKTARGETTYPE_DBAREA );
2059
0
        }
2060
293
        else if ( aPropertyName == SC_UNO_LINKDISPNAME )
2061
0
            aRet <<= aName;
2062
293
        else if (aPropertyName == SC_UNONAME_AUTOFLT )
2063
0
        {
2064
0
            bool bAutoFilter(GetDBData_Impl()->HasAutoFilter());
2065
2066
0
            aRet <<= bAutoFilter;
2067
0
        }
2068
293
        else if (aPropertyName == SC_UNONAME_USEFLTCRT )
2069
0
        {
2070
0
            ScRange aRange;
2071
0
            bool bIsAdvancedSource(GetDBData_Impl()->GetAdvancedQuerySource(aRange));
2072
2073
0
            aRet <<= bIsAdvancedSource;
2074
0
        }
2075
293
        else if (aPropertyName == SC_UNONAME_FLTCRT )
2076
0
        {
2077
0
            table::CellRangeAddress aRange;
2078
0
            ScRange aCoreRange;
2079
0
            if (GetDBData_Impl()->GetAdvancedQuerySource(aCoreRange))
2080
0
                ScUnoConversion::FillApiRange(aRange, aCoreRange);
2081
2082
0
            aRet <<= aRange;
2083
0
        }
2084
293
        else if (aPropertyName == SC_UNONAME_FROMSELECT )
2085
0
        {
2086
0
            aRet <<= GetDBData_Impl()->HasImportSelection();
2087
0
        }
2088
293
        else if (aPropertyName == SC_UNONAME_REFPERIOD )
2089
0
        {
2090
0
            sal_Int32 nRefresh(GetDBData_Impl()->GetRefreshDelaySeconds());
2091
0
            aRet <<= nRefresh;
2092
0
        }
2093
293
        else if (aPropertyName == SC_UNONAME_CONRES )
2094
0
        {
2095
0
        }
2096
293
        else if (aPropertyName == SC_UNONAME_TOKENINDEX )
2097
293
        {
2098
            // get index for use in formula tokens (read-only)
2099
293
            aRet <<= static_cast<sal_Int32>(GetDBData_Impl()->GetIndex());
2100
293
        }
2101
0
        else if (aPropertyName == SC_UNONAME_TOTALSROW )
2102
0
        {
2103
0
            bool bTotals(GetDBData_Impl()->HasTotals());
2104
2105
0
            aRet <<= bTotals;
2106
0
        }
2107
0
        else if (aPropertyName == SC_UNONAME_CONTHDR )
2108
0
        {
2109
0
            bool bHeader(GetDBData_Impl()->HasHeader());
2110
2111
0
            aRet <<= bHeader;
2112
0
        }
2113
0
        else if (aPropertyName == SC_UNONAME_TABLETYPE )
2114
0
        {
2115
0
            OUString sType(GetDBData_Impl()->GetTableType());
2116
2117
0
            aRet <<= sType;
2118
0
        }
2119
0
        else if (aPropertyName == SC_UNONAME_TABLE_STYLENAME)
2120
0
        {
2121
0
            const ScTableStyleParam* pTableStyleInfo = GetDBData_Impl()->GetTableStyleInfo();
2122
0
            if (pTableStyleInfo)
2123
0
                aRet <<= pTableStyleInfo->maStyleID;
2124
0
            else
2125
0
                aRet <<= OUString();
2126
2127
0
        }
2128
0
        else if (aPropertyName == SC_UNONAME_ROW_STRIPES || aPropertyName == SC_UNONAME_COL_STRIPES || aPropertyName == SC_UNONAME_FIRST_COL || aPropertyName == SC_UNONAME_LAST_COL)
2129
0
        {
2130
0
            const ScTableStyleParam* pTableStyleInfo = GetDBData_Impl()->GetTableStyleInfo();
2131
0
            bool bVal = false;
2132
            // tdf#170842 - check for missing table style info on plain database ranges
2133
0
            if (pTableStyleInfo)
2134
0
            {
2135
0
                if (aPropertyName == SC_UNONAME_ROW_STRIPES)
2136
0
                    bVal = pTableStyleInfo->mbRowStripes;
2137
0
                else if (aPropertyName == SC_UNONAME_COL_STRIPES)
2138
0
                    bVal = pTableStyleInfo->mbColumnStripes;
2139
0
                else if (aPropertyName == SC_UNONAME_FIRST_COL)
2140
0
                    bVal = pTableStyleInfo->mbFirstColumn;
2141
0
                else if (aPropertyName == SC_UNONAME_LAST_COL)
2142
0
                    bVal = pTableStyleInfo->mbLastColumn;
2143
0
            }
2144
2145
0
            aRet <<= bVal;
2146
0
        }
2147
293
    }
2148
293
    return aRet;
2149
293
}
2150
2151
SC_IMPL_DUMMY_PROPERTY_LISTENER( ScDatabaseRangeObj )
2152
2153
// XServiceInfo
2154
OUString SAL_CALL ScDatabaseRangeObj::getImplementationName()
2155
0
{
2156
0
    return u"ScDatabaseRangeObj"_ustr;
2157
0
}
2158
2159
sal_Bool SAL_CALL ScDatabaseRangeObj::supportsService( const OUString& rServiceName )
2160
0
{
2161
0
    return cppu::supportsService(this, rServiceName);
2162
0
}
2163
2164
uno::Sequence<OUString> SAL_CALL ScDatabaseRangeObj::getSupportedServiceNames()
2165
0
{
2166
0
    return {u"com.sun.star.sheet.DatabaseRange"_ustr,
2167
0
            SCLINKTARGET_SERVICE};
2168
0
}
2169
2170
ScDatabaseRangesObj::ScDatabaseRangesObj(ScDocShell* pDocSh) :
2171
0
    pDocShell( pDocSh )
2172
0
{
2173
0
    pDocShell->GetDocument().AddUnoObject(*this);
2174
0
}
2175
2176
ScDatabaseRangesObj::~ScDatabaseRangesObj()
2177
0
{
2178
0
    SolarMutexGuard g;
2179
2180
0
    if (pDocShell)
2181
0
        pDocShell->GetDocument().RemoveUnoObject(*this);
2182
0
}
2183
2184
void ScDatabaseRangesObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
2185
0
{
2186
    //  reference update does not matter here
2187
2188
0
    if ( rHint.GetId() == SfxHintId::Dying )
2189
0
    {
2190
0
        pDocShell = nullptr;
2191
0
    }
2192
0
}
2193
2194
// XDatabaseRanges
2195
2196
rtl::Reference<ScDatabaseRangeObj> ScDatabaseRangesObj::GetObjectByIndex_Impl(size_t nIndex)
2197
0
{
2198
0
    if (!pDocShell)
2199
0
        return nullptr;
2200
2201
0
    ScDBCollection* pNames = pDocShell->GetDocument().GetDBCollection();
2202
0
    if (!pNames)
2203
0
        return nullptr;
2204
2205
0
    const ScDBCollection::NamedDBs& rDBs = pNames->getNamedDBs();
2206
0
    if (rDBs.empty() || nIndex >= rDBs.size())
2207
0
        return nullptr;
2208
2209
0
    ScDBCollection::NamedDBs::const_iterator itr = rDBs.begin();
2210
0
    ::std::advance(itr, nIndex); // boundary check is done above.
2211
0
    return new ScDatabaseRangeObj(pDocShell, (*itr)->GetName());
2212
0
}
2213
2214
rtl::Reference<ScDatabaseRangeObj> ScDatabaseRangesObj::GetObjectByName_Impl(const OUString& aName)
2215
0
{
2216
0
    if ( pDocShell && hasByName(aName) )
2217
0
    {
2218
0
        return new ScDatabaseRangeObj( pDocShell, aName );
2219
0
    }
2220
0
    return nullptr;
2221
0
}
2222
2223
void SAL_CALL ScDatabaseRangesObj::addNewByName( const OUString& aName,
2224
                                        const table::CellRangeAddress& aRange )
2225
0
{
2226
0
    SolarMutexGuard aGuard;
2227
0
    bool bDone = false;
2228
0
    if (pDocShell)
2229
0
    {
2230
0
        ScDBDocFunc aFunc(*pDocShell);
2231
2232
0
        ScRange aNameRange( static_cast<SCCOL>(aRange.StartColumn), static_cast<SCROW>(aRange.StartRow), aRange.Sheet,
2233
0
                            static_cast<SCCOL>(aRange.EndColumn),   static_cast<SCROW>(aRange.EndRow),   aRange.Sheet );
2234
0
        bDone = aFunc.AddDBRange( aName, aNameRange );
2235
0
    }
2236
0
    if (!bDone)
2237
0
        throw uno::RuntimeException();      // no other exceptions specified
2238
0
}
2239
2240
void SAL_CALL ScDatabaseRangesObj::removeByName( const OUString& aName )
2241
0
{
2242
0
    SolarMutexGuard aGuard;
2243
0
    bool bDone = false;
2244
0
    if (pDocShell)
2245
0
    {
2246
0
        ScDBDocFunc aFunc(*pDocShell);
2247
0
        bDone = aFunc.DeleteDBRange( aName );
2248
0
    }
2249
0
    if (!bDone)
2250
0
        throw uno::RuntimeException();      // no other exceptions specified
2251
0
}
2252
2253
// XEnumerationAccess
2254
2255
uno::Reference<container::XEnumeration> SAL_CALL ScDatabaseRangesObj::createEnumeration()
2256
0
{
2257
0
    SolarMutexGuard aGuard;
2258
0
    return new ScIndexEnumeration(this, u"com.sun.star.sheet.DatabaseRangesEnumeration"_ustr);
2259
0
}
2260
2261
// XIndexAccess
2262
2263
sal_Int32 SAL_CALL ScDatabaseRangesObj::getCount()
2264
0
{
2265
0
    SolarMutexGuard aGuard;
2266
2267
    //! need to omit "unnamed"?
2268
2269
0
    if (pDocShell)
2270
0
    {
2271
0
        ScDBCollection* pNames = pDocShell->GetDocument().GetDBCollection();
2272
0
        if (pNames)
2273
0
            return static_cast<sal_Int32>(pNames->getNamedDBs().size());
2274
0
    }
2275
0
    return 0;
2276
0
}
2277
2278
uno::Any SAL_CALL ScDatabaseRangesObj::getByIndex( sal_Int32 nIndex )
2279
0
{
2280
0
    SolarMutexGuard aGuard;
2281
0
    if (nIndex < 0)
2282
0
        throw lang::IndexOutOfBoundsException();
2283
2284
0
    rtl::Reference<ScDatabaseRangeObj> xRange(GetObjectByIndex_Impl(static_cast<size_t>(nIndex)));
2285
0
    if (!xRange.is())
2286
0
        throw lang::IndexOutOfBoundsException();
2287
2288
0
    return uno::Any(uno::Reference<sheet::XDatabaseRange>(xRange));
2289
0
}
2290
2291
uno::Type SAL_CALL ScDatabaseRangesObj::getElementType()
2292
0
{
2293
0
    return cppu::UnoType<sheet::XDatabaseRange>::get();
2294
0
}
2295
2296
sal_Bool SAL_CALL ScDatabaseRangesObj::hasElements()
2297
0
{
2298
0
    SolarMutexGuard aGuard;
2299
0
    return ( getCount() != 0 );
2300
0
}
2301
2302
// XNameAccess
2303
2304
uno::Any SAL_CALL ScDatabaseRangesObj::getByName( const OUString& aName )
2305
0
{
2306
0
    SolarMutexGuard aGuard;
2307
0
    rtl::Reference<ScDatabaseRangeObj> xRange(GetObjectByName_Impl(aName));
2308
0
    if (!xRange.is())
2309
0
        throw container::NoSuchElementException();
2310
2311
0
    return uno::Any(uno::Reference<sheet::XDatabaseRange>(xRange));
2312
0
}
2313
2314
uno::Sequence<OUString> SAL_CALL ScDatabaseRangesObj::getElementNames()
2315
0
{
2316
0
    SolarMutexGuard aGuard;
2317
2318
    //! need to omit "unnamed"?
2319
2320
0
    if (pDocShell)
2321
0
    {
2322
0
        ScDBCollection* pNames = pDocShell->GetDocument().GetDBCollection();
2323
0
        if (pNames)
2324
0
        {
2325
0
            const ScDBCollection::NamedDBs& rDBs = pNames->getNamedDBs();
2326
0
            uno::Sequence<OUString> aSeq(rDBs.size());
2327
0
            auto aSeqRange = asNonConstRange(aSeq);
2328
0
            size_t i = 0;
2329
0
            for (const auto& rDB : rDBs)
2330
0
            {
2331
0
                aSeqRange[i] = rDB->GetName();
2332
0
                ++i;
2333
0
            }
2334
2335
0
            return aSeq;
2336
0
        }
2337
0
    }
2338
0
    return {};
2339
0
}
2340
2341
sal_Bool SAL_CALL ScDatabaseRangesObj::hasByName( const OUString& aName )
2342
0
{
2343
0
    SolarMutexGuard aGuard;
2344
2345
    //! need to omit "unnamed"?
2346
2347
0
    if (pDocShell)
2348
0
    {
2349
0
        ScDBCollection* pNames = pDocShell->GetDocument().GetDBCollection();
2350
0
        if (pNames)
2351
0
            return pNames->getNamedDBs().findByUpperName(ScGlobal::getCharClass().uppercase(aName)) != nullptr;
2352
0
    }
2353
0
    return false;
2354
0
}
2355
2356
ScUnnamedDatabaseRangesObj::ScUnnamedDatabaseRangesObj(ScDocShell* pDocSh) :
2357
0
    pDocShell( pDocSh )
2358
0
{
2359
0
    pDocShell->GetDocument().AddUnoObject(*this);
2360
0
}
2361
2362
ScUnnamedDatabaseRangesObj::~ScUnnamedDatabaseRangesObj()
2363
0
{
2364
0
    SolarMutexGuard g;
2365
2366
0
    if (pDocShell)
2367
0
        pDocShell->GetDocument().RemoveUnoObject(*this);
2368
0
}
2369
2370
void ScUnnamedDatabaseRangesObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
2371
0
{
2372
    //  reference update does not matter here
2373
2374
0
    if ( rHint.GetId() == SfxHintId::Dying )
2375
0
    {
2376
0
        pDocShell = nullptr;
2377
0
    }
2378
0
}
2379
2380
// XUnnamedDatabaseRanges
2381
2382
void ScUnnamedDatabaseRangesObj::setByTable( const table::CellRangeAddress& aRange )
2383
0
{
2384
0
    SolarMutexGuard aGuard;
2385
0
    bool bDone = false;
2386
0
    if (pDocShell)
2387
0
    {
2388
0
        if ( pDocShell->GetDocument().GetTableCount() <= aRange.Sheet )
2389
0
            throw lang::IndexOutOfBoundsException();
2390
2391
0
        ScDBDocFunc aFunc(*pDocShell);
2392
0
        ScRange aUnnamedRange( static_cast<SCCOL>(aRange.StartColumn), static_cast<SCROW>(aRange.StartRow), aRange.Sheet,
2393
0
                            static_cast<SCCOL>(aRange.EndColumn),   static_cast<SCROW>(aRange.EndRow),   aRange.Sheet );
2394
0
        bDone = aFunc.AddDBRange( STR_DB_LOCAL_NONAME, aUnnamedRange );
2395
0
    }
2396
0
    if (!bDone)
2397
0
        throw uno::RuntimeException();      // no other exceptions specified
2398
0
}
2399
2400
uno::Any ScUnnamedDatabaseRangesObj::getByTable( sal_Int32 nTab )
2401
0
{
2402
0
    SolarMutexGuard aGuard;
2403
0
    if (!pDocShell)
2404
0
        throw uno::RuntimeException();
2405
2406
0
    if ( pDocShell->GetDocument().GetTableCount() <= nTab )
2407
0
        throw lang::IndexOutOfBoundsException();
2408
0
    uno::Reference<sheet::XDatabaseRange> xRange(
2409
0
        new ScDatabaseRangeObj(pDocShell, static_cast<SCTAB>(nTab)));
2410
0
    if (!xRange.is())
2411
0
        throw container::NoSuchElementException();
2412
2413
0
    return uno::Any(xRange);
2414
0
}
2415
2416
sal_Bool ScUnnamedDatabaseRangesObj::hasByTable( sal_Int32 nTab )
2417
0
{
2418
0
    SolarMutexGuard aGuard;
2419
0
    if (pDocShell)
2420
0
    {
2421
0
        if (pDocShell->GetDocument().GetTableCount() <= nTab)
2422
0
            throw lang::IndexOutOfBoundsException();
2423
0
        if (pDocShell->GetDocument().GetAnonymousDBData(static_cast<SCTAB>(nTab)))
2424
0
            return true;
2425
0
        return false;
2426
0
    }
2427
0
    else
2428
0
        return false;
2429
0
}
2430
2431
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */