starmath/inc/cursor.hxx      |    3 ++-
 starmath/inc/visitors.hxx    |   25 +++++++++++++++++--------
 starmath/source/cursor.cxx   |    8 +++++++-
 starmath/source/view.cxx     |   24 +++++++++++++++++++++++-
 starmath/source/visitors.cxx |   42 +++++++++++++++++++-----------------------
 5 files changed, 68 insertions(+), 34 deletions(-)

New commits:
commit 1b1a066b935158dc029939520c8fe70b029cb311
Author:     Mike Kaganski <mike.kagan...@collabora.com>
AuthorDate: Sat Nov 5 21:16:29 2022 +0300
Commit:     Mike Kaganski <mike.kagan...@collabora.com>
CommitDate: Sat Nov 5 23:37:35 2022 +0100

    lok: show Math selection
    
    Change-Id: I950ae3e5fb000d6acec4c26ff143b918a4e48a27
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/142342
    Tested-by: Jenkins
    Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com>

diff --git a/starmath/inc/cursor.hxx b/starmath/inc/cursor.hxx
index a1491c5decfe..0a8a35071f10 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 b29bb26fb5b0..eaf329034c7d 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 f6d93b8f11cf..c7c27616b3f9 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 95a175081737..1bcfc0d3efc7 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 fdf268b65960..6efe9936b948 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;

Reply via email to