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