xref: /trunk/main/sc/source/core/tool/dbcolect.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
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