Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include <vcl/svapp.hxx>
30 : :
31 : : #include "document.hxx"
32 : : #include "brdcst.hxx"
33 : : #include "bcaslot.hxx"
34 : : #include "cell.hxx"
35 : : #include "formula/errorcodes.hxx" // errCircularReference
36 : : #include "scerrors.hxx"
37 : : #include "docoptio.hxx"
38 : : #include "refupdat.hxx"
39 : : #include "table.hxx"
40 : : #include "progress.hxx"
41 : : #include "scmod.hxx" // SC_MOD
42 : : #include "inputopt.hxx" // GetExpandRefs
43 : : #include "conditio.hxx"
44 : : #include "colorscale.hxx"
45 : : #include "sheetevents.hxx"
46 : : #include <tools/shl.hxx>
47 : :
48 : :
49 : : #include "globstr.hrc"
50 : :
51 : : extern const ScFormulaCell* pLastFormulaTreeTop; // cellform.cxx Err527 WorkAround
52 : :
53 : : // STATIC DATA -----------------------------------------------------------
54 : :
55 : : // -----------------------------------------------------------------------
56 : :
57 : 10410 : void ScDocument::StartListeningArea( const ScRange& rRange,
58 : : SvtListener* pListener
59 : : )
60 : : {
61 [ + - ]: 10410 : if ( pBASM )
62 : 10410 : pBASM->StartListeningArea( rRange, pListener );
63 : 10410 : }
64 : :
65 : :
66 : 2769 : void ScDocument::EndListeningArea( const ScRange& rRange,
67 : : SvtListener* pListener
68 : : )
69 : : {
70 [ + - ]: 2769 : if ( pBASM )
71 : 2769 : pBASM->EndListeningArea( rRange, pListener );
72 : 2769 : }
73 : :
74 : :
75 : 10023 : void ScDocument::Broadcast( sal_uLong nHint, const ScAddress& rAddr,
76 : : ScBaseCell* pCell
77 : : )
78 : : {
79 [ + - ]: 10023 : if ( !pBASM )
80 : 10023 : return ; // Clipboard or Undo
81 [ + - ]: 10023 : ScHint aHint( nHint, rAddr, pCell );
82 [ + - ][ + - ]: 10023 : Broadcast( aHint );
83 : : }
84 : :
85 : :
86 : 42052 : void ScDocument::Broadcast( const ScHint& rHint )
87 : : {
88 [ + + ]: 42052 : if ( !pBASM )
89 : 42052 : return ; // Clipboard or Undo
90 [ + + ]: 41566 : if ( !bHardRecalcState )
91 : : {
92 [ + - ]: 41472 : ScBulkBroadcast aBulkBroadcast( pBASM); // scoped bulk broadcast
93 : 41472 : bool bIsBroadcasted = false;
94 : 41472 : ScBaseCell* pCell = rHint.GetCell();
95 [ + + ]: 41472 : if ( pCell )
96 : : {
97 : 31543 : SvtBroadcaster* pBC = pCell->GetBroadcaster();
98 [ + + ]: 31543 : if ( pBC )
99 : : {
100 [ + - ]: 491 : pBC->Broadcast( rHint );
101 : 491 : bIsBroadcasted = true;
102 : : }
103 : : }
104 [ + - ][ + + ]: 41472 : if ( pBASM->AreaBroadcast( rHint ) || bIsBroadcasted )
[ + + ][ + + ]
105 [ + - ][ + - ]: 41472 : TrackFormulas( rHint.GetId() );
106 : : }
107 : :
108 : : // Repaint fuer bedingte Formate mit relativen Referenzen:
109 [ + + ]: 98567 : for(SCTAB nTab = 0; nTab < static_cast<SCTAB>(maTabs.size()); ++nTab)
110 : : {
111 [ - + ]: 57001 : if(!maTabs[nTab])
112 : 0 : continue;
113 : :
114 : 57001 : ScConditionalFormatList* pCondFormList = GetCondFormList(nTab);
115 [ + + ][ + - ]: 57001 : if ( pCondFormList && rHint.GetAddress() != BCA_BRDCST_ALWAYS )
[ + + ][ + - ]
116 : 40792 : pCondFormList->SourceChanged( rHint.GetAddress() );
117 : :
118 : : }
119 : :
120 [ + + ]: 41566 : if ( rHint.GetAddress() != BCA_BRDCST_ALWAYS )
121 : : {
122 : 31543 : SCTAB nTab = rHint.GetAddress().Tab();
123 [ + - ][ + + ]: 31543 : if (nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] && maTabs[nTab]->IsStreamValid())
[ + + ][ + - ]
124 : 14 : maTabs[nTab]->SetStreamValid(false);
125 : : }
126 : : }
127 : :
128 : :
129 : 0 : void ScDocument::AreaBroadcast( const ScHint& rHint )
130 : : {
131 [ # # ]: 0 : if ( !pBASM )
132 : 0 : return ; // Clipboard or Undo
133 [ # # ]: 0 : if ( !bHardRecalcState )
134 : : {
135 [ # # ]: 0 : ScBulkBroadcast aBulkBroadcast( pBASM); // scoped bulk broadcast
136 [ # # ][ # # ]: 0 : if ( pBASM->AreaBroadcast( rHint ) )
137 [ # # ][ # # ]: 0 : TrackFormulas( rHint.GetId() );
138 : : }
139 : :
140 [ # # ]: 0 : for(SCTAB nTab = 0; nTab < static_cast<SCTAB>(maTabs.size()); ++nTab)
141 : : {
142 [ # # ]: 0 : if(!maTabs[nTab])
143 : 0 : continue;
144 : :
145 : 0 : ScConditionalFormatList* pCondFormList = GetCondFormList(nTab);
146 [ # # ][ # # ]: 0 : if ( pCondFormList && rHint.GetAddress() != BCA_BRDCST_ALWAYS )
[ # # ][ # # ]
147 : 0 : pCondFormList->SourceChanged( rHint.GetAddress() );
148 : : }
149 : : }
150 : :
151 : :
152 : 13 : void ScDocument::AreaBroadcastInRange( const ScRange& rRange, const ScHint& rHint )
153 : : {
154 [ + - ]: 13 : if ( !pBASM )
155 : 13 : return ; // Clipboard or Undo
156 [ + - ]: 13 : if ( !bHardRecalcState )
157 : : {
158 [ + - ]: 13 : ScBulkBroadcast aBulkBroadcast( pBASM); // scoped bulk broadcast
159 [ + - ][ - + ]: 13 : if ( pBASM->AreaBroadcastInRange( rRange, rHint ) )
160 [ # # ][ + - ]: 13 : TrackFormulas( rHint.GetId() );
161 : : }
162 : :
163 : : // Repaint for conditional formats containing relative references.
164 : : //! This is _THE_ bottle neck!
165 : 13 : TableContainer::iterator itr = maTabs.begin();
166 [ + - ][ + + ]: 35 : for(; itr != maTabs.end(); ++itr)
167 : : {
168 [ - + ]: 22 : if(!*itr)
169 : 0 : continue;
170 : :
171 [ + - ]: 22 : ScConditionalFormatList* pCondFormList = (*itr)->GetCondFormList();
172 [ + - ]: 22 : if ( pCondFormList )
173 : : {
174 : : SCCOL nCol1;
175 : : SCROW nRow1;
176 : : SCTAB nTab1;
177 : : SCCOL nCol2;
178 : : SCROW nRow2;
179 : : SCTAB nTab2;
180 : 22 : rRange.GetVars( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
181 : 22 : ScAddress aAddress( rRange.aStart );
182 [ + + ]: 44 : for ( SCTAB nTab = nTab1; nTab <= nTab2; ++nTab )
183 : : {
184 : 22 : aAddress.SetTab( nTab );
185 [ + + ]: 44 : for ( SCCOL nCol = nCol1; nCol <= nCol2; ++nCol )
186 : : {
187 : 22 : aAddress.SetCol( nCol );
188 [ + + ]: 74 : for ( SCROW nRow = nRow1; nRow <= nRow2; ++nRow )
189 : : {
190 : 52 : aAddress.SetRow( nRow );
191 [ + - ]: 52 : pCondFormList->SourceChanged( aAddress );
192 : : }
193 : : }
194 : : }
195 : : }
196 : :
197 : : }
198 : : }
199 : :
200 : :
201 : 128 : void ScDocument::DelBroadcastAreasInRange( const ScRange& rRange )
202 : : {
203 [ + - ]: 128 : if ( pBASM )
204 : 128 : pBASM->DelBroadcastAreasInRange( rRange );
205 : 128 : }
206 : :
207 : 5121 : void ScDocument::StartListeningCell( const ScAddress& rAddress,
208 : : SvtListener* pListener )
209 : : {
210 : : OSL_ENSURE(pListener, "StartListeningCell: pListener Null");
211 : 5121 : SCTAB nTab = rAddress.Tab();
212 [ + - ][ + - ]: 5121 : if (VALIDTAB(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab])
[ + - ][ + - ]
213 : 5121 : maTabs[nTab]->StartListening( rAddress, pListener );
214 : 5121 : }
215 : :
216 : 488 : void ScDocument::EndListeningCell( const ScAddress& rAddress,
217 : : SvtListener* pListener )
218 : : {
219 : : OSL_ENSURE(pListener, "EndListeningCell: pListener Null");
220 : 488 : SCTAB nTab = rAddress.Tab();
221 [ + - ][ + - ]: 488 : if (VALIDTAB(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab])
[ + - ][ + - ]
222 : 488 : maTabs[nTab]->EndListening( rAddress, pListener );
223 : 488 : }
224 : :
225 : :
226 : 4350 : void ScDocument::PutInFormulaTree( ScFormulaCell* pCell )
227 : : {
228 : : OSL_ENSURE( pCell, "PutInFormulaTree: pCell Null" );
229 : 4350 : RemoveFromFormulaTree( pCell );
230 : : // anhaengen
231 [ + + ]: 4350 : if ( pEOFormulaTree )
232 : 3856 : pEOFormulaTree->SetNext( pCell );
233 : : else
234 : 494 : pFormulaTree = pCell; // kein Ende, kein Anfang..
235 : 4350 : pCell->SetPrevious( pEOFormulaTree );
236 : 4350 : pCell->SetNext( 0 );
237 : 4350 : pEOFormulaTree = pCell;
238 : 4350 : nFormulaCodeInTree += pCell->GetCode()->GetCodeLen();
239 : 4350 : }
240 : :
241 : :
242 : 15625 : void ScDocument::RemoveFromFormulaTree( ScFormulaCell* pCell )
243 : : {
244 : : OSL_ENSURE( pCell, "RemoveFromFormulaTree: pCell Null" );
245 : 15625 : ScFormulaCell* pPrev = pCell->GetPrevious();
246 : : // wenn die Zelle die erste oder sonstwo ist
247 [ + + ][ + + ]: 15625 : if ( pPrev || pFormulaTree == pCell )
248 : : {
249 : 4304 : ScFormulaCell* pNext = pCell->GetNext();
250 [ + + ]: 4304 : if ( pPrev )
251 : 2429 : pPrev->SetNext( pNext ); // gibt Vorlaeufer
252 : : else
253 : 1875 : pFormulaTree = pNext; // ist erste Zelle
254 [ + + ]: 4304 : if ( pNext )
255 : 3455 : pNext->SetPrevious( pPrev ); // gibt Nachfolger
256 : : else
257 : 849 : pEOFormulaTree = pPrev; // ist letzte Zelle
258 : 4304 : pCell->SetPrevious( 0 );
259 : 4304 : pCell->SetNext( 0 );
260 : 4304 : sal_uInt16 nRPN = pCell->GetCode()->GetCodeLen();
261 [ + + ]: 4304 : if ( nFormulaCodeInTree >= nRPN )
262 : 4235 : nFormulaCodeInTree -= nRPN;
263 : : else
264 : : {
265 : : OSL_FAIL( "RemoveFromFormulaTree: nFormulaCodeInTree < nRPN" );
266 : 69 : nFormulaCodeInTree = 0;
267 : 4304 : }
268 : : }
269 [ + + ][ - + ]: 11321 : else if ( !pFormulaTree && nFormulaCodeInTree )
270 : : {
271 : : OSL_FAIL( "!pFormulaTree && nFormulaCodeInTree != 0" );
272 : 0 : nFormulaCodeInTree = 0;
273 : : }
274 : 15625 : }
275 : :
276 : :
277 : 4666 : bool ScDocument::IsInFormulaTree( ScFormulaCell* pCell ) const
278 : : {
279 [ + + ][ + + ]: 4666 : return pCell->GetPrevious() || pFormulaTree == pCell;
280 : : }
281 : :
282 : :
283 : 124 : void ScDocument::CalcFormulaTree( bool bOnlyForced, bool bNoProgress )
284 : : {
285 : : OSL_ENSURE( !IsCalculatingFormulaTree(), "CalcFormulaTree recursion" );
286 : : // never ever recurse into this, might end up lost in infinity
287 [ - + ]: 124 : if ( IsCalculatingFormulaTree() )
288 : 124 : return ;
289 : 124 : bCalculatingFormulaTree = true;
290 : :
291 : 124 : SetForcedFormulaPending( false );
292 : 124 : bool bOldIdleDisabled = IsIdleDisabled();
293 : 124 : DisableIdle( true );
294 : 124 : bool bOldAutoCalc = GetAutoCalc();
295 : : //! _nicht_ SetAutoCalc( true ) weil das evtl. CalcFormulaTree( true )
296 : : //! aufruft, wenn vorher disabled war und bHasForcedFormulas gesetzt ist
297 : 124 : bAutoCalc = true;
298 [ - + ]: 124 : if ( bHardRecalcState )
299 : 0 : CalcAll();
300 : : else
301 : : {
302 : 124 : ScFormulaCell* pCell = pFormulaTree;
303 [ + + ]: 374 : while ( pCell )
304 : : {
305 [ + + ]: 250 : if ( pCell->GetDirty() )
306 : 118 : pCell = pCell->GetNext(); // alles klar
307 : : else
308 : : {
309 [ + + ]: 132 : if ( pCell->GetCode()->IsRecalcModeAlways() )
310 : : {
311 : : // pCell wird im SetDirty neu angehaengt!
312 : 57 : ScFormulaCell* pNext = pCell->GetNext();
313 : 57 : pCell->SetDirty();
314 : : // falls pNext==0 und neue abhaengige hinten angehaengt
315 : : // wurden, so macht das nichts, da die alle bDirty sind
316 : 57 : pCell = pNext;
317 : : }
318 : : else
319 : : { // andere simpel berechnen
320 : 75 : pCell->SetDirtyVar();
321 : 75 : pCell = pCell->GetNext();
322 : : }
323 : : }
324 : : }
325 [ + - ][ + + ]: 124 : bool bProgress = !bOnlyForced && nFormulaCodeInTree && !bNoProgress;
[ + + ]
326 [ + + ]: 124 : if ( bProgress )
327 : 10 : ScProgress::CreateInterpretProgress( this, true );
328 : :
329 : 124 : pCell = pFormulaTree;
330 : 124 : ScFormulaCell* pLastNoGood = 0;
331 [ + + ]: 329 : while ( pCell )
332 : : {
333 : : // Interpret setzt bDirty zurueck und callt Remove, auch der referierten!
334 : : // bei RECALCMODE_ALWAYS bleibt die Zelle
335 [ - + ]: 205 : if ( bOnlyForced )
336 : : {
337 [ # # ]: 0 : if ( pCell->GetCode()->IsRecalcModeForced() )
338 : 0 : pCell->Interpret();
339 : : }
340 : : else
341 : : {
342 : 205 : pCell->Interpret();
343 : : }
344 [ + + ][ + + ]: 205 : if ( pCell->GetPrevious() || pCell == pFormulaTree )
[ + + ]
345 : : { // (IsInFormulaTree(pCell)) kein Remove gewesen => next
346 : 57 : pLastNoGood = pCell;
347 : 57 : pCell = pCell->GetNext();
348 : : }
349 : : else
350 : : {
351 [ + + ]: 148 : if ( pFormulaTree )
352 : : {
353 [ + + ][ + - ]: 126 : if ( pFormulaTree->GetDirty() && !bOnlyForced )
[ + + ]
354 : : {
355 : 63 : pCell = pFormulaTree;
356 : 63 : pLastNoGood = 0;
357 : : }
358 : : else
359 : : {
360 : : // IsInFormulaTree(pLastNoGood)
361 [ + - ][ + + ]: 63 : if ( pLastNoGood && (pLastNoGood->GetPrevious() ||
[ + - ][ + - ]
362 : : pLastNoGood == pFormulaTree) )
363 : 63 : pCell = pLastNoGood->GetNext();
364 : : else
365 : : {
366 : 0 : pCell = pFormulaTree;
367 [ # # ][ # # ]: 0 : while ( pCell && !pCell->GetDirty() )
[ # # ]
368 : 0 : pCell = pCell->GetNext();
369 [ # # ]: 0 : if ( pCell )
370 : 0 : pLastNoGood = pCell->GetPrevious();
371 : : }
372 : : }
373 : : }
374 : : else
375 : 22 : pCell = 0;
376 : : }
377 [ - + ]: 205 : if ( ScProgress::IsUserBreak() )
378 : 0 : pCell = 0;
379 : : }
380 [ + + ]: 124 : if ( bProgress )
381 : 10 : ScProgress::DeleteInterpretProgress();
382 : : }
383 : 124 : bAutoCalc = bOldAutoCalc;
384 : 124 : DisableIdle( bOldIdleDisabled );
385 : 124 : bCalculatingFormulaTree = false;
386 : : }
387 : :
388 : :
389 : 205 : void ScDocument::ClearFormulaTree()
390 : : {
391 : : ScFormulaCell* pCell;
392 : 205 : ScFormulaCell* pTree = pFormulaTree;
393 [ + + ]: 277 : while ( pTree )
394 : : {
395 : 72 : pCell = pTree;
396 : 72 : pTree = pCell->GetNext();
397 [ - + ]: 72 : if ( !pCell->GetCode()->IsRecalcModeAlways() )
398 : 0 : RemoveFromFormulaTree( pCell );
399 : : }
400 : 205 : }
401 : :
402 : :
403 : 2444 : void ScDocument::AppendToFormulaTrack( ScFormulaCell* pCell )
404 : : {
405 : : OSL_ENSURE( pCell, "AppendToFormulaTrack: pCell Null" );
406 : : // Zelle kann nicht in beiden Listen gleichzeitig sein
407 : 2444 : RemoveFromFormulaTrack( pCell );
408 : 2444 : RemoveFromFormulaTree( pCell );
409 [ + + ]: 2444 : if ( pEOFormulaTrack )
410 : 1070 : pEOFormulaTrack->SetNextTrack( pCell );
411 : : else
412 : 1374 : pFormulaTrack = pCell; // kein Ende, kein Anfang..
413 : 2444 : pCell->SetPreviousTrack( pEOFormulaTrack );
414 : 2444 : pCell->SetNextTrack( 0 );
415 : 2444 : pEOFormulaTrack = pCell;
416 : 2444 : ++nFormulaTrackCount;
417 : 2444 : }
418 : :
419 : :
420 : 4888 : void ScDocument::RemoveFromFormulaTrack( ScFormulaCell* pCell )
421 : : {
422 : : OSL_ENSURE( pCell, "RemoveFromFormulaTrack: pCell Null" );
423 : 4888 : ScFormulaCell* pPrev = pCell->GetPreviousTrack();
424 : : // wenn die Zelle die erste oder sonstwo ist
425 [ + + ][ + - ]: 4888 : if ( pPrev || pFormulaTrack == pCell )
426 : : {
427 : 2444 : ScFormulaCell* pNext = pCell->GetNextTrack();
428 [ - + ]: 2444 : if ( pPrev )
429 : 0 : pPrev->SetNextTrack( pNext ); // gibt Vorlaeufer
430 : : else
431 : 2444 : pFormulaTrack = pNext; // ist erste Zelle
432 [ + + ]: 2444 : if ( pNext )
433 : 1070 : pNext->SetPreviousTrack( pPrev ); // gibt Nachfolger
434 : : else
435 : 1374 : pEOFormulaTrack = pPrev; // ist letzte Zelle
436 : 2444 : pCell->SetPreviousTrack( 0 );
437 : 2444 : pCell->SetNextTrack( 0 );
438 : 2444 : --nFormulaTrackCount;
439 : : }
440 : 4888 : }
441 : :
442 : :
443 : 1626 : bool ScDocument::IsInFormulaTrack( ScFormulaCell* pCell ) const
444 : : {
445 [ + + ][ + + ]: 1626 : return pCell->GetPreviousTrack() || pFormulaTrack == pCell;
446 : : }
447 : :
448 : :
449 : : /*
450 : : Der erste wird gebroadcastet,
451 : : die dadurch entstehenden werden durch das Notify an den Track gehaengt.
452 : : Der nachfolgende broadcastet wieder usw.
453 : : View stoesst Interpret an.
454 : : */
455 : 1721 : void ScDocument::TrackFormulas( sal_uLong nHintId )
456 : : {
457 : :
458 [ + + ]: 1721 : if ( pFormulaTrack )
459 : : {
460 : : // outside the loop, check if any sheet has a "calculate" event script
461 : 1374 : bool bCalcEvent = HasAnySheetEventScript( SC_SHEETEVENT_CALCULATE, true );
462 : : SvtBroadcaster* pBC;
463 : : ScFormulaCell* pTrack;
464 : : ScFormulaCell* pNext;
465 : 1374 : pTrack = pFormulaTrack;
466 [ + + ]: 2444 : do
467 : : {
468 [ + - ][ + - ]: 2444 : ScHint aHint( nHintId, pTrack->aPos, pTrack );
469 [ + + ]: 2444 : if ( ( pBC = pTrack->GetBroadcaster() ) != NULL )
470 [ + - ]: 199 : pBC->Broadcast( aHint );
471 [ + - ]: 2444 : pBASM->AreaBroadcast( aHint );
472 : : // Repaint fuer bedingte Formate mit relativen Referenzen:
473 : 2444 : TableContainer::iterator itr = maTabs.begin();
474 [ + - ][ + + ]: 5595 : for(; itr != maTabs.end(); ++itr)
475 : : {
476 [ - + ]: 3151 : if(!*itr)
477 : 0 : continue;
478 [ + - ]: 3151 : ScConditionalFormatList* pCondFormList = (*itr)->GetCondFormList();
479 [ + - ]: 3151 : if ( pCondFormList )
480 [ + - ]: 3151 : pCondFormList->SourceChanged( pTrack->aPos );
481 : : }
482 : : // for "calculate" event, keep track of which sheets are affected by tracked formulas
483 [ - + ]: 2444 : if ( bCalcEvent )
484 [ # # ]: 0 : SetCalcNotification( pTrack->aPos.Tab() );
485 [ + - ]: 2444 : pTrack = pTrack->GetNextTrack();
486 : : } while ( pTrack );
487 : 1374 : pTrack = pFormulaTrack;
488 : 1374 : bool bHaveForced = false;
489 [ + + ]: 2444 : do
490 : : {
491 : 2444 : pNext = pTrack->GetNextTrack();
492 : 2444 : RemoveFromFormulaTrack( pTrack );
493 : 2444 : PutInFormulaTree( pTrack );
494 [ - + ]: 2444 : if ( pTrack->GetCode()->IsRecalcModeForced() )
495 : 0 : bHaveForced = true;
496 : 2444 : pTrack = pNext;
497 : : } while ( pTrack );
498 [ - + ]: 1374 : if ( bHaveForced )
499 : : {
500 : 0 : SetForcedFormulas( true );
501 [ # # ]: 0 : if ( bAutoCalc && !IsAutoCalcShellDisabled() && !IsInInterpreter()
[ # # # # ]
[ # # ][ # # ]
502 : 0 : && !IsCalculatingFormulaTree() )
503 : 0 : CalcFormulaTree( true );
504 : : else
505 : 0 : SetForcedFormulaPending( true );
506 : : }
507 : : }
508 : : OSL_ENSURE( nFormulaTrackCount==0, "TrackFormulas: nFormulaTrackCount!=0" );
509 : 1721 : }
510 : :
511 : :
512 : 21 : void ScDocument::StartAllListeners()
513 : : {
514 [ + + ]: 42 : for ( SCTAB i = 0; i < static_cast<SCTAB>(maTabs.size()); ++i )
515 [ + - ]: 21 : if ( maTabs[i] )
516 : 21 : maTabs[i]->StartAllListeners();
517 : 21 : }
518 : :
519 : 221 : void ScDocument::UpdateBroadcastAreas( UpdateRefMode eUpdateRefMode,
520 : : const ScRange& rRange, SCsCOL nDx, SCsROW nDy, SCsTAB nDz
521 : : )
522 : : {
523 : 221 : bool bExpandRefsOld = IsExpandRefs();
524 [ + + ][ + + ]: 221 : if ( eUpdateRefMode == URM_INSDEL && (nDx > 0 || nDy > 0 || nDz > 0) )
[ + + ][ + - ]
525 : 96 : SetExpandRefs( SC_MOD()->GetInputOptions().GetExpandRefs() );
526 [ + - ]: 221 : if ( pBASM )
527 : 221 : pBASM->UpdateBroadcastAreas( eUpdateRefMode, rRange, nDx, nDy, nDz );
528 : 221 : SetExpandRefs( bExpandRefsOld );
529 : 221 : }
530 : :
531 : 2127658 : void ScDocument::SetAutoCalc( bool bNewAutoCalc )
532 : : {
533 : 2127658 : bool bOld = bAutoCalc;
534 : 2127658 : bAutoCalc = bNewAutoCalc;
535 [ + + ][ + + ]: 2127658 : if ( !bOld && bNewAutoCalc && bHasForcedFormulas )
[ - + ]
536 : : {
537 [ # # ]: 0 : if ( IsAutoCalcShellDisabled() )
538 : 0 : SetForcedFormulaPending( true );
539 [ # # ]: 0 : else if ( !IsInInterpreter() )
540 : 0 : CalcFormulaTree( true );
541 : : }
542 : 2127658 : }
543 : :
544 : :
545 : :
546 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|