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