summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarco Cecchetti <marco.cecchetti@collabora.com>2020-08-26 09:06:59 +0200
committerAndras Timar <andras.timar@collabora.com>2020-09-11 14:09:59 +0200
commitdbca79d09acf5439e59c693db941b1d6e73c94c9 (patch)
tree8f3219f981d7dd0e8bba3d049d4af4717737b5ae
parent5dac68c8f6af9f53b771942f6880e9c86caeaa0c (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.cxx2
-rw-r--r--editeng/source/editeng/impedit.cxx279
-rw-r--r--editeng/source/editeng/impedit.hxx2
-rw-r--r--editeng/source/editeng/impedit3.cxx5
-rw-r--r--sd/qa/unit/tiledrendering/LOKitSearchTest.cxx4
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()