LCOV - code coverage report
Current view: top level - sc/source/core/data - documen7.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 283 320 88.4 %
Date: 2014-04-11 Functions: 27 27 100.0 %
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 <vcl/svapp.hxx>
      21             : 
      22             : #include "document.hxx"
      23             : #include "brdcst.hxx"
      24             : #include "bcaslot.hxx"
      25             : #include "formulacell.hxx"
      26             : #include "formula/errorcodes.hxx"
      27             : #include "scerrors.hxx"
      28             : #include "docoptio.hxx"
      29             : #include "refupdat.hxx"
      30             : #include "table.hxx"
      31             : #include "progress.hxx"
      32             : #include "scmod.hxx"
      33             : #include "inputopt.hxx"
      34             : #include "conditio.hxx"
      35             : #include "colorscale.hxx"
      36             : #include "sheetevents.hxx"
      37             : #include "tokenarray.hxx"
      38             : #include "listenercontext.hxx"
      39             : #include "formulagroup.hxx"
      40             : #include <refhint.hxx>
      41             : 
      42             : #include <tools/shl.hxx>
      43             : 
      44             : 
      45             : #include "globstr.hrc"
      46             : 
      47             : extern const ScFormulaCell* pLastFormulaTreeTop;    // cellform.cxx Err527 WorkAround
      48             : 
      49             : // STATIC DATA -----------------------------------------------------------
      50             : 
      51        8181 : void ScDocument::StartListeningArea( const ScRange& rRange,
      52             :         SvtListener* pListener
      53             :     )
      54             : {
      55        8181 :     if ( pBASM )
      56        8181 :         pBASM->StartListeningArea( rRange, pListener );
      57        8181 : }
      58             : 
      59             : 
      60        6590 : void ScDocument::EndListeningArea( const ScRange& rRange,
      61             :         SvtListener* pListener
      62             :     )
      63             : {
      64        6590 :     if ( pBASM )
      65        6590 :         pBASM->EndListeningArea( rRange, pListener );
      66        6590 : }
      67             : 
      68       47750 : void ScDocument::Broadcast( const ScHint& rHint )
      69             : {
      70       47750 :     if ( !pBASM )
      71       48466 :         return ;    // Clipboard or Undo
      72       47034 :     if ( !bHardRecalcState )
      73             :     {
      74       46926 :         ScBulkBroadcast aBulkBroadcast( pBASM);     // scoped bulk broadcast
      75       46926 :         bool bIsBroadcasted = false;
      76       46926 :         SvtBroadcaster* pBC = GetBroadcaster(rHint.GetAddress());
      77       46926 :         if ( pBC )
      78             :         {
      79         310 :             pBC->Broadcast( rHint );
      80         310 :             bIsBroadcasted = true;
      81             :         }
      82       46926 :         if ( pBASM->AreaBroadcast( rHint ) || bIsBroadcasted )
      83         459 :             TrackFormulas( rHint.GetId() );
      84             :     }
      85             : 
      86             :     //  Repaint fuer bedingte Formate mit relativen Referenzen:
      87      123543 :     for(SCTAB nTab = 0; nTab < static_cast<SCTAB>(maTabs.size()); ++nTab)
      88             :     {
      89       76509 :         if(!maTabs[nTab])
      90           0 :             continue;
      91             : 
      92       76509 :         ScConditionalFormatList* pCondFormList = GetCondFormList(nTab);
      93       76509 :         if ( pCondFormList && rHint.GetAddress() != BCA_BRDCST_ALWAYS )
      94       47926 :             pCondFormList->SourceChanged( rHint.GetAddress() );
      95             : 
      96             :     }
      97             : 
      98       47034 :     if ( rHint.GetAddress() != BCA_BRDCST_ALWAYS )
      99             :     {
     100       32260 :         SCTAB nTab = rHint.GetAddress().Tab();
     101       32260 :         if (nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] && maTabs[nTab]->IsStreamValid())
     102          12 :             maTabs[nTab]->SetStreamValid(false);
     103             :     }
     104             : }
     105             : 
     106          15 : void ScDocument::BroadcastCells( const ScRange& rRange, sal_uLong nHint )
     107             : {
     108          15 :     ClearFormulaContext();
     109             : 
     110          15 :     ScBulkBroadcast aBulkBroadcast(pBASM);
     111             : 
     112          30 :     ScHint aHint(nHint, ScAddress());
     113          15 :     ScAddress& rPos = aHint.GetAddress();
     114          31 :     for (SCTAB nTab = rRange.aStart.Tab(); nTab <= rRange.aEnd.Tab(); ++nTab)
     115             :     {
     116          16 :         rPos.SetTab(nTab);
     117          42 :         for (SCCOL nCol = rRange.aStart.Col(); nCol <= rRange.aEnd.Col(); ++nCol)
     118             :         {
     119          26 :             rPos.SetCol(nCol);
     120          94 :             for (SCROW nRow = rRange.aStart.Row(); nRow <= rRange.aEnd.Row(); ++nRow)
     121             :             {
     122          68 :                 rPos.SetRow(nRow);
     123          68 :                 Broadcast(aHint);
     124             :             }
     125             :         }
     126             :     }
     127             : 
     128          30 :     BroadcastUno(SfxSimpleHint(SC_HINT_DATACHANGED));
     129          15 : }
     130             : 
     131           3 : void ScDocument::BroadcastRefMoved( const sc::RefMovedHint& rHint )
     132             : {
     133           3 :     if (!pBASM)
     134             :         // clipboard or undo document.
     135           3 :         return;
     136             : 
     137           3 :     const ScRange& rSrcRange = rHint.getRange(); // old range
     138           3 :     const ScAddress& rDelta = rHint.getDelta();
     139             : 
     140             :     // Get all area listeners that listens on the old range, and end their listening.
     141           3 :     std::vector<sc::AreaListener> aAreaListeners = pBASM->GetAllListeners(rSrcRange);
     142             :     {
     143           3 :         std::vector<sc::AreaListener>::iterator it = aAreaListeners.begin(), itEnd = aAreaListeners.end();
     144           5 :         for (; it != itEnd; ++it)
     145             :         {
     146           2 :             pBASM->EndListeningArea(it->maArea, it->mpListener);
     147           2 :             it->mpListener->Notify(rHint); // Adjust the references.
     148             :         }
     149             :     }
     150             : 
     151           6 :     for (SCTAB nTab = rSrcRange.aStart.Tab(); nTab <= rSrcRange.aEnd.Tab(); ++nTab)
     152             :     {
     153           3 :         ScTable* pTab = FetchTable(nTab);
     154           3 :         if (!pTab)
     155           0 :             continue;
     156             : 
     157           3 :         SCTAB nDestTab = nTab + rDelta.Tab();
     158           3 :         ScTable* pDestTab = FetchTable(nDestTab);
     159           3 :         if (!pDestTab)
     160           0 :             continue;
     161             : 
     162             :         // Adjust the references.
     163           3 :         pTab->BroadcastRefMoved(rHint);
     164             :         // Move the listeners from the old location to the new.
     165             :         pTab->TransferListeners(
     166           3 :             *pDestTab, rSrcRange.aStart.Col(), rSrcRange.aStart.Row(),
     167           6 :             rSrcRange.aEnd.Col(), rSrcRange.aEnd.Row(), rDelta.Col(), rDelta.Row());
     168             :     }
     169             : 
     170             :     // Re-start area listeners on the new range.
     171             :     {
     172           3 :         std::vector<sc::AreaListener>::iterator it = aAreaListeners.begin(), itEnd = aAreaListeners.end();
     173           5 :         for (; it != itEnd; ++it)
     174             :         {
     175           2 :             ScRange aNewRange = it->maArea;
     176           2 :             aNewRange.Move(rDelta.Col(), rDelta.Row(), rDelta.Tab());
     177           2 :             pBASM->StartListeningArea(aNewRange, it->mpListener);
     178             :         }
     179           3 :     }
     180             : }
     181             : 
     182          13 : void ScDocument::AreaBroadcast( const ScHint& rHint )
     183             : {
     184          13 :     if ( !pBASM )
     185          13 :         return ;    // Clipboard or Undo
     186          13 :     if ( !bHardRecalcState )
     187             :     {
     188          13 :         ScBulkBroadcast aBulkBroadcast( pBASM);     // scoped bulk broadcast
     189          13 :         if ( pBASM->AreaBroadcast( rHint ) )
     190           0 :             TrackFormulas( rHint.GetId() );
     191             :     }
     192             : 
     193          29 :     for(SCTAB nTab = 0; nTab < static_cast<SCTAB>(maTabs.size()); ++nTab)
     194             :     {
     195          16 :         if(!maTabs[nTab])
     196           0 :             continue;
     197             : 
     198          16 :         ScConditionalFormatList* pCondFormList = GetCondFormList(nTab);
     199          16 :         if ( pCondFormList && rHint.GetAddress() != BCA_BRDCST_ALWAYS )
     200          16 :             pCondFormList->SourceChanged( rHint.GetAddress() );
     201             :     }
     202             : }
     203             : 
     204             : 
     205          38 : void ScDocument::AreaBroadcastInRange( const ScRange& rRange, const ScHint& rHint )
     206             : {
     207          38 :     if ( !pBASM )
     208          38 :         return ;    // Clipboard or Undo
     209          38 :     if ( !bHardRecalcState )
     210             :     {
     211          38 :         ScBulkBroadcast aBulkBroadcast( pBASM);     // scoped bulk broadcast
     212          38 :         if ( pBASM->AreaBroadcastInRange( rRange, rHint ) )
     213           0 :             TrackFormulas( rHint.GetId() );
     214             :     }
     215             : 
     216             :     // Repaint for conditional formats containing relative references.
     217             :     //! This is _THE_ bottle neck!
     218          38 :     TableContainer::iterator itr = maTabs.begin();
     219          76 :     for(; itr != maTabs.end(); ++itr)
     220             :     {
     221          38 :         if(!*itr)
     222           0 :             continue;
     223             : 
     224          38 :         ScConditionalFormatList* pCondFormList = (*itr)->GetCondFormList();
     225          38 :         if ( pCondFormList )
     226             :         {
     227             :             SCCOL nCol1;
     228             :             SCROW nRow1;
     229             :             SCTAB nTab1;
     230             :             SCCOL nCol2;
     231             :             SCROW nRow2;
     232             :             SCTAB nTab2;
     233          38 :             rRange.GetVars( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
     234          38 :             ScAddress aAddress( rRange.aStart );
     235          76 :             for ( SCTAB nTab = nTab1; nTab <= nTab2; ++nTab )
     236             :             {
     237          38 :                 aAddress.SetTab( nTab );
     238          76 :                 for ( SCCOL nCol = nCol1; nCol <= nCol2; ++nCol )
     239             :                 {
     240          38 :                     aAddress.SetCol( nCol );
     241         159 :                     for ( SCROW nRow = nRow1; nRow <= nRow2; ++nRow )
     242             :                     {
     243         121 :                         aAddress.SetRow( nRow );
     244         121 :                         pCondFormList->SourceChanged( aAddress );
     245             :                     }
     246             :                 }
     247             :             }
     248             :         }
     249             : 
     250             :     }
     251             : }
     252             : 
     253             : 
     254         136 : void ScDocument::DelBroadcastAreasInRange( const ScRange& rRange )
     255             : {
     256         136 :     if ( pBASM )
     257         136 :         pBASM->DelBroadcastAreasInRange( rRange );
     258         136 : }
     259             : 
     260        6179 : void ScDocument::StartListeningCell( const ScAddress& rAddress,
     261             :                                             SvtListener* pListener )
     262             : {
     263             :     OSL_ENSURE(pListener, "StartListeningCell: pListener Null");
     264        6179 :     SCTAB nTab = rAddress.Tab();
     265        6179 :     if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab])
     266        6154 :         maTabs[nTab]->StartListening( rAddress, pListener );
     267        6179 : }
     268             : 
     269         422 : void ScDocument::EndListeningCell( const ScAddress& rAddress,
     270             :                                             SvtListener* pListener )
     271             : {
     272             :     OSL_ENSURE(pListener, "EndListeningCell: pListener Null");
     273         422 :     SCTAB nTab = rAddress.Tab();
     274         422 :     if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab])
     275         406 :         maTabs[nTab]->EndListening( rAddress, pListener );
     276         422 : }
     277             : 
     278        5996 : void ScDocument::StartListeningCell(
     279             :     sc::StartListeningContext& rCxt, const ScAddress& rPos, SvtListener& rListener )
     280             : {
     281        5996 :     ScTable* pTab = FetchTable(rPos.Tab());
     282        5996 :     if (!pTab)
     283        5996 :         return;
     284             : 
     285        5996 :     pTab->StartListening(rCxt, rPos.Col(), rPos.Row(), rListener);
     286             : }
     287             : 
     288         218 : void ScDocument::EndListeningCell(
     289             :     sc::EndListeningContext& rCxt, const ScAddress& rPos, SvtListener& rListener )
     290             : {
     291         218 :     ScTable* pTab = FetchTable(rPos.Tab());
     292         218 :     if (!pTab)
     293         218 :         return;
     294             : 
     295         218 :     pTab->EndListening(rCxt, rPos.Col(), rPos.Row(), rListener);
     296             : }
     297             : 
     298        4408 : void ScDocument::EndListeningFormulaCells( std::vector<ScFormulaCell*>& rCells )
     299             : {
     300        4408 :     if (rCells.empty())
     301        8712 :         return;
     302             : 
     303         104 :     sc::EndListeningContext aCxt(*this);
     304         104 :     std::vector<ScFormulaCell*>::iterator it = rCells.begin(), itEnd = rCells.end();
     305         381 :     for (; it != itEnd; ++it)
     306         277 :         (*it)->EndListeningTo(aCxt);
     307             : 
     308         104 :     aCxt.purgeEmptyBroadcasters();
     309             : }
     310             : 
     311       25665 : void ScDocument::PutInFormulaTree( ScFormulaCell* pCell )
     312             : {
     313             :     OSL_ENSURE( pCell, "PutInFormulaTree: pCell Null" );
     314       25665 :     RemoveFromFormulaTree( pCell );
     315             :     // anhaengen
     316       25665 :     if ( pEOFormulaTree )
     317       24996 :         pEOFormulaTree->SetNext( pCell );
     318             :     else
     319         669 :         pFormulaTree = pCell;               // kein Ende, kein Anfang..
     320       25665 :     pCell->SetPrevious( pEOFormulaTree );
     321       25665 :     pCell->SetNext( 0 );
     322       25665 :     pEOFormulaTree = pCell;
     323       25665 :     nFormulaCodeInTree += pCell->GetCode()->GetCodeLen();
     324       25665 : }
     325             : 
     326             : 
     327       66832 : void ScDocument::RemoveFromFormulaTree( ScFormulaCell* pCell )
     328             : {
     329             :     OSL_ENSURE( pCell, "RemoveFromFormulaTree: pCell Null" );
     330       66832 :     ScFormulaCell* pPrev = pCell->GetPrevious();
     331             :     // wenn die Zelle die erste oder sonstwo ist
     332       66832 :     if ( pPrev || pFormulaTree == pCell )
     333             :     {
     334       25503 :         ScFormulaCell* pNext = pCell->GetNext();
     335       25503 :         if ( pPrev )
     336        2614 :             pPrev->SetNext( pNext );        // gibt Vorlaeufer
     337             :         else
     338       22889 :             pFormulaTree = pNext;           // ist erste Zelle
     339       25503 :         if ( pNext )
     340       24576 :             pNext->SetPrevious( pPrev );    // gibt Nachfolger
     341             :         else
     342         927 :             pEOFormulaTree = pPrev;         // ist letzte Zelle
     343       25503 :         pCell->SetPrevious( 0 );
     344       25503 :         pCell->SetNext( 0 );
     345       25503 :         sal_uInt16 nRPN = pCell->GetCode()->GetCodeLen();
     346       25503 :         if ( nFormulaCodeInTree >= nRPN )
     347       25503 :             nFormulaCodeInTree -= nRPN;
     348             :         else
     349             :         {
     350             :             OSL_FAIL( "RemoveFromFormulaTree: nFormulaCodeInTree < nRPN" );
     351           0 :             nFormulaCodeInTree = 0;
     352       25503 :         }
     353             :     }
     354       41329 :     else if ( !pFormulaTree && nFormulaCodeInTree )
     355             :     {
     356             :         OSL_FAIL( "!pFormulaTree && nFormulaCodeInTree != 0" );
     357           0 :         nFormulaCodeInTree = 0;
     358             :     }
     359       66832 : }
     360             : 
     361             : 
     362       66577 : bool ScDocument::IsInFormulaTree( ScFormulaCell* pCell ) const
     363             : {
     364       66577 :     return pCell->GetPrevious() || pFormulaTree == pCell;
     365             : }
     366             : 
     367             : 
     368          53 : void ScDocument::CalcFormulaTree( bool bOnlyForced, bool bProgressBar, bool bSetAllDirty )
     369             : {
     370             :     OSL_ENSURE( !IsCalculatingFormulaTree(), "CalcFormulaTree recursion" );
     371             :     // never ever recurse into this, might end up lost in infinity
     372          53 :     if ( IsCalculatingFormulaTree() )
     373          53 :         return ;
     374             : 
     375          53 :     mpFormulaGroupCxt.reset();
     376          53 :     bCalculatingFormulaTree = true;
     377             : 
     378          53 :     SetForcedFormulaPending( false );
     379          53 :     bool bOldIdleEnabled = IsIdleEnabled();
     380          53 :     EnableIdle(false);
     381          53 :     bool bOldAutoCalc = GetAutoCalc();
     382             :     //! _nicht_ SetAutoCalc( true ) weil das evtl. CalcFormulaTree( true )
     383             :     //! aufruft, wenn vorher disabled war und bHasForcedFormulas gesetzt ist
     384          53 :     bAutoCalc = true;
     385          53 :     if ( bHardRecalcState )
     386           0 :         CalcAll();
     387             :     else
     388             :     {
     389          53 :         ScFormulaCell* pCell = pFormulaTree;
     390         199 :         while ( pCell )
     391             :         {
     392          93 :             if ( pCell->GetDirty() )
     393          91 :                 pCell = pCell->GetNext();       // alles klar
     394             :             else
     395             :             {
     396           2 :                 if ( pCell->GetCode()->IsRecalcModeAlways() )
     397             :                 {
     398             :                     // pCell wird im SetDirty neu angehaengt!
     399           2 :                     ScFormulaCell* pNext = pCell->GetNext();
     400           2 :                     pCell->SetDirty();
     401             :                     // falls pNext==0 und neue abhaengige hinten angehaengt
     402             :                     // wurden, so macht das nichts, da die alle bDirty sind
     403           2 :                     pCell = pNext;
     404             :                 }
     405             :                 else
     406             :                 {   // andere simpel berechnen
     407           0 :                     if( bSetAllDirty )
     408           0 :                         pCell->SetDirtyVar();
     409           0 :                     pCell = pCell->GetNext();
     410             :                 }
     411             :             }
     412             :         }
     413          53 :         bool bProgress = !bOnlyForced && nFormulaCodeInTree && bProgressBar;
     414          53 :         if ( bProgress )
     415           5 :             ScProgress::CreateInterpretProgress( this, true );
     416             : 
     417          53 :         pCell = pFormulaTree;
     418          53 :         ScFormulaCell* pLastNoGood = 0;
     419         199 :         while ( pCell )
     420             :         {
     421             :             // Interpret setzt bDirty zurueck und callt Remove, auch der referierten!
     422             :             // bei RECALCMODE_ALWAYS bleibt die Zelle
     423          93 :             if ( bOnlyForced )
     424             :             {
     425           0 :                 if ( pCell->GetCode()->IsRecalcModeForced() )
     426           0 :                     pCell->Interpret();
     427             :             }
     428             :             else
     429             :             {
     430          93 :                 pCell->Interpret();
     431             :             }
     432          93 :             if ( pCell->GetPrevious() || pCell == pFormulaTree )
     433             :             {   // (IsInFormulaTree(pCell)) kein Remove gewesen => next
     434           2 :                 pLastNoGood = pCell;
     435           2 :                 pCell = pCell->GetNext();
     436             :             }
     437             :             else
     438             :             {
     439          91 :                 if ( pFormulaTree )
     440             :                 {
     441          83 :                     if ( pFormulaTree->GetDirty() && !bOnlyForced )
     442             :                     {
     443          83 :                         pCell = pFormulaTree;
     444          83 :                         pLastNoGood = 0;
     445             :                     }
     446             :                     else
     447             :                     {
     448             :                         // IsInFormulaTree(pLastNoGood)
     449           0 :                         if ( pLastNoGood && (pLastNoGood->GetPrevious() ||
     450           0 :                                 pLastNoGood == pFormulaTree) )
     451           0 :                             pCell = pLastNoGood->GetNext();
     452             :                         else
     453             :                         {
     454           0 :                             pCell = pFormulaTree;
     455           0 :                             while ( pCell && !pCell->GetDirty() )
     456           0 :                                 pCell = pCell->GetNext();
     457           0 :                             if ( pCell )
     458           0 :                                 pLastNoGood = pCell->GetPrevious();
     459             :                         }
     460             :                     }
     461             :                 }
     462             :                 else
     463           8 :                     pCell = 0;
     464             :             }
     465          93 :             if ( ScProgress::IsUserBreak() )
     466           0 :                 pCell = 0;
     467             :         }
     468          53 :         if ( bProgress )
     469           5 :             ScProgress::DeleteInterpretProgress();
     470             :     }
     471          53 :     bAutoCalc = bOldAutoCalc;
     472          53 :     EnableIdle(bOldIdleEnabled);
     473          53 :     bCalculatingFormulaTree = false;
     474             : 
     475          53 :     mpFormulaGroupCxt.reset();
     476             : }
     477             : 
     478             : 
     479         189 : void ScDocument::ClearFormulaTree()
     480             : {
     481             :     ScFormulaCell* pCell;
     482         189 :     ScFormulaCell* pTree = pFormulaTree;
     483         558 :     while ( pTree )
     484             :     {
     485         180 :         pCell = pTree;
     486         180 :         pTree = pCell->GetNext();
     487         180 :         if ( !pCell->GetCode()->IsRecalcModeAlways() )
     488         156 :             RemoveFromFormulaTree( pCell );
     489             :     }
     490         189 : }
     491             : 
     492             : 
     493       22742 : void ScDocument::AppendToFormulaTrack( ScFormulaCell* pCell )
     494             : {
     495             :     OSL_ENSURE( pCell, "AppendToFormulaTrack: pCell Null" );
     496             :     // Zelle kann nicht in beiden Listen gleichzeitig sein
     497       22742 :     RemoveFromFormulaTrack( pCell );
     498       22742 :     RemoveFromFormulaTree( pCell );
     499       22742 :     if ( pEOFormulaTrack )
     500       21105 :         pEOFormulaTrack->SetNextTrack( pCell );
     501             :     else
     502        1637 :         pFormulaTrack = pCell;              // kein Ende, kein Anfang..
     503       22742 :     pCell->SetPreviousTrack( pEOFormulaTrack );
     504       22742 :     pCell->SetNextTrack( 0 );
     505       22742 :     pEOFormulaTrack = pCell;
     506       22742 :     ++nFormulaTrackCount;
     507       22742 : }
     508             : 
     509             : 
     510       45484 : void ScDocument::RemoveFromFormulaTrack( ScFormulaCell* pCell )
     511             : {
     512             :     OSL_ENSURE( pCell, "RemoveFromFormulaTrack: pCell Null" );
     513       45484 :     ScFormulaCell* pPrev = pCell->GetPreviousTrack();
     514             :     // wenn die Zelle die erste oder sonstwo ist
     515       45484 :     if ( pPrev || pFormulaTrack == pCell )
     516             :     {
     517       22742 :         ScFormulaCell* pNext = pCell->GetNextTrack();
     518       22742 :         if ( pPrev )
     519           0 :             pPrev->SetNextTrack( pNext );       // gibt Vorlaeufer
     520             :         else
     521       22742 :             pFormulaTrack = pNext;              // ist erste Zelle
     522       22742 :         if ( pNext )
     523       21105 :             pNext->SetPreviousTrack( pPrev );   // gibt Nachfolger
     524             :         else
     525        1637 :             pEOFormulaTrack = pPrev;            // ist letzte Zelle
     526       22742 :         pCell->SetPreviousTrack( 0 );
     527       22742 :         pCell->SetNextTrack( 0 );
     528       22742 :         --nFormulaTrackCount;
     529             :     }
     530       45484 : }
     531             : 
     532             : 
     533       21514 : bool ScDocument::IsInFormulaTrack( ScFormulaCell* pCell ) const
     534             : {
     535       21514 :     return pCell->GetPreviousTrack() || pFormulaTrack == pCell;
     536             : }
     537             : 
     538             : 
     539             : /*
     540             :     Der erste wird gebroadcastet,
     541             :     die dadurch entstehenden werden durch das Notify an den Track gehaengt.
     542             :     Der nachfolgende broadcastet wieder usw.
     543             :     View stoesst Interpret an.
     544             :  */
     545        1857 : void ScDocument::TrackFormulas( sal_uLong nHintId )
     546             : {
     547             : 
     548        1857 :     if ( pFormulaTrack )
     549             :     {
     550             :         // outside the loop, check if any sheet has a "calculate" event script
     551        1637 :         bool bCalcEvent = HasAnySheetEventScript( SC_SHEETEVENT_CALCULATE, true );
     552             :         SvtBroadcaster* pBC;
     553             :         ScFormulaCell* pTrack;
     554             :         ScFormulaCell* pNext;
     555        1637 :         pTrack = pFormulaTrack;
     556       22742 :         do
     557             :         {
     558       22742 :             pBC = GetBroadcaster(pTrack->aPos);
     559       22742 :             ScHint aHint(nHintId, pTrack->aPos);
     560       22742 :             if (pBC)
     561         407 :                 pBC->Broadcast( aHint );
     562       22742 :             pBASM->AreaBroadcast( aHint );
     563             :             //  Repaint fuer bedingte Formate mit relativen Referenzen:
     564       22742 :             TableContainer::iterator itr = maTabs.begin();
     565       46494 :             for(; itr != maTabs.end(); ++itr)
     566             :             {
     567       23752 :                 if(!*itr)
     568           0 :                     continue;
     569       23752 :                 ScConditionalFormatList* pCondFormList = (*itr)->GetCondFormList();
     570       23752 :                 if ( pCondFormList )
     571       23752 :                     pCondFormList->SourceChanged( pTrack->aPos );
     572             :             }
     573             :             // for "calculate" event, keep track of which sheets are affected by tracked formulas
     574       22742 :             if ( bCalcEvent )
     575           0 :                 SetCalcNotification( pTrack->aPos.Tab() );
     576       22742 :             pTrack = pTrack->GetNextTrack();
     577             :         } while ( pTrack );
     578        1637 :         pTrack = pFormulaTrack;
     579        1637 :         bool bHaveForced = false;
     580       22742 :         do
     581             :         {
     582       22742 :             pNext = pTrack->GetNextTrack();
     583       22742 :             RemoveFromFormulaTrack( pTrack );
     584       22742 :             PutInFormulaTree( pTrack );
     585       22742 :             if ( pTrack->GetCode()->IsRecalcModeForced() )
     586           0 :                 bHaveForced = true;
     587       22742 :             pTrack = pNext;
     588             :         } while ( pTrack );
     589        1637 :         if ( bHaveForced )
     590             :         {
     591           0 :             SetForcedFormulas( true );
     592           0 :             if ( bAutoCalc && !IsAutoCalcShellDisabled() && !IsInInterpreter()
     593           0 :                     && !IsCalculatingFormulaTree() )
     594           0 :                 CalcFormulaTree( true );
     595             :             else
     596           0 :                 SetForcedFormulaPending( true );
     597             :         }
     598             :     }
     599             :     OSL_ENSURE( nFormulaTrackCount==0, "TrackFormulas: nFormulaTrackCount!=0" );
     600        1857 : }
     601             : 
     602             : 
     603           7 : void ScDocument::StartAllListeners()
     604             : {
     605          14 :     for ( SCTAB i = 0; i < static_cast<SCTAB>(maTabs.size()); ++i )
     606           7 :         if ( maTabs[i] )
     607           7 :             maTabs[i]->StartAllListeners();
     608           7 : }
     609             : 
     610         245 : void ScDocument::UpdateBroadcastAreas( UpdateRefMode eUpdateRefMode,
     611             :         const ScRange& rRange, SCsCOL nDx, SCsROW nDy, SCsTAB nDz
     612             :     )
     613             : {
     614         245 :     bool bExpandRefsOld = IsExpandRefs();
     615         245 :     if ( eUpdateRefMode == URM_INSDEL && (nDx > 0 || nDy > 0 || nDz > 0) )
     616         110 :         SetExpandRefs( SC_MOD()->GetInputOptions().GetExpandRefs() );
     617         245 :     if ( pBASM )
     618         245 :         pBASM->UpdateBroadcastAreas( eUpdateRefMode, rRange, nDx, nDy, nDz );
     619         245 :     SetExpandRefs( bExpandRefsOld );
     620         245 : }
     621             : 
     622     2360774 : void ScDocument::SetAutoCalc( bool bNewAutoCalc )
     623             : {
     624     2360774 :     bool bOld = bAutoCalc;
     625     2360774 :     bAutoCalc = bNewAutoCalc;
     626     2360774 :     if ( !bOld && bNewAutoCalc && bHasForcedFormulas )
     627             :     {
     628           0 :         if ( IsAutoCalcShellDisabled() )
     629           0 :             SetForcedFormulaPending( true );
     630           0 :         else if ( !IsInInterpreter() )
     631           0 :             CalcFormulaTree( true );
     632             :     }
     633     2360876 : }
     634             : 
     635             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10