LCOV - code coverage report
Current view: top level - sc/source/core/tool - dbdata.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 310 466 66.5 %
Date: 2014-04-11 Functions: 71 87 81.6 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <unotools/transliterationwrapper.hxx>
      21             : 
      22             : #include "dbdata.hxx"
      23             : #include "globalnames.hxx"
      24             : #include "refupdat.hxx"
      25             : #include "rechead.hxx"
      26             : #include "document.hxx"
      27             : #include "queryparam.hxx"
      28             : #include "queryentry.hxx"
      29             : #include "globstr.hrc"
      30             : #include "subtotalparam.hxx"
      31             : #include "sortparam.hxx"
      32             : 
      33             : #include <memory>
      34             : 
      35             : using ::std::auto_ptr;
      36             : using ::std::unary_function;
      37             : using ::std::for_each;
      38             : using ::std::find_if;
      39             : using ::std::remove_if;
      40             : using ::std::pair;
      41             : 
      42          81 : bool ScDBData::less::operator() (const ScDBData& left, const ScDBData& right) const
      43             : {
      44          81 :     return ScGlobal::GetpTransliteration()->compareString(left.GetUpperName(), right.GetUpperName()) < 0;
      45             : }
      46             : 
      47          37 : ScDBData::ScDBData( const OUString& rName,
      48             :                     SCTAB nTab,
      49             :                     SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
      50             :                     bool bByR, bool bHasH) :
      51          37 :     mpSortParam(new ScSortParam),
      52          37 :     mpQueryParam(new ScQueryParam),
      53          37 :     mpSubTotal(new ScSubTotalParam),
      54          37 :     mpImportParam(new ScImportParam),
      55             :     aName       (rName),
      56             :     aUpper      (rName),
      57             :     nTable      (nTab),
      58             :     nStartCol   (nCol1),
      59             :     nStartRow   (nRow1),
      60             :     nEndCol     (nCol2),
      61             :     nEndRow     (nRow2),
      62             :     bByRow      (bByR),
      63             :     bHasHeader  (bHasH),
      64             :     bDoSize     (false),
      65             :     bKeepFmt    (false),
      66             :     bStripData  (false),
      67             :     bIsAdvanced (false),
      68             :     bDBSelection(false),
      69             :     nIndex      (0),
      70             :     bAutoFilter (false),
      71         185 :     bModified   (false)
      72             : {
      73          37 :     aUpper = ScGlobal::pCharClass->uppercase(aUpper);
      74          37 : }
      75             : 
      76         415 : ScDBData::ScDBData( const ScDBData& rData ) :
      77             :     ScRefreshTimer      ( rData ),
      78         830 :     mpSortParam(new ScSortParam(*rData.mpSortParam)),
      79         830 :     mpQueryParam(new ScQueryParam(*rData.mpQueryParam)),
      80         830 :     mpSubTotal(new ScSubTotalParam(*rData.mpSubTotal)),
      81         830 :     mpImportParam(new ScImportParam(*rData.mpImportParam)),
      82             :     aName               (rData.aName),
      83             :     aUpper              (rData.aUpper),
      84             :     nTable              (rData.nTable),
      85             :     nStartCol           (rData.nStartCol),
      86             :     nStartRow           (rData.nStartRow),
      87             :     nEndCol             (rData.nEndCol),
      88             :     nEndRow             (rData.nEndRow),
      89             :     bByRow              (rData.bByRow),
      90             :     bHasHeader          (rData.bHasHeader),
      91             :     bDoSize             (rData.bDoSize),
      92             :     bKeepFmt            (rData.bKeepFmt),
      93             :     bStripData          (rData.bStripData),
      94             :     bIsAdvanced         (rData.bIsAdvanced),
      95             :     aAdvSource          (rData.aAdvSource),
      96             :     bDBSelection        (rData.bDBSelection),
      97             :     nIndex              (rData.nIndex),
      98             :     bAutoFilter         (rData.bAutoFilter),
      99        3735 :     bModified           (rData.bModified)
     100             : {
     101         415 : }
     102             : 
     103           2 : ScDBData::ScDBData( const OUString& rName, const ScDBData& rData ) :
     104             :     ScRefreshTimer      ( rData ),
     105           4 :     mpSortParam(new ScSortParam(*rData.mpSortParam)),
     106           4 :     mpQueryParam(new ScQueryParam(*rData.mpQueryParam)),
     107           4 :     mpSubTotal(new ScSubTotalParam(*rData.mpSubTotal)),
     108           4 :     mpImportParam(new ScImportParam(*rData.mpImportParam)),
     109             :     aName               (rName),
     110             :     aUpper              (rName),
     111             :     nTable              (rData.nTable),
     112             :     nStartCol           (rData.nStartCol),
     113             :     nStartRow           (rData.nStartRow),
     114             :     nEndCol             (rData.nEndCol),
     115             :     nEndRow             (rData.nEndRow),
     116             :     bByRow              (rData.bByRow),
     117             :     bHasHeader          (rData.bHasHeader),
     118             :     bDoSize             (rData.bDoSize),
     119             :     bKeepFmt            (rData.bKeepFmt),
     120             :     bStripData          (rData.bStripData),
     121             :     bIsAdvanced         (rData.bIsAdvanced),
     122             :     aAdvSource          (rData.aAdvSource),
     123             :     bDBSelection        (rData.bDBSelection),
     124             :     nIndex              (rData.nIndex),
     125             :     bAutoFilter         (rData.bAutoFilter),
     126          18 :     bModified           (rData.bModified)
     127             : {
     128           2 :     aUpper = ScGlobal::pCharClass->uppercase(aUpper);
     129           2 : }
     130             : 
     131          49 : ScDBData& ScDBData::operator= (const ScDBData& rData)
     132             : {
     133             :     // Don't modify the name.  The name is not mutable as it is used as a key
     134             :     // in the container to keep the db ranges sorted by the name.
     135          49 :     ScRefreshTimer::operator=( rData );
     136          49 :     mpSortParam.reset(new ScSortParam(*rData.mpSortParam));
     137          49 :     mpQueryParam.reset(new ScQueryParam(*rData.mpQueryParam));
     138          49 :     mpSubTotal.reset(new ScSubTotalParam(*rData.mpSubTotal));
     139          49 :     mpImportParam.reset(new ScImportParam(*rData.mpImportParam));
     140          49 :     nTable              = rData.nTable;
     141          49 :     nStartCol           = rData.nStartCol;
     142          49 :     nStartRow           = rData.nStartRow;
     143          49 :     nEndCol             = rData.nEndCol;
     144          49 :     nEndRow             = rData.nEndRow;
     145          49 :     bByRow              = rData.bByRow;
     146          49 :     bHasHeader          = rData.bHasHeader;
     147          49 :     bDoSize             = rData.bDoSize;
     148          49 :     bKeepFmt            = rData.bKeepFmt;
     149          49 :     bStripData          = rData.bStripData;
     150          49 :     bIsAdvanced         = rData.bIsAdvanced;
     151          49 :     aAdvSource          = rData.aAdvSource;
     152          49 :     bDBSelection        = rData.bDBSelection;
     153          49 :     nIndex              = rData.nIndex;
     154          49 :     bAutoFilter         = rData.bAutoFilter;
     155             : 
     156          49 :     return *this;
     157             : }
     158             : 
     159           0 : bool ScDBData::operator== (const ScDBData& rData) const
     160             : {
     161             :     //  Daten, die nicht in den Params sind
     162             : 
     163           0 :     if ( nTable     != rData.nTable     ||
     164           0 :          bDoSize    != rData.bDoSize    ||
     165           0 :          bKeepFmt   != rData.bKeepFmt   ||
     166           0 :          bIsAdvanced!= rData.bIsAdvanced||
     167           0 :          bStripData != rData.bStripData ||
     168             : //       SAB: I think this should be here, but I don't want to break something
     169             : //         bAutoFilter!= rData.bAutoFilter||
     170           0 :          ScRefreshTimer::operator!=( rData )
     171             :         )
     172           0 :         return false;
     173             : 
     174           0 :     if ( bIsAdvanced && aAdvSource != rData.aAdvSource )
     175           0 :         return false;
     176             : 
     177           0 :     ScSortParam aSort1, aSort2;
     178           0 :     GetSortParam(aSort1);
     179           0 :     rData.GetSortParam(aSort2);
     180           0 :     if (!(aSort1 == aSort2))
     181           0 :         return false;
     182             : 
     183           0 :     ScQueryParam aQuery1, aQuery2;
     184           0 :     GetQueryParam(aQuery1);
     185           0 :     rData.GetQueryParam(aQuery2);
     186           0 :     if (!(aQuery1 == aQuery2))
     187           0 :         return false;
     188             : 
     189           0 :     ScSubTotalParam aSubTotal1, aSubTotal2;
     190           0 :     GetSubTotalParam(aSubTotal1);
     191           0 :     rData.GetSubTotalParam(aSubTotal2);
     192           0 :     if (!(aSubTotal1 == aSubTotal2))
     193           0 :         return false;
     194             : 
     195           0 :     ScImportParam aImport1, aImport2;
     196           0 :     GetImportParam(aImport1);
     197           0 :     rData.GetImportParam(aImport2);
     198           0 :     if (!(aImport1 == aImport2))
     199           0 :         return false;
     200             : 
     201           0 :     return true;
     202             : }
     203             : 
     204        1307 : ScDBData::~ScDBData()
     205             : {
     206         452 :     StopRefreshTimer();
     207         855 : }
     208             : 
     209           0 : OUString ScDBData::GetSourceString() const
     210             : {
     211           0 :     OUStringBuffer aBuf;
     212           0 :     if (mpImportParam->bImport)
     213             :     {
     214           0 :         aBuf.append(mpImportParam->aDBName);
     215           0 :         aBuf.append('/');
     216           0 :         aBuf.append(mpImportParam->aStatement);
     217             :     }
     218           0 :     return aBuf.makeStringAndClear();
     219             : }
     220             : 
     221           0 : OUString ScDBData::GetOperations() const
     222             : {
     223           0 :     OUStringBuffer aBuf;
     224           0 :     if (mpQueryParam->GetEntryCount())
     225             :     {
     226           0 :         const ScQueryEntry& rEntry = mpQueryParam->GetEntry(0);
     227           0 :         if (rEntry.bDoQuery)
     228           0 :             aBuf.append(ScGlobal::GetRscString(STR_OPERATION_FILTER));
     229             :     }
     230             : 
     231           0 :     if (mpSortParam->maKeyState[0].bDoSort)
     232             :     {
     233           0 :         if (!aBuf.isEmpty())
     234           0 :             aBuf.append(", ");
     235           0 :         aBuf.append(ScGlobal::GetRscString(STR_OPERATION_SORT));
     236             :     }
     237             : 
     238           0 :     if (mpSubTotal->bGroupActive[0] && !mpSubTotal->bRemoveOnly)
     239             :     {
     240           0 :         if (!aBuf.isEmpty())
     241           0 :             aBuf.append(", ");
     242           0 :         aBuf.append(ScGlobal::GetRscString(STR_OPERATION_SUBTOTAL));
     243             :     }
     244             : 
     245           0 :     if (aBuf.isEmpty())
     246           0 :         aBuf.append(ScGlobal::GetRscString(STR_OPERATION_NONE));
     247             : 
     248           0 :     return aBuf.makeStringAndClear();
     249             : }
     250             : 
     251         351 : void ScDBData::GetArea(SCTAB& rTab, SCCOL& rCol1, SCROW& rRow1, SCCOL& rCol2, SCROW& rRow2) const
     252             : {
     253         351 :     rTab  = nTable;
     254         351 :     rCol1 = nStartCol;
     255         351 :     rRow1 = nStartRow;
     256         351 :     rCol2 = nEndCol;
     257         351 :     rRow2 = nEndRow;
     258         351 : }
     259             : 
     260         201 : void ScDBData::GetArea(ScRange& rRange) const
     261             : {
     262         201 :     SCROW nNewEndRow = nEndRow;
     263         201 :     rRange = ScRange( nStartCol, nStartRow, nTable, nEndCol, nNewEndRow, nTable );
     264         201 : }
     265             : 
     266         298 : void ScDBData::SetArea(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2)
     267             : {
     268         298 :     nTable  = nTab;
     269         298 :     nStartCol = nCol1;
     270         298 :     nStartRow = nRow1;
     271         298 :     nEndCol   = nCol2;
     272         298 :     nEndRow   = nRow2;
     273         298 : }
     274             : 
     275         288 : void ScDBData::MoveTo(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2)
     276             : {
     277             :     sal_uInt16 i;
     278         288 :     long nDifX = ((long) nCol1) - ((long) nStartCol);
     279         288 :     long nDifY = ((long) nRow1) - ((long) nStartRow);
     280             : 
     281         288 :     long nSortDif = bByRow ? nDifX : nDifY;
     282         288 :     long nSortEnd = bByRow ? static_cast<long>(nCol2) : static_cast<long>(nRow2);
     283             : 
     284        1148 :     for (i=0; i<mpSortParam->GetSortKeyCount(); i++)
     285             :     {
     286         860 :         mpSortParam->maKeyState[i].nField += nSortDif;
     287         860 :         if (mpSortParam->maKeyState[i].nField > nSortEnd)
     288             :         {
     289           0 :             mpSortParam->maKeyState[i].nField = 0;
     290           0 :             mpSortParam->maKeyState[i].bDoSort = false;
     291             :         }
     292             :     }
     293             : 
     294         288 :     SCSIZE nCount = mpQueryParam->GetEntryCount();
     295        2592 :     for (i = 0; i < nCount; ++i)
     296             :     {
     297        2304 :         ScQueryEntry& rEntry = mpQueryParam->GetEntry(i);
     298        2304 :         rEntry.nField += nDifX;
     299        2304 :         if (rEntry.nField > nCol2)
     300             :         {
     301           0 :             rEntry.nField = 0;
     302           0 :             rEntry.bDoQuery = false;
     303             :         }
     304             :     }
     305        1152 :     for (i=0; i<MAXSUBTOTAL; i++)
     306             :     {
     307         864 :         mpSubTotal->nField[i] = sal::static_int_cast<SCCOL>( mpSubTotal->nField[i] + nDifX );
     308         864 :         if (mpSubTotal->nField[i] > nCol2)
     309             :         {
     310           0 :             mpSubTotal->nField[i] = 0;
     311           0 :             mpSubTotal->bGroupActive[i] = false;
     312             :         }
     313             :     }
     314             : 
     315         288 :     SetArea( nTab, nCol1, nRow1, nCol2, nRow2 );
     316         288 : }
     317             : 
     318          16 : void ScDBData::GetSortParam( ScSortParam& rSortParam ) const
     319             : {
     320          16 :     rSortParam = *mpSortParam;
     321          16 :     rSortParam.nCol1 = nStartCol;
     322          16 :     rSortParam.nRow1 = nStartRow;
     323          16 :     rSortParam.nCol2 = nEndCol;
     324          16 :     rSortParam.nRow2 = nEndRow;
     325          16 :     rSortParam.bByRow = bByRow;
     326          16 :     rSortParam.bHasHeader = bHasHeader;
     327          16 : }
     328             : 
     329           7 : void ScDBData::SetSortParam( const ScSortParam& rSortParam )
     330             : {
     331           7 :     mpSortParam.reset(new ScSortParam(rSortParam));
     332           7 :     bByRow = rSortParam.bByRow;
     333           7 : }
     334             : 
     335          63 : void ScDBData::GetQueryParam( ScQueryParam& rQueryParam ) const
     336             : {
     337          63 :     rQueryParam = *mpQueryParam;
     338          63 :     rQueryParam.nCol1 = nStartCol;
     339          63 :     rQueryParam.nRow1 = nStartRow;
     340          63 :     rQueryParam.nCol2 = nEndCol;
     341          63 :     rQueryParam.nRow2 = nEndRow;
     342          63 :     rQueryParam.nTab  = nTable;
     343          63 :     rQueryParam.bByRow = bByRow;
     344          63 :     rQueryParam.bHasHeader = bHasHeader;
     345          63 : }
     346             : 
     347          62 : void ScDBData::SetQueryParam(const ScQueryParam& rQueryParam)
     348             : {
     349          62 :     mpQueryParam.reset(new ScQueryParam(rQueryParam));
     350             : 
     351             :     //  set bIsAdvanced to false for everything that is not from the
     352             :     //  advanced filter dialog
     353          62 :     bIsAdvanced = false;
     354          62 : }
     355             : 
     356          25 : void ScDBData::SetAdvancedQuerySource(const ScRange* pSource)
     357             : {
     358          25 :     if (pSource)
     359             :     {
     360           2 :         aAdvSource = *pSource;
     361           2 :         bIsAdvanced = true;
     362             :     }
     363             :     else
     364          23 :         bIsAdvanced = false;
     365          25 : }
     366             : 
     367          40 : bool ScDBData::GetAdvancedQuerySource(ScRange& rSource) const
     368             : {
     369          40 :     rSource = aAdvSource;
     370          40 :     return bIsAdvanced;
     371             : }
     372             : 
     373          21 : void ScDBData::GetSubTotalParam(ScSubTotalParam& rSubTotalParam) const
     374             : {
     375          21 :     rSubTotalParam = *mpSubTotal;
     376             : 
     377             :     // Share the data range with the parent db data.  The range in the subtotal
     378             :     // param struct is not used.
     379          21 :     rSubTotalParam.nCol1 = nStartCol;
     380          21 :     rSubTotalParam.nRow1 = nStartRow;
     381          21 :     rSubTotalParam.nCol2 = nEndCol;
     382          21 :     rSubTotalParam.nRow2 = nEndRow;
     383          21 : }
     384             : 
     385           4 : void ScDBData::SetSubTotalParam(const ScSubTotalParam& rSubTotalParam)
     386             : {
     387           4 :     mpSubTotal.reset(new ScSubTotalParam(rSubTotalParam));
     388           4 : }
     389             : 
     390          11 : void ScDBData::GetImportParam(ScImportParam& rImportParam) const
     391             : {
     392          11 :     rImportParam = *mpImportParam;
     393             :     // set the range.
     394          11 :     rImportParam.nCol1 = nStartCol;
     395          11 :     rImportParam.nRow1 = nStartRow;
     396          11 :     rImportParam.nCol2 = nEndCol;
     397          11 :     rImportParam.nRow2 = nEndRow;
     398          11 : }
     399             : 
     400          18 : void ScDBData::SetImportParam(const ScImportParam& rImportParam)
     401             : {
     402             :     // the range is ignored.
     403          18 :     mpImportParam.reset(new ScImportParam(rImportParam));
     404          18 : }
     405             : 
     406           9 : bool ScDBData::IsDBAtCursor(SCCOL nCol, SCROW nRow, SCTAB nTab, bool bStartOnly) const
     407             : {
     408           9 :     if (nTab == nTable)
     409             :     {
     410           9 :         if ( bStartOnly )
     411           0 :             return ( nCol == nStartCol && nRow == nStartRow );
     412             :         else
     413          27 :             return ( nCol >= nStartCol && nCol <= nEndCol &&
     414          27 :                      nRow >= nStartRow && nRow <= nEndRow );
     415             :     }
     416             : 
     417           0 :     return false;
     418             : }
     419             : 
     420          39 : bool ScDBData::IsDBAtArea(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2) const
     421             : {
     422          39 :     return (bool)((nTab == nTable)
     423          39 :                     && (nCol1 == nStartCol) && (nRow1 == nStartRow)
     424          74 :                     && (nCol2 == nEndCol) && (nRow2 == nEndRow));
     425             : }
     426             : 
     427          33 : bool ScDBData::HasImportParam() const
     428             : {
     429          33 :     return mpImportParam && mpImportParam->bImport;
     430             : }
     431             : 
     432           0 : bool ScDBData::HasQueryParam() const
     433             : {
     434           0 :     if (!mpQueryParam)
     435           0 :         return false;
     436             : 
     437           0 :     if (!mpQueryParam->GetEntryCount())
     438           0 :         return false;
     439             : 
     440           0 :     return mpQueryParam->GetEntry(0).bDoQuery;
     441             : }
     442             : 
     443           0 : bool ScDBData::HasSortParam() const
     444             : {
     445           0 :     return mpSortParam &&
     446           0 :         !mpSortParam->maKeyState.empty() &&
     447           0 :         mpSortParam->maKeyState[0].bDoSort;
     448             : }
     449             : 
     450           0 : bool ScDBData::HasSubTotalParam() const
     451             : {
     452           0 :     return mpSubTotal && mpSubTotal->bGroupActive[0];
     453             : }
     454             : 
     455           0 : void ScDBData::UpdateMoveTab(SCTAB nOldPos, SCTAB nNewPos)
     456             : {
     457           0 :         ScRange aRange;
     458           0 :         GetArea( aRange );
     459           0 :         SCTAB nTab = aRange.aStart.Tab();               // hat nur eine Tabelle
     460             : 
     461             :         //  anpassen wie die aktuelle Tabelle bei ScTablesHint (tabvwsh5.cxx)
     462             : 
     463           0 :         if ( nTab == nOldPos )                          // verschobene Tabelle
     464           0 :             nTab = nNewPos;
     465           0 :         else if ( nOldPos < nNewPos )                   // nach hinten verschoben
     466             :         {
     467           0 :             if ( nTab > nOldPos && nTab <= nNewPos )    // nachrueckender Bereich
     468           0 :                 --nTab;
     469             :         }
     470             :         else                                            // nach vorne verschoben
     471             :         {
     472           0 :             if ( nTab >= nNewPos && nTab < nOldPos )    // nachrueckender Bereich
     473           0 :                 ++nTab;
     474             :         }
     475             : 
     476           0 :         bool bChanged = ( nTab != aRange.aStart.Tab() );
     477           0 :         if (bChanged)
     478           0 :             SetArea( nTab, aRange.aStart.Col(), aRange.aStart.Row(),
     479           0 :                                     aRange.aEnd.Col(),aRange.aEnd .Row() );
     480             : 
     481             :         //  MoveTo ist nicht noetig, wenn nur die Tabelle geaendert ist
     482             : 
     483           0 :         SetModified(bChanged);
     484             : 
     485           0 : }
     486             : 
     487          10 : void ScDBData::UpdateReference(ScDocument* pDoc, UpdateRefMode eUpdateRefMode,
     488             :                                 SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
     489             :                                 SCCOL nCol2, SCROW nRow2, SCTAB nTab2,
     490             :                                 SCsCOL nDx, SCsROW nDy, SCsTAB nDz)
     491             : {
     492             :     SCCOL theCol1;
     493             :     SCROW theRow1;
     494             :     SCTAB theTab1;
     495             :     SCCOL theCol2;
     496             :     SCROW theRow2;
     497             :     SCTAB theTab2;
     498          10 :     GetArea( theTab1, theCol1, theRow1, theCol2, theRow2 );
     499          10 :     theTab2 = theTab1;
     500             : 
     501             :     bool bDoUpdate = ScRefUpdate::Update( pDoc, eUpdateRefMode,
     502             :                                             nCol1,nRow1,nTab1, nCol2,nRow2,nTab2, nDx,nDy,nDz,
     503          10 :                                             theCol1,theRow1,theTab1, theCol2,theRow2,theTab2 ) != UR_NOTHING;
     504          10 :     if (bDoUpdate)
     505           7 :         MoveTo( theTab1, theCol1, theRow1, theCol2, theRow2 );
     506             : 
     507          10 :     ScRange aRangeAdvSource;
     508          10 :     if ( GetAdvancedQuerySource(aRangeAdvSource) )
     509             :     {
     510           0 :         aRangeAdvSource.GetVars( theCol1,theRow1,theTab1, theCol2,theRow2,theTab2 );
     511           0 :         if ( ScRefUpdate::Update( pDoc, eUpdateRefMode,
     512             :                                     nCol1,nRow1,nTab1, nCol2,nRow2,nTab2, nDx,nDy,nDz,
     513           0 :                                     theCol1,theRow1,theTab1, theCol2,theRow2,theTab2 ) )
     514             :         {
     515           0 :             aRangeAdvSource.aStart.Set( theCol1,theRow1,theTab1 );
     516           0 :             aRangeAdvSource.aEnd.Set( theCol2,theRow2,theTab2 );
     517           0 :             SetAdvancedQuerySource( &aRangeAdvSource );
     518             : 
     519           0 :             bDoUpdate = true;       // DBData is modified
     520             :         }
     521             :     }
     522             : 
     523          10 :     SetModified(bDoUpdate);
     524             : 
     525             :     //!     Testen, ob mitten aus dem Bereich geloescht/eingefuegt wurde !!!
     526          10 : }
     527             : 
     528           0 : void ScDBData::ExtendDataArea(ScDocument* pDoc)
     529             : {
     530             :     // Extend the DB area to include data rows immediately below.
     531             :     // or shrink it if all cells are empty
     532           0 :     pDoc->GetDataArea(nTable, nStartCol, nStartRow, nEndCol, nEndRow, false, true);
     533           0 : }
     534             : 
     535             : namespace {
     536             : 
     537             : class FindByTable : public unary_function<ScDBData, bool>
     538             : {
     539             :     SCTAB mnTab;
     540             : public:
     541          81 :     FindByTable(SCTAB nTab) : mnTab(nTab) {}
     542             : 
     543           8 :     bool operator() (const ScDBData& r) const
     544             :     {
     545           8 :         ScRange aRange;
     546           8 :         r.GetArea(aRange);
     547           8 :         return aRange.aStart.Tab() == mnTab;
     548             :     }
     549             : };
     550             : 
     551             : class UpdateRefFunc : public unary_function<ScDBData, void>
     552             : {
     553             :     ScDocument* mpDoc;
     554             :     UpdateRefMode meMode;
     555             :     SCCOL mnCol1;
     556             :     SCROW mnRow1;
     557             :     SCTAB mnTab1;
     558             :     SCCOL mnCol2;
     559             :     SCROW mnRow2;
     560             :     SCTAB mnTab2;
     561             :     SCsCOL mnDx;
     562             :     SCsROW mnDy;
     563             :     SCsTAB mnDz;
     564             : 
     565             : public:
     566         255 :     UpdateRefFunc(ScDocument* pDoc, UpdateRefMode eMode,
     567             :                     SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
     568             :                     SCCOL nCol2, SCROW nRow2, SCTAB nTab2,
     569             :                     SCsCOL nDx, SCsROW nDy, SCsTAB nDz) :
     570             :         mpDoc(pDoc), meMode(eMode),
     571             :         mnCol1(nCol1), mnRow1(nRow1), mnTab1(nTab1),
     572             :         mnCol2(nCol2), mnRow2(nRow2), mnTab2(nTab2),
     573         255 :         mnDx(nDx), mnDy(nDy), mnDz(nDz) {}
     574             : 
     575           6 :     void operator() (ScDBData& r)
     576             :     {
     577           6 :         r.UpdateReference(mpDoc, meMode, mnCol1, mnRow1, mnTab1, mnCol2, mnRow2, mnTab2, mnDx, mnDy, mnDz);
     578           6 :     }
     579             : };
     580             : 
     581             : class UpdateMoveTabFunc : public unary_function<ScDBData, void>
     582             : {
     583             :     SCTAB mnOldTab;
     584             :     SCTAB mnNewTab;
     585             : public:
     586          14 :     UpdateMoveTabFunc(SCTAB nOld, SCTAB nNew) : mnOldTab(nOld), mnNewTab(nNew) {}
     587           0 :     void operator() (ScDBData& r)
     588             :     {
     589           0 :         r.UpdateMoveTab(mnOldTab, mnNewTab);
     590           0 :     }
     591             : };
     592             : 
     593             : class FindByCursor : public unary_function<ScDBData, bool>
     594             : {
     595             :     SCCOL mnCol;
     596             :     SCROW mnRow;
     597             :     SCTAB mnTab;
     598             :     bool mbStartOnly;
     599             : public:
     600          11 :     FindByCursor(SCCOL nCol, SCROW nRow, SCTAB nTab, bool bStartOnly) :
     601          11 :         mnCol(nCol), mnRow(nRow), mnTab(nTab), mbStartOnly(bStartOnly) {}
     602             : 
     603           2 :     bool operator() (const ScDBData& r)
     604             :     {
     605           2 :         return r.IsDBAtCursor(mnCol, mnRow, mnTab, mbStartOnly);
     606             :     }
     607             : };
     608             : 
     609             : class FindByRange : public unary_function<ScDBData, bool>
     610             : {
     611             :     const ScRange& mrRange;
     612             : public:
     613          58 :     FindByRange(const ScRange& rRange) : mrRange(rRange) {}
     614             : 
     615           5 :     bool operator() (const ScDBData& r)
     616             :     {
     617             :         return r.IsDBAtArea(
     618           5 :             mrRange.aStart.Tab(), mrRange.aStart.Col(), mrRange.aStart.Row(), mrRange.aEnd.Col(), mrRange.aEnd.Row());
     619             :     }
     620             : };
     621             : 
     622             : class FindByIndex : public unary_function<ScDBData, bool>
     623             : {
     624             :     sal_uInt16 mnIndex;
     625             : public:
     626           2 :     FindByIndex(sal_uInt16 nIndex) : mnIndex(nIndex) {}
     627           2 :     bool operator() (const ScDBData& r) const
     628             :     {
     629           2 :         return r.GetIndex() == mnIndex;
     630             :     }
     631             : };
     632             : 
     633             : class FindByUpperName : public unary_function<ScDBData, bool>
     634             : {
     635             :     const OUString& mrName;
     636             : public:
     637         188 :     FindByUpperName(const OUString& rName) : mrName(rName) {}
     638         196 :     bool operator() (const ScDBData& r) const
     639             :     {
     640         196 :         return r.GetUpperName() == mrName;
     641             :     }
     642             : };
     643             : 
     644             : }
     645             : 
     646        1899 : ScDBCollection::NamedDBs::NamedDBs(ScDBCollection& rParent, ScDocument& rDoc) :
     647        1899 :     mrParent(rParent), mrDoc(rDoc) {}
     648             : 
     649         155 : ScDBCollection::NamedDBs::NamedDBs(const NamedDBs& r) :
     650         155 :     maDBs(r.maDBs), mrParent(r.mrParent), mrDoc(r.mrDoc) {}
     651             : 
     652         606 : ScDBCollection::NamedDBs::iterator ScDBCollection::NamedDBs::begin()
     653             : {
     654         606 :     return maDBs.begin();
     655             : }
     656             : 
     657         661 : ScDBCollection::NamedDBs::iterator ScDBCollection::NamedDBs::end()
     658             : {
     659         661 :     return maDBs.end();
     660             : }
     661             : 
     662         257 : ScDBCollection::NamedDBs::const_iterator ScDBCollection::NamedDBs::begin() const
     663             : {
     664         257 :     return maDBs.begin();
     665             : }
     666             : 
     667         256 : ScDBCollection::NamedDBs::const_iterator ScDBCollection::NamedDBs::end() const
     668             : {
     669         256 :     return maDBs.end();
     670             : }
     671             : 
     672           2 : ScDBData* ScDBCollection::NamedDBs::findByIndex(sal_uInt16 nIndex)
     673             : {
     674             :     DBsType::iterator itr = find_if(
     675           2 :         maDBs.begin(), maDBs.end(), FindByIndex(nIndex));
     676           2 :     return itr == maDBs.end() ? NULL : &(*itr);
     677             : }
     678             : 
     679         188 : ScDBData* ScDBCollection::NamedDBs::findByUpperName(const OUString& rName)
     680             : {
     681             :     DBsType::iterator itr = find_if(
     682         188 :         maDBs.begin(), maDBs.end(), FindByUpperName(rName));
     683         188 :     return itr == maDBs.end() ? NULL : &(*itr);
     684             : }
     685             : 
     686          19 : bool ScDBCollection::NamedDBs::insert(ScDBData* p)
     687             : {
     688             :     SAL_WNODEPRECATED_DECLARATIONS_PUSH
     689          19 :     auto_ptr<ScDBData> pData(p);
     690             :     SAL_WNODEPRECATED_DECLARATIONS_POP
     691          19 :     if (!pData->GetIndex())
     692          17 :         pData->SetIndex(mrParent.nEntryIndex++);
     693             : 
     694          19 :     pair<DBsType::iterator, bool> r = maDBs.insert(pData);
     695             : 
     696          19 :     if (r.second && p->HasImportParam() && !p->HasImportSelection())
     697             :     {
     698           1 :         p->SetRefreshHandler(mrParent.GetRefreshHandler());
     699           1 :         p->SetRefreshControl(mrDoc.GetRefreshTimerControlAddress());
     700             :     }
     701          19 :     return r.second;
     702             : }
     703             : 
     704           2 : void ScDBCollection::NamedDBs::erase(iterator itr)
     705             : {
     706           2 :     maDBs.erase(itr);
     707           2 : }
     708             : 
     709           2 : void ScDBCollection::NamedDBs::erase(const ScDBData& r)
     710             : {
     711           2 :     maDBs.erase(r);
     712           2 : }
     713             : 
     714          40 : bool ScDBCollection::NamedDBs::empty() const
     715             : {
     716          40 :     return maDBs.empty();
     717             : }
     718             : 
     719          22 : size_t ScDBCollection::NamedDBs::size() const
     720             : {
     721          22 :     return maDBs.size();
     722             : }
     723             : 
     724          49 : bool ScDBCollection::NamedDBs::operator== (const NamedDBs& r) const
     725             : {
     726          49 :     return maDBs == r.maDBs;
     727             : }
     728             : 
     729         350 : ScDBCollection::AnonDBs::iterator ScDBCollection::AnonDBs::begin()
     730             : {
     731         350 :     return maDBs.begin();
     732             : }
     733             : 
     734         350 : ScDBCollection::AnonDBs::iterator ScDBCollection::AnonDBs::end()
     735             : {
     736         350 :     return maDBs.end();
     737             : }
     738             : 
     739           0 : ScDBCollection::AnonDBs::const_iterator ScDBCollection::AnonDBs::begin() const
     740             : {
     741           0 :     return maDBs.begin();
     742             : }
     743             : 
     744           0 : ScDBCollection::AnonDBs::const_iterator ScDBCollection::AnonDBs::end() const
     745             : {
     746           0 :     return maDBs.end();
     747             : }
     748             : 
     749           1 : const ScDBData* ScDBCollection::AnonDBs::findAtCursor(SCCOL nCol, SCROW nRow, SCTAB nTab, bool bStartOnly) const
     750             : {
     751             :     DBsType::const_iterator itr = find_if(
     752           1 :         maDBs.begin(), maDBs.end(), FindByCursor(nCol, nRow, nTab, bStartOnly));
     753           1 :     return itr == maDBs.end() ? NULL : &(*itr);
     754             : }
     755             : 
     756          13 : const ScDBData* ScDBCollection::AnonDBs::findByRange(const ScRange& rRange) const
     757             : {
     758             :     DBsType::const_iterator itr = find_if(
     759          13 :         maDBs.begin(), maDBs.end(), FindByRange(rRange));
     760          13 :     return itr == maDBs.end() ? NULL : &(*itr);
     761             : }
     762             : 
     763           0 : ScDBData* ScDBCollection::AnonDBs::getByRange(const ScRange& rRange)
     764             : {
     765           0 :     const ScDBData* pData = findByRange(rRange);
     766           0 :     if (!pData)
     767             :     {
     768             :         // Insert a new db data.  They all have identical names.
     769           0 :         OUString aName(STR_DB_GLOBAL_NONAME);
     770             :         SAL_WNODEPRECATED_DECLARATIONS_PUSH
     771             :         ::std::auto_ptr<ScDBData> pNew(new ScDBData(
     772           0 :             aName, rRange.aStart.Tab(), rRange.aStart.Col(), rRange.aStart.Row(),
     773           0 :             rRange.aEnd.Col(), rRange.aEnd.Row(), true, false));
     774             :         SAL_WNODEPRECATED_DECLARATIONS_POP
     775           0 :         pData = pNew.get();
     776           0 :         maDBs.push_back(pNew);
     777             :     }
     778           0 :     return const_cast<ScDBData*>(pData);
     779             : }
     780             : 
     781           0 : void ScDBCollection::AnonDBs::insert(ScDBData* p)
     782             : {
     783             :     SAL_WNODEPRECATED_DECLARATIONS_PUSH
     784           0 :     ::std::auto_ptr<ScDBData> pNew(p);
     785             :         SAL_WNODEPRECATED_DECLARATIONS_POP
     786           0 :     maDBs.push_back(pNew);
     787           0 : }
     788             : 
     789          37 : bool ScDBCollection::AnonDBs::empty() const
     790             : {
     791          37 :     return maDBs.empty();
     792             : }
     793             : 
     794          49 : bool ScDBCollection::AnonDBs::operator== (const AnonDBs& r) const
     795             : {
     796          49 :     return maDBs == r.maDBs;
     797             : }
     798             : 
     799        1899 : ScDBCollection::ScDBCollection(ScDocument* pDocument) :
     800        1899 :     pDoc(pDocument), nEntryIndex(SC_START_INDEX_DB_COLL), maNamedDBs(*this, *pDocument) {}
     801             : 
     802         155 : ScDBCollection::ScDBCollection(const ScDBCollection& r) :
     803         155 :     pDoc(r.pDoc), nEntryIndex(r.nEntryIndex), maNamedDBs(r.maNamedDBs), maAnonDBs(r.maAnonDBs) {}
     804             : 
     805         654 : ScDBCollection::NamedDBs& ScDBCollection::getNamedDBs()
     806             : {
     807         654 :     return maNamedDBs;
     808             : }
     809             : 
     810          17 : const ScDBCollection::NamedDBs& ScDBCollection::getNamedDBs() const
     811             : {
     812          17 :     return maNamedDBs;
     813             : }
     814             : 
     815          32 : ScDBCollection::AnonDBs& ScDBCollection::getAnonDBs()
     816             : {
     817          32 :     return maAnonDBs;
     818             : }
     819             : 
     820           0 : const ScDBCollection::AnonDBs& ScDBCollection::getAnonDBs() const
     821             : {
     822           0 :     return maAnonDBs;
     823             : }
     824             : 
     825           0 : const ScDBData* ScDBCollection::GetDBAtCursor(SCCOL nCol, SCROW nRow, SCTAB nTab, bool bStartOnly) const
     826             : {
     827             :     // First, search the global named db ranges.
     828             :     NamedDBs::DBsType::const_iterator itr = find_if(
     829           0 :         maNamedDBs.begin(), maNamedDBs.end(), FindByCursor(nCol, nRow, nTab, bStartOnly));
     830           0 :     if (itr != maNamedDBs.end())
     831           0 :         return &(*itr);
     832             : 
     833             :     // Check for the sheet-local anonymous db range.
     834           0 :     const ScDBData* pNoNameData = pDoc->GetAnonymousDBData(nTab);
     835           0 :     if (pNoNameData)
     836           0 :         if (pNoNameData->IsDBAtCursor(nCol,nRow,nTab,bStartOnly))
     837           0 :             return pNoNameData;
     838             : 
     839             :     // Check the global anonymous db ranges.
     840           0 :     const ScDBData* pData = getAnonDBs().findAtCursor(nCol, nRow, nTab, bStartOnly);
     841           0 :     if (pData)
     842           0 :         return pData;
     843             : 
     844           0 :     return NULL;
     845             : }
     846             : 
     847          10 : ScDBData* ScDBCollection::GetDBAtCursor(SCCOL nCol, SCROW nRow, SCTAB nTab, bool bStartOnly)
     848             : {
     849             :     // First, search the global named db ranges.
     850             :     NamedDBs::DBsType::iterator itr = find_if(
     851          10 :         maNamedDBs.begin(), maNamedDBs.end(), FindByCursor(nCol, nRow, nTab, bStartOnly));
     852          10 :     if (itr != maNamedDBs.end())
     853           2 :         return &(*itr);
     854             : 
     855             :     // Check for the sheet-local anonymous db range.
     856           8 :     ScDBData* pNoNameData = pDoc->GetAnonymousDBData(nTab);
     857           8 :     if (pNoNameData)
     858           7 :         if (pNoNameData->IsDBAtCursor(nCol,nRow,nTab,bStartOnly))
     859           7 :             return pNoNameData;
     860             : 
     861             :     // Check the global anonymous db ranges.
     862           1 :     const ScDBData* pData = getAnonDBs().findAtCursor(nCol, nRow, nTab, bStartOnly);
     863           1 :     if (pData)
     864           0 :         return const_cast<ScDBData*>(pData);
     865             : 
     866           1 :     return NULL;
     867             : }
     868             : 
     869           0 : const ScDBData* ScDBCollection::GetDBAtArea(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2) const
     870             : {
     871             :     // First, search the global named db ranges.
     872           0 :     ScRange aRange(nCol1, nRow1, nTab, nCol2, nRow2, nTab);
     873             :     NamedDBs::DBsType::const_iterator itr = find_if(
     874           0 :         maNamedDBs.begin(), maNamedDBs.end(), FindByRange(aRange));
     875           0 :     if (itr != maNamedDBs.end())
     876           0 :         return &(*itr);
     877             : 
     878             :     // Check for the sheet-local anonymous db range.
     879           0 :     ScDBData* pNoNameData = pDoc->GetAnonymousDBData(nTab);
     880           0 :     if (pNoNameData)
     881           0 :         if (pNoNameData->IsDBAtArea(nTab, nCol1, nRow1, nCol2, nRow2))
     882           0 :             return pNoNameData;
     883             : 
     884             :     // Lastly, check the global anonymous db ranges.
     885           0 :     return maAnonDBs.findByRange(aRange);
     886             : }
     887             : 
     888          45 : ScDBData* ScDBCollection::GetDBAtArea(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2)
     889             : {
     890             :     // First, search the global named db ranges.
     891          45 :     ScRange aRange(nCol1, nRow1, nTab, nCol2, nRow2, nTab);
     892             :     NamedDBs::DBsType::iterator itr = find_if(
     893          45 :         maNamedDBs.begin(), maNamedDBs.end(), FindByRange(aRange));
     894          45 :     if (itr != maNamedDBs.end())
     895           1 :         return &(*itr);
     896             : 
     897             :     // Check for the sheet-local anonymous db range.
     898          44 :     ScDBData* pNoNameData = pDoc->GetAnonymousDBData(nTab);
     899          44 :     if (pNoNameData)
     900          34 :         if (pNoNameData->IsDBAtArea(nTab, nCol1, nRow1, nCol2, nRow2))
     901          31 :             return pNoNameData;
     902             : 
     903             :     // Lastly, check the global anonymous db ranges.
     904          13 :     const ScDBData* pData = getAnonDBs().findByRange(aRange);
     905          13 :     if (pData)
     906           0 :         return const_cast<ScDBData*>(pData);
     907             : 
     908          13 :     return NULL;
     909             : }
     910             : 
     911          81 : void ScDBCollection::DeleteOnTab( SCTAB nTab )
     912             : {
     913          81 :     FindByTable func(nTab);
     914             :     // First, collect the positions of all items that need to be deleted.
     915          81 :     ::std::vector<NamedDBs::DBsType::iterator> v;
     916             :     {
     917          81 :         NamedDBs::DBsType::iterator itr = maNamedDBs.begin(), itrEnd = maNamedDBs.end();
     918          89 :         for (; itr != itrEnd; ++itr)
     919             :         {
     920           8 :             if (func(*itr))
     921           2 :                 v.push_back(itr);
     922             :         }
     923             :     }
     924             : 
     925             :     // Delete them all.
     926          81 :     ::std::vector<NamedDBs::DBsType::iterator>::iterator itr = v.begin(), itrEnd = v.end();
     927          83 :     for (; itr != itrEnd; ++itr)
     928           2 :         maNamedDBs.erase(*itr);
     929             : 
     930          81 :     remove_if(maAnonDBs.begin(), maAnonDBs.end(), func);
     931          81 : }
     932             : 
     933         255 : void ScDBCollection::UpdateReference(UpdateRefMode eUpdateRefMode,
     934             :                                 SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
     935             :                                 SCCOL nCol2, SCROW nRow2, SCTAB nTab2,
     936             :                                 SCsCOL nDx, SCsROW nDy, SCsTAB nDz )
     937             : {
     938         255 :     ScDBData* pData = pDoc->GetAnonymousDBData(nTab1);
     939         255 :     if (pData)
     940             :     {
     941           4 :         if (nTab1 == nTab2 && nDz == 0)
     942             :         {
     943             :             pData->UpdateReference(
     944             :                 pDoc, eUpdateRefMode,
     945           4 :                 nCol1, nRow1, nTab1, nCol2, nRow2, nTab2, nDx, nDy, nDz);
     946             :         }
     947             :         else
     948             :         {
     949             :             //this will perhabs break undo
     950             :         }
     951             :     }
     952             : 
     953         255 :     UpdateRefFunc func(pDoc, eUpdateRefMode, nCol1, nRow1, nTab1, nCol2, nRow2, nTab2, nDx, nDy, nDz);
     954         255 :     for_each(maNamedDBs.begin(), maNamedDBs.end(), func);
     955         255 :     for_each(maAnonDBs.begin(), maAnonDBs.end(), func);
     956         255 : }
     957             : 
     958          14 : void ScDBCollection::UpdateMoveTab( SCTAB nOldPos, SCTAB nNewPos )
     959             : {
     960          14 :     UpdateMoveTabFunc func(nOldPos, nNewPos);
     961          14 :     for_each(maNamedDBs.begin(), maNamedDBs.end(), func);
     962          14 :     for_each(maAnonDBs.begin(), maAnonDBs.end(), func);
     963          14 : }
     964             : 
     965          13 : ScDBData* ScDBCollection::GetDBNearCursor(SCCOL nCol, SCROW nRow, SCTAB nTab )
     966             : {
     967          13 :     ScDBData* pNearData = NULL;
     968          13 :     NamedDBs::DBsType::iterator itr = maNamedDBs.begin(), itrEnd = maNamedDBs.end();
     969          13 :     for (; itr != itrEnd; ++itr)
     970             :     {
     971             :         SCTAB nAreaTab;
     972             :         SCCOL nStartCol, nEndCol;
     973             :         SCROW nStartRow, nEndRow;
     974           0 :         itr->GetArea( nAreaTab, nStartCol, nStartRow, nEndCol, nEndRow );
     975           0 :         if ( nTab == nAreaTab && nCol+1 >= nStartCol && nCol <= nEndCol+1 &&
     976           0 :                                  nRow+1 >= nStartRow && nRow <= nEndRow+1 )
     977             :         {
     978           0 :             if ( nCol < nStartCol || nCol > nEndCol || nRow < nStartRow || nRow > nEndRow )
     979             :             {
     980           0 :                 if (!pNearData)
     981           0 :                     pNearData = &(*itr);    // ersten angrenzenden Bereich merken
     982             :             }
     983             :             else
     984           0 :                 return &(*itr);             // nicht "unbenannt" und Cursor steht wirklich drin
     985             :         }
     986             :     }
     987          13 :     if (pNearData)
     988           0 :         return pNearData;               // angrenzender, wenn nichts direkt getroffen
     989          13 :     return pDoc->GetAnonymousDBData(nTab);                  // "unbenannt" nur zurueck, wenn sonst nichts gefunden
     990             : }
     991             : 
     992          20 : bool ScDBCollection::empty() const
     993             : {
     994          20 :     return maNamedDBs.empty() && maAnonDBs.empty();
     995             : }
     996             : 
     997          49 : bool ScDBCollection::operator== (const ScDBCollection& r) const
     998             : {
     999         147 :     return maNamedDBs == r.maNamedDBs && maAnonDBs == r.maAnonDBs &&
    1000         147 :         nEntryIndex == r.nEntryIndex && pDoc == r.pDoc && aRefreshHandler == r.aRefreshHandler;
    1001             : }
    1002             : 
    1003             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10