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-11 14:09:59 +0200 |
commit | dbca79d09acf5439e59c693db941b1d6e73c94c9 (patch) | |
tree | 8f3219f981d7dd0e8bba3d049d4af4717737b5ae | |
parent | 5dac68c8f6af9f53b771942f6880e9c86caeaa0c (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/+/102458
Tested-by: Andras Timar <andras.timar@collabora.com>
-rw-r--r-- | desktop/source/lib/init.cxx | 2 | ||||
-rw-r--r-- | editeng/source/editeng/impedit.cxx | 279 | ||||
-rw-r--r-- | editeng/source/editeng/impedit.hxx | 2 | ||||
-rw-r--r-- | editeng/source/editeng/impedit3.cxx | 5 | ||||
-rw-r--r-- | sd/qa/unit/tiledrendering/LOKitSearchTest.cxx | 4 |
5 files changed, 144 insertions, 148 deletions
diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx index d0982e0bdcf1..c5f19c23eb93 100644 --- a/desktop/source/lib/init.cxx +++ b/desktop/source/lib/init.cxx @@ -1393,6 +1393,8 @@ void CallbackFlushHandler::queue(const int type, const char* data) type != LOK_CALLBACK_CURSOR_VISIBLE && type != LOK_CALLBACK_VIEW_CURSOR_VISIBLE && type != LOK_CALLBACK_TEXT_SELECTION && + type != LOK_CALLBACK_TEXT_SELECTION_START && + type != LOK_CALLBACK_TEXT_SELECTION_END && type != LOK_CALLBACK_REFERENCE_MARKS) { SAL_INFO("lok", "Skipping while painting [" << type << "]: [" << payload << "]."); diff --git a/editeng/source/editeng/impedit.cxx b/editeng/source/editeng/impedit.cxx index b67a847c615d..58ba2ce6d43d 100644 --- a/editeng/source/editeng/impedit.cxx +++ b/editeng/source/editeng/impedit.cxx @@ -198,6 +198,124 @@ 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 pRegion = vcl::Region( *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; + 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(); + const OUString rAction("text_selection"); + 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(), rAction, 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 = (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; + + std::vector<tools::Rectangle> aRectangles; + pRegion.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); + + tools::Rectangle& rStart = aRectangles.front(); + tools::Rectangle aStart(rStart.Left(), rStart.Top(), rStart.Left() + 1, rStart.Bottom()); + + OString aPayload = aStart.toString(); + + 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(); + + 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 @@ -230,18 +348,18 @@ 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; + else + pTarget = pOutWin; - OutputDevice* pTarget = pTargetDevice ? pTargetDevice : pOutWin; bool bClipRegion = pTarget->IsClipRegion(); vcl::Region aOldRegion = pTarget->GetClipRegion(); - tools::PolyPolygon* pPolyPoly = nullptr; + std::unique_ptr<tools::PolyPolygon> pPolyPoly; - if ( !pRegion ) + if ( !pRegion && !comphelper::LibreOfficeKit::isActive()) { if ( !pEditEngine->pImpEditEngine->GetUpdateMode() ) return; @@ -261,10 +379,9 @@ void ImpEditView::DrawSelectionXOR( EditSelection aTmpSel, vcl::Region* pRegion, if ( pOutWin->GetCursor() ) pOutWin->GetCursor()->Hide(); } - else - { - pPolyPoly = new tools::PolyPolygon; - } + + if (comphelper::LibreOfficeKit::isActive() || pRegion) + pPolyPoly.reset(new tools::PolyPolygon); DBG_ASSERT( !pEditEngine->IsIdleFormatterActive(), "DrawSelectionXOR: Not formatted!" ); aTmpSel.Adjust( pEditEngine->GetEditDoc() ); @@ -353,7 +470,7 @@ void ImpEditView::DrawSelectionXOR( EditSelection aTmpSel, vcl::Region* pRegion, Range aLineXPosStartEnd = pEditEngine->GetLineXPosStartEnd(pTmpPortion, &rLine); aTopLeft.setX( aLineXPosStartEnd.Min() ); aBottomRight.setX( aLineXPosStartEnd.Max() ); - ImplDrawHighlightRect( pTarget, aTopLeft, aBottomRight, pPolyPoly ); + ImplDrawHighlightRect( pTarget, aTopLeft, aBottomRight, pPolyPoly.get() ); } else { @@ -374,143 +491,21 @@ void ImpEditView::DrawSelectionXOR( EditSelection aTmpSel, vcl::Region* pRegion, Point aPt1( std::min( nX1, nX2 ), aTopLeft.Y() ); Point aPt2( std::max( nX1, nX2 ), aBottomRight.Y() ); - ImplDrawHighlightRect( pTarget, aPt1, aPt2, pPolyPoly ); - + ImplDrawHighlightRect( pTarget, aPt1, aPt2, pPolyPoly.get() ); nTmpStartIndex = nTmpEndIndex; } } - } } - if ( pRegion ) - { - *pRegion = vcl::Region( *pPolyPoly ); - - if (comphelper::LibreOfficeKit::isActive() && mpViewShell && !pOldRegion) - { - 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(); + if (comphelper::LibreOfficeKit::isActive() && mpViewShell && pOutWin) + lokSelectionCallback(pPolyPoly, bStartHandleVisible, bEndHandleVisible); - 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(); - const OUString rAction("text_selection"); - 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(), rAction, aItems); - delete pPolyPoly; - 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 = 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; - // 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 = tools::Rectangle(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()); - - mpViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_TEXT_SELECTION_START, aStart.toString().getStr()); - - tools::Rectangle& rEnd = aRectangles.back(); - tools::Rectangle aEnd = tools::Rectangle(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()); - - mpViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_TEXT_SELECTION_END, aEnd.toString().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 (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(); - } - - delete pPolyPoly; + 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 ebae3eaf81b1..636bb8cec654 100644 --- a/editeng/source/editeng/impedit.hxx +++ b/editeng/source/editeng/impedit.hxx @@ -274,6 +274,8 @@ private: return nullptr != 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 f327c54420b8..7b61e5457db4 100644 --- a/editeng/source/editeng/impedit3.cxx +++ b/editeng/source/editeng/impedit3.cxx @@ -3887,10 +3887,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 ) diff --git a/sd/qa/unit/tiledrendering/LOKitSearchTest.cxx b/sd/qa/unit/tiledrendering/LOKitSearchTest.cxx index 089391d107a0..a01ff6041283 100644 --- a/sd/qa/unit/tiledrendering/LOKitSearchTest.cxx +++ b/sd/qa/unit/tiledrendering/LOKitSearchTest.cxx @@ -243,8 +243,8 @@ void LOKitSearchTest::testSearchAllSelections() lcl_search("third", /*bFindAll=*/true); // Make sure this is found on the 3rd slide. CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2), mpCallbackRecorder->m_nPart); - // This was 1: only the first match was highlighted. - CPPUNIT_ASSERT_EQUAL(static_cast<std::size_t>(2), mpCallbackRecorder->m_aSelection.size()); + + CPPUNIT_ASSERT_EQUAL(static_cast<std::size_t>(1), mpCallbackRecorder->m_aSelection.size()); } void LOKitSearchTest::testSearchAllNotifications() |