xref: /aoo42x/main/sc/source/core/tool/dbcolect.cxx (revision b3f79822)
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 #include <tools/debug.hxx>
29 #include <unotools/transliterationwrapper.hxx>
30 
31 #include "dbcolect.hxx"
32 #include "global.hxx"
33 #include "refupdat.hxx"
34 #include "rechead.hxx"
35 #include "document.hxx"
36 #include "queryparam.hxx"
37 #include "globstr.hrc"
38 
39 
40 //---------------------------------------------------------------------------------------
41 
42 ScDBData::ScDBData( const String& rName,
43 					SCTAB nTab,
44 					SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
45 					sal_Bool bByR, sal_Bool bHasH) :
46 	aName		(rName),
47 	nTable		(nTab),
48 	nStartCol	(nCol1),
49 	nStartRow	(nRow1),
50 	nEndCol		(nCol2),
51 	nEndRow		(nRow2),
52 	bByRow		(bByR),
53 	bHasHeader	(bHasH),
54 	bDoSize		(sal_False),
55 	bKeepFmt	(sal_False),
56 	bStripData	(sal_False),
57 	bIsAdvanced	(sal_False),
58 	bDBSelection(sal_False),
59 	nIndex 		(0),
60 	bAutoFilter (sal_False),
61 	bModified	(sal_False)
62 {
63 	sal_uInt16 i;
64 
65 	ScSortParam aSortParam;
66 	ScQueryParam aQueryParam;
67 	ScSubTotalParam aSubTotalParam;
68 	ScImportParam aImportParam;
69 
70 	for (i=0; i<MAXQUERY; i++)
71 		pQueryStr[i] = new String;
72 
73 	for (i=0; i<MAXSUBTOTAL; i++)
74 	{
75 		nSubTotals[i] = 0;
76 		pSubTotals[i] = NULL;
77 		pFunctions[i] = NULL;
78 	}
79 
80 	SetSortParam( aSortParam );
81 	SetQueryParam( aQueryParam );
82 	SetSubTotalParam( aSubTotalParam );
83 	SetImportParam( aImportParam );
84 }
85 
86 ScDBData::ScDBData( const ScDBData& rData ) :
87     ScDataObject(),
88 	ScRefreshTimer		( rData ),
89 	aName				(rData.aName),
90 	nTable				(rData.nTable),
91 	nStartCol			(rData.nStartCol),
92 	nStartRow			(rData.nStartRow),
93 	nEndCol				(rData.nEndCol),
94 	nEndRow				(rData.nEndRow),
95 	bByRow				(rData.bByRow),
96 	bHasHeader			(rData.bHasHeader),
97 	bDoSize				(rData.bDoSize),
98 	bKeepFmt			(rData.bKeepFmt),
99 	bStripData			(rData.bStripData),
100 	bSortCaseSens   	(rData.bSortCaseSens),
101 	bIncludePattern 	(rData.bIncludePattern),
102 	bSortInplace		(rData.bSortInplace),
103 	bSortUserDef		(rData.bSortUserDef),
104 	nSortUserIndex		(rData.nSortUserIndex),
105 	nSortDestTab		(rData.nSortDestTab),
106 	nSortDestCol		(rData.nSortDestCol),
107 	nSortDestRow		(rData.nSortDestRow),
108 	aSortLocale			(rData.aSortLocale),
109 	aSortAlgorithm		(rData.aSortAlgorithm),
110 	bQueryInplace   	(rData.bQueryInplace),
111 	bQueryCaseSens  	(rData.bQueryCaseSens),
112 	bQueryRegExp		(rData.bQueryRegExp),
113 	bQueryDuplicate		(rData.bQueryDuplicate),
114 	nQueryDestTab   	(rData.nQueryDestTab),
115 	nQueryDestCol	  	(rData.nQueryDestCol),
116 	nQueryDestRow  		(rData.nQueryDestRow),
117 	bIsAdvanced			(rData.bIsAdvanced),
118 	aAdvSource			(rData.aAdvSource),
119 	bSubRemoveOnly		(rData.bSubRemoveOnly),
120 	bSubReplace			(rData.bSubReplace),
121 	bSubPagebreak		(rData.bSubPagebreak),
122 	bSubCaseSens		(rData.bSubCaseSens),
123 	bSubDoSort			(rData.bSubDoSort),
124 	bSubAscending		(rData.bSubAscending),
125 	bSubIncludePattern	(rData.bSubIncludePattern),
126 	bSubUserDef			(rData.bSubUserDef),
127 	nSubUserIndex		(rData.nSubUserIndex),
128 	bDBImport			(rData.bDBImport),
129 	aDBName				(rData.aDBName),
130 	aDBStatement		(rData.aDBStatement),
131 	bDBNative			(rData.bDBNative),
132 	bDBSelection		(rData.bDBSelection),
133 	bDBSql				(rData.bDBSql),
134 	nDBType				(rData.nDBType),
135 	nIndex   			(rData.nIndex),
136 	bAutoFilter			(rData.bAutoFilter),
137 	bModified			(rData.bModified)
138 {
139 	sal_uInt16 i;
140 	sal_uInt16 j;
141 
142 	for (i=0; i<MAXSORT; i++)
143 	{
144 		bDoSort[i]		= rData.bDoSort[i];
145 		nSortField[i]	= rData.nSortField[i];
146 		bAscending[i]	= rData.bAscending[i];
147 	}
148 	for (i=0; i<MAXQUERY; i++)
149 	{
150 		bDoQuery[i]			= rData.bDoQuery[i];
151 		nQueryField[i]		= rData.nQueryField[i];
152 		eQueryOp[i]			= rData.eQueryOp[i];
153 		bQueryByString[i]	= rData.bQueryByString[i];
154         bQueryByDate[i]     = rData.bQueryByDate[i];
155 		pQueryStr[i]		= new String( *(rData.pQueryStr[i]) );
156 		nQueryVal[i]		= rData.nQueryVal[i];
157 		eQueryConnect[i]	= rData.eQueryConnect[i];
158 	}
159 	for (i=0; i<MAXSUBTOTAL; i++)
160 	{
161 		bDoSubTotal[i]		= rData.bDoSubTotal[i];
162 		nSubField[i]		= rData.nSubField[i];
163 
164 		SCCOL nCount	= rData.nSubTotals[i];
165 		nSubTotals[i]	= nCount;
166 		pFunctions[i]	= nCount > 0 ? new ScSubTotalFunc [nCount] : NULL;
167 		pSubTotals[i]	= nCount > 0 ? new SCCOL		  [nCount] : NULL;
168 
169 		for (j=0; j<nCount; j++)
170 		{
171 			pSubTotals[i][j] = rData.pSubTotals[i][j];
172 			pFunctions[i][j] = rData.pFunctions[i][j];
173 		}
174 	}
175 }
176 
177 ScDBData& ScDBData::operator= (const ScDBData& rData)
178 {
179 	sal_uInt16 i;
180 	sal_uInt16 j;
181 
182 	ScRefreshTimer::operator=( rData );
183 	aName				= rData.aName;
184 	nTable				= rData.nTable;
185 	nStartCol			= rData.nStartCol;
186 	nStartRow			= rData.nStartRow;
187 	nEndCol				= rData.nEndCol;
188 	nEndRow				= rData.nEndRow;
189 	bByRow				= rData.bByRow;
190 	bHasHeader			= rData.bHasHeader;
191 	bDoSize				= rData.bDoSize;
192 	bKeepFmt			= rData.bKeepFmt;
193 	bStripData			= rData.bStripData;
194 	bSortCaseSens   	= rData.bSortCaseSens;
195 	bIncludePattern 	= rData.bIncludePattern;
196 	bSortInplace		= rData.bSortInplace;
197 	nSortDestTab		= rData.nSortDestTab;
198 	nSortDestCol		= rData.nSortDestCol;
199 	nSortDestRow		= rData.nSortDestRow;
200 	bSortUserDef		= rData.bSortUserDef;
201 	nSortUserIndex		= rData.nSortUserIndex;
202 	aSortLocale			= rData.aSortLocale;
203 	aSortAlgorithm		= rData.aSortAlgorithm;
204 	bQueryInplace   	= rData.bQueryInplace;
205 	bQueryCaseSens  	= rData.bQueryCaseSens;
206 	bQueryRegExp		= rData.bQueryRegExp;
207 	bQueryDuplicate		= rData.bQueryDuplicate;
208 	nQueryDestTab   	= rData.nQueryDestTab;
209 	nQueryDestCol	  	= rData.nQueryDestCol;
210 	nQueryDestRow  		= rData.nQueryDestRow;
211 	bIsAdvanced			= rData.bIsAdvanced;
212 	aAdvSource			= rData.aAdvSource;
213 	bSubRemoveOnly		= rData.bSubRemoveOnly;
214 	bSubReplace			= rData.bSubReplace;
215 	bSubPagebreak		= rData.bSubPagebreak;
216 	bSubCaseSens		= rData.bSubCaseSens;
217 	bSubDoSort			= rData.bSubDoSort;
218 	bSubAscending		= rData.bSubAscending;
219 	bSubIncludePattern	= rData.bSubIncludePattern;
220 	bSubUserDef			= rData.bSubUserDef;
221 	nSubUserIndex		= rData.nSubUserIndex;
222 	bDBImport			= rData.bDBImport;
223 	aDBName				= rData.aDBName;
224 	aDBStatement		= rData.aDBStatement;
225 	bDBNative			= rData.bDBNative;
226 	bDBSelection		= rData.bDBSelection;
227 	bDBSql				= rData.bDBSql;
228 	nDBType				= rData.nDBType;
229 	nIndex   			= rData.nIndex;
230     bAutoFilter         = rData.bAutoFilter;
231 
232 	for (i=0; i<MAXSORT; i++)
233 	{
234 		bDoSort[i]		= rData.bDoSort[i];
235 		nSortField[i]	= rData.nSortField[i];
236 		bAscending[i]	= rData.bAscending[i];
237 	}
238 	for (i=0; i<MAXQUERY; i++)
239 	{
240 		bDoQuery[i]			= rData.bDoQuery[i];
241 		nQueryField[i]		= rData.nQueryField[i];
242 		eQueryOp[i]			= rData.eQueryOp[i];
243 		bQueryByString[i]	= rData.bQueryByString[i];
244         bQueryByDate[i]     = rData.bQueryByDate[i];
245 		*pQueryStr[i]		= *rData.pQueryStr[i];
246 		nQueryVal[i]		= rData.nQueryVal[i];
247 		eQueryConnect[i]	= rData.eQueryConnect[i];
248 	}
249 	for (i=0; i<MAXSUBTOTAL; i++)
250 	{
251 		bDoSubTotal[i]		= rData.bDoSubTotal[i];
252 		nSubField[i]		= rData.nSubField[i];
253 		SCCOL nCount	= rData.nSubTotals[i];
254 		nSubTotals[i]	= nCount;
255 
256 		delete[] pSubTotals[i];
257 		delete[] pFunctions[i];
258 
259 		pSubTotals[i] = nCount > 0 ? new SCCOL			[nCount] : NULL;
260 		pFunctions[i] = nCount > 0 ? new ScSubTotalFunc [nCount] : NULL;
261 		for (j=0; j<nCount; j++)
262 		{
263 			pSubTotals[i][j] = rData.pSubTotals[i][j];
264 			pFunctions[i][j] = rData.pFunctions[i][j];
265 		}
266 	}
267 
268 	return *this;
269 }
270 
271 sal_Bool ScDBData::operator== (const ScDBData& rData) const
272 {
273 	//	Daten, die nicht in den Params sind
274 
275 	if ( nTable		!= rData.nTable		||
276 		 bDoSize	!= rData.bDoSize	||
277 		 bKeepFmt	!= rData.bKeepFmt	||
278 		 bIsAdvanced!= rData.bIsAdvanced||
279 		 bStripData	!= rData.bStripData ||
280 //       SAB: I think this should be here, but I don't want to break something
281 //         bAutoFilter!= rData.bAutoFilter||
282 		 ScRefreshTimer::operator!=( rData )
283 		)
284 		return sal_False;
285 
286 	if ( bIsAdvanced && aAdvSource != rData.aAdvSource )
287 		return sal_False;
288 
289 	ScSortParam aSort1, aSort2;
290 	GetSortParam(aSort1);
291 	rData.GetSortParam(aSort2);
292 	if (!(aSort1 == aSort2))
293 		return sal_False;
294 
295 	ScQueryParam aQuery1, aQuery2;
296 	GetQueryParam(aQuery1);
297 	rData.GetQueryParam(aQuery2);
298 	if (!(aQuery1 == aQuery2))
299 		return sal_False;
300 
301 	ScSubTotalParam aSubTotal1, aSubTotal2;
302 	GetSubTotalParam(aSubTotal1);
303 	rData.GetSubTotalParam(aSubTotal2);
304 	if (!(aSubTotal1 == aSubTotal2))
305 		return sal_False;
306 
307 	ScImportParam aImport1, aImport2;
308 	GetImportParam(aImport1);
309 	rData.GetImportParam(aImport2);
310 	if (!(aImport1 == aImport2))
311 		return sal_False;
312 
313 	return sal_True;
314 }
315 
316 ScDBData::~ScDBData()
317 {
318 	StopRefreshTimer();
319 	sal_uInt16 i;
320 
321 	for (i=0; i<MAXQUERY; i++)
322 		delete pQueryStr[i];
323 	for (i=0; i<MAXSUBTOTAL; i++)
324 	{
325 		delete[] pSubTotals[i];
326 		delete[] pFunctions[i];
327 	}
328 }
329 
330 //UNUSED2008-05  sal_Bool ScDBData::IsBeyond(SCROW nMaxRow) const
331 //UNUSED2008-05  {
332 //UNUSED2008-05      return ( nStartRow > nMaxRow ||
333 //UNUSED2008-05               nEndRow > nMaxRow ||
334 //UNUSED2008-05               nQueryDestRow > nMaxRow );
335 //UNUSED2008-05  }
336 
337 String ScDBData::GetSourceString() const
338 {
339 	String aVal;
340 	if (bDBImport)
341 	{
342 		aVal = aDBName;
343 		aVal += '/';
344 		aVal += aDBStatement;
345 	}
346 	return aVal;
347 }
348 
349 String ScDBData::GetOperations() const
350 {
351 	String aVal;
352 	if (bDoQuery[0])
353 		aVal = ScGlobal::GetRscString(STR_OPERATION_FILTER);
354 
355 	if (bDoSort[0])
356 	{
357 		if (aVal.Len())
358 			aVal.AppendAscii( RTL_CONSTASCII_STRINGPARAM(", ") );
359 		aVal += ScGlobal::GetRscString(STR_OPERATION_SORT);
360 	}
361 
362 	if (bDoSubTotal[0] && !bSubRemoveOnly)
363 	{
364 		if (aVal.Len())
365 			aVal.AppendAscii( RTL_CONSTASCII_STRINGPARAM(", ") );
366 		aVal += ScGlobal::GetRscString(STR_OPERATION_SUBTOTAL);
367 	}
368 
369 	if (!aVal.Len())
370 		aVal = ScGlobal::GetRscString(STR_OPERATION_NONE);
371 
372 	return aVal;
373 }
374 
375 void ScDBData::GetArea(SCTAB& rTab, SCCOL& rCol1, SCROW& rRow1, SCCOL& rCol2, SCROW& rRow2) const
376 {
377 	rTab  = nTable;
378 	rCol1 = nStartCol;
379 	rRow1 = nStartRow;
380 	rCol2 = nEndCol;
381 	rRow2 = nEndRow;
382 }
383 
384 void ScDBData::GetArea(ScRange& rRange) const
385 {
386 	rRange = ScRange( nStartCol,nStartRow,nTable, nEndCol,nEndRow,nTable );
387 }
388 
389 void ScDBData::SetArea(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2)
390 {
391 	nTable	= nTab;
392 	nStartCol = nCol1;
393 	nStartRow = nRow1;
394 	nEndCol   = nCol2;
395 	nEndRow   = nRow2;
396 }
397 
398 void ScDBData::MoveTo(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2)
399 {
400 	sal_uInt16 i;
401 	long nDifX = ((long) nCol1) - ((long) nStartCol);
402 	long nDifY = ((long) nRow1) - ((long) nStartRow);
403 
404 	long nSortDif = bByRow ? nDifX : nDifY;
405 	long nSortEnd = bByRow ? static_cast<long>(nCol2) : static_cast<long>(nRow2);
406 
407 	for (i=0; i<MAXSORT; i++)
408 	{
409 		nSortField[i] += nSortDif;
410 		if (nSortField[i] > nSortEnd)
411 		{
412 			nSortField[i] = 0;
413 			bDoSort[i]	  = sal_False;
414 		}
415 	}
416 	for (i=0; i<MAXQUERY; i++)
417 	{
418 		nQueryField[i] += nDifX;
419 		if (nQueryField[i] > nCol2)
420 		{
421 			nQueryField[i] = 0;
422 			bDoQuery[i]	   = sal_False;
423 		}
424 	}
425 	for (i=0; i<MAXSUBTOTAL; i++)
426 	{
427         nSubField[i] = sal::static_int_cast<SCCOL>( nSubField[i] + nDifX );
428 		if (nSubField[i] > nCol2)
429 		{
430 			nSubField[i]   = 0;
431 			bDoSubTotal[i] = sal_False;
432 		}
433 	}
434 
435 	SetArea( nTab, nCol1, nRow1, nCol2, nRow2 );
436 }
437 
438 void ScDBData::GetSortParam( ScSortParam& rSortParam ) const
439 {
440 	rSortParam.nCol1 = nStartCol;
441 	rSortParam.nRow1 = nStartRow;
442 	rSortParam.nCol2 = nEndCol;
443 	rSortParam.nRow2 = nEndRow;
444 	rSortParam.bByRow = bByRow;
445 	rSortParam.bHasHeader = bHasHeader;
446 	rSortParam.bCaseSens = bSortCaseSens;
447 	rSortParam.bInplace = bSortInplace;
448 	rSortParam.nDestTab = nSortDestTab;
449 	rSortParam.nDestCol = nSortDestCol;
450 	rSortParam.nDestRow = nSortDestRow;
451 	rSortParam.bIncludePattern = bIncludePattern;
452 	rSortParam.bUserDef	= bSortUserDef;
453 	rSortParam.nUserIndex = nSortUserIndex;
454 	for (sal_uInt16 i=0; i<MAXSORT; i++)
455 	{
456 		rSortParam.bDoSort[i] 	 = bDoSort[i];
457 		rSortParam.nField[i] 	 = nSortField[i];
458 		rSortParam.bAscending[i] = bAscending[i];
459 	}
460 	rSortParam.aCollatorLocale = aSortLocale;
461 	rSortParam.aCollatorAlgorithm = aSortAlgorithm;
462 }
463 
464 void ScDBData::SetSortParam( const ScSortParam& rSortParam )
465 {
466 	bSortCaseSens = rSortParam.bCaseSens;
467 	bIncludePattern = rSortParam.bIncludePattern;
468 	bSortInplace = rSortParam.bInplace;
469 	nSortDestTab = rSortParam.nDestTab;
470 	nSortDestCol = rSortParam.nDestCol;
471 	nSortDestRow = rSortParam.nDestRow;
472 	bSortUserDef = rSortParam.bUserDef;
473 	nSortUserIndex = rSortParam.nUserIndex;
474 	for (sal_uInt16 i=0; i<MAXSORT; i++)
475 	{
476 		bDoSort[i]	  = rSortParam.bDoSort[i];
477 		nSortField[i] = rSortParam.nField[i];
478 		bAscending[i] = rSortParam.bAscending[i];
479 	}
480 	aSortLocale = rSortParam.aCollatorLocale;
481 	aSortAlgorithm = rSortParam.aCollatorAlgorithm;
482 
483 	//#98317#; set the orientation
484 	bByRow = rSortParam.bByRow;
485 }
486 
487 void ScDBData::GetQueryParam( ScQueryParam& rQueryParam ) const
488 {
489 	rQueryParam.nCol1 = nStartCol;
490 	rQueryParam.nRow1 = nStartRow;
491 	rQueryParam.nCol2 = nEndCol;
492 	rQueryParam.nRow2 = nEndRow;
493 	rQueryParam.nTab  = nTable;
494 	rQueryParam.bByRow = bByRow;
495 	rQueryParam.bHasHeader = bHasHeader;
496 	rQueryParam.bInplace = bQueryInplace;
497 	rQueryParam.bCaseSens = bQueryCaseSens;
498 	rQueryParam.bRegExp = bQueryRegExp;
499 	rQueryParam.bDuplicate = bQueryDuplicate;
500 	rQueryParam.nDestTab = nQueryDestTab;
501 	rQueryParam.nDestCol = nQueryDestCol;
502 	rQueryParam.nDestRow = nQueryDestRow;
503 
504 	rQueryParam.Resize( MAXQUERY );
505 	for (SCSIZE i=0; i<MAXQUERY; i++)
506 	{
507 		ScQueryEntry& rEntry = rQueryParam.GetEntry(i);
508 
509 		rEntry.bDoQuery = bDoQuery[i];
510 		rEntry.nField = nQueryField[i];
511 		rEntry.eOp = eQueryOp[i];
512 		rEntry.bQueryByString = bQueryByString[i];
513         rEntry.bQueryByDate = bQueryByDate[i];
514 		*rEntry.pStr = *pQueryStr[i];
515 		rEntry.nVal = nQueryVal[i];
516 		rEntry.eConnect = eQueryConnect[i];
517 	}
518 }
519 
520 void ScDBData::SetQueryParam(const ScQueryParam& rQueryParam)
521 {
522 	DBG_ASSERT( rQueryParam.GetEntryCount() <= MAXQUERY ||
523 				!rQueryParam.GetEntry(MAXQUERY).bDoQuery,
524 				"zuviele Eintraege bei ScDBData::SetQueryParam" );
525 
526 	//	set bIsAdvanced to sal_False for everything that is not from the
527 	//	advanced filter dialog
528 	bIsAdvanced = sal_False;
529 
530 	bQueryInplace = rQueryParam.bInplace;
531 	bQueryCaseSens = rQueryParam.bCaseSens;
532 	bQueryRegExp = rQueryParam.bRegExp;
533 	bQueryDuplicate = rQueryParam.bDuplicate;
534 	nQueryDestTab = rQueryParam.nDestTab;
535 	nQueryDestCol = rQueryParam.nDestCol;
536 	nQueryDestRow = rQueryParam.nDestRow;
537 	for (SCSIZE i=0; i<MAXQUERY; i++)
538 	{
539 		ScQueryEntry& rEntry = rQueryParam.GetEntry(i);
540 
541 		bDoQuery[i] = rEntry.bDoQuery;
542 		nQueryField[i] = rEntry.nField;
543 		eQueryOp[i] = rEntry.eOp;
544 		bQueryByString[i] = rEntry.bQueryByString;
545         bQueryByDate[i] = rEntry.bQueryByDate;
546 		*pQueryStr[i] = *rEntry.pStr;
547 		nQueryVal[i] = rEntry.nVal;
548 		eQueryConnect[i] = rEntry.eConnect;
549 	}
550 }
551 
552 void ScDBData::SetAdvancedQuerySource(const ScRange* pSource)
553 {
554 	if (pSource)
555 	{
556 		aAdvSource = *pSource;
557 		bIsAdvanced = sal_True;
558 	}
559 	else
560 		bIsAdvanced = sal_False;
561 }
562 
563 sal_Bool ScDBData::GetAdvancedQuerySource(ScRange& rSource) const
564 {
565 	rSource = aAdvSource;
566 	return bIsAdvanced;
567 }
568 
569 void ScDBData::GetSubTotalParam(ScSubTotalParam& rSubTotalParam) const
570 {
571 	sal_uInt16 i;
572 	sal_uInt16 j;
573 
574 	rSubTotalParam.nCol1 = nStartCol;
575 	rSubTotalParam.nRow1 = nStartRow;
576 	rSubTotalParam.nCol2 = nEndCol;
577 	rSubTotalParam.nRow2 = nEndRow;
578 
579 	rSubTotalParam.bRemoveOnly		= bSubRemoveOnly;
580 	rSubTotalParam.bReplace			= bSubReplace;
581 	rSubTotalParam.bPagebreak		= bSubPagebreak;
582 	rSubTotalParam.bCaseSens		= bSubCaseSens;
583 	rSubTotalParam.bDoSort			= bSubDoSort;
584 	rSubTotalParam.bAscending		= bSubAscending;
585 	rSubTotalParam.bIncludePattern	= bSubIncludePattern;
586 	rSubTotalParam.bUserDef			= bSubUserDef;
587 	rSubTotalParam.nUserIndex		= nSubUserIndex;
588 
589 	for (i=0; i<MAXSUBTOTAL; i++)
590 	{
591 		rSubTotalParam.bGroupActive[i]	= bDoSubTotal[i];
592 		rSubTotalParam.nField[i]		= nSubField[i];
593 		SCCOL nCount = nSubTotals[i];
594 
595 		rSubTotalParam.nSubTotals[i] = nCount;
596 		delete[] rSubTotalParam.pSubTotals[i];
597 		delete[] rSubTotalParam.pFunctions[i];
598 		rSubTotalParam.pSubTotals[i] = nCount > 0 ? new SCCOL[nCount] : NULL;
599 		rSubTotalParam.pFunctions[i] = nCount > 0 ? new ScSubTotalFunc[nCount]
600 											  : NULL;
601 		for (j=0; j<nCount; j++)
602 		{
603 			rSubTotalParam.pSubTotals[i][j] = pSubTotals[i][j];
604 			rSubTotalParam.pFunctions[i][j] = pFunctions[i][j];
605 		}
606 	}
607 }
608 
609 void ScDBData::SetSubTotalParam(const ScSubTotalParam& rSubTotalParam)
610 {
611 	sal_uInt16 i;
612 	sal_uInt16 j;
613 
614 	bSubRemoveOnly		= rSubTotalParam.bRemoveOnly;
615 	bSubReplace			= rSubTotalParam.bReplace;
616 	bSubPagebreak		= rSubTotalParam.bPagebreak;
617 	bSubCaseSens		= rSubTotalParam.bCaseSens;
618 	bSubDoSort			= rSubTotalParam.bDoSort;
619 	bSubAscending		= rSubTotalParam.bAscending;
620 	bSubIncludePattern	= rSubTotalParam.bIncludePattern;
621 	bSubUserDef			= rSubTotalParam.bUserDef;
622 	nSubUserIndex		= rSubTotalParam.nUserIndex;
623 
624 	for (i=0; i<MAXSUBTOTAL; i++)
625 	{
626 		bDoSubTotal[i]	= rSubTotalParam.bGroupActive[i];
627 		nSubField[i]	= rSubTotalParam.nField[i];
628 		SCCOL nCount = rSubTotalParam.nSubTotals[i];
629 
630 		nSubTotals[i] = nCount;
631 		delete[] pSubTotals[i];
632 		delete[] pFunctions[i];
633 		pSubTotals[i] = nCount > 0 ? new SCCOL			[nCount] : NULL;
634 		pFunctions[i] = nCount > 0 ? new ScSubTotalFunc [nCount] : NULL;
635 		for (j=0; j<nCount; j++)
636 		{
637 			pSubTotals[i][j] = rSubTotalParam.pSubTotals[i][j];
638 			pFunctions[i][j] = rSubTotalParam.pFunctions[i][j];
639 		}
640 	}
641 }
642 
643 void ScDBData::GetImportParam(ScImportParam& rImportParam) const
644 {
645 	rImportParam.nCol1 = nStartCol;
646 	rImportParam.nRow1 = nStartRow;
647 	rImportParam.nCol2 = nEndCol;
648 	rImportParam.nRow2 = nEndRow;
649 
650 	rImportParam.bImport	= bDBImport;
651 	rImportParam.aDBName	= aDBName;
652 	rImportParam.aStatement	= aDBStatement;
653 	rImportParam.bNative	= bDBNative;
654 	rImportParam.bSql		= bDBSql;
655 	rImportParam.nType		= nDBType;
656 }
657 
658 void ScDBData::SetImportParam(const ScImportParam& rImportParam)
659 {
660 	bDBImport		= rImportParam.bImport;
661 	aDBName			= rImportParam.aDBName;
662 	aDBStatement	= rImportParam.aStatement;
663 	bDBNative		= rImportParam.bNative;
664 	bDBSql			= rImportParam.bSql;
665 	nDBType			= rImportParam.nType;
666 }
667 
668 sal_Bool ScDBData::IsDBAtCursor(SCCOL nCol, SCROW nRow, SCTAB nTab, sal_Bool bStartOnly) const
669 {
670 	if (nTab == nTable)
671 	{
672 		if ( bStartOnly )
673 			return ( nCol == nStartCol && nRow == nStartRow );
674 		else
675 			return ( nCol >= nStartCol && nCol <= nEndCol &&
676 					 nRow >= nStartRow && nRow <= nEndRow );
677 	}
678 
679 	return sal_False;
680 }
681 
682 sal_Bool ScDBData::IsDBAtArea(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2) const
683 {
684 	return (sal_Bool)((nTab == nTable)
685 					&& (nCol1 == nStartCol) && (nRow1 == nStartRow)
686 					&& (nCol2 == nEndCol) && (nRow2 == nEndRow));
687 }
688 
689 ScDataObject*	ScDBData::Clone() const
690 {
691 	return new ScDBData(*this);
692 }
693 
694 
695 //---------------------------------------------------------------------------------------
696 //	Compare zum Sortieren
697 
698 short ScDBCollection::Compare(ScDataObject* pKey1, ScDataObject* pKey2) const
699 {
700 	const String& rStr1 = ((ScDBData*)pKey1)->GetName();
701 	const String& rStr2 = ((ScDBData*)pKey2)->GetName();
702     return (short) ScGlobal::GetpTransliteration()->compareString( rStr1, rStr2 );
703 }
704 
705 //	IsEqual - alles gleich
706 
707 sal_Bool ScDBCollection::IsEqual(ScDataObject* pKey1, ScDataObject* pKey2) const
708 {
709 	return *(ScDBData*)pKey1 == *(ScDBData*)pKey2;
710 }
711 
712 ScDBData* ScDBCollection::GetDBAtCursor(SCCOL nCol, SCROW nRow, SCTAB nTab, sal_Bool bStartOnly) const
713 {
714 	ScDBData* pNoNameData = NULL;
715 	if (pItems)
716 	{
717 		const String& rNoName = ScGlobal::GetRscString( STR_DB_NONAME );
718 
719 		for (sal_uInt16 i = 0; i < nCount; i++)
720 			if (((ScDBData*)pItems[i])->IsDBAtCursor(nCol, nRow, nTab, bStartOnly))
721 			{
722 				ScDBData* pDB = (ScDBData*)pItems[i];
723 				if ( pDB->GetName() == rNoName )
724 					pNoNameData = pDB;
725 				else
726 					return pDB;
727 			}
728 	}
729 	return pNoNameData;				// "unbenannt" nur zurueck, wenn sonst nichts gefunden
730 }
731 
732 ScDBData* ScDBCollection::GetDBAtArea(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2) const
733 {
734 	ScDBData* pNoNameData = NULL;
735 	if (pItems)
736 	{
737 		const String& rNoName = ScGlobal::GetRscString( STR_DB_NONAME );
738 
739 		for (sal_uInt16 i = 0; i < nCount; i++)
740 			if (((ScDBData*)pItems[i])->IsDBAtArea(nTab, nCol1, nRow1, nCol2, nRow2))
741 			{
742 				ScDBData* pDB = (ScDBData*)pItems[i];
743 				if ( pDB->GetName() == rNoName )
744 					pNoNameData = pDB;
745 				else
746 					return pDB;
747 			}
748 	}
749 	return pNoNameData;				// "unbenannt" nur zurueck, wenn sonst nichts gefunden
750 }
751 
752 ScDBData* ScDBCollection::GetFilterDBAtTable(SCTAB nTab) const
753 {
754     ScDBData* pDataEmpty = NULL;
755     if (pItems)
756     {
757         for (sal_uInt16 i = 0; i < nCount; i++)
758         {
759             ScDBData* pDBTemp = (ScDBData*)pItems[i];
760             if ( pDBTemp->nTable == nTab )
761             {
762                 sal_Bool bFilter = pDBTemp->HasAutoFilter() || pDBTemp->HasQueryParam();
763 
764                 if ( bFilter )
765                     return pDBTemp;
766             }
767         }
768     }
769 
770     return pDataEmpty;
771 }
772 
773 sal_Bool ScDBCollection::SearchName( const String& rName, sal_uInt16& rIndex ) const
774 {
775 	ScDBData aDataObj( rName, 0,0,0,0,0 );
776 	return Search( &aDataObj, rIndex );
777 }
778 
779 void ScDBCollection::DeleteOnTab( SCTAB nTab )
780 {
781     sal_uInt16 nPos = 0;
782     while ( nPos < nCount )
783     {
784         // look for output positions on the deleted sheet
785 
786         SCCOL nEntryCol1, nEntryCol2;
787         SCROW nEntryRow1, nEntryRow2;
788         SCTAB nEntryTab;
789         static_cast<const ScDBData*>(At(nPos))->GetArea( nEntryTab, nEntryCol1, nEntryRow1, nEntryCol2, nEntryRow2 );
790         if ( nEntryTab == nTab )
791             AtFree(nPos);
792         else
793             ++nPos;
794     }
795 }
796 
797 void ScDBCollection::UpdateReference(UpdateRefMode eUpdateRefMode,
798 								SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
799 								SCCOL nCol2, SCROW nRow2, SCTAB nTab2,
800 								SCsCOL nDx, SCsROW nDy, SCsTAB nDz )
801 {
802 	for (sal_uInt16 i=0; i<nCount; i++)
803 	{
804 		SCCOL theCol1;
805 		SCROW theRow1;
806 		SCTAB theTab1;
807 		SCCOL theCol2;
808 		SCROW theRow2;
809 		SCTAB theTab2;
810 		((ScDBData*)pItems[i])->GetArea( theTab1, theCol1, theRow1, theCol2, theRow2 );
811 		theTab2 = theTab1;
812 
813 		sal_Bool bDoUpdate = ScRefUpdate::Update( pDoc, eUpdateRefMode,
814 												nCol1,nRow1,nTab1, nCol2,nRow2,nTab2, nDx,nDy,nDz,
815                                                 theCol1,theRow1,theTab1, theCol2,theRow2,theTab2 ) != UR_NOTHING;
816 		if (bDoUpdate)
817 			((ScDBData*)pItems[i])->MoveTo( theTab1, theCol1, theRow1, theCol2, theRow2 );
818 
819 		ScRange aAdvSource;
820 		if ( ((ScDBData*)pItems[i])->GetAdvancedQuerySource(aAdvSource) )
821 		{
822 			aAdvSource.GetVars( theCol1,theRow1,theTab1, theCol2,theRow2,theTab2 );
823 			if ( ScRefUpdate::Update( pDoc, eUpdateRefMode,
824 										nCol1,nRow1,nTab1, nCol2,nRow2,nTab2, nDx,nDy,nDz,
825 										theCol1,theRow1,theTab1, theCol2,theRow2,theTab2 ) )
826 			{
827 				aAdvSource.aStart.Set( theCol1,theRow1,theTab1 );
828 				aAdvSource.aEnd.Set( theCol2,theRow2,theTab2 );
829 				((ScDBData*)pItems[i])->SetAdvancedQuerySource( &aAdvSource );
830 
831 				bDoUpdate = sal_True;		// DBData is modified
832 			}
833 		}
834 
835 		((ScDBData*)pItems[i])->SetModified(bDoUpdate);
836 
837 		//!		Testen, ob mitten aus dem Bereich geloescht/eingefuegt wurde !!!
838 	}
839 }
840 
841 
842 void ScDBCollection::UpdateMoveTab( SCTAB nOldPos, SCTAB nNewPos )
843 {
844 	//	wenn nOldPos vor nNewPos liegt, ist nNewPos schon angepasst
845 
846 	for (sal_uInt16 i=0; i<nCount; i++)
847 	{
848 		ScRange aRange;
849 		ScDBData* pData = (ScDBData*)pItems[i];
850 		pData->GetArea( aRange );
851 		SCTAB nTab = aRange.aStart.Tab();				// hat nur eine Tabelle
852 
853 		//	anpassen wie die aktuelle Tabelle bei ScTablesHint (tabvwsh5.cxx)
854 
855 		if ( nTab == nOldPos )							// verschobene Tabelle
856 			nTab = nNewPos;
857 		else if ( nOldPos < nNewPos )					// nach hinten verschoben
858 		{
859 			if ( nTab > nOldPos && nTab <= nNewPos )	// nachrueckender Bereich
860 				--nTab;
861 		}
862 		else											// nach vorne verschoben
863 		{
864 			if ( nTab >= nNewPos && nTab < nOldPos )	// nachrueckender Bereich
865 				++nTab;
866 		}
867 
868 		sal_Bool bChanged = ( nTab != aRange.aStart.Tab() );
869 		if (bChanged)
870 			pData->SetArea( nTab, aRange.aStart.Col(), aRange.aStart.Row(),
871 									aRange.aEnd.Col(),aRange.aEnd .Row() );
872 
873 		//	MoveTo ist nicht noetig, wenn nur die Tabelle geaendert ist
874 
875 		pData->SetModified(bChanged);
876 	}
877 }
878 
879 
880 ScDBData* ScDBCollection::FindIndex(sal_uInt16 nIndex)
881 {
882 	sal_uInt16 i = 0;
883 	while (i < nCount)
884 	{
885 		if ((*this)[i]->GetIndex() == nIndex)
886 			return (*this)[i];
887 		i++;
888 	}
889 	return NULL;
890 }
891 
892 sal_Bool ScDBCollection::Insert(ScDataObject* pScDataObject)
893 {
894 	ScDBData* pData = (ScDBData*) pScDataObject;
895 	if (!pData->GetIndex())		// schon gesetzt?
896 		pData->SetIndex(nEntryIndex++);
897 	sal_Bool bInserted = ScSortedCollection::Insert(pScDataObject);
898 	if ( bInserted && pData->HasImportParam() && !pData->HasImportSelection() )
899 	{
900 		pData->SetRefreshHandler( GetRefreshHandler() );
901 		pData->SetRefreshControl( pDoc->GetRefreshTimerControlAddress() );
902 	}
903 	return bInserted;
904 }
905 
906 
907 
908 
909