xref: /AOO41X/main/sc/source/core/tool/dbcolect.cxx (revision ff0525f24f03981d56b7579b645949f111420994)
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 #define SC_DBNAME_UNNAMED "__Anonymous_Sheet_DB__"
40 
41 //---------------------------------------------------------------------------------------
42 
43 ScDBData::ScDBData( const String& rName,
44                     SCTAB nTab,
45                     SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
46                     sal_Bool bByR, sal_Bool bHasH) :
47     aName       (rName),
48     nTable      (nTab),
49     nStartCol   (nCol1),
50     nStartRow   (nRow1),
51     nEndCol     (nCol2),
52     nEndRow     (nRow2),
53     bByRow      (bByR),
54     bHasHeader  (bHasH),
55     bDoSize     (sal_False),
56     bKeepFmt    (sal_False),
57     bStripData  (sal_False),
58     bIsAdvanced (sal_False),
59     bDBSelection(sal_False),
60     nIndex      (0),
61     bAutoFilter (sal_False),
62     bModified   (sal_False)
63 {
64     sal_uInt16 i;
65 
66     ScSortParam aSortParam;
67     ScQueryParam aQueryParam;
68     ScSubTotalParam aSubTotalParam;
69     ScImportParam aImportParam;
70 
71     for (i=0; i<MAXQUERY; i++)
72         pQueryStr[i] = new String;
73 
74     for (i=0; i<MAXSUBTOTAL; i++)
75     {
76         nSubTotals[i] = 0;
77         pSubTotals[i] = NULL;
78         pFunctions[i] = NULL;
79     }
80 
81     SetSortParam( aSortParam );
82     SetQueryParam( aQueryParam );
83     SetSubTotalParam( aSubTotalParam );
84     SetImportParam( aImportParam );
85 }
86 
87 ScDBData::ScDBData( const ScDBData& rData ) :
88     ScDataObject(),
89     ScRefreshTimer      ( rData ),
90     aName               (rData.aName),
91     nTable              (rData.nTable),
92     nStartCol           (rData.nStartCol),
93     nStartRow           (rData.nStartRow),
94     nEndCol             (rData.nEndCol),
95     nEndRow             (rData.nEndRow),
96     bByRow              (rData.bByRow),
97     bHasHeader          (rData.bHasHeader),
98     bDoSize             (rData.bDoSize),
99     bKeepFmt            (rData.bKeepFmt),
100     bStripData          (rData.bStripData),
101     bSortCaseSens       (rData.bSortCaseSens),
102     bIncludePattern     (rData.bIncludePattern),
103     bSortInplace        (rData.bSortInplace),
104     bSortUserDef        (rData.bSortUserDef),
105     nSortUserIndex      (rData.nSortUserIndex),
106     nSortDestTab        (rData.nSortDestTab),
107     nSortDestCol        (rData.nSortDestCol),
108     nSortDestRow        (rData.nSortDestRow),
109     aSortLocale         (rData.aSortLocale),
110     aSortAlgorithm      (rData.aSortAlgorithm),
111     bQueryInplace       (rData.bQueryInplace),
112     bQueryCaseSens      (rData.bQueryCaseSens),
113     bQueryRegExp        (rData.bQueryRegExp),
114     bQueryDuplicate     (rData.bQueryDuplicate),
115     nQueryDestTab       (rData.nQueryDestTab),
116     nQueryDestCol       (rData.nQueryDestCol),
117     nQueryDestRow       (rData.nQueryDestRow),
118     bIsAdvanced         (rData.bIsAdvanced),
119     aAdvSource          (rData.aAdvSource),
120     bSubRemoveOnly      (rData.bSubRemoveOnly),
121     bSubReplace         (rData.bSubReplace),
122     bSubPagebreak       (rData.bSubPagebreak),
123     bSubCaseSens        (rData.bSubCaseSens),
124     bSubDoSort          (rData.bSubDoSort),
125     bSubAscending       (rData.bSubAscending),
126     bSubIncludePattern  (rData.bSubIncludePattern),
127     bSubUserDef         (rData.bSubUserDef),
128     nSubUserIndex       (rData.nSubUserIndex),
129     bDBImport           (rData.bDBImport),
130     aDBName             (rData.aDBName),
131     aDBStatement        (rData.aDBStatement),
132     bDBNative           (rData.bDBNative),
133     bDBSelection        (rData.bDBSelection),
134     bDBSql              (rData.bDBSql),
135     nDBType             (rData.nDBType),
136     nIndex              (rData.nIndex),
137     bAutoFilter         (rData.bAutoFilter),
138     bModified           (rData.bModified)
139 {
140     sal_uInt16 i;
141     sal_uInt16 j;
142 
143     for (i=0; i<MAXSORT; i++)
144     {
145         bDoSort[i]      = rData.bDoSort[i];
146         nSortField[i]   = rData.nSortField[i];
147         bAscending[i]   = rData.bAscending[i];
148     }
149     for (i=0; i<MAXQUERY; i++)
150     {
151         bDoQuery[i]         = rData.bDoQuery[i];
152         nQueryField[i]      = rData.nQueryField[i];
153         eQueryOp[i]         = rData.eQueryOp[i];
154         bQueryByString[i]   = rData.bQueryByString[i];
155         bQueryByDate[i]     = rData.bQueryByDate[i];
156         pQueryStr[i]        = new String( *(rData.pQueryStr[i]) );
157         nQueryVal[i]        = rData.nQueryVal[i];
158         eQueryConnect[i]    = rData.eQueryConnect[i];
159     }
160     for (i=0; i<MAXSUBTOTAL; i++)
161     {
162         bDoSubTotal[i]      = rData.bDoSubTotal[i];
163         nSubField[i]        = rData.nSubField[i];
164 
165         SCCOL nCount    = rData.nSubTotals[i];
166         nSubTotals[i]   = nCount;
167         pFunctions[i]   = nCount > 0 ? new ScSubTotalFunc [nCount] : NULL;
168         pSubTotals[i]   = nCount > 0 ? new SCCOL          [nCount] : NULL;
169 
170         for (j=0; j<nCount; j++)
171         {
172             pSubTotals[i][j] = rData.pSubTotals[i][j];
173             pFunctions[i][j] = rData.pFunctions[i][j];
174         }
175     }
176 }
177 
178 ScDBData& ScDBData::operator= (const ScDBData& rData)
179 {
180     sal_uInt16 i;
181     sal_uInt16 j;
182 
183     ScRefreshTimer::operator=( rData );
184     aName               = rData.aName;
185     nTable              = rData.nTable;
186     nStartCol           = rData.nStartCol;
187     nStartRow           = rData.nStartRow;
188     nEndCol             = rData.nEndCol;
189     nEndRow             = rData.nEndRow;
190     bByRow              = rData.bByRow;
191     bHasHeader          = rData.bHasHeader;
192     bDoSize             = rData.bDoSize;
193     bKeepFmt            = rData.bKeepFmt;
194     bStripData          = rData.bStripData;
195     bSortCaseSens       = rData.bSortCaseSens;
196     bIncludePattern     = rData.bIncludePattern;
197     bSortInplace        = rData.bSortInplace;
198     nSortDestTab        = rData.nSortDestTab;
199     nSortDestCol        = rData.nSortDestCol;
200     nSortDestRow        = rData.nSortDestRow;
201     bSortUserDef        = rData.bSortUserDef;
202     nSortUserIndex      = rData.nSortUserIndex;
203     aSortLocale         = rData.aSortLocale;
204     aSortAlgorithm      = rData.aSortAlgorithm;
205     bQueryInplace       = rData.bQueryInplace;
206     bQueryCaseSens      = rData.bQueryCaseSens;
207     bQueryRegExp        = rData.bQueryRegExp;
208     bQueryDuplicate     = rData.bQueryDuplicate;
209     nQueryDestTab       = rData.nQueryDestTab;
210     nQueryDestCol       = rData.nQueryDestCol;
211     nQueryDestRow       = rData.nQueryDestRow;
212     bIsAdvanced         = rData.bIsAdvanced;
213     aAdvSource          = rData.aAdvSource;
214     bSubRemoveOnly      = rData.bSubRemoveOnly;
215     bSubReplace         = rData.bSubReplace;
216     bSubPagebreak       = rData.bSubPagebreak;
217     bSubCaseSens        = rData.bSubCaseSens;
218     bSubDoSort          = rData.bSubDoSort;
219     bSubAscending       = rData.bSubAscending;
220     bSubIncludePattern  = rData.bSubIncludePattern;
221     bSubUserDef         = rData.bSubUserDef;
222     nSubUserIndex       = rData.nSubUserIndex;
223     bDBImport           = rData.bDBImport;
224     aDBName             = rData.aDBName;
225     aDBStatement        = rData.aDBStatement;
226     bDBNative           = rData.bDBNative;
227     bDBSelection        = rData.bDBSelection;
228     bDBSql              = rData.bDBSql;
229     nDBType             = rData.nDBType;
230     nIndex              = rData.nIndex;
231     bAutoFilter         = rData.bAutoFilter;
232 
233     for (i=0; i<MAXSORT; i++)
234     {
235         bDoSort[i]      = rData.bDoSort[i];
236         nSortField[i]   = rData.nSortField[i];
237         bAscending[i]   = rData.bAscending[i];
238     }
239     for (i=0; i<MAXQUERY; i++)
240     {
241         bDoQuery[i]         = rData.bDoQuery[i];
242         nQueryField[i]      = rData.nQueryField[i];
243         eQueryOp[i]         = rData.eQueryOp[i];
244         bQueryByString[i]   = rData.bQueryByString[i];
245         bQueryByDate[i]     = rData.bQueryByDate[i];
246         *pQueryStr[i]       = *rData.pQueryStr[i];
247         nQueryVal[i]        = rData.nQueryVal[i];
248         eQueryConnect[i]    = rData.eQueryConnect[i];
249     }
250     for (i=0; i<MAXSUBTOTAL; i++)
251     {
252         bDoSubTotal[i]      = rData.bDoSubTotal[i];
253         nSubField[i]        = rData.nSubField[i];
254         SCCOL nCount    = rData.nSubTotals[i];
255         nSubTotals[i]   = nCount;
256 
257         delete[] pSubTotals[i];
258         delete[] pFunctions[i];
259 
260         pSubTotals[i] = nCount > 0 ? new SCCOL          [nCount] : NULL;
261         pFunctions[i] = nCount > 0 ? new ScSubTotalFunc [nCount] : NULL;
262         for (j=0; j<nCount; j++)
263         {
264             pSubTotals[i][j] = rData.pSubTotals[i][j];
265             pFunctions[i][j] = rData.pFunctions[i][j];
266         }
267     }
268 
269     return *this;
270 }
271 
272 sal_Bool ScDBData::operator== (const ScDBData& rData) const
273 {
274     //  Daten, die nicht in den Params sind
275 
276     if ( nTable     != rData.nTable     ||
277          bDoSize    != rData.bDoSize    ||
278          bKeepFmt   != rData.bKeepFmt   ||
279          bIsAdvanced!= rData.bIsAdvanced||
280          bStripData != rData.bStripData ||
281 //       SAB: I think this should be here, but I don't want to break something
282 //         bAutoFilter!= rData.bAutoFilter||
283          ScRefreshTimer::operator!=( rData )
284         )
285         return sal_False;
286 
287     if ( bIsAdvanced && aAdvSource != rData.aAdvSource )
288         return sal_False;
289 
290     ScSortParam aSort1, aSort2;
291     GetSortParam(aSort1);
292     rData.GetSortParam(aSort2);
293     if (!(aSort1 == aSort2))
294         return sal_False;
295 
296     ScQueryParam aQuery1, aQuery2;
297     GetQueryParam(aQuery1);
298     rData.GetQueryParam(aQuery2);
299     if (!(aQuery1 == aQuery2))
300         return sal_False;
301 
302     ScSubTotalParam aSubTotal1, aSubTotal2;
303     GetSubTotalParam(aSubTotal1);
304     rData.GetSubTotalParam(aSubTotal2);
305     if (!(aSubTotal1 == aSubTotal2))
306         return sal_False;
307 
308     ScImportParam aImport1, aImport2;
309     GetImportParam(aImport1);
310     rData.GetImportParam(aImport2);
311     if (!(aImport1 == aImport2))
312         return sal_False;
313 
314     return sal_True;
315 }
316 
317 ScDBData::~ScDBData()
318 {
319     StopRefreshTimer();
320     sal_uInt16 i;
321 
322     for (i=0; i<MAXQUERY; i++)
323         delete pQueryStr[i];
324     for (i=0; i<MAXSUBTOTAL; i++)
325     {
326         delete[] pSubTotals[i];
327         delete[] pFunctions[i];
328     }
329 }
330 
331 //UNUSED2008-05  sal_Bool ScDBData::IsBeyond(SCROW nMaxRow) const
332 //UNUSED2008-05  {
333 //UNUSED2008-05      return ( nStartRow > nMaxRow ||
334 //UNUSED2008-05               nEndRow > nMaxRow ||
335 //UNUSED2008-05               nQueryDestRow > nMaxRow );
336 //UNUSED2008-05  }
337 
338 String ScDBData::GetSourceString() const
339 {
340     String aVal;
341     if (bDBImport)
342     {
343         aVal = aDBName;
344         aVal += '/';
345         aVal += aDBStatement;
346     }
347     return aVal;
348 }
349 
350 String ScDBData::GetOperations() const
351 {
352     String aVal;
353     if (bDoQuery[0])
354         aVal = ScGlobal::GetRscString(STR_OPERATION_FILTER);
355 
356     if (bDoSort[0])
357     {
358         if (aVal.Len())
359             aVal.AppendAscii( RTL_CONSTASCII_STRINGPARAM(", ") );
360         aVal += ScGlobal::GetRscString(STR_OPERATION_SORT);
361     }
362 
363     if (bDoSubTotal[0] && !bSubRemoveOnly)
364     {
365         if (aVal.Len())
366             aVal.AppendAscii( RTL_CONSTASCII_STRINGPARAM(", ") );
367         aVal += ScGlobal::GetRscString(STR_OPERATION_SUBTOTAL);
368     }
369 
370     if (!aVal.Len())
371         aVal = ScGlobal::GetRscString(STR_OPERATION_NONE);
372 
373     return aVal;
374 }
375 
376 void ScDBData::GetArea(SCTAB& rTab, SCCOL& rCol1, SCROW& rRow1, SCCOL& rCol2, SCROW& rRow2) const
377 {
378     rTab  = nTable;
379     rCol1 = nStartCol;
380     rRow1 = nStartRow;
381     rCol2 = nEndCol;
382     rRow2 = nEndRow;
383 }
384 
385 void ScDBData::GetArea(ScRange& rRange) const
386 {
387     rRange = ScRange( nStartCol,nStartRow,nTable, nEndCol,nEndRow,nTable );
388 }
389 
390 void ScDBData::SetArea(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2)
391 {
392     nTable  = nTab;
393     nStartCol = nCol1;
394     nStartRow = nRow1;
395     nEndCol   = nCol2;
396     nEndRow   = nRow2;
397 }
398 
399 void ScDBData::MoveTo(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2)
400 {
401     sal_uInt16 i;
402     long nDifX = ((long) nCol1) - ((long) nStartCol);
403     long nDifY = ((long) nRow1) - ((long) nStartRow);
404 
405     long nSortDif = bByRow ? nDifX : nDifY;
406     long nSortEnd = bByRow ? static_cast<long>(nCol2) : static_cast<long>(nRow2);
407 
408     for (i=0; i<MAXSORT; i++)
409     {
410         nSortField[i] += nSortDif;
411         if (nSortField[i] > nSortEnd)
412         {
413             nSortField[i] = 0;
414             bDoSort[i]    = sal_False;
415         }
416     }
417     for (i=0; i<MAXQUERY; i++)
418     {
419         nQueryField[i] += nDifX;
420         if (nQueryField[i] > nCol2)
421         {
422             nQueryField[i] = 0;
423             bDoQuery[i]    = sal_False;
424         }
425     }
426     for (i=0; i<MAXSUBTOTAL; i++)
427     {
428         nSubField[i] = sal::static_int_cast<SCCOL>( nSubField[i] + nDifX );
429         if (nSubField[i] > nCol2)
430         {
431             nSubField[i]   = 0;
432             bDoSubTotal[i] = sal_False;
433         }
434     }
435 
436     SetArea( nTab, nCol1, nRow1, nCol2, nRow2 );
437 }
438 
439 void ScDBData::GetSortParam( ScSortParam& rSortParam ) const
440 {
441     rSortParam.nCol1 = nStartCol;
442     rSortParam.nRow1 = nStartRow;
443     rSortParam.nCol2 = nEndCol;
444     rSortParam.nRow2 = nEndRow;
445     rSortParam.bByRow = bByRow;
446     rSortParam.bHasHeader = bHasHeader;
447     rSortParam.bCaseSens = bSortCaseSens;
448     rSortParam.bInplace = bSortInplace;
449     rSortParam.nDestTab = nSortDestTab;
450     rSortParam.nDestCol = nSortDestCol;
451     rSortParam.nDestRow = nSortDestRow;
452     rSortParam.bIncludePattern = bIncludePattern;
453     rSortParam.bUserDef = bSortUserDef;
454     rSortParam.nUserIndex = nSortUserIndex;
455     for (sal_uInt16 i=0; i<MAXSORT; i++)
456     {
457         rSortParam.bDoSort[i]    = bDoSort[i];
458         rSortParam.nField[i]     = nSortField[i];
459         rSortParam.bAscending[i] = bAscending[i];
460     }
461     rSortParam.aCollatorLocale = aSortLocale;
462     rSortParam.aCollatorAlgorithm = aSortAlgorithm;
463 }
464 
465 void ScDBData::SetSortParam( const ScSortParam& rSortParam )
466 {
467     bSortCaseSens = rSortParam.bCaseSens;
468     bIncludePattern = rSortParam.bIncludePattern;
469     bSortInplace = rSortParam.bInplace;
470     nSortDestTab = rSortParam.nDestTab;
471     nSortDestCol = rSortParam.nDestCol;
472     nSortDestRow = rSortParam.nDestRow;
473     bSortUserDef = rSortParam.bUserDef;
474     nSortUserIndex = rSortParam.nUserIndex;
475     for (sal_uInt16 i=0; i<MAXSORT; i++)
476     {
477         bDoSort[i]    = rSortParam.bDoSort[i];
478         nSortField[i] = rSortParam.nField[i];
479         bAscending[i] = rSortParam.bAscending[i];
480     }
481     aSortLocale = rSortParam.aCollatorLocale;
482     aSortAlgorithm = rSortParam.aCollatorAlgorithm;
483 
484     //#98317#; set the orientation
485     bByRow = rSortParam.bByRow;
486 }
487 
488 void ScDBData::GetQueryParam( ScQueryParam& rQueryParam ) const
489 {
490     rQueryParam.nCol1 = nStartCol;
491     rQueryParam.nRow1 = nStartRow;
492     rQueryParam.nCol2 = nEndCol;
493     rQueryParam.nRow2 = nEndRow;
494     rQueryParam.nTab  = nTable;
495     rQueryParam.bByRow = bByRow;
496     rQueryParam.bHasHeader = bHasHeader;
497     rQueryParam.bInplace = bQueryInplace;
498     rQueryParam.bCaseSens = bQueryCaseSens;
499     rQueryParam.bRegExp = bQueryRegExp;
500     rQueryParam.bDuplicate = bQueryDuplicate;
501     rQueryParam.nDestTab = nQueryDestTab;
502     rQueryParam.nDestCol = nQueryDestCol;
503     rQueryParam.nDestRow = nQueryDestRow;
504 
505     rQueryParam.Resize( MAXQUERY );
506     for (SCSIZE i=0; i<MAXQUERY; i++)
507     {
508         ScQueryEntry& rEntry = rQueryParam.GetEntry(i);
509 
510         rEntry.bDoQuery = bDoQuery[i];
511         rEntry.nField = nQueryField[i];
512         rEntry.eOp = eQueryOp[i];
513         rEntry.bQueryByString = bQueryByString[i];
514         rEntry.bQueryByDate = bQueryByDate[i];
515         *rEntry.pStr = *pQueryStr[i];
516         rEntry.nVal = nQueryVal[i];
517         rEntry.eConnect = eQueryConnect[i];
518     }
519 }
520 
521 void ScDBData::SetQueryParam(const ScQueryParam& rQueryParam)
522 {
523     DBG_ASSERT( rQueryParam.GetEntryCount() <= MAXQUERY ||
524                 !rQueryParam.GetEntry(MAXQUERY).bDoQuery,
525                 "zuviele Eintraege bei ScDBData::SetQueryParam" );
526 
527     //  set bIsAdvanced to sal_False for everything that is not from the
528     //  advanced filter dialog
529     bIsAdvanced = sal_False;
530 
531     bQueryInplace = rQueryParam.bInplace;
532     bQueryCaseSens = rQueryParam.bCaseSens;
533     bQueryRegExp = rQueryParam.bRegExp;
534     bQueryDuplicate = rQueryParam.bDuplicate;
535     nQueryDestTab = rQueryParam.nDestTab;
536     nQueryDestCol = rQueryParam.nDestCol;
537     nQueryDestRow = rQueryParam.nDestRow;
538     for (SCSIZE i=0; i<MAXQUERY; i++)
539     {
540         ScQueryEntry& rEntry = rQueryParam.GetEntry(i);
541 
542         bDoQuery[i] = rEntry.bDoQuery;
543         nQueryField[i] = rEntry.nField;
544         eQueryOp[i] = rEntry.eOp;
545         bQueryByString[i] = rEntry.bQueryByString;
546         bQueryByDate[i] = rEntry.bQueryByDate;
547         *pQueryStr[i] = *rEntry.pStr;
548         nQueryVal[i] = rEntry.nVal;
549         eQueryConnect[i] = rEntry.eConnect;
550     }
551 }
552 
553 void ScDBData::SetAdvancedQuerySource(const ScRange* pSource)
554 {
555     if (pSource)
556     {
557         aAdvSource = *pSource;
558         bIsAdvanced = sal_True;
559     }
560     else
561         bIsAdvanced = sal_False;
562 }
563 
564 sal_Bool ScDBData::GetAdvancedQuerySource(ScRange& rSource) const
565 {
566     rSource = aAdvSource;
567     return bIsAdvanced;
568 }
569 
570 void ScDBData::GetSubTotalParam(ScSubTotalParam& rSubTotalParam) const
571 {
572     sal_uInt16 i;
573     sal_uInt16 j;
574 
575     rSubTotalParam.nCol1 = nStartCol;
576     rSubTotalParam.nRow1 = nStartRow;
577     rSubTotalParam.nCol2 = nEndCol;
578     rSubTotalParam.nRow2 = nEndRow;
579 
580     rSubTotalParam.bRemoveOnly      = bSubRemoveOnly;
581     rSubTotalParam.bReplace         = bSubReplace;
582     rSubTotalParam.bPagebreak       = bSubPagebreak;
583     rSubTotalParam.bCaseSens        = bSubCaseSens;
584     rSubTotalParam.bDoSort          = bSubDoSort;
585     rSubTotalParam.bAscending       = bSubAscending;
586     rSubTotalParam.bIncludePattern  = bSubIncludePattern;
587     rSubTotalParam.bUserDef         = bSubUserDef;
588     rSubTotalParam.nUserIndex       = nSubUserIndex;
589 
590     for (i=0; i<MAXSUBTOTAL; i++)
591     {
592         rSubTotalParam.bGroupActive[i]  = bDoSubTotal[i];
593         rSubTotalParam.nField[i]        = nSubField[i];
594         SCCOL nCount = nSubTotals[i];
595 
596         rSubTotalParam.nSubTotals[i] = nCount;
597         delete[] rSubTotalParam.pSubTotals[i];
598         delete[] rSubTotalParam.pFunctions[i];
599         rSubTotalParam.pSubTotals[i] = nCount > 0 ? new SCCOL[nCount] : NULL;
600         rSubTotalParam.pFunctions[i] = nCount > 0 ? new ScSubTotalFunc[nCount]
601                                               : NULL;
602         for (j=0; j<nCount; j++)
603         {
604             rSubTotalParam.pSubTotals[i][j] = pSubTotals[i][j];
605             rSubTotalParam.pFunctions[i][j] = pFunctions[i][j];
606         }
607     }
608 }
609 
610 void ScDBData::SetSubTotalParam(const ScSubTotalParam& rSubTotalParam)
611 {
612     sal_uInt16 i;
613     sal_uInt16 j;
614 
615     bSubRemoveOnly      = rSubTotalParam.bRemoveOnly;
616     bSubReplace         = rSubTotalParam.bReplace;
617     bSubPagebreak       = rSubTotalParam.bPagebreak;
618     bSubCaseSens        = rSubTotalParam.bCaseSens;
619     bSubDoSort          = rSubTotalParam.bDoSort;
620     bSubAscending       = rSubTotalParam.bAscending;
621     bSubIncludePattern  = rSubTotalParam.bIncludePattern;
622     bSubUserDef         = rSubTotalParam.bUserDef;
623     nSubUserIndex       = rSubTotalParam.nUserIndex;
624 
625     for (i=0; i<MAXSUBTOTAL; i++)
626     {
627         bDoSubTotal[i]  = rSubTotalParam.bGroupActive[i];
628         nSubField[i]    = rSubTotalParam.nField[i];
629         SCCOL nCount = rSubTotalParam.nSubTotals[i];
630 
631         nSubTotals[i] = nCount;
632         delete[] pSubTotals[i];
633         delete[] pFunctions[i];
634         pSubTotals[i] = nCount > 0 ? new SCCOL          [nCount] : NULL;
635         pFunctions[i] = nCount > 0 ? new ScSubTotalFunc [nCount] : NULL;
636         for (j=0; j<nCount; j++)
637         {
638             pSubTotals[i][j] = rSubTotalParam.pSubTotals[i][j];
639             pFunctions[i][j] = rSubTotalParam.pFunctions[i][j];
640         }
641     }
642 }
643 
644 void ScDBData::GetImportParam(ScImportParam& rImportParam) const
645 {
646     rImportParam.nCol1 = nStartCol;
647     rImportParam.nRow1 = nStartRow;
648     rImportParam.nCol2 = nEndCol;
649     rImportParam.nRow2 = nEndRow;
650 
651     rImportParam.bImport    = bDBImport;
652     rImportParam.aDBName    = aDBName;
653     rImportParam.aStatement = aDBStatement;
654     rImportParam.bNative    = bDBNative;
655     rImportParam.bSql       = bDBSql;
656     rImportParam.nType      = nDBType;
657 }
658 
659 void ScDBData::SetImportParam(const ScImportParam& rImportParam)
660 {
661     bDBImport       = rImportParam.bImport;
662     aDBName         = rImportParam.aDBName;
663     aDBStatement    = rImportParam.aStatement;
664     bDBNative       = rImportParam.bNative;
665     bDBSql          = rImportParam.bSql;
666     nDBType         = rImportParam.nType;
667 }
668 
669 sal_Bool ScDBData::IsDBAtCursor(SCCOL nCol, SCROW nRow, SCTAB nTab, sal_Bool bStartOnly) const
670 {
671     if (nTab == nTable)
672     {
673         if ( bStartOnly )
674             return ( nCol == nStartCol && nRow == nStartRow );
675         else
676             return ( nCol >= nStartCol && nCol <= nEndCol &&
677                      nRow >= nStartRow && nRow <= nEndRow );
678     }
679 
680     return sal_False;
681 }
682 
683 sal_Bool ScDBData::IsDBAtArea(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2) const
684 {
685     return (sal_Bool)((nTab == nTable)
686                     && (nCol1 == nStartCol) && (nRow1 == nStartRow)
687                     && (nCol2 == nEndCol) && (nRow2 == nEndRow));
688 }
689 
690 ScDataObject*   ScDBData::Clone() const
691 {
692     return new ScDBData(*this);
693 }
694 sal_Bool    ScDBData::IsBuildin()
695 {
696     String  aNoName = String::CreateFromAscii(SC_DBNAME_UNNAMED);
697     String  aBeginName = aName.Copy(0,22);
698     return  (sal_Bool)(!ScGlobal::GetpTransliteration()->compareString( aNoName, aBeginName ));
699 }
700 
701 //---------------------------------------------------------------------------------------
702 //  Compare zum Sortieren
703 
704 short ScDBCollection::Compare(ScDataObject* pKey1, ScDataObject* pKey2) const
705 {
706     const String& rStr1 = ((ScDBData*)pKey1)->GetName();
707     const String& rStr2 = ((ScDBData*)pKey2)->GetName();
708     return (short) ScGlobal::GetpTransliteration()->compareString( rStr1, rStr2 );
709 }
710 
711 //  IsEqual - alles gleich
712 
713 sal_Bool ScDBCollection::IsEqual(ScDataObject* pKey1, ScDataObject* pKey2) const
714 {
715     return *(ScDBData*)pKey1 == *(ScDBData*)pKey2;
716 }
717 
718 ScDBData* ScDBCollection::GetDBAtCursor(SCCOL nCol, SCROW nRow, SCTAB nTab, sal_Bool bStartOnly) const
719 {
720     ScDBData* pNoNameData = NULL;
721     if (pItems)
722     {
723 
724         for (sal_uInt16 i = 0; i < nCount; i++)
725             if (((ScDBData*)pItems[i])->IsDBAtCursor(nCol, nRow, nTab, bStartOnly))
726             {
727                 ScDBData* pDB = (ScDBData*)pItems[i];
728                 if ( pDB->IsBuildin() )
729                     pNoNameData = pDB;
730                 else
731                     return pDB;
732             }
733     }
734     return pNoNameData;             // "unbenannt" nur zurueck, wenn sonst nichts gefunden
735 }
736 
737 ScDBData* ScDBCollection::GetDBAtArea(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2) const
738 {
739     ScDBData* pNoNameData = NULL;
740     if (pItems)
741     {
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->IsBuildin() )
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 String ScDBCollection::GetNewDefaultDBName()
911 {
912     String  aNoName = String::CreateFromAscii(SC_DBNAME_UNNAMED);
913     String  aNewName;
914     unsigned short  nDummy;
915     int     i = 1;
916     do
917     {
918         aNewName = aNoName;
919         aNewName += String::CreateFromInt32( i++ );
920     }while(SearchName(aNewName,nDummy));
921     return  aNewName;
922 }
923 /*
924 sal_Bool ScDBCollection::IsFiltered(SCTAB nTab, SCROW nRow)
925 {
926     SCCOL   nLastCol;
927     SCROW   nLastRow;
928     pDoc->GetLastAttrCellArea(nTab, nLastCol, nLastRow);
929 
930     if ( pItems )
931     {
932         for (unsigned short i = 0; i < nCount; i++)
933         {
934             ScDBData*   pData = (ScDBData*)pItems[i];
935             if ( pData->nTable == nTab && pData->HasQueryParam() && pData->bQueryInplace )
936                 if ( nRow >= (pData->nStartRow + (pData->HasHeader()?1:0)) && nRow <= pData->nEndRow && nRow <= nLastRow )
937                     return sal_True;
938         }
939     }
940     return sal_False;
941 }
942 */
943 ScDBData* ScDBCollection::GetDBAtTable(SCTAB nTab, ScGetDBMode eMode) const
944 {
945     ScDBData* pDataEmpty = NULL;
946     if (pItems)
947     {
948         for (unsigned short i = 0; i < nCount; i++)
949         {
950             ScDBData* pDBTemp = (ScDBData*)pItems[i];
951             if ( pDBTemp->nTable == nTab )                      //Sym2_7885 mod
952             {
953                 sal_Bool bImport = pDBTemp->HasImportParam();
954                 sal_Bool bFilter = pDBTemp->HasAutoFilter() || pDBTemp->HasQueryParam();
955                 sal_Bool bSort = pDBTemp->HasSortParam();
956                 sal_Bool bSubtotal = pDBTemp->HasSubTotalParam();
957                 sal_Bool bAnyParam = bImport || bFilter || bSort || bSubtotal;
958                 if ( ((eMode == SC_DB_MAKE_SORT)    && bSort && !bFilter) ||      //Sym2_7334 mod 20100420
959                     ((eMode == SC_DB_MAKE_SUBTOTAL) && bSubtotal && !bFilter ) ||
960                     ((eMode == SC_DB_MAKE_FILTER || eMode == SC_DB_OLD_FILTER) && bFilter ) )
961                 {
962                     return pDBTemp;
963                 }
964                 else if ( pDBTemp->IsBuildin() && !bAnyParam )  //Sym2_7885 mod
965                 {
966                     pDataEmpty = pDBTemp;
967                 }
968             }
969         }
970     }
971 
972     return pDataEmpty;
973 }
974