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