1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <datauno.hxx>
22 #include <svl/hint.hxx>
23 #include <svl/numformat.hxx>
24 #include <svl/sharedstringpool.hxx>
26 #include <vcl/svapp.hxx>
27 #include <unotools/charclass.hxx>
28 #include <osl/diagnose.h>
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>
42 #include <dapiuno.hxx>
43 #include <cellsuno.hxx>
44 #include <miscuno.hxx>
45 #include <targuno.hxx>
46 #include <rangeutl.hxx>
49 #include <dbdocfun.hxx>
50 #include <unonames.hxx>
51 #include <globalnames.hxx>
52 #include <convuno.hxx>
55 #include <dpshttab.hxx>
56 #include <queryentry.hxx>
58 #include <sortparam.hxx>
59 #include <dpobject.hxx>
60 #include <filterentries.hxx>
62 #include <comphelper/extract.hxx>
63 #include <cppuhelper/supportsservice.hxx>
64 #include <svx/dataaccessdescriptor.hxx>
68 using namespace com::sun::star
;
69 using namespace css::sheet
;
71 // everything without Which-ID, map only for PropertySetInfo
73 static std::span
<const SfxItemPropertyMapEntry
> lcl_GetSubTotalPropertyMap()
75 // some old property names are for 5.2 compatibility
77 static const SfxItemPropertyMapEntry aSubTotalPropertyMap_Impl
[] =
79 { SC_UNONAME_BINDFMT
, 0, cppu::UnoType
<bool>::get(), 0, 0},
80 { SC_UNONAME_CASE
, 0, cppu::UnoType
<bool>::get(), 0, 0},
81 { SC_UNONAME_ENABSORT
, 0, cppu::UnoType
<bool>::get(), 0, 0},
82 { SC_UNONAME_ENUSLIST
, 0, cppu::UnoType
<bool>::get(), 0, 0},
83 { SC_UNONAME_FORMATS
, 0, cppu::UnoType
<bool>::get(), 0, 0},
84 { SC_UNONAME_INSBRK
, 0, cppu::UnoType
<bool>::get(), 0, 0},
85 { SC_UNONAME_ISCASE
, 0, cppu::UnoType
<bool>::get(), 0, 0},
86 { SC_UNONAME_MAXFLD
, 0, cppu::UnoType
<sal_Int32
>::get(), beans::PropertyAttribute::READONLY
, 0},
87 { SC_UNONAME_SORTASC
, 0, cppu::UnoType
<bool>::get(), 0, 0},
88 { SC_UNONAME_ULIST
, 0, cppu::UnoType
<bool>::get(), 0, 0},
89 { SC_UNONAME_UINDEX
, 0, cppu::UnoType
<sal_Int32
>::get(), 0, 0},
90 { SC_UNONAME_USINDEX
, 0, cppu::UnoType
<sal_Int32
>::get(), 0, 0},
92 return aSubTotalPropertyMap_Impl
;
95 static std::span
<const SfxItemPropertyMapEntry
> lcl_GetFilterPropertyMap()
97 static const SfxItemPropertyMapEntry aFilterPropertyMap_Impl
[] =
99 { SC_UNONAME_CONTHDR
, 0, cppu::UnoType
<bool>::get(), 0, 0},
100 { SC_UNONAME_COPYOUT
, 0, cppu::UnoType
<bool>::get(), 0, 0},
101 { SC_UNONAME_ISCASE
, 0, cppu::UnoType
<bool>::get(), 0, 0},
102 { SC_UNONAME_MAXFLD
, 0, cppu::UnoType
<sal_Int32
>::get(), beans::PropertyAttribute::READONLY
, 0},
103 { SC_UNONAME_ORIENT
, 0, cppu::UnoType
<table::TableOrientation
>::get(), 0, 0},
104 { SC_UNONAME_OUTPOS
, 0, cppu::UnoType
<table::CellAddress
>::get(), 0, 0},
105 { SC_UNONAME_SAVEOUT
, 0, cppu::UnoType
<bool>::get(), 0, 0},
106 { SC_UNONAME_SKIPDUP
, 0, cppu::UnoType
<bool>::get(), 0, 0},
107 { SC_UNONAME_USEREGEX
, 0, cppu::UnoType
<bool>::get(), 0, 0},
109 return aFilterPropertyMap_Impl
;
112 static std::span
<const SfxItemPropertyMapEntry
> lcl_GetDBRangePropertyMap()
114 static const SfxItemPropertyMapEntry aDBRangePropertyMap_Impl
[] =
116 { SC_UNONAME_AUTOFLT
, 0, cppu::UnoType
<bool>::get(), 0, 0},
117 { SC_UNONAME_FLTCRT
, 0, cppu::UnoType
<table::CellRangeAddress
>::get(), 0, 0},
118 { SC_UNONAME_FROMSELECT
,0, cppu::UnoType
<bool>::get(), 0, 0},
119 { SC_UNONAME_ISUSER
, 0, cppu::UnoType
<bool>::get(), beans::PropertyAttribute::READONLY
, 0 },
120 { SC_UNONAME_KEEPFORM
, 0, cppu::UnoType
<bool>::get(), 0, 0},
121 { SC_UNO_LINKDISPBIT
, 0, cppu::UnoType
<awt::XBitmap
>::get(), beans::PropertyAttribute::READONLY
, 0 },
122 { SC_UNO_LINKDISPNAME
, 0, cppu::UnoType
<OUString
>::get(), beans::PropertyAttribute::READONLY
, 0 },
123 { SC_UNONAME_MOVCELLS
, 0, cppu::UnoType
<bool>::get(), 0, 0},
124 { SC_UNONAME_REFPERIOD
, 0, cppu::UnoType
<sal_Int32
>::get(), 0, 0},
125 { SC_UNONAME_STRIPDAT
, 0, cppu::UnoType
<bool>::get(), 0, 0},
126 { SC_UNONAME_TOKENINDEX
,0, cppu::UnoType
<sal_Int32
>::get(), beans::PropertyAttribute::READONLY
, 0 },
127 { SC_UNONAME_USEFLTCRT
,0, cppu::UnoType
<bool>::get(), 0, 0},
128 { SC_UNONAME_TOTALSROW
,0, cppu::UnoType
<bool>::get(), 0, 0},
129 { SC_UNONAME_CONTHDR
,0, cppu::UnoType
<bool>::get(), 0, 0},
131 return aDBRangePropertyMap_Impl
;
134 SC_SIMPLE_SERVICE_INFO( ScConsolidationDescriptor
, u
"ScConsolidationDescriptor"_ustr
, u
"com.sun.star.sheet.ConsolidationDescriptor"_ustr
)
135 SC_SIMPLE_SERVICE_INFO( ScDatabaseRangesObj
, u
"ScDatabaseRangesObj"_ustr
, u
"com.sun.star.sheet.DatabaseRanges"_ustr
)
136 SC_SIMPLE_SERVICE_INFO( ScFilterDescriptorBase
, u
"ScFilterDescriptorBase"_ustr
, u
"com.sun.star.sheet.SheetFilterDescriptor"_ustr
)
137 SC_SIMPLE_SERVICE_INFO( ScSubTotalDescriptorBase
, u
"ScSubTotalDescriptorBase"_ustr
, u
"com.sun.star.sheet.SubTotalDescriptor"_ustr
)
138 SC_SIMPLE_SERVICE_INFO( ScSubTotalFieldObj
, u
"ScSubTotalFieldObj"_ustr
, u
"com.sun.star.sheet.SubTotalField"_ustr
)
140 sheet::GeneralFunction
ScDataUnoConversion::SubTotalToGeneral( ScSubTotalFunc eSubTotal
)
142 sheet::GeneralFunction eGeneral
;
145 case SUBTOTAL_FUNC_NONE
: eGeneral
= sheet::GeneralFunction_NONE
; break;
146 case SUBTOTAL_FUNC_AVE
: eGeneral
= sheet::GeneralFunction_AVERAGE
; break;
147 case SUBTOTAL_FUNC_CNT
: eGeneral
= sheet::GeneralFunction_COUNTNUMS
; break;
148 case SUBTOTAL_FUNC_CNT2
: eGeneral
= sheet::GeneralFunction_COUNT
; break;
149 case SUBTOTAL_FUNC_MAX
: eGeneral
= sheet::GeneralFunction_MAX
; break;
150 case SUBTOTAL_FUNC_MIN
: eGeneral
= sheet::GeneralFunction_MIN
; break;
151 case SUBTOTAL_FUNC_PROD
: eGeneral
= sheet::GeneralFunction_PRODUCT
; break;
152 case SUBTOTAL_FUNC_STD
: eGeneral
= sheet::GeneralFunction_STDEV
; break;
153 case SUBTOTAL_FUNC_STDP
: eGeneral
= sheet::GeneralFunction_STDEVP
; break;
154 case SUBTOTAL_FUNC_SUM
: eGeneral
= sheet::GeneralFunction_SUM
; break;
155 case SUBTOTAL_FUNC_VAR
: eGeneral
= sheet::GeneralFunction_VAR
; break;
156 case SUBTOTAL_FUNC_VARP
: eGeneral
= sheet::GeneralFunction_VARP
; break;
158 OSL_FAIL("SubTotalToGeneral: wrong enum");
159 eGeneral
= sheet::GeneralFunction_NONE
;
165 void ScImportDescriptor::FillProperties( uno::Sequence
<beans::PropertyValue
>& rSeq
, const ScImportParam
& rParam
)
167 OSL_ENSURE( rSeq
.getLength() == GetPropertyCount(), "wrong Count" );
169 beans::PropertyValue
* pArray
= rSeq
.getArray();
171 sheet::DataImportMode eMode
= sheet::DataImportMode_NONE
;
172 if ( rParam
.bImport
)
175 eMode
= sheet::DataImportMode_SQL
;
176 else if ( rParam
.nType
== ScDbQuery
)
177 eMode
= sheet::DataImportMode_QUERY
;
179 eMode
= sheet::DataImportMode_TABLE
; // type always ScDbQuery or ScDbTable
182 svx::ODataAccessDescriptor aDescriptor
;
183 aDescriptor
.setDataSource(rParam
.aDBName
);
184 if (aDescriptor
.has( svx::DataAccessDescriptorProperty::DataSource
))
186 pArray
[0].Name
= SC_UNONAME_DBNAME
;
187 pArray
[0].Value
<<= rParam
.aDBName
;
189 else if (aDescriptor
.has( svx::DataAccessDescriptorProperty::ConnectionResource
))
191 pArray
[0].Name
= SC_UNONAME_CONRES
;
192 pArray
[0].Value
<<= rParam
.aDBName
;
195 pArray
[1].Name
= SC_UNONAME_SRCTYPE
;
196 pArray
[1].Value
<<= eMode
;
198 pArray
[2].Name
= SC_UNONAME_SRCOBJ
;
199 pArray
[2].Value
<<= rParam
.aStatement
;
201 pArray
[3].Name
= SC_UNONAME_ISNATIVE
;
202 pArray
[3].Value
<<= rParam
.bNative
;
205 void ScImportDescriptor::FillImportParam( ScImportParam
& rParam
, const uno::Sequence
<beans::PropertyValue
>& rSeq
)
208 for (const beans::PropertyValue
& rProp
: rSeq
)
210 OUString
aPropName(rProp
.Name
);
212 if (aPropName
== SC_UNONAME_ISNATIVE
)
213 rParam
.bNative
= ScUnoHelpFunctions::GetBoolFromAny( rProp
.Value
);
214 else if (aPropName
== SC_UNONAME_DBNAME
)
216 if ( rProp
.Value
>>= aStrVal
)
217 rParam
.aDBName
= aStrVal
;
219 else if (aPropName
== SC_UNONAME_CONRES
)
221 if ( rProp
.Value
>>= aStrVal
)
222 rParam
.aDBName
= aStrVal
;
224 else if (aPropName
== SC_UNONAME_SRCOBJ
)
226 if ( rProp
.Value
>>= aStrVal
)
227 rParam
.aStatement
= aStrVal
;
229 else if (aPropName
== SC_UNONAME_SRCTYPE
)
231 //! test for correct enum type?
232 sheet::DataImportMode eMode
= static_cast<sheet::DataImportMode
>(ScUnoHelpFunctions::GetEnumFromAny( rProp
.Value
));
235 case sheet::DataImportMode_NONE
:
236 rParam
.bImport
= false;
238 case sheet::DataImportMode_SQL
:
239 rParam
.bImport
= true;
242 case sheet::DataImportMode_TABLE
:
243 rParam
.bImport
= true;
245 rParam
.nType
= ScDbTable
;
247 case sheet::DataImportMode_QUERY
:
248 rParam
.bImport
= true;
250 rParam
.nType
= ScDbQuery
;
253 OSL_FAIL("wrong mode");
254 rParam
.bImport
= false;
260 void ScSortDescriptor::FillProperties( uno::Sequence
<beans::PropertyValue
>& rSeq
, const ScSortParam
& rParam
)
262 OSL_ENSURE( rSeq
.getLength() == GetPropertyCount(), "wrong count" );
264 beans::PropertyValue
* pArray
= rSeq
.getArray();
266 // gather Uno values together
268 table::CellAddress aOutPos
;
269 aOutPos
.Sheet
= rParam
.nDestTab
;
270 aOutPos
.Column
= rParam
.nDestCol
;
271 aOutPos
.Row
= rParam
.nDestRow
;
273 sal_uInt16 nSortCount
= 0;
274 while ( nSortCount
< rParam
.GetSortKeyCount() && rParam
.maKeyState
[nSortCount
].bDoSort
)
277 uno::Sequence
<table::TableSortField
> aFields(nSortCount
);
280 table::TableSortField
* pFieldArray
= aFields
.getArray();
281 for (sal_uInt16 i
=0; i
<nSortCount
; i
++)
283 pFieldArray
[i
].Field
= rParam
.maKeyState
[i
].nField
;
284 pFieldArray
[i
].IsAscending
= rParam
.maKeyState
[i
].bAscending
;
285 pFieldArray
[i
].FieldType
= table::TableSortFieldType_AUTOMATIC
; // always automatic
286 pFieldArray
[i
].IsCaseSensitive
= rParam
.bCaseSens
;
287 pFieldArray
[i
].CollatorLocale
= rParam
.aCollatorLocale
;
288 pFieldArray
[i
].CollatorAlgorithm
= rParam
.aCollatorAlgorithm
;
294 pArray
[0].Name
= SC_UNONAME_ISSORTCOLUMNS
;
295 pArray
[0].Value
<<= !rParam
.bByRow
;
297 pArray
[1].Name
= SC_UNONAME_CONTHDR
;
298 pArray
[1].Value
<<= rParam
.bHasHeader
;
300 pArray
[2].Name
= SC_UNONAME_MAXFLD
;
301 pArray
[2].Value
<<= static_cast<sal_Int32
>( rParam
.GetSortKeyCount() );
303 pArray
[3].Name
= SC_UNONAME_SORTFLD
;
304 pArray
[3].Value
<<= aFields
;
306 pArray
[4].Name
= SC_UNONAME_BINDFMT
;
307 pArray
[4].Value
<<= rParam
.aDataAreaExtras
.mbCellFormats
;
309 pArray
[5].Name
= SC_UNONAME_COPYOUT
;
310 pArray
[5].Value
<<= !rParam
.bInplace
;
312 pArray
[6].Name
= SC_UNONAME_OUTPOS
;
313 pArray
[6].Value
<<= aOutPos
;
315 pArray
[7].Name
= SC_UNONAME_ISULIST
;
316 pArray
[7].Value
<<= rParam
.bUserDef
;
318 pArray
[8].Name
= SC_UNONAME_UINDEX
;
319 pArray
[8].Value
<<= static_cast<sal_Int32
>( rParam
.nUserIndex
);
322 void ScSortDescriptor::FillSortParam( ScSortParam
& rParam
, const uno::Sequence
<beans::PropertyValue
>& rSeq
)
324 sal_Int32 nSortSize
= static_cast<sal_Int32
>(rParam
.GetSortKeyCount());
326 for (const beans::PropertyValue
& rProp
: rSeq
)
328 OUString
aPropName(rProp
.Name
);
330 if (aPropName
== SC_UNONAME_ORIENT
)
332 //! test for correct enum type?
333 table::TableOrientation eOrient
= static_cast<table::TableOrientation
>(ScUnoHelpFunctions::GetEnumFromAny( rProp
.Value
));
334 rParam
.bByRow
= ( eOrient
!= table::TableOrientation_COLUMNS
);
336 else if (aPropName
== SC_UNONAME_ISSORTCOLUMNS
)
338 rParam
.bByRow
= !::cppu::any2bool(rProp
.Value
);
340 else if (aPropName
== SC_UNONAME_CONTHDR
)
341 rParam
.bHasHeader
= ScUnoHelpFunctions::GetBoolFromAny( rProp
.Value
);
342 else if (aPropName
== SC_UNONAME_MAXFLD
)
345 if ( (rProp
.Value
>>= nVal
) && nVal
> nSortSize
)
347 //! specify exceptions
348 //! throw lang::IllegalArgumentException();
351 else if (aPropName
== SC_UNONAME_SORTFLD
)
353 uno::Sequence
<util::SortField
> aSeq
;
354 uno::Sequence
<table::TableSortField
> aNewSeq
;
355 if ( rProp
.Value
>>= aSeq
)
357 sal_Int32 nCount
= aSeq
.getLength();
359 if ( nCount
> static_cast<sal_Int32
>( rParam
.GetSortKeyCount() ) )
361 // tdf#105301 - increase the size of the sorting keys
363 rParam
.maKeyState
.resize(nCount
);
365 const util::SortField
* pFieldArray
= aSeq
.getConstArray();
366 for (i
=0; i
<nCount
; i
++)
368 rParam
.maKeyState
[i
].nField
= static_cast<SCCOLROW
>( pFieldArray
[i
].Field
);
369 rParam
.maKeyState
[i
].bAscending
= pFieldArray
[i
].SortAscending
;
371 // FieldType is ignored
372 rParam
.maKeyState
[i
].bDoSort
= true;
374 for (i
=nCount
; i
<nSortSize
; i
++)
375 rParam
.maKeyState
[i
].bDoSort
= false;
377 else if ( rProp
.Value
>>= aNewSeq
)
379 sal_Int32 nCount
= aNewSeq
.getLength();
381 if ( nCount
> nSortSize
)
384 rParam
.maKeyState
.resize(nCount
);
386 const table::TableSortField
* pFieldArray
= aNewSeq
.getConstArray();
387 for (i
=0; i
<nCount
; i
++)
389 rParam
.maKeyState
[i
].nField
= static_cast<SCCOLROW
>( pFieldArray
[i
].Field
);
390 rParam
.maKeyState
[i
].bAscending
= pFieldArray
[i
].IsAscending
;
392 // only one is possible, sometime we should make it possible to have different for every entry
393 rParam
.bCaseSens
= pFieldArray
[i
].IsCaseSensitive
;
394 rParam
.aCollatorLocale
= pFieldArray
[i
].CollatorLocale
;
395 rParam
.aCollatorAlgorithm
= pFieldArray
[i
].CollatorAlgorithm
;
397 // FieldType is ignored
398 rParam
.maKeyState
[i
].bDoSort
= true;
400 for (i
=nCount
; i
<nSortSize
; i
++)
401 rParam
.maKeyState
[i
].bDoSort
= false;
404 else if (aPropName
== SC_UNONAME_ISCASE
)
406 rParam
.bCaseSens
= ScUnoHelpFunctions::GetBoolFromAny( rProp
.Value
);
408 else if (aPropName
== SC_UNONAME_BINDFMT
)
409 rParam
.aDataAreaExtras
.mbCellFormats
= ScUnoHelpFunctions::GetBoolFromAny( rProp
.Value
);
410 else if (aPropName
== SC_UNONAME_COPYOUT
)
411 rParam
.bInplace
= !ScUnoHelpFunctions::GetBoolFromAny( rProp
.Value
);
412 else if (aPropName
== SC_UNONAME_OUTPOS
)
414 table::CellAddress aAddress
;
415 if ( rProp
.Value
>>= aAddress
)
417 rParam
.nDestTab
= aAddress
.Sheet
;
418 rParam
.nDestCol
= static_cast<SCCOL
>(aAddress
.Column
);
419 rParam
.nDestRow
= static_cast<SCROW
>(aAddress
.Row
);
422 else if (aPropName
== SC_UNONAME_ISULIST
)
423 rParam
.bUserDef
= ScUnoHelpFunctions::GetBoolFromAny( rProp
.Value
);
424 else if (aPropName
== SC_UNONAME_UINDEX
)
427 if ( rProp
.Value
>>= nVal
)
428 rParam
.nUserIndex
= static_cast<sal_uInt16
>(nVal
);
430 else if (aPropName
== SC_UNONAME_COLLLOC
)
432 rProp
.Value
>>= rParam
.aCollatorLocale
;
434 else if (aPropName
== SC_UNONAME_COLLALG
)
437 if ( rProp
.Value
>>= sStr
)
438 rParam
.aCollatorAlgorithm
= sStr
;
443 ScSubTotalFieldObj::ScSubTotalFieldObj( ScSubTotalDescriptorBase
* pDesc
, sal_uInt16 nP
) :
447 OSL_ENSURE(pDesc
, "ScSubTotalFieldObj: Parent is 0");
450 ScSubTotalFieldObj::~ScSubTotalFieldObj()
456 sal_Int32 SAL_CALL
ScSubTotalFieldObj::getGroupColumn()
458 SolarMutexGuard aGuard
;
459 ScSubTotalParam aParam
;
460 xParent
->GetData(aParam
);
462 return aParam
.aGroups
[nPos
].nField
;
465 void SAL_CALL
ScSubTotalFieldObj::setGroupColumn( sal_Int32 nGroupColumn
)
467 SolarMutexGuard aGuard
;
468 ScSubTotalParam aParam
;
469 xParent
->GetData(aParam
);
471 aParam
.aGroups
[nPos
].nField
= static_cast<SCCOL
>(nGroupColumn
);
473 xParent
->PutData(aParam
);
476 uno::Sequence
<sheet::SubTotalColumn
> SAL_CALL
ScSubTotalFieldObj::getSubTotalColumns()
478 SolarMutexGuard aGuard
;
479 ScSubTotalParam aParam
;
480 xParent
->GetData(aParam
);
482 SCCOL nCount
= aParam
.aGroups
[nPos
].nSubTotals
;
483 uno::Sequence
<sheet::SubTotalColumn
> aSeq(nCount
);
484 sheet::SubTotalColumn
* pAry
= aSeq
.getArray();
485 for (SCCOL i
=0; i
<nCount
; i
++)
487 pAry
[i
].Column
= aParam
.aGroups
[nPos
].col(i
);
488 pAry
[i
].Function
= ScDataUnoConversion::SubTotalToGeneral(aParam
.aGroups
[nPos
].func(i
));
493 void SAL_CALL
ScSubTotalFieldObj::setSubTotalColumns(
494 const uno::Sequence
<sheet::SubTotalColumn
>& aSubTotalColumns
)
496 SolarMutexGuard aGuard
;
497 ScSubTotalParam aParam
;
498 xParent
->GetData(aParam
);
500 if (aSubTotalColumns
.getLength() <= SCCOL_MAX
)
501 aParam
.aGroups
[nPos
].SetSubtotals(aSubTotalColumns
);
502 //! otherwise exception or so? (too many columns)
504 xParent
->PutData(aParam
);
507 ScSubTotalDescriptorBase::ScSubTotalDescriptorBase() :
508 aPropSet( lcl_GetSubTotalPropertyMap() )
512 ScSubTotalDescriptorBase::~ScSubTotalDescriptorBase()
516 // XSubTotalDescriptor
518 rtl::Reference
<ScSubTotalFieldObj
> ScSubTotalDescriptorBase::GetObjectByIndex_Impl(sal_uInt16 nIndex
)
520 if ( nIndex
< getCount() )
521 return new ScSubTotalFieldObj( this, nIndex
);
525 void SAL_CALL
ScSubTotalDescriptorBase::clear()
527 SolarMutexGuard aGuard
;
528 ScSubTotalParam aParam
;
531 for (auto& group
: aParam
.aGroups
)
532 group
.bActive
= false;
534 //! notify the field objects???
539 void SAL_CALL
ScSubTotalDescriptorBase::addNew(
540 const uno::Sequence
<sheet::SubTotalColumn
>& aSubTotalColumns
,
541 sal_Int32 nGroupColumn
)
543 SolarMutexGuard aGuard
;
544 ScSubTotalParam aParam
;
548 while (nPos
< MAXSUBTOTAL
&& aParam
.aGroups
[nPos
].bActive
)
551 if (nPos
>= MAXSUBTOTAL
|| aSubTotalColumns
.getLength() > SCCOL_MAX
)
552 // too many fields / columns
553 throw uno::RuntimeException(); // no other exceptions specified
554 auto& group
= aParam
.aGroups
[nPos
];
556 group
.bActive
= true;
557 group
.nField
= static_cast<SCCOL
>(nGroupColumn
);
558 group
.SetSubtotals(aSubTotalColumns
);
563 // flags/settings as properties
565 // XEnumerationAccess
567 uno::Reference
<container::XEnumeration
> SAL_CALL
ScSubTotalDescriptorBase::createEnumeration()
569 SolarMutexGuard aGuard
;
570 return new ScIndexEnumeration(this, u
"com.sun.star.sheet.SubTotalFieldsEnumeration"_ustr
);
575 sal_Int32 SAL_CALL
ScSubTotalDescriptorBase::getCount()
577 SolarMutexGuard aGuard
;
578 ScSubTotalParam aParam
;
581 sal_uInt16 nCount
= 0;
582 while ( nCount
< MAXSUBTOTAL
&& aParam
.aGroups
[nCount
].bActive
)
587 uno::Any SAL_CALL
ScSubTotalDescriptorBase::getByIndex( sal_Int32 nIndex
)
589 SolarMutexGuard aGuard
;
590 uno::Reference
<sheet::XSubTotalField
> xField(GetObjectByIndex_Impl(static_cast<sal_uInt16
>(nIndex
)));
592 throw lang::IndexOutOfBoundsException();
594 return uno::Any(xField
);
597 uno::Type SAL_CALL
ScSubTotalDescriptorBase::getElementType()
599 return cppu::UnoType
<sheet::XSubTotalField
>::get();
602 sal_Bool SAL_CALL
ScSubTotalDescriptorBase::hasElements()
604 SolarMutexGuard aGuard
;
605 return ( getCount() != 0 );
610 uno::Reference
<beans::XPropertySetInfo
> SAL_CALL
ScSubTotalDescriptorBase::getPropertySetInfo()
612 SolarMutexGuard aGuard
;
613 static uno::Reference
<beans::XPropertySetInfo
> aRef(
614 new SfxItemPropertySetInfo( aPropSet
.getPropertyMap() ));
618 void SAL_CALL
ScSubTotalDescriptorBase::setPropertyValue(
619 const OUString
& aPropertyName
, const uno::Any
& aValue
)
621 SolarMutexGuard aGuard
;
622 ScSubTotalParam aParam
;
625 // some old property names are for 5.2 compatibility
627 if (aPropertyName
== SC_UNONAME_CASE
|| aPropertyName
== SC_UNONAME_ISCASE
)
628 aParam
.bCaseSens
= ScUnoHelpFunctions::GetBoolFromAny( aValue
);
629 else if (aPropertyName
== SC_UNONAME_FORMATS
|| aPropertyName
== SC_UNONAME_BINDFMT
)
630 aParam
.bIncludePattern
= ScUnoHelpFunctions::GetBoolFromAny( aValue
);
631 else if (aPropertyName
== SC_UNONAME_ENABSORT
)
632 aParam
.bDoSort
= ScUnoHelpFunctions::GetBoolFromAny( aValue
);
633 else if (aPropertyName
== SC_UNONAME_SORTASC
)
634 aParam
.bAscending
= ScUnoHelpFunctions::GetBoolFromAny( aValue
);
635 else if (aPropertyName
== SC_UNONAME_INSBRK
)
636 aParam
.bPagebreak
= ScUnoHelpFunctions::GetBoolFromAny( aValue
);
637 else if (aPropertyName
== SC_UNONAME_ULIST
|| aPropertyName
== SC_UNONAME_ENUSLIST
)
638 aParam
.bUserDef
= ScUnoHelpFunctions::GetBoolFromAny( aValue
);
639 else if (aPropertyName
== SC_UNONAME_UINDEX
|| aPropertyName
== SC_UNONAME_USINDEX
)
642 if ( aValue
>>= nVal
)
643 aParam
.nUserIndex
= static_cast<sal_uInt16
>(nVal
);
645 else if (aPropertyName
== SC_UNONAME_MAXFLD
)
648 if ( (aValue
>>= nVal
) && nVal
> sal::static_int_cast
<sal_Int32
>(MAXSUBTOTAL
) )
650 throw lang::IllegalArgumentException();
657 uno::Any SAL_CALL
ScSubTotalDescriptorBase::getPropertyValue( const OUString
& aPropertyName
)
659 SolarMutexGuard aGuard
;
660 ScSubTotalParam aParam
;
665 // some old property names are for 5.2 compatibility
667 if (aPropertyName
== SC_UNONAME_CASE
|| aPropertyName
== SC_UNONAME_ISCASE
)
668 aRet
<<= aParam
.bCaseSens
;
669 else if (aPropertyName
== SC_UNONAME_FORMATS
|| aPropertyName
== SC_UNONAME_BINDFMT
)
670 aRet
<<= aParam
.bIncludePattern
;
671 else if (aPropertyName
== SC_UNONAME_ENABSORT
)
672 aRet
<<= aParam
.bDoSort
;
673 else if (aPropertyName
== SC_UNONAME_SORTASC
)
674 aRet
<<= aParam
.bAscending
;
675 else if (aPropertyName
== SC_UNONAME_INSBRK
)
676 aRet
<<= aParam
.bPagebreak
;
677 else if (aPropertyName
== SC_UNONAME_ULIST
|| aPropertyName
== SC_UNONAME_ENUSLIST
)
678 aRet
<<= aParam
.bUserDef
;
679 else if (aPropertyName
== SC_UNONAME_UINDEX
|| aPropertyName
== SC_UNONAME_USINDEX
)
680 aRet
<<= static_cast<sal_Int32
>(aParam
.nUserIndex
);
681 else if (aPropertyName
== SC_UNONAME_MAXFLD
)
682 aRet
<<= sal_Int32(MAXSUBTOTAL
);
687 SC_IMPL_DUMMY_PROPERTY_LISTENER( ScSubTotalDescriptorBase
)
689 ScSubTotalDescriptor::ScSubTotalDescriptor()
693 ScSubTotalDescriptor::~ScSubTotalDescriptor()
697 void ScSubTotalDescriptor::GetData( ScSubTotalParam
& rParam
) const
699 rParam
= aStoredParam
; // query for interface
702 void ScSubTotalDescriptor::PutData( const ScSubTotalParam
& rParam
)
704 aStoredParam
= rParam
; // set by the interface
707 void ScSubTotalDescriptor::SetParam( const ScSubTotalParam
& rNew
)
709 aStoredParam
= rNew
; // set from outside
712 ScRangeSubTotalDescriptor::ScRangeSubTotalDescriptor(ScDatabaseRangeObj
* pPar
) :
717 ScRangeSubTotalDescriptor::~ScRangeSubTotalDescriptor()
721 void ScRangeSubTotalDescriptor::GetData( ScSubTotalParam
& rParam
) const
724 mxParent
->GetSubTotalParam( rParam
);
727 void ScRangeSubTotalDescriptor::PutData( const ScSubTotalParam
& rParam
)
730 mxParent
->SetSubTotalParam( rParam
);
733 ScConsolidationDescriptor::ScConsolidationDescriptor()
737 ScConsolidationDescriptor::~ScConsolidationDescriptor()
741 void ScConsolidationDescriptor::SetParam( const ScConsolidateParam
& rNew
)
746 // XConsolidationDescriptor
748 sheet::GeneralFunction SAL_CALL
ScConsolidationDescriptor::getFunction()
750 SolarMutexGuard aGuard
;
751 return ScDataUnoConversion::SubTotalToGeneral(aParam
.eFunction
);
754 void SAL_CALL
ScConsolidationDescriptor::setFunction( sheet::GeneralFunction nFunction
)
756 SolarMutexGuard aGuard
;
757 aParam
.eFunction
= ScDPUtil::toSubTotalFunc(static_cast<ScGeneralFunction
>(nFunction
));
760 uno::Sequence
<table::CellRangeAddress
> SAL_CALL
ScConsolidationDescriptor::getSources()
762 SolarMutexGuard aGuard
;
763 sal_uInt16 nCount
= aParam
.nDataAreaCount
;
764 if (!aParam
.pDataAreas
)
766 table::CellRangeAddress aRange
;
767 uno::Sequence
<table::CellRangeAddress
> aSeq(nCount
);
768 table::CellRangeAddress
* pAry
= aSeq
.getArray();
769 for (sal_uInt16 i
=0; i
<nCount
; i
++)
771 ScArea
const & rArea
= aParam
.pDataAreas
[i
];
772 aRange
.Sheet
= rArea
.nTab
;
773 aRange
.StartColumn
= rArea
.nColStart
;
774 aRange
.StartRow
= rArea
.nRowStart
;
775 aRange
.EndColumn
= rArea
.nColEnd
;
776 aRange
.EndRow
= rArea
.nRowEnd
;
782 void SAL_CALL
ScConsolidationDescriptor::setSources(
783 const uno::Sequence
<table::CellRangeAddress
>& aSources
)
785 SolarMutexGuard aGuard
;
786 sal_uInt16 nCount
= static_cast<sal_uInt16
>(aSources
.getLength());
789 const table::CellRangeAddress
* pAry
= aSources
.getConstArray();
790 std::unique_ptr
<ScArea
[]> pNew(new ScArea
[nCount
]);
792 for (i
=0; i
<nCount
; i
++)
793 pNew
[i
] = ScArea( pAry
[i
].Sheet
,
794 static_cast<SCCOL
>(pAry
[i
].StartColumn
), pAry
[i
].StartRow
,
795 static_cast<SCCOL
>(pAry
[i
].EndColumn
), pAry
[i
].EndRow
);
797 aParam
.SetAreas( std::move(pNew
), nCount
); // copy everything
800 aParam
.ClearDataAreas();
803 table::CellAddress SAL_CALL
ScConsolidationDescriptor::getStartOutputPosition()
805 SolarMutexGuard aGuard
;
806 table::CellAddress aPos
;
807 aPos
.Column
= aParam
.nCol
;
808 aPos
.Row
= aParam
.nRow
;
809 aPos
.Sheet
= aParam
.nTab
;
813 void SAL_CALL
ScConsolidationDescriptor::setStartOutputPosition(
814 const table::CellAddress
& aStartOutputPosition
)
816 SolarMutexGuard aGuard
;
817 aParam
.nCol
= static_cast<SCCOL
>(aStartOutputPosition
.Column
);
818 aParam
.nRow
= static_cast<SCROW
>(aStartOutputPosition
.Row
);
819 aParam
.nTab
= aStartOutputPosition
.Sheet
;
822 sal_Bool SAL_CALL
ScConsolidationDescriptor::getUseColumnHeaders()
824 SolarMutexGuard aGuard
;
825 return aParam
.bByCol
;
828 void SAL_CALL
ScConsolidationDescriptor::setUseColumnHeaders( sal_Bool bUseColumnHeaders
)
830 SolarMutexGuard aGuard
;
831 aParam
.bByCol
= bUseColumnHeaders
;
834 sal_Bool SAL_CALL
ScConsolidationDescriptor::getUseRowHeaders()
836 SolarMutexGuard aGuard
;
837 return aParam
.bByRow
;
840 void SAL_CALL
ScConsolidationDescriptor::setUseRowHeaders( sal_Bool bUseRowHeaders
)
842 SolarMutexGuard aGuard
;
843 aParam
.bByRow
= bUseRowHeaders
;
846 sal_Bool SAL_CALL
ScConsolidationDescriptor::getInsertLinks()
848 SolarMutexGuard aGuard
;
849 return aParam
.bReferenceData
;
852 void SAL_CALL
ScConsolidationDescriptor::setInsertLinks( sal_Bool bInsertLinks
)
854 SolarMutexGuard aGuard
;
855 aParam
.bReferenceData
= bInsertLinks
;
858 ScFilterDescriptorBase::ScFilterDescriptorBase(ScDocShell
* pDocShell
) :
859 aPropSet( lcl_GetFilterPropertyMap() ),
863 pDocSh
->GetDocument().AddUnoObject(*this);
866 ScFilterDescriptorBase::~ScFilterDescriptorBase()
871 pDocSh
->GetDocument().RemoveUnoObject(*this);
874 void ScFilterDescriptorBase::Notify( SfxBroadcaster
&, const SfxHint
& rHint
)
876 if ( rHint
.GetId() == SfxHintId::Dying
)
878 pDocSh
= nullptr; // invalid
882 // XSheetFilterDescriptor and XSheetFilterDescriptor2
884 uno::Sequence
<sheet::TableFilterField
> SAL_CALL
ScFilterDescriptorBase::getFilterFields()
886 SolarMutexGuard aGuard
;
890 SCSIZE nEntries
= aParam
.GetEntryCount(); // allocated entries in Param
891 SCSIZE nCount
= 0; // active
892 while ( nCount
< nEntries
&&
893 aParam
.GetEntry(nCount
).bDoQuery
)
896 sheet::TableFilterField aField
;
897 uno::Sequence
<sheet::TableFilterField
> aSeq(static_cast<sal_Int32
>(nCount
));
898 sheet::TableFilterField
* pAry
= aSeq
.getArray();
899 for (SCSIZE i
=0; i
<nCount
; i
++)
901 const ScQueryEntry
& rEntry
= aParam
.GetEntry(i
);
902 if (rEntry
.GetQueryItems().empty())
905 const ScQueryEntry::Item
& rItem
= rEntry
.GetQueryItems().front();
907 aField
.Connection
= (rEntry
.eConnect
== SC_AND
) ? sheet::FilterConnection_AND
:
908 sheet::FilterConnection_OR
;
909 aField
.Field
= rEntry
.nField
;
910 aField
.IsNumeric
= rItem
.meType
!= ScQueryEntry::ByString
;
911 aField
.StringValue
= rItem
.maString
.getString();
912 aField
.NumericValue
= rItem
.mfVal
;
914 switch (rEntry
.eOp
) // ScQueryOp
918 aField
.Operator
= sheet::FilterOperator_EQUAL
;
919 if (rEntry
.IsQueryByEmpty())
921 aField
.Operator
= sheet::FilterOperator_EMPTY
;
922 aField
.NumericValue
= 0;
924 else if (rEntry
.IsQueryByNonEmpty())
926 aField
.Operator
= sheet::FilterOperator_NOT_EMPTY
;
927 aField
.NumericValue
= 0;
931 case SC_LESS
: aField
.Operator
= sheet::FilterOperator_LESS
; break;
932 case SC_GREATER
: aField
.Operator
= sheet::FilterOperator_GREATER
; break;
933 case SC_LESS_EQUAL
: aField
.Operator
= sheet::FilterOperator_LESS_EQUAL
; break;
934 case SC_GREATER_EQUAL
: aField
.Operator
= sheet::FilterOperator_GREATER_EQUAL
; break;
935 case SC_NOT_EQUAL
: aField
.Operator
= sheet::FilterOperator_NOT_EQUAL
; break;
936 case SC_TOPVAL
: aField
.Operator
= sheet::FilterOperator_TOP_VALUES
; break;
937 case SC_BOTVAL
: aField
.Operator
= sheet::FilterOperator_BOTTOM_VALUES
; break;
938 case SC_TOPPERC
: aField
.Operator
= sheet::FilterOperator_TOP_PERCENT
; break;
939 case SC_BOTPERC
: aField
.Operator
= sheet::FilterOperator_BOTTOM_PERCENT
; break;
941 OSL_FAIL("wrong filter enum");
942 aField
.Operator
= sheet::FilterOperator_EMPTY
;
952 void convertQueryEntryToUno(const ScQueryEntry
& rEntry
, T
& rField
)
954 rField
.Connection
= (rEntry
.eConnect
== SC_AND
) ? sheet::FilterConnection_AND
: sheet::FilterConnection_OR
;
955 rField
.Field
= rEntry
.nField
;
957 switch (rEntry
.eOp
) // ScQueryOp
959 case SC_EQUAL
: rField
.Operator
= sheet::FilterOperator2::EQUAL
; break;
960 case SC_LESS
: rField
.Operator
= sheet::FilterOperator2::LESS
; break;
961 case SC_GREATER
: rField
.Operator
= sheet::FilterOperator2::GREATER
; break;
962 case SC_LESS_EQUAL
: rField
.Operator
= sheet::FilterOperator2::LESS_EQUAL
; break;
963 case SC_GREATER_EQUAL
: rField
.Operator
= sheet::FilterOperator2::GREATER_EQUAL
; break;
964 case SC_NOT_EQUAL
: rField
.Operator
= sheet::FilterOperator2::NOT_EQUAL
; break;
965 case SC_TOPVAL
: rField
.Operator
= sheet::FilterOperator2::TOP_VALUES
; break;
966 case SC_BOTVAL
: rField
.Operator
= sheet::FilterOperator2::BOTTOM_VALUES
; break;
967 case SC_TOPPERC
: rField
.Operator
= sheet::FilterOperator2::TOP_PERCENT
; break;
968 case SC_BOTPERC
: rField
.Operator
= sheet::FilterOperator2::BOTTOM_PERCENT
; break;
969 case SC_CONTAINS
: rField
.Operator
= sheet::FilterOperator2::CONTAINS
; break;
970 case SC_DOES_NOT_CONTAIN
: rField
.Operator
= sheet::FilterOperator2::DOES_NOT_CONTAIN
; break;
971 case SC_BEGINS_WITH
: rField
.Operator
= sheet::FilterOperator2::BEGINS_WITH
; break;
972 case SC_DOES_NOT_BEGIN_WITH
: rField
.Operator
= sheet::FilterOperator2::DOES_NOT_BEGIN_WITH
; break;
973 case SC_ENDS_WITH
: rField
.Operator
= sheet::FilterOperator2::ENDS_WITH
; break;
974 case SC_DOES_NOT_END_WITH
: rField
.Operator
= sheet::FilterOperator2::DOES_NOT_END_WITH
; break;
976 OSL_FAIL("Unknown filter operator value.");
977 rField
.Operator
= sheet::FilterOperator2::EMPTY
;
982 void convertUnoToQueryEntry(const T
& rField
, ScQueryEntry
& rEntry
)
984 rEntry
.bDoQuery
= true;
985 rEntry
.eConnect
= (rField
.Connection
== sheet::FilterConnection_AND
) ? SC_AND
: SC_OR
;
986 rEntry
.nField
= rField
.Field
;
988 switch (rField
.Operator
) // FilterOperator
990 case sheet::FilterOperator2::EQUAL
: rEntry
.eOp
= SC_EQUAL
; break;
991 case sheet::FilterOperator2::LESS
: rEntry
.eOp
= SC_LESS
; break;
992 case sheet::FilterOperator2::GREATER
: rEntry
.eOp
= SC_GREATER
; break;
993 case sheet::FilterOperator2::LESS_EQUAL
: rEntry
.eOp
= SC_LESS_EQUAL
; break;
994 case sheet::FilterOperator2::GREATER_EQUAL
: rEntry
.eOp
= SC_GREATER_EQUAL
; break;
995 case sheet::FilterOperator2::NOT_EQUAL
: rEntry
.eOp
= SC_NOT_EQUAL
; break;
996 case sheet::FilterOperator2::TOP_VALUES
: rEntry
.eOp
= SC_TOPVAL
; break;
997 case sheet::FilterOperator2::BOTTOM_VALUES
: rEntry
.eOp
= SC_BOTVAL
; break;
998 case sheet::FilterOperator2::TOP_PERCENT
: rEntry
.eOp
= SC_TOPPERC
; break;
999 case sheet::FilterOperator2::BOTTOM_PERCENT
: rEntry
.eOp
= SC_BOTPERC
; break;
1000 case sheet::FilterOperator2::CONTAINS
: rEntry
.eOp
= SC_CONTAINS
; break;
1001 case sheet::FilterOperator2::DOES_NOT_CONTAIN
: rEntry
.eOp
= SC_DOES_NOT_CONTAIN
; break;
1002 case sheet::FilterOperator2::BEGINS_WITH
: rEntry
.eOp
= SC_BEGINS_WITH
; break;
1003 case sheet::FilterOperator2::DOES_NOT_BEGIN_WITH
: rEntry
.eOp
= SC_DOES_NOT_BEGIN_WITH
;break;
1004 case sheet::FilterOperator2::ENDS_WITH
: rEntry
.eOp
= SC_ENDS_WITH
; break;
1005 case sheet::FilterOperator2::DOES_NOT_END_WITH
: rEntry
.eOp
= SC_DOES_NOT_END_WITH
; break;
1006 case sheet::FilterOperator2::EMPTY
:
1007 rEntry
.SetQueryByEmpty();
1009 case sheet::FilterOperator2::NOT_EMPTY
:
1010 rEntry
.SetQueryByNonEmpty();
1013 OSL_FAIL("Unknown filter operator type.");
1014 rEntry
.eOp
= SC_EQUAL
;
1018 void fillQueryParam(
1019 ScQueryParam
& rParam
, ScDocument
* pDoc
,
1020 const uno::Sequence
<sheet::TableFilterField2
>& aFilterFields
)
1022 size_t nCount
= static_cast<size_t>(aFilterFields
.getLength());
1023 rParam
.Resize(nCount
);
1025 const sheet::TableFilterField2
* pAry
= aFilterFields
.getConstArray();
1026 svl::SharedStringPool
& rPool
= pDoc
->GetSharedStringPool();
1027 for (size_t i
= 0; i
< nCount
; ++i
)
1029 ScQueryEntry
& rEntry
= rParam
.GetEntry(i
);
1030 convertUnoToQueryEntry(pAry
[i
], rEntry
);
1032 if (pAry
[i
].Operator
!= sheet::FilterOperator2::EMPTY
&& pAry
[i
].Operator
!= sheet::FilterOperator2::NOT_EMPTY
)
1034 ScQueryEntry::QueryItemsType
& rItems
= rEntry
.GetQueryItems();
1036 ScQueryEntry::Item
& rItem
= rItems
.front();
1037 rItem
.meType
= pAry
[i
].IsNumeric
? ScQueryEntry::ByValue
: ScQueryEntry::ByString
;
1038 rItem
.mfVal
= pAry
[i
].NumericValue
;
1039 rItem
.maString
= rPool
.intern(pAry
[i
].StringValue
);
1041 if (rItem
.meType
== ScQueryEntry::ByValue
)
1043 OUString aStr
= pDoc
->GetFormatTable()->GetInputLineString(rItem
.mfVal
, 0);
1044 rItem
.maString
= rPool
.intern(aStr
);
1049 size_t nParamCount
= rParam
.GetEntryCount(); // if below eight Param isn't resized
1050 for (size_t i
= nCount
; i
< nParamCount
; ++i
)
1051 rParam
.GetEntry(i
).bDoQuery
= false; // reset surplus fields
1054 void fillQueryParam(
1055 ScQueryParam
& rParam
, ScDocument
* pDoc
,
1056 const uno::Sequence
<sheet::TableFilterField3
>& aFilterFields
)
1058 size_t nCount
= static_cast<size_t>(aFilterFields
.getLength());
1059 rParam
.Resize(nCount
);
1061 svl::SharedStringPool
& rPool
= pDoc
->GetSharedStringPool();
1062 const sheet::TableFilterField3
* pAry
= aFilterFields
.getConstArray();
1063 for (size_t i
= 0; i
< nCount
; ++i
)
1065 ScQueryEntry
& rEntry
= rParam
.GetEntry(i
);
1066 convertUnoToQueryEntry(pAry
[i
], rEntry
);
1068 if (pAry
[i
].Operator
!= sheet::FilterOperator2::EMPTY
&& pAry
[i
].Operator
!= sheet::FilterOperator2::NOT_EMPTY
)
1070 ScQueryEntry::QueryItemsType
& rItems
= rEntry
.GetQueryItems();
1072 const uno::Sequence
<sheet::FilterFieldValue
>& rVals
= pAry
[i
].Values
;
1073 for (const auto& rVal
: rVals
)
1075 ScQueryEntry::Item aItem
;
1076 switch (rVal
.FilterType
)
1078 case FilterFieldType::NUMERIC
:
1079 aItem
.meType
= ScQueryEntry::ByValue
;
1081 case FilterFieldType::STRING
:
1082 aItem
.meType
= ScQueryEntry::ByString
;
1084 case FilterFieldType::DATE
:
1085 aItem
.meType
= ScQueryEntry::ByDate
;
1087 case FilterFieldType::TEXT_COLOR
:
1088 aItem
.meType
= ScQueryEntry::ByTextColor
;
1090 case FilterFieldType::BACKGROUND_COLOR
:
1091 aItem
.meType
= ScQueryEntry::ByBackgroundColor
;
1094 aItem
.mfVal
= rVal
.NumericValue
;
1095 aItem
.maString
= rPool
.intern(rVal
.StringValue
);
1097 if (aItem
.meType
== ScQueryEntry::ByValue
)
1099 OUString aStr
= pDoc
->GetFormatTable()->GetInputLineString(aItem
.mfVal
, 0);
1100 aItem
.maString
= rPool
.intern(aStr
);
1102 else if (aItem
.meType
== ScQueryEntry::ByTextColor
1103 || aItem
.meType
== ScQueryEntry::ByBackgroundColor
)
1105 aItem
.maColor
= Color(ColorTransparency
, rVal
.ColorValue
);
1108 // filter all dates starting with the given date filter YYYY or YYYY-MM and filter all datetimes
1109 // starting with the given datetime filter YYYY-MM-DD, YYYY-MM-DD HH, or YYYY-MM-DD HH:MM
1110 if( aItem
.meType
== ScQueryEntry::ByDate
&& aItem
.maString
.getLength() < 19 )
1112 ScFilterEntries aFilterEntries
;
1113 pDoc
->GetFilterEntries(rEntry
.nField
, rParam
.nRow1
, rParam
.nTab
, aFilterEntries
);
1114 for( const auto& rFilter
: aFilterEntries
)
1116 if( rFilter
.GetString().startsWith(rVal
.StringValue
) )
1118 aItem
.maString
= rPool
.intern(rFilter
.GetString());
1119 rItems
.push_back(aItem
);
1125 rItems
.push_back(aItem
);
1131 size_t nParamCount
= rParam
.GetEntryCount(); // if below eight Param isn't resized
1132 for (size_t i
= nCount
; i
< nParamCount
; ++i
)
1133 rParam
.GetEntry(i
).bDoQuery
= false; // reset surplus fields
1138 uno::Sequence
<sheet::TableFilterField2
> SAL_CALL
ScFilterDescriptorBase::getFilterFields2()
1140 SolarMutexGuard aGuard
;
1141 ScQueryParam aParam
;
1144 SCSIZE nEntries
= aParam
.GetEntryCount(); // allocated entries in Param
1145 SCSIZE nCount
= 0; // active
1146 while ( nCount
< nEntries
&&
1147 aParam
.GetEntry(nCount
).bDoQuery
)
1150 sheet::TableFilterField2 aField
;
1151 uno::Sequence
<sheet::TableFilterField2
> aSeq(static_cast<sal_Int32
>(nCount
));
1152 sheet::TableFilterField2
* pAry
= aSeq
.getArray();
1153 for (SCSIZE i
=0; i
<nCount
; i
++)
1155 const ScQueryEntry
& rEntry
= aParam
.GetEntry(i
);
1156 convertQueryEntryToUno(rEntry
, aField
);
1158 bool bByEmpty
= false;
1159 if (aField
.Operator
== sheet::FilterOperator2::EQUAL
)
1161 if (rEntry
.IsQueryByEmpty())
1163 aField
.Operator
= sheet::FilterOperator2::EMPTY
;
1164 aField
.NumericValue
= 0;
1167 else if (rEntry
.IsQueryByNonEmpty())
1169 aField
.Operator
= sheet::FilterOperator2::NOT_EMPTY
;
1170 aField
.NumericValue
= 0;
1175 if (!bByEmpty
&& !rEntry
.GetQueryItems().empty())
1177 const ScQueryEntry::Item
& rItem
= rEntry
.GetQueryItems().front();
1178 aField
.IsNumeric
= rItem
.meType
!= ScQueryEntry::ByString
;
1179 aField
.StringValue
= rItem
.maString
.getString();
1180 aField
.NumericValue
= rItem
.mfVal
;
1188 uno::Sequence
<sheet::TableFilterField3
> SAL_CALL
ScFilterDescriptorBase::getFilterFields3()
1190 SolarMutexGuard aGuard
;
1191 ScQueryParam aParam
;
1194 SCSIZE nEntries
= aParam
.GetEntryCount(); // allocated entries in Param
1195 SCSIZE nCount
= 0; // active
1196 while ( nCount
< nEntries
&&
1197 aParam
.GetEntry(nCount
).bDoQuery
)
1200 sheet::TableFilterField3 aField
;
1201 uno::Sequence
<sheet::TableFilterField3
> aSeq(static_cast<sal_Int32
>(nCount
));
1202 sheet::TableFilterField3
* pAry
= aSeq
.getArray();
1203 for (SCSIZE i
= 0; i
< nCount
; ++i
)
1205 const ScQueryEntry
& rEntry
= aParam
.GetEntry(i
);
1206 convertQueryEntryToUno(rEntry
, aField
);
1208 bool bByEmpty
= false;
1209 if (aField
.Operator
== sheet::FilterOperator2::EQUAL
)
1211 if (rEntry
.IsQueryByEmpty())
1213 aField
.Operator
= sheet::FilterOperator2::EMPTY
;
1214 aField
.Values
.realloc(1);
1215 aField
.Values
.getArray()[0].NumericValue
= 0;
1218 else if (rEntry
.IsQueryByNonEmpty())
1220 aField
.Operator
= sheet::FilterOperator2::NOT_EMPTY
;
1221 aField
.Values
.realloc(1);
1222 aField
.Values
.getArray()[0].NumericValue
= 0;
1229 const ScQueryEntry::QueryItemsType
& rItems
= rEntry
.GetQueryItems();
1230 size_t nItemCount
= rItems
.size();
1231 aField
.Values
.realloc(nItemCount
);
1232 auto pValues
= aField
.Values
.getArray();
1234 for (const auto& rItem
: rItems
)
1236 pValues
[j
].IsNumeric
= rItem
.meType
!= ScQueryEntry::ByString
;
1237 pValues
[j
].StringValue
= rItem
.maString
.getString();
1238 pValues
[j
].NumericValue
= rItem
.mfVal
;
1248 void SAL_CALL
ScFilterDescriptorBase::setFilterFields(
1249 const uno::Sequence
<sheet::TableFilterField
>& aFilterFields
)
1251 SolarMutexGuard aGuard
;
1252 ScQueryParam aParam
;
1255 SCSIZE nCount
= static_cast<SCSIZE
>(aFilterFields
.getLength());
1256 aParam
.Resize( nCount
);
1258 ScDocument
& rDoc
= pDocSh
->GetDocument();
1259 svl::SharedStringPool
& rPool
= rDoc
.GetSharedStringPool();
1260 const sheet::TableFilterField
* pAry
= aFilterFields
.getConstArray();
1262 for (i
=0; i
<nCount
; i
++)
1264 ScQueryEntry
& rEntry
= aParam
.GetEntry(i
);
1265 ScQueryEntry::QueryItemsType
& rItems
= rEntry
.GetQueryItems();
1267 ScQueryEntry::Item
& rItem
= rItems
.front();
1268 rEntry
.bDoQuery
= true;
1269 rEntry
.eConnect
= (pAry
[i
].Connection
== sheet::FilterConnection_AND
) ? SC_AND
: SC_OR
;
1270 rEntry
.nField
= pAry
[i
].Field
;
1271 rItem
.meType
= pAry
[i
].IsNumeric
? ScQueryEntry::ByValue
: ScQueryEntry::ByString
;
1272 rItem
.mfVal
= pAry
[i
].NumericValue
;
1273 rItem
.maString
= rPool
.intern(pAry
[i
].StringValue
);
1275 if (rItem
.meType
!= ScQueryEntry::ByString
)
1277 OUString aStr
= rDoc
.GetFormatTable()->GetInputLineString(rItem
.mfVal
, 0);
1278 rItem
.maString
= rPool
.intern(aStr
);
1281 switch (pAry
[i
].Operator
) // FilterOperator
1283 case sheet::FilterOperator_EQUAL
: rEntry
.eOp
= SC_EQUAL
; break;
1284 case sheet::FilterOperator_LESS
: rEntry
.eOp
= SC_LESS
; break;
1285 case sheet::FilterOperator_GREATER
: rEntry
.eOp
= SC_GREATER
; break;
1286 case sheet::FilterOperator_LESS_EQUAL
: rEntry
.eOp
= SC_LESS_EQUAL
; break;
1287 case sheet::FilterOperator_GREATER_EQUAL
: rEntry
.eOp
= SC_GREATER_EQUAL
; break;
1288 case sheet::FilterOperator_NOT_EQUAL
: rEntry
.eOp
= SC_NOT_EQUAL
; break;
1289 case sheet::FilterOperator_TOP_VALUES
: rEntry
.eOp
= SC_TOPVAL
; break;
1290 case sheet::FilterOperator_BOTTOM_VALUES
: rEntry
.eOp
= SC_BOTVAL
; break;
1291 case sheet::FilterOperator_TOP_PERCENT
: rEntry
.eOp
= SC_TOPPERC
; break;
1292 case sheet::FilterOperator_BOTTOM_PERCENT
: rEntry
.eOp
= SC_BOTPERC
; break;
1293 case sheet::FilterOperator_EMPTY
:
1294 rEntry
.SetQueryByEmpty();
1296 case sheet::FilterOperator_NOT_EMPTY
:
1297 rEntry
.SetQueryByNonEmpty();
1300 OSL_FAIL("Wrong query enum");
1301 rEntry
.eOp
= SC_EQUAL
;
1305 SCSIZE nParamCount
= aParam
.GetEntryCount(); // if below eight Param isn't resized
1306 for (i
=nCount
; i
<nParamCount
; i
++)
1307 aParam
.GetEntry(i
).bDoQuery
= false; // reset surplus fields
1312 void SAL_CALL
ScFilterDescriptorBase::setFilterFields2(
1313 const uno::Sequence
<sheet::TableFilterField2
>& aFilterFields
)
1315 SolarMutexGuard aGuard
;
1316 ScQueryParam aParam
;
1318 fillQueryParam(aParam
, &pDocSh
->GetDocument(), aFilterFields
);
1322 void SAL_CALL
ScFilterDescriptorBase::setFilterFields3(
1323 const uno::Sequence
<sheet::TableFilterField3
>& aFilterFields
)
1325 SolarMutexGuard aGuard
;
1326 ScQueryParam aParam
;
1328 fillQueryParam(aParam
, &pDocSh
->GetDocument(), aFilterFields
);
1332 // Rest are Properties
1336 uno::Reference
<beans::XPropertySetInfo
> SAL_CALL
ScFilterDescriptorBase::getPropertySetInfo()
1338 SolarMutexGuard aGuard
;
1339 static uno::Reference
<beans::XPropertySetInfo
> aRef(
1340 new SfxItemPropertySetInfo( aPropSet
.getPropertyMap() ));
1344 void SAL_CALL
ScFilterDescriptorBase::setPropertyValue(
1345 const OUString
& aPropertyName
, const uno::Any
& aValue
)
1347 SolarMutexGuard aGuard
;
1348 ScQueryParam aParam
;
1351 if (aPropertyName
== SC_UNONAME_CONTHDR
)
1352 aParam
.bHasHeader
= ScUnoHelpFunctions::GetBoolFromAny( aValue
);
1353 else if (aPropertyName
== SC_UNONAME_COPYOUT
)
1354 aParam
.bInplace
= !(ScUnoHelpFunctions::GetBoolFromAny( aValue
));
1355 else if (aPropertyName
== SC_UNONAME_ISCASE
)
1356 aParam
.bCaseSens
= ScUnoHelpFunctions::GetBoolFromAny( aValue
);
1357 else if (aPropertyName
== SC_UNONAME_MAXFLD
)
1361 else if (aPropertyName
== SC_UNONAME_ORIENT
)
1363 //! test for correct enum type?
1364 table::TableOrientation eOrient
= static_cast<table::TableOrientation
>(ScUnoHelpFunctions::GetEnumFromAny( aValue
));
1365 aParam
.bByRow
= ( eOrient
!= table::TableOrientation_COLUMNS
);
1367 else if (aPropertyName
== SC_UNONAME_OUTPOS
)
1369 table::CellAddress aAddress
;
1370 if ( aValue
>>= aAddress
)
1372 aParam
.nDestTab
= aAddress
.Sheet
;
1373 aParam
.nDestCol
= static_cast<SCCOL
>(aAddress
.Column
);
1374 aParam
.nDestRow
= static_cast<SCROW
>(aAddress
.Row
);
1377 else if (aPropertyName
== SC_UNONAME_SAVEOUT
)
1378 aParam
.bDestPers
= ScUnoHelpFunctions::GetBoolFromAny( aValue
);
1379 else if (aPropertyName
== SC_UNONAME_SKIPDUP
)
1380 aParam
.bDuplicate
= !(ScUnoHelpFunctions::GetBoolFromAny( aValue
));
1381 else if (aPropertyName
== SC_UNONAME_USEREGEX
)
1382 aParam
.eSearchType
= ScUnoHelpFunctions::GetBoolFromAny( aValue
) ? utl::SearchParam::SearchType::Regexp
:
1383 utl::SearchParam::SearchType::Normal
;
1388 uno::Any SAL_CALL
ScFilterDescriptorBase::getPropertyValue( const OUString
& aPropertyName
)
1390 SolarMutexGuard aGuard
;
1391 ScQueryParam aParam
;
1396 if (aPropertyName
== SC_UNONAME_CONTHDR
)
1397 aRet
<<= aParam
.bHasHeader
;
1398 else if (aPropertyName
== SC_UNONAME_COPYOUT
)
1399 aRet
<<= !(aParam
.bInplace
);
1400 else if (aPropertyName
== SC_UNONAME_ISCASE
)
1401 aRet
<<= aParam
.bCaseSens
;
1402 else if (aPropertyName
== SC_UNONAME_MAXFLD
)
1403 aRet
<<= static_cast<sal_Int32
>(aParam
.GetEntryCount());
1404 else if (aPropertyName
== SC_UNONAME_ORIENT
)
1406 table::TableOrientation eOrient
= aParam
.bByRow
? table::TableOrientation_ROWS
:
1407 table::TableOrientation_COLUMNS
;
1410 else if (aPropertyName
== SC_UNONAME_OUTPOS
)
1412 table::CellAddress aOutPos
;
1413 aOutPos
.Sheet
= aParam
.nDestTab
;
1414 aOutPos
.Column
= aParam
.nDestCol
;
1415 aOutPos
.Row
= aParam
.nDestRow
;
1418 else if (aPropertyName
== SC_UNONAME_SAVEOUT
)
1419 aRet
<<= aParam
.bDestPers
;
1420 else if (aPropertyName
== SC_UNONAME_SKIPDUP
)
1421 aRet
<<= !(aParam
.bDuplicate
);
1422 else if (aPropertyName
== SC_UNONAME_USEREGEX
)
1423 aRet
<<= (aParam
.eSearchType
== utl::SearchParam::SearchType::Regexp
);
1428 SC_IMPL_DUMMY_PROPERTY_LISTENER( ScFilterDescriptorBase
)
1430 ScFilterDescriptor::ScFilterDescriptor(ScDocShell
* pDocShell
)
1432 ScFilterDescriptorBase(pDocShell
)
1436 ScFilterDescriptor::~ScFilterDescriptor()
1440 void ScFilterDescriptor::GetData( ScQueryParam
& rParam
) const
1442 rParam
= aStoredParam
; // query for interface
1445 void ScFilterDescriptor::PutData( const ScQueryParam
& rParam
)
1447 aStoredParam
= rParam
; // set by the interface
1450 void ScFilterDescriptor::SetParam( const ScQueryParam
& rNew
)
1452 aStoredParam
= rNew
; // set from outside
1455 ScRangeFilterDescriptor::ScRangeFilterDescriptor(ScDocShell
* pDocShell
, ScDatabaseRangeObj
* pPar
) :
1456 ScFilterDescriptorBase(pDocShell
),
1461 ScRangeFilterDescriptor::~ScRangeFilterDescriptor()
1465 void ScRangeFilterDescriptor::GetData( ScQueryParam
& rParam
) const
1468 mxParent
->GetQueryParam( rParam
);
1471 void ScRangeFilterDescriptor::PutData( const ScQueryParam
& rParam
)
1474 mxParent
->SetQueryParam( rParam
);
1477 ScDataPilotFilterDescriptor::ScDataPilotFilterDescriptor(ScDocShell
* pDocShell
, ScDataPilotDescriptorBase
* pPar
) :
1478 ScFilterDescriptorBase(pDocShell
),
1483 ScDataPilotFilterDescriptor::~ScDataPilotFilterDescriptor()
1487 void ScDataPilotFilterDescriptor::GetData( ScQueryParam
& rParam
) const
1491 ScDPObject
* pDPObj
= mxParent
->GetDPObject();
1492 if (pDPObj
&& pDPObj
->IsSheetData())
1493 rParam
= pDPObj
->GetSheetDesc()->GetQueryParam();
1497 void ScDataPilotFilterDescriptor::PutData( const ScQueryParam
& rParam
)
1502 ScDPObject
* pDPObj
= mxParent
->GetDPObject();
1505 ScSheetSourceDesc
aSheetDesc(&mxParent
->GetDocShell()->GetDocument());
1506 if (pDPObj
->IsSheetData())
1507 aSheetDesc
= *pDPObj
->GetSheetDesc();
1508 aSheetDesc
.SetQueryParam(rParam
);
1509 pDPObj
->SetSheetDesc(aSheetDesc
);
1510 mxParent
->SetDPObject(pDPObj
);
1514 ScDatabaseRangeObj::ScDatabaseRangeObj(ScDocShell
* pDocSh
, OUString aNm
) :
1515 pDocShell( pDocSh
),
1516 aName(std::move( aNm
)),
1517 aPropSet( lcl_GetDBRangePropertyMap() ),
1521 pDocShell
->GetDocument().AddUnoObject(*this);
1524 ScDatabaseRangeObj::ScDatabaseRangeObj(ScDocShell
* pDocSh
, const SCTAB nTab
) :
1525 pDocShell( pDocSh
),
1526 aName(STR_DB_LOCAL_NONAME
),
1527 aPropSet( lcl_GetDBRangePropertyMap() ),
1531 pDocShell
->GetDocument().AddUnoObject(*this);
1534 ScDatabaseRangeObj::~ScDatabaseRangeObj()
1539 pDocShell
->GetDocument().RemoveUnoObject(*this);
1542 void ScDatabaseRangeObj::Notify( SfxBroadcaster
&, const SfxHint
& rHint
)
1545 if ( rHint
.GetId() == SfxHintId::Dying
)
1546 pDocShell
= nullptr;
1547 else if ( rHint
.GetId() == SfxHintId::ScDBRangeRefreshed
)
1549 auto pRefreshHint
= static_cast<const ScDBRangeRefreshedHint
*>(&rHint
);
1550 ScDBData
* pDBData
= GetDBData_Impl();
1551 ScImportParam aParam
;
1552 pDBData
->GetImportParam(aParam
);
1553 if (aParam
== pRefreshHint
->GetImportParam())
1560 ScDBData
* ScDatabaseRangeObj::GetDBData_Impl() const
1562 ScDBData
* pRet
= nullptr;
1567 pRet
= pDocShell
->GetDocument().GetAnonymousDBData(aTab
);
1571 ScDBCollection
* pNames
= pDocShell
->GetDocument().GetDBCollection();
1574 ScDBData
* p
= pNames
->getNamedDBs().findByUpperName(ScGlobal::getCharClass().uppercase(aName
));
1585 OUString SAL_CALL
ScDatabaseRangeObj::getName()
1587 SolarMutexGuard aGuard
;
1591 void SAL_CALL
ScDatabaseRangeObj::setName( const OUString
& aNewName
)
1593 SolarMutexGuard aGuard
;
1596 ScDBDocFunc
aFunc(*pDocShell
);
1597 bool bOk
= aFunc
.RenameDBRange( aName
, aNewName
);
1605 table::CellRangeAddress SAL_CALL
ScDatabaseRangeObj::getDataArea()
1607 SolarMutexGuard aGuard
;
1608 table::CellRangeAddress aAddress
;
1609 ScDBData
* pData
= GetDBData_Impl();
1613 pData
->GetArea(aRange
);
1614 aAddress
.Sheet
= aRange
.aStart
.Tab();
1615 aAddress
.StartColumn
= aRange
.aStart
.Col();
1616 aAddress
.StartRow
= aRange
.aStart
.Row();
1617 aAddress
.EndColumn
= aRange
.aEnd
.Col();
1618 aAddress
.EndRow
= aRange
.aEnd
.Row();
1623 void SAL_CALL
ScDatabaseRangeObj::setDataArea( const table::CellRangeAddress
& aDataArea
)
1625 SolarMutexGuard aGuard
;
1626 ScDBData
* pData
= GetDBData_Impl();
1627 if ( pDocShell
&& pData
)
1629 ScDBData
aNewData( *pData
);
1631 aNewData
.SetArea( aDataArea
.Sheet
, static_cast<SCCOL
>(aDataArea
.StartColumn
), static_cast<SCROW
>(aDataArea
.StartRow
),
1632 static_cast<SCCOL
>(aDataArea
.EndColumn
), static_cast<SCROW
>(aDataArea
.EndRow
) );
1633 ScDBDocFunc
aFunc(*pDocShell
);
1634 aFunc
.ModifyDBData(aNewData
);
1638 uno::Sequence
<beans::PropertyValue
> SAL_CALL
ScDatabaseRangeObj::getSortDescriptor()
1640 SolarMutexGuard aGuard
;
1642 const ScDBData
* pData
= GetDBData_Impl();
1645 pData
->GetSortParam(aParam
);
1647 // SortDescriptor contains the counted fields inside the area
1649 pData
->GetArea(aDBRange
);
1650 SCCOLROW nFieldStart
= aParam
.bByRow
? static_cast<SCCOLROW
>(aDBRange
.aStart
.Col()) : static_cast<SCCOLROW
>(aDBRange
.aStart
.Row());
1651 for (sal_uInt16 i
=0; i
<aParam
.GetSortKeyCount(); i
++)
1652 if ( aParam
.maKeyState
[i
].bDoSort
&& aParam
.maKeyState
[i
].nField
>= nFieldStart
)
1653 aParam
.maKeyState
[i
].nField
-= nFieldStart
;
1656 uno::Sequence
<beans::PropertyValue
> aSeq( ScSortDescriptor::GetPropertyCount() );
1657 ScSortDescriptor::FillProperties( aSeq
, aParam
);
1661 void ScDatabaseRangeObj::GetQueryParam(ScQueryParam
& rQueryParam
) const
1663 const ScDBData
* pData
= GetDBData_Impl();
1667 pData
->GetQueryParam(rQueryParam
);
1669 // FilterDescriptor contains the counted fields inside the area
1671 pData
->GetArea(aDBRange
);
1672 SCCOLROW nFieldStart
= rQueryParam
.bByRow
? static_cast<SCCOLROW
>(aDBRange
.aStart
.Col()) : static_cast<SCCOLROW
>(aDBRange
.aStart
.Row());
1673 SCSIZE nCount
= rQueryParam
.GetEntryCount();
1674 for (SCSIZE i
=0; i
<nCount
; i
++)
1676 ScQueryEntry
& rEntry
= rQueryParam
.GetEntry(i
);
1677 if (rEntry
.bDoQuery
&& rEntry
.nField
>= nFieldStart
)
1678 rEntry
.nField
-= nFieldStart
;
1682 void ScDatabaseRangeObj::SetQueryParam(const ScQueryParam
& rQueryParam
)
1684 const ScDBData
* pData
= GetDBData_Impl();
1688 // FilterDescriptor contains the counted fields inside the area
1689 ScQueryParam
aParam(rQueryParam
);
1691 pData
->GetArea(aDBRange
);
1692 SCCOLROW nFieldStart
= aParam
.bByRow
? static_cast<SCCOLROW
>(aDBRange
.aStart
.Col()) : static_cast<SCCOLROW
>(aDBRange
.aStart
.Row());
1694 SCSIZE nCount
= aParam
.GetEntryCount();
1695 for (SCSIZE i
=0; i
<nCount
; i
++)
1697 ScQueryEntry
& rEntry
= aParam
.GetEntry(i
);
1698 if (rEntry
.bDoQuery
)
1699 rEntry
.nField
+= nFieldStart
;
1702 ScDBData
aNewData( *pData
);
1703 aNewData
.SetQueryParam(aParam
);
1704 aNewData
.SetHeader(aParam
.bHasHeader
); // not in ScDBData::SetQueryParam
1705 aNewData
.SetTotals(aParam
.bHasTotals
); // not in ScDBData::SetQueryParam
1706 ScDBDocFunc
aFunc(*pDocShell
);
1707 aFunc
.ModifyDBData(aNewData
);
1710 uno::Reference
<sheet::XSheetFilterDescriptor
> SAL_CALL
ScDatabaseRangeObj::getFilterDescriptor()
1712 SolarMutexGuard aGuard
;
1713 return new ScRangeFilterDescriptor(pDocShell
, this);
1716 void ScDatabaseRangeObj::GetSubTotalParam(ScSubTotalParam
& rSubTotalParam
) const
1718 const ScDBData
* pData
= GetDBData_Impl();
1722 pData
->GetSubTotalParam(rSubTotalParam
);
1724 // FilterDescriptor contains the counted fields inside the area
1726 pData
->GetArea(aDBRange
);
1727 SCCOL nFieldStart
= aDBRange
.aStart
.Col();
1728 for (auto& group
: rSubTotalParam
.aGroups
)
1732 if (group
.nField
>= nFieldStart
)
1733 group
.nField
-= nFieldStart
;
1734 for (SCCOL j
= 0; j
< group
.nSubTotals
; j
++)
1735 if (group
.col(j
) >= nFieldStart
)
1736 group
.col(j
) -= nFieldStart
;
1741 void ScDatabaseRangeObj::SetSubTotalParam(const ScSubTotalParam
& rSubTotalParam
)
1743 const ScDBData
* pData
= GetDBData_Impl();
1747 // FilterDescriptor contains the counted fields inside the area
1748 ScSubTotalParam
aParam(rSubTotalParam
);
1750 pData
->GetArea(aDBRange
);
1751 SCCOL nFieldStart
= aDBRange
.aStart
.Col();
1752 for (auto& group
: aParam
.aGroups
)
1756 group
.nField
+= nFieldStart
;
1757 for (SCCOL j
= 0; j
< group
.nSubTotals
; j
++)
1758 group
.col(j
) += nFieldStart
;
1762 ScDBData
aNewData( *pData
);
1763 aNewData
.SetSubTotalParam(aParam
);
1764 ScDBDocFunc
aFunc(*pDocShell
);
1765 aFunc
.ModifyDBData(aNewData
);
1768 uno::Reference
<sheet::XSubTotalDescriptor
> SAL_CALL
ScDatabaseRangeObj::getSubTotalDescriptor()
1770 SolarMutexGuard aGuard
;
1771 return new ScRangeSubTotalDescriptor(this);
1774 uno::Sequence
<beans::PropertyValue
> SAL_CALL
ScDatabaseRangeObj::getImportDescriptor()
1776 SolarMutexGuard aGuard
;
1777 ScImportParam aParam
;
1778 const ScDBData
* pData
= GetDBData_Impl();
1780 pData
->GetImportParam(aParam
);
1782 uno::Sequence
<beans::PropertyValue
> aSeq( ScImportDescriptor::GetPropertyCount() );
1783 ScImportDescriptor::FillProperties( aSeq
, aParam
);
1789 void SAL_CALL
ScDatabaseRangeObj::refresh()
1791 SolarMutexGuard aGuard
;
1792 ScDBData
* pData
= GetDBData_Impl();
1793 if ( !(pDocShell
&& pData
) )
1796 ScDBDocFunc
aFunc(*pDocShell
);
1799 bool bContinue
= true;
1800 ScImportParam aImportParam
;
1801 pData
->GetImportParam( aImportParam
);
1802 if (aImportParam
.bImport
&& !pData
->HasImportSelection())
1807 pData
->GetArea( nTab
, nDummyCol
,nDummyRow
,nDummyCol
,nDummyRow
);
1808 bContinue
= aFunc
.DoImport( nTab
, aImportParam
, nullptr ); //! Api-Flag as parameter
1811 // if no error then internal operations (sort, query, subtotal)
1813 aFunc
.RepeatDB( pData
->GetName(), true, bIsUnnamed
, aTab
);
1816 void SAL_CALL
ScDatabaseRangeObj::addRefreshListener(
1817 const uno::Reference
<util::XRefreshListener
>& xListener
)
1819 SolarMutexGuard aGuard
;
1820 aRefreshListeners
.emplace_back( xListener
);
1822 // hold one additional ref to keep this object alive as long as there are listeners
1823 if ( aRefreshListeners
.size() == 1 )
1827 void SAL_CALL
ScDatabaseRangeObj::removeRefreshListener(
1828 const uno::Reference
<util::XRefreshListener
>& xListener
)
1830 SolarMutexGuard aGuard
;
1831 sal_uInt16 nCount
= aRefreshListeners
.size();
1832 for ( sal_uInt16 n
=nCount
; n
--; )
1834 uno::Reference
<util::XRefreshListener
>& rObj
= aRefreshListeners
[n
];
1835 if ( rObj
== xListener
)
1837 aRefreshListeners
.erase( aRefreshListeners
.begin() + n
);
1838 if ( aRefreshListeners
.empty() )
1839 release(); // release ref for listeners
1845 void ScDatabaseRangeObj::Refreshed_Impl()
1847 lang::EventObject aEvent
;
1848 aEvent
.Source
= getXWeak();
1849 for (uno::Reference
<util::XRefreshListener
> & xRefreshListener
: aRefreshListeners
)
1850 xRefreshListener
->refreshed( aEvent
);
1855 uno::Reference
<table::XCellRange
> SAL_CALL
ScDatabaseRangeObj::getReferredCells()
1857 SolarMutexGuard aGuard
;
1858 ScDBData
* pData
= GetDBData_Impl();
1861 //! static function to create ScCellObj/ScCellRange on ScCellRangeObj ???
1864 pData
->GetArea(aRange
);
1865 if ( aRange
.aStart
== aRange
.aEnd
)
1866 return new ScCellObj( pDocShell
, aRange
.aStart
);
1868 return new ScCellRangeObj( pDocShell
, aRange
);
1875 uno::Reference
<beans::XPropertySetInfo
> SAL_CALL
ScDatabaseRangeObj::getPropertySetInfo()
1877 SolarMutexGuard aGuard
;
1878 static uno::Reference
<beans::XPropertySetInfo
> aRef(
1879 new SfxItemPropertySetInfo( aPropSet
.getPropertyMap() ));
1883 void SAL_CALL
ScDatabaseRangeObj::setPropertyValue(
1884 const OUString
& aPropertyName
, const uno::Any
& aValue
)
1886 SolarMutexGuard aGuard
;
1887 ScDBData
* pData
= GetDBData_Impl();
1888 if ( !(pDocShell
&& pData
) )
1891 ScDBData
aNewData( *pData
);
1894 if ( aPropertyName
== SC_UNONAME_KEEPFORM
)
1895 aNewData
.SetKeepFmt( ScUnoHelpFunctions::GetBoolFromAny( aValue
) );
1896 else if ( aPropertyName
== SC_UNONAME_MOVCELLS
)
1897 aNewData
.SetDoSize( ScUnoHelpFunctions::GetBoolFromAny( aValue
) );
1898 else if ( aPropertyName
== SC_UNONAME_STRIPDAT
)
1899 aNewData
.SetStripData( ScUnoHelpFunctions::GetBoolFromAny( aValue
) );
1900 else if (aPropertyName
== SC_UNONAME_AUTOFLT
)
1902 bool bAutoFilter(ScUnoHelpFunctions::GetBoolFromAny( aValue
));
1903 aNewData
.SetAutoFilter(bAutoFilter
);
1905 aNewData
.GetArea(aRange
);
1906 ScDocument
& rDoc
= pDocShell
->GetDocument();
1908 rDoc
.ApplyFlagsTab( aRange
.aStart
.Col(), aRange
.aStart
.Row(),
1909 aRange
.aEnd
.Col(), aRange
.aStart
.Row(),
1910 aRange
.aStart
.Tab(), ScMF::Auto
);
1911 else if (!bAutoFilter
)
1912 rDoc
.RemoveFlagsTab(aRange
.aStart
.Col(), aRange
.aStart
.Row(),
1913 aRange
.aEnd
.Col(), aRange
.aStart
.Row(),
1914 aRange
.aStart
.Tab(), ScMF::Auto
);
1915 ScRange
aPaintRange(aRange
.aStart
, aRange
.aEnd
);
1916 aPaintRange
.aEnd
.SetRow(aPaintRange
.aStart
.Row());
1917 pDocShell
->PostPaint(aPaintRange
, PaintPartFlags::Grid
);
1919 else if (aPropertyName
== SC_UNONAME_USEFLTCRT
)
1921 if (ScUnoHelpFunctions::GetBoolFromAny( aValue
))
1923 // only here to set bIsAdvanced in ScDBData
1925 (void)aNewData
.GetAdvancedQuerySource(aRange
);
1926 aNewData
.SetAdvancedQuerySource(&aRange
);
1929 aNewData
.SetAdvancedQuerySource(nullptr);
1931 else if (aPropertyName
== SC_UNONAME_FLTCRT
)
1933 table::CellRangeAddress aRange
;
1934 if (aValue
>>= aRange
)
1937 ScUnoConversion::FillScRange(aCoreRange
, aRange
);
1939 aNewData
.SetAdvancedQuerySource(&aCoreRange
);
1942 else if (aPropertyName
== SC_UNONAME_FROMSELECT
)
1944 aNewData
.SetImportSelection(::cppu::any2bool(aValue
));
1946 else if (aPropertyName
== SC_UNONAME_REFPERIOD
)
1948 sal_Int32 nRefresh
= 0;
1949 if (aValue
>>= nRefresh
)
1951 ScDocument
& rDoc
= pDocShell
->GetDocument();
1952 aNewData
.SetRefreshDelay(nRefresh
);
1953 if (rDoc
.GetDBCollection())
1955 aNewData
.SetRefreshHandler( rDoc
.GetDBCollection()->GetRefreshHandler() );
1956 aNewData
.SetRefreshControl( &rDoc
.GetRefreshTimerControlAddress() );
1960 else if (aPropertyName
== SC_UNONAME_CONRES
)
1963 else if ( aPropertyName
== SC_UNONAME_TOTALSROW
)
1964 aNewData
.SetTotals( ScUnoHelpFunctions::GetBoolFromAny( aValue
) );
1965 else if ( aPropertyName
== SC_UNONAME_CONTHDR
)
1966 aNewData
.SetHeader( ScUnoHelpFunctions::GetBoolFromAny( aValue
) );
1972 ScDBDocFunc
aFunc(*pDocShell
);
1973 aFunc
.ModifyDBData(aNewData
);
1977 uno::Any SAL_CALL
ScDatabaseRangeObj::getPropertyValue( const OUString
& aPropertyName
)
1979 SolarMutexGuard aGuard
;
1981 ScDBData
* pData
= GetDBData_Impl();
1984 if ( aPropertyName
== SC_UNONAME_KEEPFORM
)
1985 aRet
<<= pData
->IsKeepFmt();
1986 else if ( aPropertyName
== SC_UNONAME_MOVCELLS
)
1987 aRet
<<= pData
->IsDoSize();
1988 else if ( aPropertyName
== SC_UNONAME_STRIPDAT
)
1989 aRet
<<= pData
->IsStripData();
1990 else if ( aPropertyName
== SC_UNONAME_ISUSER
)
1992 // all database ranges except "unnamed" are user defined
1993 aRet
<<= (pData
->GetName() != STR_DB_LOCAL_NONAME
);
1995 else if ( aPropertyName
== SC_UNO_LINKDISPBIT
)
1997 // no target bitmaps for individual entries (would be all equal)
1998 // ScLinkTargetTypeObj::SetLinkTargetBitmap( aRet, SC_LINKTARGETTYPE_DBAREA );
2000 else if ( aPropertyName
== SC_UNO_LINKDISPNAME
)
2002 else if (aPropertyName
== SC_UNONAME_AUTOFLT
)
2004 bool bAutoFilter(GetDBData_Impl()->HasAutoFilter());
2006 aRet
<<= bAutoFilter
;
2008 else if (aPropertyName
== SC_UNONAME_USEFLTCRT
)
2011 bool bIsAdvancedSource(GetDBData_Impl()->GetAdvancedQuerySource(aRange
));
2013 aRet
<<= bIsAdvancedSource
;
2015 else if (aPropertyName
== SC_UNONAME_FLTCRT
)
2017 table::CellRangeAddress aRange
;
2019 if (GetDBData_Impl()->GetAdvancedQuerySource(aCoreRange
))
2020 ScUnoConversion::FillApiRange(aRange
, aCoreRange
);
2024 else if (aPropertyName
== SC_UNONAME_FROMSELECT
)
2026 aRet
<<= GetDBData_Impl()->HasImportSelection();
2028 else if (aPropertyName
== SC_UNONAME_REFPERIOD
)
2030 sal_Int32
nRefresh(GetDBData_Impl()->GetRefreshDelaySeconds());
2033 else if (aPropertyName
== SC_UNONAME_CONRES
)
2036 else if (aPropertyName
== SC_UNONAME_TOKENINDEX
)
2038 // get index for use in formula tokens (read-only)
2039 aRet
<<= static_cast<sal_Int32
>(GetDBData_Impl()->GetIndex());
2041 else if (aPropertyName
== SC_UNONAME_TOTALSROW
)
2043 bool bTotals(GetDBData_Impl()->HasTotals());
2047 else if (aPropertyName
== SC_UNONAME_CONTHDR
)
2049 bool bHeader(GetDBData_Impl()->HasHeader());
2057 SC_IMPL_DUMMY_PROPERTY_LISTENER( ScDatabaseRangeObj
)
2060 OUString SAL_CALL
ScDatabaseRangeObj::getImplementationName()
2062 return u
"ScDatabaseRangeObj"_ustr
;
2065 sal_Bool SAL_CALL
ScDatabaseRangeObj::supportsService( const OUString
& rServiceName
)
2067 return cppu::supportsService(this, rServiceName
);
2070 uno::Sequence
<OUString
> SAL_CALL
ScDatabaseRangeObj::getSupportedServiceNames()
2072 return {u
"com.sun.star.sheet.DatabaseRange"_ustr
,
2073 SCLINKTARGET_SERVICE
};
2076 ScDatabaseRangesObj::ScDatabaseRangesObj(ScDocShell
* pDocSh
) :
2079 pDocShell
->GetDocument().AddUnoObject(*this);
2082 ScDatabaseRangesObj::~ScDatabaseRangesObj()
2087 pDocShell
->GetDocument().RemoveUnoObject(*this);
2090 void ScDatabaseRangesObj::Notify( SfxBroadcaster
&, const SfxHint
& rHint
)
2092 // reference update does not matter here
2094 if ( rHint
.GetId() == SfxHintId::Dying
)
2096 pDocShell
= nullptr;
2102 rtl::Reference
<ScDatabaseRangeObj
> ScDatabaseRangesObj::GetObjectByIndex_Impl(size_t nIndex
)
2107 ScDBCollection
* pNames
= pDocShell
->GetDocument().GetDBCollection();
2111 const ScDBCollection::NamedDBs
& rDBs
= pNames
->getNamedDBs();
2112 if (rDBs
.empty() || nIndex
>= rDBs
.size())
2115 ScDBCollection::NamedDBs::const_iterator itr
= rDBs
.begin();
2116 ::std::advance(itr
, nIndex
); // boundary check is done above.
2117 return new ScDatabaseRangeObj(pDocShell
, (*itr
)->GetName());
2120 rtl::Reference
<ScDatabaseRangeObj
> ScDatabaseRangesObj::GetObjectByName_Impl(const OUString
& aName
)
2122 if ( pDocShell
&& hasByName(aName
) )
2124 return new ScDatabaseRangeObj( pDocShell
, aName
);
2129 void SAL_CALL
ScDatabaseRangesObj::addNewByName( const OUString
& aName
,
2130 const table::CellRangeAddress
& aRange
)
2132 SolarMutexGuard aGuard
;
2136 ScDBDocFunc
aFunc(*pDocShell
);
2138 ScRange
aNameRange( static_cast<SCCOL
>(aRange
.StartColumn
), static_cast<SCROW
>(aRange
.StartRow
), aRange
.Sheet
,
2139 static_cast<SCCOL
>(aRange
.EndColumn
), static_cast<SCROW
>(aRange
.EndRow
), aRange
.Sheet
);
2140 bDone
= aFunc
.AddDBRange( aName
, aNameRange
);
2143 throw uno::RuntimeException(); // no other exceptions specified
2146 void SAL_CALL
ScDatabaseRangesObj::removeByName( const OUString
& aName
)
2148 SolarMutexGuard aGuard
;
2152 ScDBDocFunc
aFunc(*pDocShell
);
2153 bDone
= aFunc
.DeleteDBRange( aName
);
2156 throw uno::RuntimeException(); // no other exceptions specified
2159 // XEnumerationAccess
2161 uno::Reference
<container::XEnumeration
> SAL_CALL
ScDatabaseRangesObj::createEnumeration()
2163 SolarMutexGuard aGuard
;
2164 return new ScIndexEnumeration(this, u
"com.sun.star.sheet.DatabaseRangesEnumeration"_ustr
);
2169 sal_Int32 SAL_CALL
ScDatabaseRangesObj::getCount()
2171 SolarMutexGuard aGuard
;
2173 //! need to omit "unnamed"?
2177 ScDBCollection
* pNames
= pDocShell
->GetDocument().GetDBCollection();
2179 return static_cast<sal_Int32
>(pNames
->getNamedDBs().size());
2184 uno::Any SAL_CALL
ScDatabaseRangesObj::getByIndex( sal_Int32 nIndex
)
2186 SolarMutexGuard aGuard
;
2188 throw lang::IndexOutOfBoundsException();
2190 uno::Reference
<sheet::XDatabaseRange
> xRange(GetObjectByIndex_Impl(static_cast<size_t>(nIndex
)));
2192 throw lang::IndexOutOfBoundsException();
2194 return uno::Any(xRange
);
2197 uno::Type SAL_CALL
ScDatabaseRangesObj::getElementType()
2199 return cppu::UnoType
<sheet::XDatabaseRange
>::get();
2202 sal_Bool SAL_CALL
ScDatabaseRangesObj::hasElements()
2204 SolarMutexGuard aGuard
;
2205 return ( getCount() != 0 );
2210 uno::Any SAL_CALL
ScDatabaseRangesObj::getByName( const OUString
& aName
)
2212 SolarMutexGuard aGuard
;
2213 uno::Reference
<sheet::XDatabaseRange
> xRange(GetObjectByName_Impl(aName
));
2215 throw container::NoSuchElementException();
2217 return uno::Any(xRange
);
2220 uno::Sequence
<OUString
> SAL_CALL
ScDatabaseRangesObj::getElementNames()
2222 SolarMutexGuard aGuard
;
2224 //! need to omit "unnamed"?
2228 ScDBCollection
* pNames
= pDocShell
->GetDocument().GetDBCollection();
2231 const ScDBCollection::NamedDBs
& rDBs
= pNames
->getNamedDBs();
2232 uno::Sequence
<OUString
> aSeq(rDBs
.size());
2233 auto aSeqRange
= asNonConstRange(aSeq
);
2235 for (const auto& rDB
: rDBs
)
2237 aSeqRange
[i
] = rDB
->GetName();
2247 sal_Bool SAL_CALL
ScDatabaseRangesObj::hasByName( const OUString
& aName
)
2249 SolarMutexGuard aGuard
;
2251 //! need to omit "unnamed"?
2255 ScDBCollection
* pNames
= pDocShell
->GetDocument().GetDBCollection();
2257 return pNames
->getNamedDBs().findByUpperName(ScGlobal::getCharClass().uppercase(aName
)) != nullptr;
2262 ScUnnamedDatabaseRangesObj::ScUnnamedDatabaseRangesObj(ScDocShell
* pDocSh
) :
2265 pDocShell
->GetDocument().AddUnoObject(*this);
2268 ScUnnamedDatabaseRangesObj::~ScUnnamedDatabaseRangesObj()
2273 pDocShell
->GetDocument().RemoveUnoObject(*this);
2276 void ScUnnamedDatabaseRangesObj::Notify( SfxBroadcaster
&, const SfxHint
& rHint
)
2278 // reference update does not matter here
2280 if ( rHint
.GetId() == SfxHintId::Dying
)
2282 pDocShell
= nullptr;
2286 // XUnnamedDatabaseRanges
2288 void ScUnnamedDatabaseRangesObj::setByTable( const table::CellRangeAddress
& aRange
)
2290 SolarMutexGuard aGuard
;
2294 if ( pDocShell
->GetDocument().GetTableCount() <= aRange
.Sheet
)
2295 throw lang::IndexOutOfBoundsException();
2297 ScDBDocFunc
aFunc(*pDocShell
);
2298 ScRange
aUnnamedRange( static_cast<SCCOL
>(aRange
.StartColumn
), static_cast<SCROW
>(aRange
.StartRow
), aRange
.Sheet
,
2299 static_cast<SCCOL
>(aRange
.EndColumn
), static_cast<SCROW
>(aRange
.EndRow
), aRange
.Sheet
);
2300 bDone
= aFunc
.AddDBRange( STR_DB_LOCAL_NONAME
, aUnnamedRange
);
2303 throw uno::RuntimeException(); // no other exceptions specified
2306 uno::Any
ScUnnamedDatabaseRangesObj::getByTable( sal_Int32 nTab
)
2308 SolarMutexGuard aGuard
;
2310 throw uno::RuntimeException();
2312 if ( pDocShell
->GetDocument().GetTableCount() <= nTab
)
2313 throw lang::IndexOutOfBoundsException();
2314 uno::Reference
<sheet::XDatabaseRange
> xRange(
2315 new ScDatabaseRangeObj(pDocShell
, static_cast<SCTAB
>(nTab
)));
2317 throw container::NoSuchElementException();
2319 return uno::Any(xRange
);
2322 sal_Bool
ScUnnamedDatabaseRangesObj::hasByTable( sal_Int32 nTab
)
2324 SolarMutexGuard aGuard
;
2327 if (pDocShell
->GetDocument().GetTableCount() <= nTab
)
2328 throw lang::IndexOutOfBoundsException();
2329 if (pDocShell
->GetDocument().GetAnonymousDBData(static_cast<SCTAB
>(nTab
)))
2337 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */