diff options
author | Marco Cecchetti <marco.cecchetti@collabora.com> | 2020-08-26 09:06:59 +0200 |
---|---|---|
committer | Andras Timar <andras.timar@collabora.com> | 2020-09-15 21:54:22 +0200 |
commit | 8c18cd6823ddf4ef5ba67801a84cee26c9b5a9a6 (patch) | |
tree | 1e5005f4e28ebb55936a9803f7175fcc43ad135c /editeng | |
parent | cee4736f545bd260a21bea8e3c306ec3b7482d5b (diff) |
Online: selection highlight in Calc should follow font size changes.
When user changes font size of selected text, markers and highlight rectangle should be updated.
impedit3.cxx: Line had no effect, removed.
Lokitsearchtest.cxx: Test had bug.
Other changes: LOKit code is separated. Now callback_text_selection is fired when font size is changed (Calc). On Writer it already behaves that way.
Change-Id: I9b7e3224ad162bfb7d8f0853b6cb17b4feafa0cf
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/101193
Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice@gmail.com>
Reviewed-by: Marco Cecchetti <marco.cecchetti@collabora.com>
Reviewed-by: Andras Timar <andras.timar@collabora.com>
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/102465
Tested-by: Jenkins
Diffstat (limited to 'editeng')
-rw-r--r-- | editeng/source/editeng/impedit.cxx | 289 | ||||
-rw-r--r-- | editeng/source/editeng/impedit.hxx | 2 | ||||
-rw-r--r-- | editeng/source/editeng/impedit3.cxx | 5 |
3 files changed, 140 insertions, 156 deletions
diff --git a/editeng/source/editeng/impedit.cxx b/editeng/source/editeng/impedit.cxx index d90aa81be0c4..f6851b5f292f 100644 --- a/editeng/source/editeng/impedit.cxx +++ b/editeng/source/editeng/impedit.cxx @@ -311,6 +311,134 @@ void ImpEditView::SelectionChanged() } } +// This function is also called when a text's font || size is changed. Because its highlight rectangle must be updated. +void ImpEditView::lokSelectionCallback(std::unique_ptr<tools::PolyPolygon> &pPolyPoly, bool bStartHandleVisible, bool bEndHandleVisible) { + VclPtr<vcl::Window> pParent = pOutWin->GetParentWithLOKNotifier(); + vcl::Region aRegion( *pPolyPoly ); + + if (pParent && pParent->GetLOKWindowId() != 0) + { + const long nX = pOutWin->GetOutOffXPixel() - pParent->GetOutOffXPixel(); + const long nY = pOutWin->GetOutOffYPixel() - pParent->GetOutOffYPixel(); + + std::vector<tools::Rectangle> aRectangles; + aRegion.GetRegionRectangles(aRectangles); + + std::vector<OString> v; + for (tools::Rectangle & rRectangle : aRectangles) + { + rRectangle = pOutWin->LogicToPixel(rRectangle); + rRectangle.Move(nX, nY); + v.emplace_back(rRectangle.toString().getStr()); + } + OString sRectangle = comphelper::string::join("; ", v); + + const vcl::ILibreOfficeKitNotifier* pNotifier = pParent->GetLOKNotifier(); + std::vector<vcl::LOKPayloadItem> aItems; + aItems.emplace_back("rectangles", sRectangle); + aItems.emplace_back("startHandleVisible", OString::boolean(bStartHandleVisible)); + aItems.emplace_back("endHandleVisible", OString::boolean(bEndHandleVisible)); + pNotifier->notifyWindow(pParent->GetLOKWindowId(), "text_selection", aItems); + } + else + { + pOutWin->Push(PushFlags::MAPMODE); + if (pOutWin->GetMapMode().GetMapUnit() == MapUnit::MapTwip) + { + // Find the parent that is not right + // on top of us to use its offset. + vcl::Window* parent = pOutWin->GetParent(); + while (parent && + parent->GetOutOffXPixel() == pOutWin->GetOutOffXPixel() && + parent->GetOutOffYPixel() == pOutWin->GetOutOffYPixel()) + { + parent = parent->GetParent(); + } + + if (parent) + { + lcl_translateTwips(*parent, *pOutWin); + } + } + + bool bMm100ToTwip = !mpLOKSpecialPositioning && + (pOutWin->GetMapMode().GetMapUnit() == MapUnit::Map100thMM); + + Point aOrigin; + if (pOutWin->GetMapMode().GetMapUnit() == MapUnit::MapTwip) + // Writer comments: they use editeng, but are separate widgets. + aOrigin = pOutWin->GetMapMode().GetOrigin(); + + OString sRectangle; + OString sRefPoint; + if (mpLOKSpecialPositioning) + sRefPoint = mpLOKSpecialPositioning->GetRefPoint().toString(); + + std::vector<tools::Rectangle> aRectangles; + aRegion.GetRegionRectangles(aRectangles); + + if (!aRectangles.empty()) + { + if (pOutWin->IsChart()) + { + const vcl::Window* pViewShellWindow = mpViewShell->GetEditWindowForActiveOLEObj(); + if (pViewShellWindow && pViewShellWindow->IsAncestorOf(*pOutWin)) + { + Point aOffsetPx = pOutWin->GetOffsetPixelFrom(*pViewShellWindow); + Point aLogicOffset = pOutWin->PixelToLogic(aOffsetPx); + for (tools::Rectangle& rRect : aRectangles) + rRect.Move(aLogicOffset.getX(), aLogicOffset.getY()); + } + } + + std::vector<OString> v; + for (tools::Rectangle & rRectangle : aRectangles) + { + if (bMm100ToTwip) + rRectangle = OutputDevice::LogicToLogic(rRectangle, MapMode(MapUnit::Map100thMM), MapMode(MapUnit::MapTwip)); + rRectangle.Move(aOrigin.getX(), aOrigin.getY()); + v.emplace_back(rRectangle.toString().getStr()); + } + sRectangle = comphelper::string::join("; ", v); + + if (mpLOKSpecialPositioning && !sRectangle.isEmpty()) + sRectangle += ":: " + sRefPoint; + + tools::Rectangle& rStart = aRectangles.front(); + tools::Rectangle aStart(rStart.Left(), rStart.Top(), rStart.Left() + 1, rStart.Bottom()); + + OString aPayload = aStart.toString(); + if (mpLOKSpecialPositioning) + aPayload += ":: " + sRefPoint; + + mpViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_TEXT_SELECTION_START, aPayload.getStr()); + + tools::Rectangle& rEnd = aRectangles.back(); + tools::Rectangle aEnd(rEnd.Right() - 1, rEnd.Top(), rEnd.Right(), rEnd.Bottom()); + + aPayload = aEnd.toString(); + if (mpLOKSpecialPositioning) + aPayload += ":: " + sRefPoint; + + mpViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_TEXT_SELECTION_END, aPayload.getStr()); + } + + if (mpOtherShell) + { + // Another shell wants to know about our existing selection. + if (mpViewShell != mpOtherShell) + mpViewShell->NotifyOtherView(mpOtherShell, LOK_CALLBACK_TEXT_VIEW_SELECTION, "selection", sRectangle); + } + else + { + mpViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_TEXT_SELECTION, sRectangle.getStr()); + mpViewShell->NotifyOtherViews(LOK_CALLBACK_TEXT_VIEW_SELECTION, "selection", sRectangle); + } + + pOutWin->Pop(); + } +} + // renamed from DrawSelection to DrawSelectionXOR to better reflect what this // method was used for: Paint Selection in XOR, change it and again paint it in XOR. // This can be safely assumed due to the EditView only being capable of painting the @@ -343,11 +471,6 @@ void ImpEditView::DrawSelectionXOR( EditSelection aTmpSel, vcl::Region* pRegion, // pRegion: When not NULL, then only calculate Region. - vcl::Region* pOldRegion = pRegion; - vcl::Region aRegion; - if (comphelper::LibreOfficeKit::isActive() && !pRegion) - pRegion = &aRegion; - OutputDevice* pTarget; if (pTargetDevice) pTarget = pTargetDevice; @@ -358,7 +481,7 @@ void ImpEditView::DrawSelectionXOR( EditSelection aTmpSel, vcl::Region* pRegion, std::unique_ptr<tools::PolyPolygon> pPolyPoly; - if ( !pRegion ) + if ( !pRegion && !comphelper::LibreOfficeKit::isActive()) { if ( !pEditEngine->pImpEditEngine->GetUpdateMode() ) return; @@ -378,10 +501,9 @@ void ImpEditView::DrawSelectionXOR( EditSelection aTmpSel, vcl::Region* pRegion, if (pOutWin && pOutWin->GetCursor()) pOutWin->GetCursor()->Hide(); } - else - { + + if (comphelper::LibreOfficeKit::isActive() || pRegion) pPolyPoly.reset(new tools::PolyPolygon); - } DBG_ASSERT( !pEditEngine->IsIdleFormatterActive(), "DrawSelectionXOR: Not formatted!" ); aTmpSel.Adjust( pEditEngine->GetEditDoc() ); @@ -492,156 +614,19 @@ void ImpEditView::DrawSelectionXOR( EditSelection aTmpSel, vcl::Region* pRegion, Point aPt2( std::max( nX1, nX2 ), aBottomRight.Y() ); ImplDrawHighlightRect( pTarget, aPt1, aPt2, pPolyPoly.get() ); - nTmpStartIndex = nTmpEndIndex; } } - } } - if ( pRegion ) - { - *pRegion = vcl::Region( *pPolyPoly ); - - if (comphelper::LibreOfficeKit::isActive() && mpViewShell && !pOldRegion && pOutWin) - { - VclPtr<vcl::Window> pParent = pOutWin->GetParentWithLOKNotifier(); - if (pParent && pParent->GetLOKWindowId() != 0) - { - const long nX = pOutWin->GetOutOffXPixel() - pParent->GetOutOffXPixel(); - const long nY = pOutWin->GetOutOffYPixel() - pParent->GetOutOffYPixel(); - - std::vector<tools::Rectangle> aRectangles; - pRegion->GetRegionRectangles(aRectangles); - - std::vector<OString> v; - for (tools::Rectangle & rRectangle : aRectangles) - { - rRectangle = pOutWin->LogicToPixel(rRectangle); - rRectangle.Move(nX, nY); - v.emplace_back(rRectangle.toString().getStr()); - } - OString sRectangle = comphelper::string::join("; ", v); - - const vcl::ILibreOfficeKitNotifier* pNotifier = pParent->GetLOKNotifier(); - std::vector<vcl::LOKPayloadItem> aItems; - aItems.emplace_back("rectangles", sRectangle); - aItems.emplace_back("startHandleVisible", OString::boolean(bStartHandleVisible)); - aItems.emplace_back("endHandleVisible", OString::boolean(bEndHandleVisible)); - pNotifier->notifyWindow(pParent->GetLOKWindowId(), "text_selection", aItems); - pPolyPoly.reset(); - return; - } - - pOutWin->Push(PushFlags::MAPMODE); - if (pOutWin->GetMapMode().GetMapUnit() == MapUnit::MapTwip) - { - // Find the parent that is not right - // on top of us to use its offset. - vcl::Window* parent = pOutWin->GetParent(); - while (parent && - parent->GetOutOffXPixel() == pOutWin->GetOutOffXPixel() && - parent->GetOutOffYPixel() == pOutWin->GetOutOffYPixel()) - { - parent = parent->GetParent(); - } - - if (parent) - { - lcl_translateTwips(*parent, *pOutWin); - } - } - - bool bMm100ToTwip = !mpLOKSpecialPositioning && - (pOutWin->GetMapMode().GetMapUnit() == MapUnit::Map100thMM); - - Point aOrigin; - if (pOutWin->GetMapMode().GetMapUnit() == MapUnit::MapTwip) - // Writer comments: they use editeng, but are separate widgets. - aOrigin = pOutWin->GetMapMode().GetOrigin(); - - OString sRectangle; - OString sRefPoint; - if (mpLOKSpecialPositioning) - sRefPoint = mpLOKSpecialPositioning->GetRefPoint().toString(); - // If we are not in selection mode, then the exported own selection should be empty. - // This is needed always in Online, regardless whether in "selection mode" (whatever - // that is) or not, for tdf#125568, but I don't have the clout to make this completely - // unconditional also for desktop LO. - if (comphelper::LibreOfficeKit::isActive() || pEditEngine->pImpEditEngine->IsInSelectionMode() || mpOtherShell) - { - std::vector<tools::Rectangle> aRectangles; - pRegion->GetRegionRectangles(aRectangles); - - if (pOutWin->IsChart()) - { - const vcl::Window* pViewShellWindow = mpViewShell->GetEditWindowForActiveOLEObj(); - if (pViewShellWindow && pViewShellWindow->IsAncestorOf(*pOutWin)) - { - Point aOffsetPx = pOutWin->GetOffsetPixelFrom(*pViewShellWindow); - Point aLogicOffset = pOutWin->PixelToLogic(aOffsetPx); - for (tools::Rectangle& rRect : aRectangles) - rRect.Move(aLogicOffset.getX(), aLogicOffset.getY()); - } - } - - if (!aRectangles.empty()) - { - tools::Rectangle& rStart = aRectangles.front(); - tools::Rectangle aStart(rStart.Left(), rStart.Top(), rStart.Left() + 1, rStart.Bottom()); - if (bMm100ToTwip) - aStart = OutputDevice::LogicToLogic(aStart, MapMode(MapUnit::Map100thMM), MapMode(MapUnit::MapTwip)); - aStart.Move(aOrigin.getX(), aOrigin.getY()); - - OString aPayload = aStart.toString(); - if (mpLOKSpecialPositioning) - aPayload += ":: " + sRefPoint; - - mpViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_TEXT_SELECTION_START, aPayload.getStr()); - - tools::Rectangle& rEnd = aRectangles.back(); - tools::Rectangle aEnd(rEnd.Right() - 1, rEnd.Top(), rEnd.Right(), rEnd.Bottom()); - if (bMm100ToTwip) - aEnd = OutputDevice::LogicToLogic(aEnd, MapMode(MapUnit::Map100thMM), MapMode(MapUnit::MapTwip)); - aEnd.Move(aOrigin.getX(), aOrigin.getY()); - - aPayload = aEnd.toString(); - if (mpLOKSpecialPositioning) - aPayload += ":: " + sRefPoint; - - mpViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_TEXT_SELECTION_END, aPayload.getStr()); - } - - std::vector<OString> v; - for (tools::Rectangle & rRectangle : aRectangles) - { - if (bMm100ToTwip) - rRectangle = OutputDevice::LogicToLogic(rRectangle, MapMode(MapUnit::Map100thMM), MapMode(MapUnit::MapTwip)); - rRectangle.Move(aOrigin.getX(), aOrigin.getY()); - v.emplace_back(rRectangle.toString().getStr()); - } - sRectangle = comphelper::string::join("; ", v); - } - - if (mpLOKSpecialPositioning && !sRectangle.isEmpty()) - sRectangle += ":: " + sRefPoint; - - if (mpOtherShell) - { - // Another shell wants to know about our existing selection. - if (mpViewShell != mpOtherShell) - mpViewShell->NotifyOtherView(mpOtherShell, LOK_CALLBACK_TEXT_VIEW_SELECTION, "selection", sRectangle); - } - else - { - mpViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_TEXT_SELECTION, sRectangle.getStr()); - mpViewShell->NotifyOtherViews(LOK_CALLBACK_TEXT_VIEW_SELECTION, "selection", sRectangle); - } - - pOutWin->Pop(); - } + if (comphelper::LibreOfficeKit::isActive() && mpViewShell && pOutWin) + lokSelectionCallback(pPolyPoly, bStartHandleVisible, bEndHandleVisible); + if (pRegion || comphelper::LibreOfficeKit::isActive()) + { + if (pRegion) + *pRegion = vcl::Region( *pPolyPoly ); pPolyPoly.reset(); } else diff --git a/editeng/source/editeng/impedit.hxx b/editeng/source/editeng/impedit.hxx index e9493ecdfa5b..cacd0440f4e1 100644 --- a/editeng/source/editeng/impedit.hxx +++ b/editeng/source/editeng/impedit.hxx @@ -305,6 +305,8 @@ private: return mpEditViewCallbacks; } + void lokSelectionCallback(std::unique_ptr<tools::PolyPolygon> &pPolyPoly, bool bStartHandleVisible, bool bEndHandleVisible); + void setEditViewCallbacks(const EditViewCallbacks* pEditViewCallbacks) { mpEditViewCallbacks = pEditViewCallbacks; diff --git a/editeng/source/editeng/impedit3.cxx b/editeng/source/editeng/impedit3.cxx index 0caebc3ae342..3b362a7704d4 100644 --- a/editeng/source/editeng/impedit3.cxx +++ b/editeng/source/editeng/impedit3.cxx @@ -3900,10 +3900,7 @@ void ImpEditEngine::Paint( ImpEditView* pView, const tools::Rectangle& rRect, Ou else pTarget->SetClipRegion(); - // In case of tiled rendering pass a region to DrawSelectionXOR(), so that - // selection callbacks are not emitted during every repaint. - vcl::Region aRegion; - pView->DrawSelectionXOR(pView->GetEditSelection(), comphelper::LibreOfficeKit::isActive() ? &aRegion : nullptr, pTarget); + pView->DrawSelectionXOR(pView->GetEditSelection(), nullptr, pTarget); } void ImpEditEngine::InsertContent( ContentNode* pNode, sal_Int32 nPos ) |