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

Generated by: LCOV version 1.10