xref: /AOO41X/main/sc/source/core/tool/dbcolect.cxx (revision 707fc0d4d52eb4f69d89a98ffec6918ca5de6326)
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