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

Generated by: LCOV version 1.11