Update ooo320-m1
[ooovba.git] / applied_patches / 0164-calc-jump-on-formula-ref-sc.diff
blobaab1a9bdf4db5f41b81f301c2b54a489e395fc30
1 diff --git sc/inc/cell.hxx sc/inc/cell.hxx
2 index 5ec1281..4c1afdb 100644
3 --- sc/inc/cell.hxx
4 +++ sc/inc/cell.hxx
5 @@ -662,6 +662,7 @@ private:
6 public:
7 ScDetectiveRefIter( ScFormulaCell* pCell );
8 BOOL GetNextRef( ScRange& rRange );
9 + ScToken* GetNextRefToken();
12 // ============================================================================
13 diff --git sc/inc/detfunc.hxx sc/inc/detfunc.hxx
14 index 49a7938..c38150d 100644
15 --- sc/inc/detfunc.hxx
16 +++ sc/inc/detfunc.hxx
17 @@ -35,6 +35,9 @@
18 #include <tools/gen.hxx>
19 #include <tools/color.hxx>
20 #include "scdllapi.h"
21 +#include "token.hxx"
23 +#include <vector>
25 class SdrObject;
26 class SdrPage;
27 @@ -46,6 +49,7 @@ class ScDetectiveData;
28 class ScDocument;
29 class ScAddress;
30 class ScRange;
31 +class ScRangeList;
33 #define SC_DET_MAXCIRCLE 1000
35 @@ -146,6 +150,9 @@ public:
37 BOOL MarkInvalid(BOOL& rOverflow);
39 + void GetAllPreds(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, ::std::vector<ScSharedTokenRef>& rRefTokens);
40 + void GetAllSuccs(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, ::std::vector<ScSharedTokenRef>& rRefTokens);
42 static void UpdateAllComments( ScDocument& rDoc ); // on all tables
43 void UpdateAllArrowColors(); // on all tables
45 diff --git sc/inc/reftokenhelper.hxx sc/inc/reftokenhelper.hxx
46 index d7b335f..44619ab 100644
47 --- sc/inc/reftokenhelper.hxx
48 +++ sc/inc/reftokenhelper.hxx
49 @@ -78,6 +78,9 @@ public:
50 static void join(::std::vector<ScSharedTokenRef>& rTokens, const ScSharedTokenRef& pToken);
52 static bool getDoubleRefDataFromToken(ScComplexRefData& rData, const ScSharedTokenRef& pToken);
54 + static ScSharedTokenRef createRefToken(const ScAddress& rAddr);
55 + static ScSharedTokenRef createRefToken(const ScRange& rRange);
58 #endif
59 diff --git sc/inc/sc.hrc sc/inc/sc.hrc
60 index bd688c8..340416b 100644
61 --- sc/inc/sc.hrc
62 +++ sc/inc/sc.hrc
63 @@ -900,6 +900,9 @@
64 #define SID_DETECTIVE_REFRESH (DETECTIVE_START+14)
65 #define SID_DETECTIVE_AUTO (DETECTIVE_START+15)
67 +#define SID_DETECTIVE_MARK_PRED (DETECTIVE_START+16)
68 +#define SID_DETECTIVE_MARK_SUCC (DETECTIVE_START+17)
70 #define DETECTIVE_END (DETECTIVE_START+20)
72 #define SID_API_SLOTS (DETECTIVE_END)
73 diff --git sc/sdi/cellsh.sdi sc/sdi/cellsh.sdi
74 index 05ab23c..b22589b 100644
75 --- sc/sdi/cellsh.sdi
76 +++ sc/sdi/cellsh.sdi
77 @@ -113,6 +113,8 @@ interface CellSelection
78 SID_DETECTIVE_ADD_ERR [ ExecMethod = ExecuteEdit; StateMethod = GetState; ]
79 SID_DETECTIVE_INVALID [ ExecMethod = ExecuteEdit; StateMethod = GetState; ]
80 SID_DETECTIVE_REFRESH [ ExecMethod = ExecuteEdit; StateMethod = GetState; ]
81 + SID_DETECTIVE_MARK_PRED [ ExecMethod = ExecuteEdit; StateMethod = GetState; ]
82 + SID_DETECTIVE_MARK_SUCC [ ExecMethod = ExecuteEdit; StateMethod = GetState; ]
83 FID_INS_ROW [ ExecMethod = ExecuteEdit; StateMethod = GetBlockState; ]
84 FID_INS_COLUMN [ ExecMethod = ExecuteEdit; StateMethod = GetBlockState; ]
85 FID_INS_CELLSDOWN [ ExecMethod = ExecuteEdit; StateMethod = GetBlockState; ]
86 diff --git sc/sdi/scalc.sdi sc/sdi/scalc.sdi
87 index 66c0a09..f8eddc2 100644
88 --- sc/sdi/scalc.sdi
89 +++ sc/sdi/scalc.sdi
90 @@ -7899,4 +7899,53 @@ SfxBoolItem ToggleSheetGrid FID_TAB_TOGGLE_GRID
91 GroupId = GID_FORMAT;
94 +//--------------------------------------------------------------------------
95 +SfxVoidItem MarkPrecedents SID_DETECTIVE_MARK_PRED
96 +()
98 + /* flags: */
99 + AutoUpdate = FALSE,
100 + Cachable = Cachable,
101 + FastCall = FALSE,
102 + HasCoreId = FALSE,
103 + HasDialog = FALSE,
104 + ReadOnlyDoc = TRUE,
105 + Toggle = FALSE,
106 + Container = FALSE,
107 + RecordAbsolute = FALSE,
108 + RecordPerSet;
109 + Synchron;
111 + /* config: */
112 + AccelConfig = TRUE,
113 + MenuConfig = TRUE,
114 + StatusBarConfig = FALSE,
115 + ToolBoxConfig = FALSE,
116 + GroupId = GID_OPTIONS;
119 +//--------------------------------------------------------------------------
120 +SfxVoidItem MarkDependents SID_DETECTIVE_MARK_SUCC
123 + /* flags: */
124 + AutoUpdate = FALSE,
125 + Cachable = Cachable,
126 + FastCall = FALSE,
127 + HasCoreId = FALSE,
128 + HasDialog = FALSE,
129 + ReadOnlyDoc = TRUE,
130 + Toggle = FALSE,
131 + Container = FALSE,
132 + RecordAbsolute = FALSE,
133 + RecordPerSet;
134 + Synchron;
136 + /* config: */
137 + AccelConfig = TRUE,
138 + MenuConfig = TRUE,
139 + StatusBarConfig = FALSE,
140 + ToolBoxConfig = FALSE,
141 + GroupId = GID_OPTIONS;
144 diff --git sc/source/core/data/cell.cxx sc/source/core/data/cell.cxx
145 index 1c3035c..4d5773d 100644
146 --- sc/source/core/data/cell.cxx
147 +++ sc/source/core/data/cell.cxx
148 @@ -1954,7 +1954,7 @@ BOOL lcl_ScDetectiveRefIter_SkipRef( ScToken* p )
149 if ( rRef1.IsColDeleted() || rRef1.IsRowDeleted() || rRef1.IsTabDeleted()
150 || !rRef1.Valid() )
151 return TRUE;
152 - if ( p->GetType() == svDoubleRef )
153 + if ( p->GetType() == svDoubleRef || p->GetType() == svExternalDoubleRef )
155 ScSingleRefData& rRef2 = p->GetDoubleRef().Ref2;
156 if ( rRef2.IsColDeleted() || rRef2.IsRowDeleted() || rRef2.IsTabDeleted()
157 @@ -1967,7 +1967,20 @@ BOOL lcl_ScDetectiveRefIter_SkipRef( ScToken* p )
158 BOOL ScDetectiveRefIter::GetNextRef( ScRange& rRange )
160 BOOL bRet = FALSE;
161 + ScToken* p = GetNextRefToken();
162 + if( p )
164 + SingleDoubleRefProvider aProv( *p );
165 + rRange.aStart.Set( aProv.Ref1.nCol, aProv.Ref1.nRow, aProv.Ref1.nTab );
166 + rRange.aEnd.Set( aProv.Ref2.nCol, aProv.Ref2.nRow, aProv.Ref2.nTab );
167 + bRet = TRUE;
170 + return bRet;
173 +ScToken* ScDetectiveRefIter::GetNextRefToken()
175 ScToken* p = static_cast<ScToken*>(pCode->GetNextReferenceRPN());
176 if (p)
177 p->CalcAbsIfRel( aPos );
178 @@ -1978,16 +1991,7 @@ BOOL ScDetectiveRefIter::GetNextRef( ScRange& rRange )
179 if (p)
180 p->CalcAbsIfRel( aPos );
183 - if( p )
185 - SingleDoubleRefProvider aProv( *p );
186 - rRange.aStart.Set( aProv.Ref1.nCol, aProv.Ref1.nRow, aProv.Ref1.nTab );
187 - rRange.aEnd.Set( aProv.Ref2.nCol, aProv.Ref2.nRow, aProv.Ref2.nTab );
188 - bRet = TRUE;
191 - return bRet;
192 + return p;
195 // ============================================================================
196 diff --git sc/source/core/tool/detfunc.cxx sc/source/core/tool/detfunc.cxx
197 index 7680bda..99e0e71 100644
198 --- sc/source/core/tool/detfunc.cxx
199 +++ sc/source/core/tool/detfunc.cxx
200 @@ -80,6 +80,12 @@
201 #include "attrib.hxx"
202 #include "scmod.hxx"
203 #include "postit.hxx"
204 +#include "rangelst.hxx"
205 +#include "reftokenhelper.hxx"
207 +#include <vector>
209 +using ::std::vector;
211 //------------------------------------------------------------------------
213 @@ -1407,6 +1413,52 @@ BOOL ScDetectiveFunc::MarkInvalid(BOOL& rOverflow)
214 return ( bDeleted || nInsCount != 0 );
217 +void ScDetectiveFunc::GetAllPreds(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
218 + vector<ScSharedTokenRef>& rRefTokens)
220 + ScCellIterator aCellIter(pDoc, nCol1, nRow1, nTab, nCol2, nRow2, nTab);
221 + for (ScBaseCell* pCell = aCellIter.GetFirst(); pCell; pCell = aCellIter.GetNext())
223 + if (pCell->GetCellType() != CELLTYPE_FORMULA)
224 + continue;
226 + ScFormulaCell* pFCell = static_cast<ScFormulaCell*>(pCell);
227 + ScDetectiveRefIter aRefIter(pFCell);
228 + for (ScToken* p = aRefIter.GetNextRefToken(); p; p = aRefIter.GetNextRefToken())
230 + ScSharedTokenRef pRef(static_cast<ScToken*>(p->Clone()));
231 + ScRefTokenHelper::join(rRefTokens, pRef);
236 +void ScDetectiveFunc::GetAllSuccs(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
237 + vector<ScSharedTokenRef>& rRefTokens)
239 + vector<ScSharedTokenRef> aSrcRange;
240 + aSrcRange.push_back(
241 + ScRefTokenHelper::createRefToken(ScRange(nCol1, nRow1, nTab, nCol2, nRow2, nTab)));
243 + ScCellIterator aCellIter(pDoc, 0, 0, nTab, MAXCOL, MAXROW, nTab);
244 + for (ScBaseCell* pCell = aCellIter.GetFirst(); pCell; pCell = aCellIter.GetNext())
246 + if (pCell->GetCellType() != CELLTYPE_FORMULA)
247 + continue;
249 + ScFormulaCell* pFCell = static_cast<ScFormulaCell*>(pCell);
250 + ScDetectiveRefIter aRefIter(pFCell);
251 + for (ScToken* p = aRefIter.GetNextRefToken(); p; p = aRefIter.GetNextRefToken())
253 + ScSharedTokenRef pRef(static_cast<ScToken*>(p->Clone()));
254 + if (ScRefTokenHelper::intersects(aSrcRange, pRef))
256 + pRef = ScRefTokenHelper::createRefToken(aCellIter.GetPos());
257 + ScRefTokenHelper::join(rRefTokens, pRef);
263 void ScDetectiveFunc::UpdateAllComments( ScDocument& rDoc )
265 // for all caption objects, update attributes and SpecialTextBoxShadow flag
266 --- sc/source/core/tool/makefile.mk
267 +++ sc/source/core/tool/makefile.mk
268 @@ -125,6 +125,7 @@
269 $(SLO)$/chartlock.obj \
270 $(SLO)$/chgtrack.obj \
271 $(SLO)$/compiler.obj \
272 + $(SLO)$/detfunc.obj \
273 $(SLO)$/doubleref.obj \
274 $(SLO)$/formulaparserpool.obj \
275 $(SLO)$/interpr1.obj \
276 diff --git sc/source/core/tool/reftokenhelper.cxx sc/source/core/tool/reftokenhelper.cxx
277 index ed196e0..635df6e 100644
278 --- sc/source/core/tool/reftokenhelper.cxx
279 +++ sc/source/core/tool/reftokenhelper.cxx
280 @@ -475,3 +475,19 @@ bool ScRefTokenHelper::getDoubleRefDataFromToken(ScComplexRefData& rData, const
282 return true;
285 +ScSharedTokenRef ScRefTokenHelper::createRefToken(const ScAddress& rAddr)
287 + ScSingleRefData aRefData;
288 + aRefData.InitAddress(rAddr);
289 + ScSharedTokenRef pRef(new ScSingleRefToken(aRefData));
290 + return pRef;
293 +ScSharedTokenRef ScRefTokenHelper::createRefToken(const ScRange& rRange)
295 + ScComplexRefData aRefData;
296 + aRefData.InitRange(rRange);
297 + ScSharedTokenRef pRef(new ScDoubleRefToken(aRefData));
298 + return pRef;
300 diff --git sc/source/ui/docshell/docfunc.cxx sc/source/ui/docshell/docfunc.cxx
301 index f55b697..a289649 100644
302 --- sc/source/ui/docshell/docfunc.cxx
303 +++ sc/source/ui/docshell/docfunc.cxx
304 @@ -102,6 +102,7 @@
306 using namespace com::sun::star;
307 using ::com::sun::star::uno::Sequence;
308 +using ::std::vector;
310 // STATIC DATA -----------------------------------------------------------
312 @@ -524,6 +525,44 @@ BOOL ScDocFunc::DetectiveRefresh( BOOL bAutomatic )
313 return bDone;
316 +static void lcl_collectAllPredOrSuccRanges(
317 + const ScRangeList& rSrcRanges, vector<ScSharedTokenRef>& rRefTokens, ScDocShell& rDocShell,
318 + bool bPred)
320 + ScDocument* pDoc = rDocShell.GetDocument();
321 + vector<ScSharedTokenRef> aRefTokens;
322 + ScRangeList aSrcRanges(rSrcRanges);
323 + ScRange* p = aSrcRanges.First();
324 + if (!p)
325 + return;
326 + ScDetectiveFunc aDetFunc(pDoc, p->aStart.Tab());
327 + ScRangeList aDestRanges;
328 + for (; p; p = aSrcRanges.Next())
330 + if (bPred)
331 + {
332 + aDetFunc.GetAllPreds(
333 + p->aStart.Col(), p->aStart.Row(), p->aEnd.Col(), p->aEnd.Row(), aRefTokens);
335 + else
336 + {
337 + aDetFunc.GetAllSuccs(
338 + p->aStart.Col(), p->aStart.Row(), p->aEnd.Col(), p->aEnd.Row(), aRefTokens);
341 + rRefTokens.swap(aRefTokens);
344 +void ScDocFunc::DetectiveCollectAllPreds(const ScRangeList& rSrcRanges, vector<ScSharedTokenRef>& rRefTokens)
346 + lcl_collectAllPredOrSuccRanges(rSrcRanges, rRefTokens, rDocShell, true);
349 +void ScDocFunc::DetectiveCollectAllSuccs(const ScRangeList& rSrcRanges, vector<ScSharedTokenRef>& rRefTokens)
351 + lcl_collectAllPredOrSuccRanges(rSrcRanges, rRefTokens, rDocShell, false);
354 //------------------------------------------------------------------------
356 BOOL ScDocFunc::DeleteContents( const ScMarkData& rMark, USHORT nFlags,
357 diff --git sc/source/ui/inc/docfunc.hxx sc/source/ui/inc/docfunc.hxx
358 index 6a1bf00..302b07d 100644
359 --- sc/source/ui/inc/docfunc.hxx
360 +++ sc/source/ui/inc/docfunc.hxx
361 @@ -34,7 +34,10 @@
362 #include <tools/link.hxx>
363 #include "global.hxx"
364 #include "formula/grammar.hxx"
365 #include "tabbgcolor.hxx"
366 +#include "token.hxx"
368 +#include <vector>
370 class ScEditEngineDefaulter;
371 class SdrUndoAction;
372 @@ -42,6 +45,7 @@ class ScDocShell;
373 class ScMarkData;
374 class ScPatternAttr;
375 class ScRange;
376 +class ScRangeList;
377 class ScRangeName;
378 class ScBaseCell;
379 class ScTokenArray;
380 @@ -77,6 +81,8 @@ public:
381 BOOL DetectiveMarkInvalid(SCTAB nTab);
382 BOOL DetectiveDelAll(SCTAB nTab);
383 BOOL DetectiveRefresh(BOOL bAutomatic = FALSE);
384 + void DetectiveCollectAllPreds(const ScRangeList& rSrcRanges, ::std::vector<ScSharedTokenRef>& rRefTokens);
385 + void DetectiveCollectAllSuccs(const ScRangeList& rSrcRanges, ::std::vector<ScSharedTokenRef>& rRefTokens);
387 BOOL DeleteContents( const ScMarkData& rMark, USHORT nFlags,
388 BOOL bRecord, BOOL bApi );
389 diff --git sc/source/ui/inc/viewfunc.hxx sc/source/ui/inc/viewfunc.hxx
390 index 7bf556d..7bd9a26 100644
391 --- sc/source/ui/inc/viewfunc.hxx
392 +++ sc/source/ui/inc/viewfunc.hxx
393 @@ -326,6 +326,8 @@ public:
394 void DetectiveMarkInvalid();
395 void DetectiveDelAll();
396 void DetectiveRefresh();
397 + void DetectiveMarkPred();
398 + void DetectiveMarkSucc();
400 void ShowNote( bool bShow = true );
401 inline void HideNote() { ShowNote( false ); }
402 @@ -366,6 +368,8 @@ private:
403 BOOL TestFormatArea( SCCOL nCol, SCROW nRow, SCTAB nTab, BOOL bAttrChanged );
404 void DoAutoAttributes( SCCOL nCol, SCROW nRow, SCTAB nTab,
405 BOOL bAttrChanged, BOOL bAddUndo );
407 + void MarkAndJumpToRanges(const ScRangeList& rRanges);
411 diff --git sc/source/ui/view/cellsh1.cxx sc/source/ui/view/cellsh1.cxx
412 index 0cd4007..d6fdb75 100644
413 --- sc/source/ui/view/cellsh1.cxx
414 +++ sc/source/ui/view/cellsh1.cxx
415 @@ -1584,6 +1584,13 @@ void ScCellShell::ExecuteEdit( SfxRequest& rReq )
416 rReq.Done();
417 break;
419 + case SID_DETECTIVE_MARK_PRED:
420 + pTabViewShell->DetectiveMarkPred();
421 + break;
422 + case SID_DETECTIVE_MARK_SUCC:
423 + pTabViewShell->DetectiveMarkSucc();
424 + break;
426 case SID_SPELL_DIALOG:
427 // pTabViewShell->DoSpellingChecker();
429 diff --git sc/source/ui/view/gridwin.cxx sc/source/ui/view/gridwin.cxx
430 index 57f1996..2b2ec31 100644
431 --- sc/source/ui/view/gridwin.cxx
432 +++ sc/source/ui/view/gridwin.cxx
433 @@ -3078,6 +3078,17 @@ void __EXPORT ScGridWindow::KeyInput(const KeyEvent& rKEvt)
434 ShowNoteMarker( pViewData->GetCurX(), pViewData->GetCurY(), TRUE );
435 return;
437 + if (aCode.GetCode() == KEY_BRACKETLEFT && aCode.GetModifier() == KEY_MOD1)
439 + pViewSh->DetectiveMarkPred();
440 + return;
442 + if (aCode.GetCode() == KEY_BRACKETRIGHT && aCode.GetModifier() == KEY_MOD1)
444 + pViewSh->DetectiveMarkSucc();
445 + return;
450 Window::KeyInput(rKEvt);
451 diff --git sc/source/ui/view/tabvwsh3.cxx sc/source/ui/view/tabvwsh3.cxx
452 index e106539..eb4c908 100644
453 --- sc/source/ui/view/tabvwsh3.cxx
454 +++ sc/source/ui/view/tabvwsh3.cxx
455 @@ -407,13 +407,15 @@ void ScTabViewShell::Execute( SfxRequest& rReq )
457 pViewData->ResetOldCursor();
458 SetCursor( nCol, nRow );
459 - AlignToCursor( nCol, nRow, SC_FOLLOW_JUMP );
460 rBindings.Invalidate( SID_CURRENTCELL );
461 rBindings.Update( nSlot );
463 if (!rReq.IsAPI())
464 rReq.Done();
466 + // align to cursor even if the cursor position hasn't changed,
467 + // because the cursor may be set outside the visible area.
468 + AlignToCursor( nCol, nRow, SC_FOLLOW_JUMP );
470 rReq.SetReturnValue( SfxStringItem( SID_CURRENTCELL, aAddress ) );
472 diff --git sc/source/ui/view/viewfun6.cxx sc/source/ui/view/viewfun6.cxx
473 index 43b3db1..e686cfc 100644
474 --- sc/source/ui/view/viewfun6.cxx
475 +++ sc/source/ui/view/viewfun6.cxx
476 @@ -50,6 +50,13 @@
477 #include "globstr.hrc"
478 #include "sc.hrc"
479 #include "fusel.hxx"
480 +#include "reftokenhelper.hxx"
481 +#include "externalrefmgr.hxx"
483 +#include <vector>
485 +using ::rtl::OUStringBuffer;
486 +using ::std::vector;
488 //==================================================================
490 @@ -140,6 +147,136 @@ void ScViewFunc::DetectiveRefresh()
491 RecalcPPT();
494 +static void lcl_jumpToRange(const ScRange& rRange, ScViewData* pView, ScDocument* pDoc)
496 + String aAddrText;
497 + rRange.Format(aAddrText, SCR_ABS_3D, pDoc);
498 + SfxStringItem aPosItem(SID_CURRENTCELL, aAddrText);
499 + SfxBoolItem aUnmarkItem(FN_PARAM_1, TRUE); // remove existing selection
500 + pView->GetDispatcher().Execute(
501 + SID_CURRENTCELL, SFX_CALLMODE_SYNCHRON | SFX_CALLMODE_RECORD,
502 + &aPosItem, &aUnmarkItem, 0L);
505 +void ScViewFunc::MarkAndJumpToRanges(const ScRangeList& rRanges)
507 + ScViewData* pView = GetViewData();
508 + ScDocShell* pDocSh = pView->GetDocShell();
510 + ScRangeList aRanges(rRanges);
511 + ScRange* p = aRanges.First();
512 + ScRangeList aRangesToMark;
513 + ScAddress aCurPos = pView->GetCurPos();
514 + for (; p; p = aRanges.Next())
516 + // Collect only those ranges that are on the same sheet as the current
517 + // cursor.
519 + if (p->aStart.Tab() == aCurPos.Tab())
520 + aRangesToMark.Append(*p);
523 + if (!aRangesToMark.Count())
524 + return;
526 + // Jump to the first range of all precedent ranges.
527 + p = aRangesToMark.First();
528 + lcl_jumpToRange(*p, pView, pDocSh->GetDocument());
530 + for (; p; p = aRangesToMark.Next())
531 + MarkRange(*p, false, true);
534 +void ScViewFunc::DetectiveMarkPred()
536 + ScViewData* pView = GetViewData();
537 + ScDocShell* pDocSh = pView->GetDocShell();
538 + ScDocument* pDoc = pDocSh->GetDocument();
539 + ScMarkData& rMarkData = pView->GetMarkData();
540 + ScAddress aCurPos = pView->GetCurPos();
541 + ScRangeList aRanges;
542 + if (rMarkData.IsMarked() || rMarkData.IsMultiMarked())
543 + rMarkData.FillRangeListWithMarks(&aRanges, false);
544 + else
545 + aRanges.Append(aCurPos);
547 + vector<ScSharedTokenRef> aRefTokens;
548 + pDocSh->GetDocFunc().DetectiveCollectAllPreds(aRanges, aRefTokens);
550 + if (aRefTokens.empty())
551 + // No precedents found. Nothing to do.
552 + return;
554 + ScSharedTokenRef p = aRefTokens.front();
555 + if (ScRefTokenHelper::isExternalRef(p))
557 + // This is external. Open the external document if available, and
558 + // jump to the destination.
560 + sal_uInt16 nFileId = p->GetIndex();
561 + ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager();
562 + const String* pPath = pRefMgr->getExternalFileName(nFileId);
564 + ScRange aRange;
565 + if (pPath && ScRefTokenHelper::getRangeFromToken(aRange, p, true))
567 + const String& rTabName = p->GetString();
568 + OUStringBuffer aBuf;
569 + aBuf.append(*pPath);
570 + aBuf.append(sal_Unicode('#'));
571 + aBuf.append(rTabName);
572 + aBuf.append(sal_Unicode('.'));
574 + String aRangeStr;
575 + aRange.Format(aRangeStr, SCA_VALID);
576 + aBuf.append(aRangeStr);
578 + ScGlobal::OpenURL(aBuf.makeStringAndClear(), String());
580 + return;
582 + else
584 + ScRange aRange;
585 + ScRefTokenHelper::getRangeFromToken(aRange, p, false);
586 + if (aRange.aStart.Tab() != aCurPos.Tab())
588 + // The first precedent range is on a different sheet. Jump to it
589 + // immediately and forget the rest.
590 + lcl_jumpToRange(aRange, pView, pDoc);
591 + return;
595 + ScRangeList aDestRanges;
596 + ScRefTokenHelper::getRangeListFromTokens(aDestRanges, aRefTokens);
597 + MarkAndJumpToRanges(aDestRanges);
600 +void ScViewFunc::DetectiveMarkSucc()
602 + ScViewData* pView = GetViewData();
603 + ScDocShell* pDocSh = pView->GetDocShell();
604 + ScMarkData& rMarkData = pView->GetMarkData();
605 + ScAddress aCurPos = pView->GetCurPos();
606 + ScRangeList aRanges;
607 + if (rMarkData.IsMarked() || rMarkData.IsMultiMarked())
608 + rMarkData.FillRangeListWithMarks(&aRanges, false);
609 + else
610 + aRanges.Append(aCurPos);
612 + vector<ScSharedTokenRef> aRefTokens;
613 + pDocSh->GetDocFunc().DetectiveCollectAllSuccs(aRanges, aRefTokens);
615 + if (aRefTokens.empty())
616 + // No dependants found. Nothing to do.
617 + return;
619 + ScRangeList aDestRanges;
620 + ScRefTokenHelper::getRangeListFromTokens(aDestRanges, aRefTokens);
621 + MarkAndJumpToRanges(aDestRanges);
624 //---------------------------------------------------------------------------
626 void ScViewFunc::ShowNote( bool bShow )