officecfg/registry/schema/org/openoffice/Office/Calc.xcs | 7 + sc/source/ui/inc/gridwin.hxx | 2 sc/source/ui/inc/tabview.hxx | 6 + sc/source/ui/inc/viewdata.hxx | 2 sc/source/ui/view/gridwin.cxx | 55 ++++++++++++ sc/source/ui/view/gridwin4.cxx | 4 sc/source/ui/view/tabview.cxx | 1 sc/source/ui/view/tabview2.cxx | 66 +++++++++++++++ sc/source/ui/view/tabview3.cxx | 28 ++++++ sc/source/ui/view/viewdata.cxx | 6 + 10 files changed, 177 insertions(+)
New commits: commit 487e30bec174342fff07f1f8cc76c9beed4c4843 Author: Sahil Gautam <gautamsahil1...@gmail.com> AuthorDate: Tue Oct 31 03:57:05 2023 +0530 Commit: Mike Kaganski <mike.kagan...@collabora.com> CommitDate: Fri Nov 17 17:35:32 2023 +0100 tdf#33201 Highlight current row and column in spreadsheet Highlighting functions added Change-Id: I65335538e394d048731c13ac87535502ea97dfa0 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/158680 Tested-by: Jenkins Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com> diff --git a/officecfg/registry/schema/org/openoffice/Office/Calc.xcs b/officecfg/registry/schema/org/openoffice/Office/Calc.xcs index 3de756beac4e..aa58fc81a9a7 100644 --- a/officecfg/registry/schema/org/openoffice/Office/Calc.xcs +++ b/officecfg/registry/schema/org/openoffice/Office/Calc.xcs @@ -121,6 +121,13 @@ </info> <value>false</value> </prop> + <prop oor:name="ColumnRowHighlighting" oor:type="xs:boolean" oor:nillable="false"> + <info> + <desc>Indicates whether the column/row highlight has been enabled or not.</desc> + <label>Column/row highlighting</label> + </info> + <value>false</value> + </prop> <prop oor:name="Anchor" oor:type="xs:boolean" oor:nillable="false"> <!-- UIHints: Tools - Options -Spreadsheets - Contents - [Section] Display --> <info> diff --git a/sc/source/ui/inc/gridwin.hxx b/sc/source/ui/inc/gridwin.hxx index 8334e5fd0d51..37c38fe069a0 100644 --- a/sc/source/ui/inc/gridwin.hxx +++ b/sc/source/ui/inc/gridwin.hxx @@ -103,6 +103,7 @@ class SAL_DLLPUBLIC_RTTI ScGridWindow : public vcl::DocWindow, public DropTarget std::unique_ptr<sdr::overlay::OverlayObjectList> mpOOCursors; std::unique_ptr<sdr::overlay::OverlayObjectList> mpOOSelection; + std::unique_ptr<sdr::overlay::OverlayObjectList> mpOOHighlight; std::unique_ptr<sdr::overlay::OverlayObjectList> mpOOSelectionBorder; std::unique_ptr<sdr::overlay::OverlayObjectList> mpOOAutoFill; std::unique_ptr<sdr::overlay::OverlayObjectList> mpOODragRect; @@ -476,6 +477,7 @@ public: void UpdateCursorOverlay(); void DeleteSelectionOverlay(); void UpdateSelectionOverlay(); + void UpdateHighlightOverlay(); void DeleteAutoFillOverlay(); void UpdateAutoFillOverlay(); void DeleteDragRectOverlay(); diff --git a/sc/source/ui/inc/tabview.hxx b/sc/source/ui/inc/tabview.hxx index edb9dd991971..8c69933cc1af 100644 --- a/sc/source/ui/inc/tabview.hxx +++ b/sc/source/ui/inc/tabview.hxx @@ -179,6 +179,7 @@ private: tools::Long nPrevDragPos; BlockMode meBlockMode; // Marks block + BlockMode meHighlightBlockMode; // Highlight row/col SCCOL nBlockStartX; SCCOL nBlockStartXOrig; @@ -263,6 +264,8 @@ private: DECL_STATIC_LINK(ScTabView, InstallLOKNotifierHdl, void*, vcl::ILibreOfficeKitNotifier*); + void UpdateHighlightOverlay(); + protected: void UpdateHeaderWidth( const ScVSplitPos* pWhich = nullptr, const SCROW* pPosY = nullptr ); @@ -536,6 +539,8 @@ public: bool bCols = false, bool bRows = false, bool bForceNeg = false ); void InitOwnBlockMode( const ScRange& rMarkRange ); void DoneBlockMode( bool bContinue = false ); + void InitBlockModeHighlight( SCCOL nCurX, SCROW nCurY, SCTAB nCurZ, bool bCols, bool bRows ); + void DoneBlockModeHighlight( bool bContinue ); bool IsBlockMode() const; @@ -561,6 +566,7 @@ public: * @param nModifier: 0, KEY_SHIFT, KEY_MOD1, KEY_SHIFT | KEY_MOD1 */ void MarkRows(SCROW nRow, sal_Int16 nModifier); + void HighlightOverlay(const ScAddress& rCell); void MarkDataArea( bool bIncludeCursor = true ); void MarkMatrixFormula(); diff --git a/sc/source/ui/inc/viewdata.hxx b/sc/source/ui/inc/viewdata.hxx index 7a6758788ad4..72386b2efa17 100644 --- a/sc/source/ui/inc/viewdata.hxx +++ b/sc/source/ui/inc/viewdata.hxx @@ -274,6 +274,7 @@ private: ::std::vector<std::unique_ptr<ScViewDataTable>> maTabData; ScMarkData maMarkData; + ScMarkData maHighlightData; ScViewDataTable* pThisTab; // Data of the displayed sheet ScDocShell* pDocShell; ScDocument& mrDoc; @@ -361,6 +362,7 @@ public: SfxDispatcher& GetDispatcher(); // from ViewShell's ViewFrame ScMarkData& GetMarkData(); + ScMarkData& GetHighlightData(); const ScMarkData& GetMarkData() const; weld::Window* GetDialogParent(); // forwarded from tabvwsh diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx index 58a7d8f0350a..ffd6362ab584 100644 --- a/sc/source/ui/view/gridwin.cxx +++ b/sc/source/ui/view/gridwin.cxx @@ -6124,6 +6124,7 @@ void ScGridWindow::ImpCreateOverlayObjects() UpdateCursorOverlay(); UpdateCopySourceOverlay(); UpdateSelectionOverlay(); + UpdateHighlightOverlay(); UpdateAutoFillOverlay(); UpdateDragRectOverlay(); UpdateHeaderOverlay(); @@ -6136,6 +6137,7 @@ void ScGridWindow::ImpDestroyOverlayObjects() DeleteCursorOverlay(); DeleteCopySourceOverlay(); DeleteSelectionOverlay(); + mpOOHighlight.reset(); // DeleteHighlightOverlay DeleteAutoFillOverlay(); DeleteDragRectOverlay(); DeleteHeaderOverlay(); @@ -6679,6 +6681,59 @@ void ScGridWindow::UpdateSelectionOverlay() SetMapMode( aOldMode ); } +void ScGridWindow::UpdateHighlightOverlay() +{ + mpOOHighlight.reset(); // DeleteHighlightOverlay + std::vector<tools::Rectangle> aRects; + if (comphelper::LibreOfficeKit::isActive() && + comphelper::LibreOfficeKit::isCompatFlagSet( + comphelper::LibreOfficeKit::Compat::scPrintTwipsMsgs)) + GetRectsAnyFor(mrViewData.GetHighlightData(), aRects, true); + else + GetPixelRectsFor(mrViewData.GetHighlightData(), aRects); + + if (!aRects.empty() && mrViewData.IsActive()) + { + // #i70788# get the OverlayManager safely + if (rtl::Reference<sdr::overlay::OverlayManager> xOverlayManager = getOverlayManager()) + { + std::vector< basegfx::B2DRange > aRanges; + const basegfx::B2DHomMatrix aTransform(GetOutDev()->GetInverseViewTransformation()); + ScDocument& rDoc = mrViewData.GetDocument(); + SCTAB nTab = mrViewData.GetTabNo(); + bool bLayoutRTL = rDoc.IsLayoutRTL( nTab ); + + for(const tools::Rectangle & rRA : aRects) + { + if (bLayoutRTL) + { + basegfx::B2DRange aRB(rRA.Left(), rRA.Top() - 1, rRA.Right() + 1, rRA.Bottom()); + aRB.transform(aTransform); + aRanges.push_back(aRB); + } + else + { + basegfx::B2DRange aRB(rRA.Left() - 1, rRA.Top() - 1, rRA.Right(), rRA.Bottom()); + aRB.transform(aTransform); + aRanges.push_back(aRB); + } + } + + const Color aHighlight = SC_MOD()->GetColorConfig().GetColorValue(svtools::APPBACKGROUND ).nColor; + + std::unique_ptr<sdr::overlay::OverlayObject> pOverlay(new sdr::overlay::OverlaySelection( + sdr::overlay::OverlayType::Transparent, + aHighlight, + std::move(aRanges), + false)); + + xOverlayManager->add(*pOverlay); + mpOOHighlight.reset(new sdr::overlay::OverlayObjectList); + mpOOHighlight->append(std::move(pOverlay)); + } + } +} + void ScGridWindow::DeleteAutoFillOverlay() { mpOOAutoFill.reset(); diff --git a/sc/source/ui/view/gridwin4.cxx b/sc/source/ui/view/gridwin4.cxx index 3639e8287698..0aede8ad69f8 100644 --- a/sc/source/ui/view/gridwin4.cxx +++ b/sc/source/ui/view/gridwin4.cxx @@ -1411,6 +1411,10 @@ void ScGridWindow::DrawContent(OutputDevice &rDevice, const ScTableInfo& rTableI if (bPage && bInitialPageBreaks) SetupInitialPageBreaks(rDoc, nTab); + + // redraw highlighting as well + ScAddress aCell = getViewData().GetCurPos(); + getViewData().GetViewShell()->SetCursor(aCell.Col(), aCell.Row()); } diff --git a/sc/source/ui/view/tabview.cxx b/sc/source/ui/view/tabview.cxx index 25d60abc2946..f580198f9bfc 100644 --- a/sc/source/ui/view/tabview.cxx +++ b/sc/source/ui/view/tabview.cxx @@ -189,6 +189,7 @@ ScTabView::ScTabView( vcl::Window* pParent, ScDocShell& rDocSh, ScTabViewShell* nTipAlign( QuickHelpFlags::NONE ), nPrevDragPos( 0 ), meBlockMode(None), + meHighlightBlockMode(None), nBlockStartX( 0 ), nBlockStartXOrig( 0 ), nBlockEndX( 0 ), diff --git a/sc/source/ui/view/tabview2.cxx b/sc/source/ui/view/tabview2.cxx index e28ff1d7eeee..d5be3d5b5956 100644 --- a/sc/source/ui/view/tabview2.cxx +++ b/sc/source/ui/view/tabview2.cxx @@ -515,6 +515,40 @@ void ScTabView::InitOwnBlockMode( const ScRange& rMarkRange ) SelectionChanged(); // status is checked with mark set } +void ScTabView::InitBlockModeHighlight( SCCOL nCurX, SCROW nCurY, SCTAB nCurZ, + bool bCols, bool bRows ) +{ + if (meHighlightBlockMode != None) + return; + + auto& rDoc = aViewData.GetDocument(); + if (!rDoc.ValidCol(nCurX)) nCurX = rDoc.MaxCol(); + if (!rDoc.ValidRow(nCurY)) nCurY = rDoc.MaxRow(); + + ScMarkData& rMark = aViewData.GetHighlightData(); + meHighlightBlockMode = Normal; + + SCROW nStartY = nCurY; + SCCOL nStartX = nCurX; + SCROW nEndY = nCurY; + SCCOL nEndX = nCurX; + + if (bCols) + { + nStartY = 0; + nEndY = rDoc.MaxRow(); + } + + if (bRows) + { + nStartX = 0; + nEndX = rDoc.MaxCol(); + } + + rMark.SetMarkArea( ScRange( nStartX, nStartY, nCurZ, nEndX, nEndY, nCurZ ) ); + UpdateHighlightOverlay(); +} + void ScTabView::InitBlockMode( SCCOL nCurX, SCROW nCurY, SCTAB nCurZ, bool bTestNeg, bool bCols, bool bRows, bool bForceNeg ) { @@ -571,6 +605,31 @@ void ScTabView::InitBlockMode( SCCOL nCurX, SCROW nCurY, SCTAB nCurZ, UpdateSelectionOverlay(); } +void ScTabView::DoneBlockModeHighlight( bool bContinue ) +{ + if (meHighlightBlockMode == None) + return; + + ScMarkData& rMark = aViewData.GetHighlightData(); + bool bFlag = rMark.GetMarkingFlag(); + rMark.SetMarking(false); + + if (bContinue) + rMark.MarkToMulti(); + else + { + SCTAB nTab = aViewData.GetTabNo(); + ScDocument& rDoc = aViewData.GetDocument(); + if ( rDoc.HasTable(nTab) ) + rMark.ResetMark(); + } + meHighlightBlockMode = None; + + rMark.SetMarking(bFlag); + if (bContinue) + rMark.SetMarking(false); +} + void ScTabView::DoneBlockMode( bool bContinue ) { // When switching between sheet and header SelectionEngine DeselectAll may be called, @@ -1149,6 +1208,13 @@ void ScTabView::UpdateSelectionOverlay() pWin->UpdateSelectionOverlay(); } +void ScTabView::UpdateHighlightOverlay() +{ + for (VclPtr<ScGridWindow> & pWin : pGridWin) + if ( pWin && pWin->IsVisible() ) + pWin->UpdateHighlightOverlay(); +} + void ScTabView::UpdateShrinkOverlay() { for (VclPtr<ScGridWindow> & pWin : pGridWin) diff --git a/sc/source/ui/view/tabview3.cxx b/sc/source/ui/view/tabview3.cxx index 723f2b4904e0..4130d7829ca1 100644 --- a/sc/source/ui/view/tabview3.cxx +++ b/sc/source/ui/view/tabview3.cxx @@ -17,6 +17,7 @@ * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ +#include <officecfg/Office/Calc.hxx> #include <rangelst.hxx> #include <scitems.hxx> @@ -374,7 +375,11 @@ void ScTabView::SetCursor( SCCOL nPosX, SCROW nPosY, bool bNew ) nPosY = std::min(nPosY, MAXTILEDROW); if ( !(nPosX != nOldX || nPosY != nOldY || bNew) ) + { + ScAddress aCell = GetViewData().GetCurPos(); + HighlightOverlay(aCell); return; + } ScTabViewShell* pViewShell = aViewData.GetViewShell(); bool bRefMode = pViewShell && pViewShell->IsRefInputMode(); @@ -390,6 +395,9 @@ void ScTabView::SetCursor( SCCOL nPosX, SCROW nPosY, bool bNew ) ShowAllCursors(); + ScAddress aCell = aViewData.GetCurPos(); + HighlightOverlay(aCell); + CursorPosChanged(); OUString aCurrAddress = ScAddress(nPosX,nPosY,0).GetColRowString(); @@ -1684,6 +1692,26 @@ void ScTabView::MarkRows(SCROW nRow, sal_Int16 nModifier) } } +void ScTabView::HighlightOverlay(const ScAddress& rCell) +{ + if (!officecfg::Office::Calc::Content::Display::ColumnRowHighlighting::get()) + { + aViewData.GetHighlightData().ResetMark(); + UpdateHighlightOverlay(); + return; + } + + SCROW nRow = rCell.Row(); + SCCOL nCol = rCell.Col(); + + bool nModifier = false; // modifier key pressed? + DoneBlockModeHighlight( nModifier ); + InitBlockModeHighlight( nCol, 0, rCell.Tab(), true, false); + nModifier = true; + DoneBlockModeHighlight( nModifier ); + InitBlockModeHighlight( 0, nRow, rCell.Tab(), false, true ); +} + void ScTabView::MarkDataArea( bool bIncludeCursor ) { ScDocument& rDoc = aViewData.GetDocument(); diff --git a/sc/source/ui/view/viewdata.cxx b/sc/source/ui/view/viewdata.cxx index 4ba5f774b83a..25e602669e80 100644 --- a/sc/source/ui/view/viewdata.cxx +++ b/sc/source/ui/view/viewdata.cxx @@ -781,6 +781,7 @@ ScViewData::ScViewData(ScDocument* pDoc, ScDocShell* pDocSh, ScTabViewShell* pVi nPPTX(0.0), nPPTY(0.0), maMarkData (pDocSh ? pDocSh->GetDocument().GetSheetLimits() : pDoc->GetSheetLimits()), + maHighlightData (pDocSh ? pDocSh->GetDocument().GetSheetLimits() : pDoc->GetSheetLimits()), pDocShell ( pDocSh ), mrDoc (pDocSh ? pDocSh->GetDocument() : *pDoc), pView ( pViewSh ), @@ -3149,6 +3150,11 @@ ScMarkData& ScViewData::GetMarkData() return maMarkData; } +ScMarkData& ScViewData::GetHighlightData() +{ + return maHighlightData; +} + const ScMarkData& ScViewData::GetMarkData() const { return maMarkData;