lok: show Math selection
Change-Id: I950ae3e5fb000d6acec4c26ff143b918a4e48a27
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/142342
Tested-by: Jenkins
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
diff --git a/starmath/inc/cursor.hxx b/starmath/inc/cursor.hxx
index a1491c5..0a8a350 100644
--- a/starmath/inc/cursor.hxx
+++ b/starmath/inc/cursor.hxx
@@ -187,6 +187,7 @@ public:
void Draw(OutputDevice& pDev, Point Offset, bool isCaretVisible);
tools::Rectangle GetCaretRectangle(OutputDevice& rOutDev) const;
tools::Rectangle GetSelectionRectangle(OutputDevice& rOutDev) const;
bool IsAtTailOfBracket(SmBracketType eBracketType) const;
@@ -275,7 +276,7 @@ private:
bool SetCaretPosition(SmCaretPos pos);
/** Set selected on nodes of the tree */
void AnnotateSelection();
void AnnotateSelection() const;
/** Clone list of nodes in a clipboard (creates a deep clone) */
static std::unique_ptr<SmNodeList> CloneList(SmClipboard& rClipboard);
diff --git a/starmath/inc/visitors.hxx b/starmath/inc/visitors.hxx
index b29bb26..eaf3290 100644
--- a/starmath/inc/visitors.hxx
+++ b/starmath/inc/visitors.hxx
@@ -424,31 +424,40 @@ private:
};
// SmSelectionDrawingVisitor
// SmSelectionRectanglesVisitor: collect selection
class SmSelectionDrawingVisitor final : public SmDefaultingVisitor
class SmSelectionRectanglesVisitor : public SmDefaultingVisitor
{
public:
/** Draws a selection on rDevice for the selection on pTree */
SmSelectionDrawingVisitor( OutputDevice& rDevice, SmNode* pTree, const Point& rOffset );
virtual ~SmSelectionDrawingVisitor() {}
SmSelectionRectanglesVisitor(OutputDevice& rDevice, SmNode* pTree);
virtual ~SmSelectionRectanglesVisitor() = default;
void Visit( SmTextNode* pNode ) override;
using SmDefaultingVisitor::Visit;
const tools::Rectangle& GetSelection() { return maSelectionArea; }
private:
/** Reference to drawing device */
OutputDevice& mrDev;
/** True if aSelectionArea have been initialized */
bool mbHasSelectionArea;
/** The current area that is selected */
tools::Rectangle maSelectionArea;
/** Extend the area that must be selected */
void ExtendSelectionArea(const tools::Rectangle& rArea);
void ExtendSelectionArea(const tools::Rectangle& rArea) { maSelectionArea.Union(rArea); }
/** Default visiting method */
void DefaultVisit( SmNode* pNode ) override;
/** Visit the children of a given pNode */
void VisitChildren( SmNode* pNode );
};
// SmSelectionDrawingVisitor
class SmSelectionDrawingVisitor final : public SmSelectionRectanglesVisitor
{
public:
/** Draws a selection on rDevice for the selection on pTree */
SmSelectionDrawingVisitor( OutputDevice& rDevice, SmNode* pTree, const Point& rOffset );
};
// SmNodeToTextVisitor
/** Extract command text from pNodes */
diff --git a/starmath/source/cursor.cxx b/starmath/source/cursor.cxx
index f6d93b8..c7c2761 100644
--- a/starmath/source/cursor.cxx
+++ b/starmath/source/cursor.cxx
@@ -165,7 +165,7 @@ bool SmCursor::SetCaretPosition(SmCaretPos pos){
return false;
}
void SmCursor::AnnotateSelection(){
void SmCursor::AnnotateSelection() const {
//TODO: Manage a state, reset it upon modification and optimize this call
SmSetSelectionVisitor(mpAnchor->CaretPos, mpPosition->CaretPos, mpTree);
}
@@ -179,6 +179,12 @@ tools::Rectangle SmCursor::GetCaretRectangle(OutputDevice& rOutDev) const
return SmCaretRectanglesVisitor(rOutDev, GetPosition()).getCaret();
}
tools::Rectangle SmCursor::GetSelectionRectangle(OutputDevice& rOutDev) const
{
AnnotateSelection();
return SmSelectionRectanglesVisitor(rOutDev, mpTree).GetSelection();
}
void SmCursor::DeletePrev(OutputDevice* pDev){
//Delete only a selection if there's a selection
if(HasSelection()){
diff --git a/starmath/source/view.cxx b/starmath/source/view.cxx
index 95a1750..1bcfc0d 100644
--- a/starmath/source/view.cxx
+++ b/starmath/source/view.cxx
@@ -2324,10 +2324,28 @@ std::optional<OString> SmViewShell::getLOKPayload(int nType, int nViewId) const
}
return SfxLokHelper::makeVisCursorInvalidation(nViewId, sRectangle, false, {});
}
case LOK_CALLBACK_INVALIDATE_VIEW_CURSOR:
case LOK_CALLBACK_TEXT_SELECTION:
{
OString sRectangle;
if (const SmGraphicWidget& widget = GetGraphicWidget(); widget.IsCursorVisible())
{
SmCursor& rCursor = GetDoc()->GetCursor();
OutputDevice& rOutDev = const_cast<SmGraphicWidget&>(widget).GetOutputDevice();
tools::Rectangle aSelection = rCursor.GetSelectionRectangle(rOutDev);
if (!aSelection.IsEmpty())
{
LokStarMathHelper helper(SfxViewShell::Current());
tools::Rectangle aBounds = helper.GetBoundingBox();
aSelection.Move(aBounds.Left(), aBounds.Top());
sRectangle = aSelection.toString();
}
}
return sRectangle;
}
case LOK_CALLBACK_TEXT_SELECTION_START:
case LOK_CALLBACK_TEXT_SELECTION_END:
case LOK_CALLBACK_INVALIDATE_VIEW_CURSOR:
case LOK_CALLBACK_TEXT_VIEW_SELECTION:
return {};
}
@@ -2342,6 +2360,10 @@ void SmViewShell::SendCaretToLOK() const
libreOfficeKitViewCallbackWithViewId(LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR,
payload->getStr(), nViewId);
}
if (const auto& payload = getLOKPayload(LOK_CALLBACK_TEXT_SELECTION, nViewId))
{
libreOfficeKitViewCallback(LOK_CALLBACK_TEXT_SELECTION, payload->getStr());
}
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/source/visitors.cxx b/starmath/source/visitors.cxx
index fdf268b..6efe993 100644
--- a/starmath/source/visitors.cxx
+++ b/starmath/source/visitors.cxx
@@ -1888,49 +1888,45 @@ void SmCloningVisitor::Visit( SmVerticalBraceNode* pNode )
// SmSelectionDrawingVisitor
SmSelectionDrawingVisitor::SmSelectionDrawingVisitor( OutputDevice& rDevice, SmNode* pTree, const Point& rOffset )
: mrDev( rDevice )
, mbHasSelectionArea( false )
: SmSelectionRectanglesVisitor( rDevice, pTree )
{
//Visit everything
SAL_WARN_IF( !pTree, "starmath", "pTree can't be null!" );
if( pTree )
pTree->Accept( this );
//Draw selection if there's any
if( !mbHasSelectionArea ) return;
if(GetSelection().IsEmpty()) return;
maSelectionArea.Move( rOffset.X( ), rOffset.Y( ) );
tools::Rectangle aSelectionArea = GetSelection() + rOffset;
//Save device state
mrDev.Push( vcl::PushFlags::LINECOLOR | vcl::PushFlags::FILLCOLOR );
rDevice.Push( vcl::PushFlags::LINECOLOR | vcl::PushFlags::FILLCOLOR );
//Change colors
mrDev.SetLineColor( );
mrDev.SetFillColor( COL_LIGHTGRAY );
rDevice.SetLineColor( );
rDevice.SetFillColor( COL_LIGHTGRAY );
//Draw rectangle
mrDev.DrawRect( maSelectionArea );
rDevice.DrawRect( aSelectionArea );
//Restore device state
mrDev.Pop( );
rDevice.Pop( );
}
void SmSelectionDrawingVisitor::ExtendSelectionArea(const tools::Rectangle& rArea)
// SmSelectionRectanglesVisitor
SmSelectionRectanglesVisitor::SmSelectionRectanglesVisitor(OutputDevice& rDevice, SmNode* pTree)
: mrDev(rDevice)
{
if ( ! mbHasSelectionArea ) {
maSelectionArea = rArea;
mbHasSelectionArea = true;
} else
maSelectionArea.Union(rArea);
// Visit everything
SAL_WARN_IF(!pTree, "starmath", "pTree can't be null!");
if (pTree)
pTree->Accept(this);
}
void SmSelectionDrawingVisitor::DefaultVisit( SmNode* pNode )
void SmSelectionRectanglesVisitor::DefaultVisit( SmNode* pNode )
{
if( pNode->IsSelected( ) )
ExtendSelectionArea( pNode->AsRectangle( ) );
VisitChildren( pNode );
}
void SmSelectionDrawingVisitor::VisitChildren( SmNode* pNode )
void SmSelectionRectanglesVisitor::VisitChildren( SmNode* pNode )
{
if(pNode->GetNumSubNodes() == 0)
return;
@@ -1942,7 +1938,7 @@ void SmSelectionDrawingVisitor::VisitChildren( SmNode* pNode )
}
}
void SmSelectionDrawingVisitor::Visit( SmTextNode* pNode )
void SmSelectionRectanglesVisitor::Visit( SmTextNode* pNode )
{
if( !pNode->IsSelected())
return;