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