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

Generated by: LCOV version 1.10