diff options
author | Kohei Yoshida <kyoshida@novell.com> | 2010-09-16 10:35:22 +0200 |
---|---|---|
committer | Fridrich Štrba <fridrich.strba@bluewin.ch> | 2010-09-16 10:35:22 +0200 |
commit | fbf28ef12b3087bd1df7b79645685955d60ba911 (patch) | |
tree | 492417136dfefefda53b5fbecf4b402c3b943724 /sc | |
parent | d8bb8c4fb850b9de762567ed7d337972467470d6 (diff) |
calc-jump-on-formula-ref-sc.diff: Migrated
n#464359, i#101018
allow ctrl-[ and ctrl-] to jump to references used in a formula expression.
Diffstat (limited to 'sc')
-rw-r--r-- | sc/inc/cell.hxx | 1 | ||||
-rw-r--r-- | sc/inc/detfunc.hxx | 7 | ||||
-rw-r--r-- | sc/inc/reftokenhelper.hxx | 3 | ||||
-rw-r--r-- | sc/inc/sc.hrc | 3 | ||||
-rw-r--r-- | sc/sdi/cellsh.sdi | 2 | ||||
-rw-r--r-- | sc/sdi/scalc.sdi | 49 | ||||
-rw-r--r-- | sc/source/core/data/cell.cxx | 26 | ||||
-rw-r--r-- | sc/source/core/tool/detfunc.cxx | 52 | ||||
-rw-r--r-- | sc/source/core/tool/makefile.mk | 1 | ||||
-rw-r--r-- | sc/source/core/tool/reftokenhelper.cxx | 16 | ||||
-rw-r--r-- | sc/source/ui/docshell/docfunc.cxx | 39 | ||||
-rw-r--r-- | sc/source/ui/inc/docfunc.hxx | 6 | ||||
-rw-r--r-- | sc/source/ui/inc/viewfunc.hxx | 4 | ||||
-rw-r--r-- | sc/source/ui/view/cellsh1.cxx | 7 | ||||
-rw-r--r-- | sc/source/ui/view/gridwin.cxx | 11 | ||||
-rw-r--r-- | sc/source/ui/view/tabvwsh3.cxx | 4 | ||||
-rw-r--r-- | sc/source/ui/view/viewfun6.cxx | 137 |
17 files changed, 356 insertions, 12 deletions
diff --git a/sc/inc/cell.hxx b/sc/inc/cell.hxx index fcedbbb06335..b4c5ebb44057 100644 --- a/sc/inc/cell.hxx +++ b/sc/inc/cell.hxx @@ -549,6 +549,7 @@ private: public: ScDetectiveRefIter( ScFormulaCell* pCell ); BOOL GetNextRef( ScRange& rRange ); + ScToken* GetNextRefToken(); }; // ============================================================================ diff --git a/sc/inc/detfunc.hxx b/sc/inc/detfunc.hxx index 5c57d32af898..fb9d0ac9569e 100644 --- a/sc/inc/detfunc.hxx +++ b/sc/inc/detfunc.hxx @@ -32,6 +32,9 @@ #include <tools/gen.hxx> #include <tools/color.hxx> #include "scdllapi.h" +#include "token.hxx" + +#include <vector> class SdrObject; class SdrPage; @@ -43,6 +46,7 @@ class ScDetectiveData; class ScDocument; class ScAddress; class ScRange; +class ScRangeList; #define SC_DET_MAXCIRCLE 1000 @@ -144,6 +148,9 @@ public: BOOL MarkInvalid(BOOL& rOverflow); + void GetAllPreds(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, ::std::vector<ScSharedTokenRef>& rRefTokens); + void GetAllSuccs(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, ::std::vector<ScSharedTokenRef>& rRefTokens); + static void UpdateAllComments( ScDocument& rDoc ); // on all tables void UpdateAllArrowColors(); // on all tables diff --git a/sc/inc/reftokenhelper.hxx b/sc/inc/reftokenhelper.hxx index 86fd36f691fa..5bf6b25d019f 100644 --- a/sc/inc/reftokenhelper.hxx +++ b/sc/inc/reftokenhelper.hxx @@ -75,6 +75,9 @@ public: static void SC_DLLPUBLIC join(::std::vector<ScSharedTokenRef>& rTokens, const ScSharedTokenRef& pToken); static bool getDoubleRefDataFromToken(ScComplexRefData& rData, const ScSharedTokenRef& pToken); + + static ScSharedTokenRef createRefToken(const ScAddress& rAddr); + static ScSharedTokenRef createRefToken(const ScRange& rRange); }; #endif diff --git a/sc/inc/sc.hrc b/sc/inc/sc.hrc index e08c6dfbd060..be9e9721a26f 100644 --- a/sc/inc/sc.hrc +++ b/sc/inc/sc.hrc @@ -902,6 +902,9 @@ #define SID_DETECTIVE_REFRESH (DETECTIVE_START+14) #define SID_DETECTIVE_AUTO (DETECTIVE_START+15) +#define SID_DETECTIVE_MARK_PRED (DETECTIVE_START+16) +#define SID_DETECTIVE_MARK_SUCC (DETECTIVE_START+17) + #define DETECTIVE_END (DETECTIVE_START+20) #define SID_API_SLOTS (DETECTIVE_END) diff --git a/sc/sdi/cellsh.sdi b/sc/sdi/cellsh.sdi index 4c27c656d15c..714314472328 100644 --- a/sc/sdi/cellsh.sdi +++ b/sc/sdi/cellsh.sdi @@ -112,6 +112,8 @@ interface CellSelection SID_DETECTIVE_ADD_ERR [ ExecMethod = ExecuteEdit; StateMethod = GetState; ] SID_DETECTIVE_INVALID [ ExecMethod = ExecuteEdit; StateMethod = GetState; ] SID_DETECTIVE_REFRESH [ ExecMethod = ExecuteEdit; StateMethod = GetState; ] + SID_DETECTIVE_MARK_PRED [ ExecMethod = ExecuteEdit; StateMethod = GetState; ] + SID_DETECTIVE_MARK_SUCC [ ExecMethod = ExecuteEdit; StateMethod = GetState; ] FID_INS_ROW [ ExecMethod = ExecuteEdit; StateMethod = GetBlockState; ] FID_INS_COLUMN [ ExecMethod = ExecuteEdit; StateMethod = GetBlockState; ] FID_INS_CELLSDOWN [ ExecMethod = ExecuteEdit; StateMethod = GetBlockState; ] diff --git a/sc/sdi/scalc.sdi b/sc/sdi/scalc.sdi index e88d3725b8aa..3f28012166f6 100644 --- a/sc/sdi/scalc.sdi +++ b/sc/sdi/scalc.sdi @@ -7853,6 +7853,55 @@ SvxColorItem TabBgColor FID_TAB_SET_TAB_BG_COLOR ] //-------------------------------------------------------------------------- +SfxVoidItem MarkPrecedents SID_DETECTIVE_MARK_PRED +() +[ + /* flags: */ + AutoUpdate = FALSE, + Cachable = Cachable, + FastCall = FALSE, + HasCoreId = FALSE, + HasDialog = FALSE, + ReadOnlyDoc = TRUE, + Toggle = FALSE, + Container = FALSE, + RecordAbsolute = FALSE, + RecordPerSet; + Synchron; + + /* config: */ + AccelConfig = TRUE, + MenuConfig = TRUE, + StatusBarConfig = FALSE, + ToolBoxConfig = FALSE, + GroupId = GID_OPTIONS; +] + +//-------------------------------------------------------------------------- +SfxVoidItem MarkDependents SID_DETECTIVE_MARK_SUCC +() +[ + /* flags: */ + AutoUpdate = FALSE, + Cachable = Cachable, + FastCall = FALSE, + HasCoreId = FALSE, + HasDialog = FALSE, + ReadOnlyDoc = TRUE, + Toggle = FALSE, + Container = FALSE, + RecordAbsolute = FALSE, + RecordPerSet; + Synchron; + + /* config: */ + AccelConfig = TRUE, + MenuConfig = TRUE, + StatusBarConfig = FALSE, + ToolBoxConfig = FALSE, + GroupId = GID_OPTIONS; +] +//-------------------------------------------------------------------------- SfxVoidItem SetTabBgColor FID_TAB_MENU_SET_TAB_BG_COLOR (SvxColorItem TabBgColor FID_TAB_SET_TAB_BG_COLOR) [ diff --git a/sc/source/core/data/cell.cxx b/sc/source/core/data/cell.cxx index aa492630ab0e..d12439bbad4f 100644 --- a/sc/source/core/data/cell.cxx +++ b/sc/source/core/data/cell.cxx @@ -1998,7 +1998,7 @@ BOOL lcl_ScDetectiveRefIter_SkipRef( ScToken* p ) if ( rRef1.IsColDeleted() || rRef1.IsRowDeleted() || rRef1.IsTabDeleted() || !rRef1.Valid() ) return TRUE; - if ( p->GetType() == svDoubleRef ) + if ( p->GetType() == svDoubleRef || p->GetType() == svExternalDoubleRef ) { ScSingleRefData& rRef2 = p->GetDoubleRef().Ref2; if ( rRef2.IsColDeleted() || rRef2.IsRowDeleted() || rRef2.IsTabDeleted() @@ -2011,7 +2011,20 @@ BOOL lcl_ScDetectiveRefIter_SkipRef( ScToken* p ) BOOL ScDetectiveRefIter::GetNextRef( ScRange& rRange ) { BOOL bRet = FALSE; + ScToken* p = GetNextRefToken(); + if( p ) + { + SingleDoubleRefProvider aProv( *p ); + rRange.aStart.Set( aProv.Ref1.nCol, aProv.Ref1.nRow, aProv.Ref1.nTab ); + rRange.aEnd.Set( aProv.Ref2.nCol, aProv.Ref2.nRow, aProv.Ref2.nTab ); + bRet = TRUE; + } + return bRet; +} + +ScToken* ScDetectiveRefIter::GetNextRefToken() +{ ScToken* p = static_cast<ScToken*>(pCode->GetNextReferenceRPN()); if (p) p->CalcAbsIfRel( aPos ); @@ -2022,16 +2035,7 @@ BOOL ScDetectiveRefIter::GetNextRef( ScRange& rRange ) if (p) p->CalcAbsIfRel( aPos ); } - - if( p ) - { - SingleDoubleRefProvider aProv( *p ); - rRange.aStart.Set( aProv.Ref1.nCol, aProv.Ref1.nRow, aProv.Ref1.nTab ); - rRange.aEnd.Set( aProv.Ref2.nCol, aProv.Ref2.nRow, aProv.Ref2.nTab ); - bRet = TRUE; - } - - return bRet; + return p; } // ============================================================================ diff --git a/sc/source/core/tool/detfunc.cxx b/sc/source/core/tool/detfunc.cxx index e86bb22646c8..3774cbee7d06 100644 --- a/sc/source/core/tool/detfunc.cxx +++ b/sc/source/core/tool/detfunc.cxx @@ -77,6 +77,12 @@ #include "attrib.hxx" #include "scmod.hxx" #include "postit.hxx" +#include "rangelst.hxx" +#include "reftokenhelper.hxx" + +#include <vector> + +using ::std::vector; //------------------------------------------------------------------------ @@ -1420,6 +1426,52 @@ BOOL ScDetectiveFunc::MarkInvalid(BOOL& rOverflow) return ( bDeleted || nInsCount != 0 ); } +void ScDetectiveFunc::GetAllPreds(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, + vector<ScSharedTokenRef>& rRefTokens) +{ + ScCellIterator aCellIter(pDoc, nCol1, nRow1, nTab, nCol2, nRow2, nTab); + for (ScBaseCell* pCell = aCellIter.GetFirst(); pCell; pCell = aCellIter.GetNext()) + { + if (pCell->GetCellType() != CELLTYPE_FORMULA) + continue; + + ScFormulaCell* pFCell = static_cast<ScFormulaCell*>(pCell); + ScDetectiveRefIter aRefIter(pFCell); + for (ScToken* p = aRefIter.GetNextRefToken(); p; p = aRefIter.GetNextRefToken()) + { + ScSharedTokenRef pRef(static_cast<ScToken*>(p->Clone())); + ScRefTokenHelper::join(rRefTokens, pRef); + } + } +} + +void ScDetectiveFunc::GetAllSuccs(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, + vector<ScSharedTokenRef>& rRefTokens) +{ + vector<ScSharedTokenRef> aSrcRange; + aSrcRange.push_back( + ScRefTokenHelper::createRefToken(ScRange(nCol1, nRow1, nTab, nCol2, nRow2, nTab))); + + ScCellIterator aCellIter(pDoc, 0, 0, nTab, MAXCOL, MAXROW, nTab); + for (ScBaseCell* pCell = aCellIter.GetFirst(); pCell; pCell = aCellIter.GetNext()) + { + if (pCell->GetCellType() != CELLTYPE_FORMULA) + continue; + + ScFormulaCell* pFCell = static_cast<ScFormulaCell*>(pCell); + ScDetectiveRefIter aRefIter(pFCell); + for (ScToken* p = aRefIter.GetNextRefToken(); p; p = aRefIter.GetNextRefToken()) + { + ScSharedTokenRef pRef(static_cast<ScToken*>(p->Clone())); + if (ScRefTokenHelper::intersects(aSrcRange, pRef)) + { + pRef = ScRefTokenHelper::createRefToken(aCellIter.GetPos()); + ScRefTokenHelper::join(rRefTokens, pRef); + } + } + } +} + void ScDetectiveFunc::UpdateAllComments( ScDocument& rDoc ) { // for all caption objects, update attributes and SpecialTextBoxShadow flag diff --git a/sc/source/core/tool/makefile.mk b/sc/source/core/tool/makefile.mk index c0258e6f0575..9c4cac26dd25 100644 --- a/sc/source/core/tool/makefile.mk +++ b/sc/source/core/tool/makefile.mk @@ -121,6 +121,7 @@ EXCEPTIONSFILES= \ $(SLO)$/chartlock.obj \ $(SLO)$/chgtrack.obj \ $(SLO)$/compiler.obj \ + $(SLO)$/detfunc.obj \ $(SLO)$/doubleref.obj \ $(SLO)$/formulaparserpool.obj \ $(SLO)$/interpr1.obj \ diff --git a/sc/source/core/tool/reftokenhelper.cxx b/sc/source/core/tool/reftokenhelper.cxx index f4976a914c39..660bdffc2cec 100644 --- a/sc/source/core/tool/reftokenhelper.cxx +++ b/sc/source/core/tool/reftokenhelper.cxx @@ -477,3 +477,19 @@ bool ScRefTokenHelper::getDoubleRefDataFromToken(ScComplexRefData& rData, const } return true; } + +ScSharedTokenRef ScRefTokenHelper::createRefToken(const ScAddress& rAddr) +{ + ScSingleRefData aRefData; + aRefData.InitAddress(rAddr); + ScSharedTokenRef pRef(new ScSingleRefToken(aRefData)); + return pRef; +} + +ScSharedTokenRef ScRefTokenHelper::createRefToken(const ScRange& rRange) +{ + ScComplexRefData aRefData; + aRefData.InitRange(rRange); + ScSharedTokenRef pRef(new ScDoubleRefToken(aRefData)); + return pRef; +} diff --git a/sc/source/ui/docshell/docfunc.cxx b/sc/source/ui/docshell/docfunc.cxx index 36b6641d94a6..b6bb1483adfe 100644 --- a/sc/source/ui/docshell/docfunc.cxx +++ b/sc/source/ui/docshell/docfunc.cxx @@ -106,6 +106,7 @@ using namespace com::sun::star; using ::com::sun::star::uno::Sequence; +using ::std::vector; // STATIC DATA ----------------------------------------------------------- @@ -536,6 +537,44 @@ BOOL ScDocFunc::DetectiveRefresh( BOOL bAutomatic ) return bDone; } +static void lcl_collectAllPredOrSuccRanges( + const ScRangeList& rSrcRanges, vector<ScSharedTokenRef>& rRefTokens, ScDocShell& rDocShell, + bool bPred) +{ + ScDocument* pDoc = rDocShell.GetDocument(); + vector<ScSharedTokenRef> aRefTokens; + ScRangeList aSrcRanges(rSrcRanges); + ScRange* p = aSrcRanges.First(); + if (!p) + return; + ScDetectiveFunc aDetFunc(pDoc, p->aStart.Tab()); + ScRangeList aDestRanges; + for (; p; p = aSrcRanges.Next()) + { + if (bPred) + { + aDetFunc.GetAllPreds( + p->aStart.Col(), p->aStart.Row(), p->aEnd.Col(), p->aEnd.Row(), aRefTokens); + } + else + { + aDetFunc.GetAllSuccs( + p->aStart.Col(), p->aStart.Row(), p->aEnd.Col(), p->aEnd.Row(), aRefTokens); + } + } + rRefTokens.swap(aRefTokens); +} + +void ScDocFunc::DetectiveCollectAllPreds(const ScRangeList& rSrcRanges, vector<ScSharedTokenRef>& rRefTokens) +{ + lcl_collectAllPredOrSuccRanges(rSrcRanges, rRefTokens, rDocShell, true); +} + +void ScDocFunc::DetectiveCollectAllSuccs(const ScRangeList& rSrcRanges, vector<ScSharedTokenRef>& rRefTokens) +{ + lcl_collectAllPredOrSuccRanges(rSrcRanges, rRefTokens, rDocShell, false); +} + //------------------------------------------------------------------------ BOOL ScDocFunc::DeleteContents( const ScMarkData& rMark, USHORT nFlags, diff --git a/sc/source/ui/inc/docfunc.hxx b/sc/source/ui/inc/docfunc.hxx index c92cc082986d..fc2f4b40d9a9 100644 --- a/sc/source/ui/inc/docfunc.hxx +++ b/sc/source/ui/inc/docfunc.hxx @@ -32,6 +32,9 @@ #include "global.hxx" #include "formula/grammar.hxx" #include "tabbgcolor.hxx" +#include "token.hxx" + +#include <vector> class ScEditEngineDefaulter; class SdrUndoAction; @@ -40,6 +43,7 @@ class ScDocShell; class ScMarkData; class ScPatternAttr; class ScRange; +class ScRangeList; class ScRangeName; class ScBaseCell; class ScTokenArray; @@ -74,6 +78,8 @@ public: BOOL DetectiveMarkInvalid(SCTAB nTab); BOOL DetectiveDelAll(SCTAB nTab); BOOL DetectiveRefresh(BOOL bAutomatic = FALSE); + void DetectiveCollectAllPreds(const ScRangeList& rSrcRanges, ::std::vector<ScSharedTokenRef>& rRefTokens); + void DetectiveCollectAllSuccs(const ScRangeList& rSrcRanges, ::std::vector<ScSharedTokenRef>& rRefTokens); BOOL DeleteContents( const ScMarkData& rMark, USHORT nFlags, BOOL bRecord, BOOL bApi ); diff --git a/sc/source/ui/inc/viewfunc.hxx b/sc/source/ui/inc/viewfunc.hxx index 59da2966cc60..b80595c09f50 100644 --- a/sc/source/ui/inc/viewfunc.hxx +++ b/sc/source/ui/inc/viewfunc.hxx @@ -328,6 +328,8 @@ public: void DetectiveMarkInvalid(); void DetectiveDelAll(); void DetectiveRefresh(); + void DetectiveMarkPred(); + void DetectiveMarkSucc(); void ShowNote( bool bShow = true ); inline void HideNote() { ShowNote( false ); } @@ -361,6 +363,8 @@ private: BOOL TestFormatArea( SCCOL nCol, SCROW nRow, SCTAB nTab, BOOL bAttrChanged ); void DoAutoAttributes( SCCOL nCol, SCROW nRow, SCTAB nTab, BOOL bAttrChanged, BOOL bAddUndo ); + + void MarkAndJumpToRanges(const ScRangeList& rRanges); }; diff --git a/sc/source/ui/view/cellsh1.cxx b/sc/source/ui/view/cellsh1.cxx index 95d86032ef56..84b09b348d0c 100644 --- a/sc/source/ui/view/cellsh1.cxx +++ b/sc/source/ui/view/cellsh1.cxx @@ -1541,6 +1541,13 @@ void ScCellShell::ExecuteEdit( SfxRequest& rReq ) rReq.Done(); break; + case SID_DETECTIVE_MARK_PRED: + pTabViewShell->DetectiveMarkPred(); + break; + case SID_DETECTIVE_MARK_SUCC: + pTabViewShell->DetectiveMarkSucc(); + break; + case SID_SPELL_DIALOG: // pTabViewShell->DoSpellingChecker(); { diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx index 59fbffc43a1e..4e17c7f872ec 100644 --- a/sc/source/ui/view/gridwin.cxx +++ b/sc/source/ui/view/gridwin.cxx @@ -3117,6 +3117,17 @@ void __EXPORT ScGridWindow::KeyInput(const KeyEvent& rKEvt) ShowNoteMarker( pViewData->GetCurX(), pViewData->GetCurY(), TRUE ); return; } + if (aCode.GetCode() == KEY_BRACKETLEFT && aCode.GetModifier() == KEY_MOD1) + { + pViewSh->DetectiveMarkPred(); + return; + } + if (aCode.GetCode() == KEY_BRACKETRIGHT && aCode.GetModifier() == KEY_MOD1) + { + pViewSh->DetectiveMarkSucc(); + return; + } + } Window::KeyInput(rKEvt); diff --git a/sc/source/ui/view/tabvwsh3.cxx b/sc/source/ui/view/tabvwsh3.cxx index c291d01d71c2..c902f6b3e587 100644 --- a/sc/source/ui/view/tabvwsh3.cxx +++ b/sc/source/ui/view/tabvwsh3.cxx @@ -403,13 +403,15 @@ void ScTabViewShell::Execute( SfxRequest& rReq ) { pViewData->ResetOldCursor(); SetCursor( nCol, nRow ); - AlignToCursor( nCol, nRow, SC_FOLLOW_JUMP ); rBindings.Invalidate( SID_CURRENTCELL ); rBindings.Update( nSlot ); if (!rReq.IsAPI()) rReq.Done(); } + // align to cursor even if the cursor position hasn't changed, + // because the cursor may be set outside the visible area. + AlignToCursor( nCol, nRow, SC_FOLLOW_JUMP ); rReq.SetReturnValue( SfxStringItem( SID_CURRENTCELL, aAddress ) ); } diff --git a/sc/source/ui/view/viewfun6.cxx b/sc/source/ui/view/viewfun6.cxx index 6f25af2a0826..f00c0bcde688 100644 --- a/sc/source/ui/view/viewfun6.cxx +++ b/sc/source/ui/view/viewfun6.cxx @@ -47,6 +47,13 @@ #include "globstr.hrc" #include "sc.hrc" #include "fusel.hxx" +#include "reftokenhelper.hxx" +#include "externalrefmgr.hxx" + +#include <vector> + +using ::rtl::OUStringBuffer; +using ::std::vector; //================================================================== @@ -137,6 +144,136 @@ void ScViewFunc::DetectiveRefresh() RecalcPPT(); } +static void lcl_jumpToRange(const ScRange& rRange, ScViewData* pView, ScDocument* pDoc) +{ + String aAddrText; + rRange.Format(aAddrText, SCR_ABS_3D, pDoc); + SfxStringItem aPosItem(SID_CURRENTCELL, aAddrText); + SfxBoolItem aUnmarkItem(FN_PARAM_1, TRUE); // remove existing selection + pView->GetDispatcher().Execute( + SID_CURRENTCELL, SFX_CALLMODE_SYNCHRON | SFX_CALLMODE_RECORD, + &aPosItem, &aUnmarkItem, 0L); +} + +void ScViewFunc::MarkAndJumpToRanges(const ScRangeList& rRanges) +{ + ScViewData* pView = GetViewData(); + ScDocShell* pDocSh = pView->GetDocShell(); + + ScRangeList aRanges(rRanges); + ScRange* p = aRanges.First(); + ScRangeList aRangesToMark; + ScAddress aCurPos = pView->GetCurPos(); + for (; p; p = aRanges.Next()) + { + // Collect only those ranges that are on the same sheet as the current + // cursor. + + if (p->aStart.Tab() == aCurPos.Tab()) + aRangesToMark.Append(*p); + } + + if (!aRangesToMark.Count()) + return; + + // Jump to the first range of all precedent ranges. + p = aRangesToMark.First(); + lcl_jumpToRange(*p, pView, pDocSh->GetDocument()); + + for (; p; p = aRangesToMark.Next()) + MarkRange(*p, false, true); +} + +void ScViewFunc::DetectiveMarkPred() +{ + ScViewData* pView = GetViewData(); + ScDocShell* pDocSh = pView->GetDocShell(); + ScDocument* pDoc = pDocSh->GetDocument(); + ScMarkData& rMarkData = pView->GetMarkData(); + ScAddress aCurPos = pView->GetCurPos(); + ScRangeList aRanges; + if (rMarkData.IsMarked() || rMarkData.IsMultiMarked()) + rMarkData.FillRangeListWithMarks(&aRanges, false); + else + aRanges.Append(aCurPos); + + vector<ScSharedTokenRef> aRefTokens; + pDocSh->GetDocFunc().DetectiveCollectAllPreds(aRanges, aRefTokens); + + if (aRefTokens.empty()) + // No precedents found. Nothing to do. + return; + + ScSharedTokenRef p = aRefTokens.front(); + if (ScRefTokenHelper::isExternalRef(p)) + { + // This is external. Open the external document if available, and + // jump to the destination. + + sal_uInt16 nFileId = p->GetIndex(); + ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager(); + const String* pPath = pRefMgr->getExternalFileName(nFileId); + + ScRange aRange; + if (pPath && ScRefTokenHelper::getRangeFromToken(aRange, p, true)) + { + const String& rTabName = p->GetString(); + OUStringBuffer aBuf; + aBuf.append(*pPath); + aBuf.append(sal_Unicode('#')); + aBuf.append(rTabName); + aBuf.append(sal_Unicode('.')); + + String aRangeStr; + aRange.Format(aRangeStr, SCA_VALID); + aBuf.append(aRangeStr); + + ScGlobal::OpenURL(aBuf.makeStringAndClear(), String()); + } + return; + } + else + { + ScRange aRange; + ScRefTokenHelper::getRangeFromToken(aRange, p, false); + if (aRange.aStart.Tab() != aCurPos.Tab()) + { + // The first precedent range is on a different sheet. Jump to it + // immediately and forget the rest. + lcl_jumpToRange(aRange, pView, pDoc); + return; + } + } + + ScRangeList aDestRanges; + ScRefTokenHelper::getRangeListFromTokens(aDestRanges, aRefTokens); + MarkAndJumpToRanges(aDestRanges); +} + +void ScViewFunc::DetectiveMarkSucc() +{ + ScViewData* pView = GetViewData(); + ScDocShell* pDocSh = pView->GetDocShell(); + ScMarkData& rMarkData = pView->GetMarkData(); + ScAddress aCurPos = pView->GetCurPos(); + ScRangeList aRanges; + if (rMarkData.IsMarked() || rMarkData.IsMultiMarked()) + rMarkData.FillRangeListWithMarks(&aRanges, false); + else + aRanges.Append(aCurPos); + + vector<ScSharedTokenRef> aRefTokens; + pDocSh->GetDocFunc().DetectiveCollectAllSuccs(aRanges, aRefTokens); + + if (aRefTokens.empty()) + // No dependants found. Nothing to do. + return; + + ScRangeList aDestRanges; + ScRefTokenHelper::getRangeListFromTokens(aDestRanges, aRefTokens); + MarkAndJumpToRanges(aDestRanges); +} + //--------------------------------------------------------------------------- void ScViewFunc::ShowNote( bool bShow ) |