diff options
-rw-r--r-- | desktop/source/lib/init.cxx | 5 | ||||
-rw-r--r-- | include/sfx2/lokcomponenthelpers.hxx | 2 | ||||
-rw-r--r-- | sfx2/source/view/lokstarmathhelper.cxx | 23 | ||||
-rw-r--r-- | starmath/inc/cursor.hxx | 2 | ||||
-rw-r--r-- | starmath/inc/view.hxx | 9 | ||||
-rw-r--r-- | starmath/inc/visitors.hxx | 60 | ||||
-rw-r--r-- | starmath/source/cursor.cxx | 14 | ||||
-rw-r--r-- | starmath/source/view.cxx | 56 | ||||
-rw-r--r-- | starmath/source/visitors.cxx | 91 |
9 files changed, 205 insertions, 57 deletions
diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx index 46dbe3e5d9c6..6414a3fe1ca9 100644 --- a/desktop/source/lib/init.cxx +++ b/desktop/source/lib/init.cxx @@ -2138,6 +2138,11 @@ void CallbackFlushHandler::enqueueUpdatedTypes() void CallbackFlushHandler::enqueueUpdatedType( int type, const SfxViewShell* viewShell, int viewId ) { + if (type == LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR) + { + if (const SfxViewShell* viewShell2 = LokStarMathHelper(viewShell).GetSmViewShell()) + viewShell = viewShell2; + } std::optional<OString> payload = viewShell->getLOKPayload( type, viewId ); if(!payload) return; // No actual payload to send. diff --git a/include/sfx2/lokcomponenthelpers.hxx b/include/sfx2/lokcomponenthelpers.hxx index b26cd0a13fb8..23bdcd44369e 100644 --- a/include/sfx2/lokcomponenthelpers.hxx +++ b/include/sfx2/lokcomponenthelpers.hxx @@ -72,6 +72,8 @@ public: vcl::Window* GetGraphicWindow(); vcl::Window* GetWidgetWindow(); + const SfxViewShell* GetSmViewShell(); + tools::Rectangle GetBoundingBox() const; void Dispatch(const OUString& cmd, const css::uno::Sequence<css::beans::PropertyValue>& rArguments) const; diff --git a/sfx2/source/view/lokstarmathhelper.cxx b/sfx2/source/view/lokstarmathhelper.cxx index fb30d9cee449..8ec65c45a274 100644 --- a/sfx2/source/view/lokstarmathhelper.cxx +++ b/sfx2/source/view/lokstarmathhelper.cxx @@ -122,14 +122,29 @@ vcl::Window* LokStarMathHelper::GetWidgetWindow() return mpWidgetWindow.get(); } +const SfxViewShell* LokStarMathHelper::GetSmViewShell() +{ + if (vcl::Window* pGraphWindow = GetGraphicWindow()) + { + return SfxViewShell::GetFirst(false, [pGraphWindow](const SfxViewShell* shell) { + return shell->GetWindow() && shell->GetWindow()->IsChild(pGraphWindow); + }); + } + return nullptr; +} + +tools::Rectangle LokStarMathHelper::GetBoundingBox() const +{ + return mpIPClient ? mpIPClient->GetObjArea() : tools::Rectangle{}; +} + bool LokStarMathHelper::postMouseEvent(int nType, int nX, int nY, int nCount, int nButtons, int nModifier, double /*fScaleX*/, double /*fScaleY*/) { - if (vcl::Window* pWindow = GetWidgetWindow()) + const tools::Rectangle rBBox = GetBoundingBox(); + if (Point aMousePos(nX, nY); rBBox.Contains(aMousePos)) { - Point aMousePos(nX, nY); - tools::Rectangle rBBox = mpIPClient->GetObjArea(); - if (rBBox.Contains(aMousePos)) + if (vcl::Window* pWindow = GetWidgetWindow()) { aMousePos -= rBBox.TopLeft(); LokMouseEventData aMouseEventData( diff --git a/starmath/inc/cursor.hxx b/starmath/inc/cursor.hxx index 5886ffaf2eac..a1491c5decfe 100644 --- a/starmath/inc/cursor.hxx +++ b/starmath/inc/cursor.hxx @@ -186,6 +186,8 @@ public: /** Draw the caret */ void Draw(OutputDevice& pDev, Point Offset, bool isCaretVisible); + tools::Rectangle GetCaretRectangle(OutputDevice& rOutDev) const; + bool IsAtTailOfBracket(SmBracketType eBracketType) const; private: diff --git a/starmath/inc/view.hxx b/starmath/inc/view.hxx index 309c89513489..1905edb02741 100644 --- a/starmath/inc/view.hxx +++ b/starmath/inc/view.hxx @@ -136,10 +136,7 @@ public: } private: - void SetIsCursorVisible(bool bVis) - { - bIsCursorVisible = bVis; - } + void SetIsCursorVisible(bool bVis); void SetCursor(const SmNode *pNode); void SetCursor(const tools::Rectangle &rRect); @@ -295,7 +292,7 @@ public: SmViewShell(SfxViewFrame *pFrame, SfxViewShell *pOldSh); virtual ~SmViewShell() override; - SmDocShell * GetDoc() + SmDocShell * GetDoc() const { return static_cast<SmDocShell *>( GetViewFrame()->GetObjectShell() ); } @@ -325,6 +322,8 @@ public: SFX_DECL_INTERFACE(SFX_INTERFACE_SMA_START+SfxInterfaceId(2)) SFX_DECL_VIEWFACTORY(SmViewShell); + void SendCaretToLOK() const; + private: /// SfxInterface initializer. static void InitInterface_Impl(); diff --git a/starmath/inc/visitors.hxx b/starmath/inc/visitors.hxx index 27c4e374e9ff..b29bb26fb5b0 100644 --- a/starmath/inc/visitors.hxx +++ b/starmath/inc/visitors.hxx @@ -111,26 +111,64 @@ protected: virtual void DefaultVisit( SmNode* pNode ) = 0; }; -// SmCaretDrawingVisitor +// SmCaretLinesVisitor: ancestor of caret rectangle enumeration and drawing visitors -/** Visitor for drawing a caret position */ -class SmCaretDrawingVisitor final : public SmDefaultingVisitor +class SmCaretLinesVisitor : public SmDefaultingVisitor { public: - /** Given position and device this constructor will draw the caret */ - SmCaretDrawingVisitor( OutputDevice& rDevice, SmCaretPos position, Point offset, bool caretVisible ); - virtual ~SmCaretDrawingVisitor() {} - void Visit( SmTextNode* pNode ) override; + SmCaretLinesVisitor(OutputDevice& rDevice, SmCaretPos position, Point offset); + virtual ~SmCaretLinesVisitor() = default; + void Visit(SmTextNode* pNode) override; using SmDefaultingVisitor::Visit; + +protected: + void DoIt(); + + OutputDevice& getDev() { return mrDev; } + virtual void ProcessCaretLine(Point from, Point to) = 0; + virtual void ProcessUnderline(Point from, Point to) = 0; + + /** Default method for drawing pNodes */ + void DefaultVisit(SmNode* pNode) override; + private: - OutputDevice &mrDev; + OutputDevice& mrDev; SmCaretPos maPos; /** Offset to draw from */ Point maOffset; - bool mbCaretVisible; +}; - /** Default method for drawing pNodes */ - void DefaultVisit( SmNode* pNode ) override; +// SmCaretRectanglesVisitor: obtains the set of rectangles to sent to lok + +class SmCaretRectanglesVisitor final : public SmCaretLinesVisitor +{ +public: + SmCaretRectanglesVisitor(OutputDevice& rDevice, SmCaretPos position); + const tools::Rectangle& getCaret() const { return maCaret; } + +protected: + virtual void ProcessCaretLine(Point from, Point to) override; + virtual void ProcessUnderline(Point from, Point to) override; + +private: + tools::Rectangle maCaret; +}; + +// SmCaretDrawingVisitor + +/** Visitor for drawing a caret position */ +class SmCaretDrawingVisitor final : public SmCaretLinesVisitor +{ +public: + /** Given position and device this constructor will draw the caret */ + SmCaretDrawingVisitor( OutputDevice& rDevice, SmCaretPos position, Point offset, bool caretVisible ); + +protected: + virtual void ProcessCaretLine(Point from, Point to) override; + virtual void ProcessUnderline(Point from, Point to) override; + +private: + bool mbCaretVisible; }; // SmCaretPos2LineVisitor diff --git a/starmath/source/cursor.cxx b/starmath/source/cursor.cxx index fc1e3c5ecb7b..f6d93b8f11cf 100644 --- a/starmath/source/cursor.cxx +++ b/starmath/source/cursor.cxx @@ -11,8 +11,11 @@ #include <document.hxx> #include <view.hxx> #include <comphelper/string.hxx> +#include <comphelper/lok.hxx> #include <editeng/editeng.hxx> +#include <LibreOfficeKit/LibreOfficeKitEnums.h> #include <osl/diagnose.h> +#include <sfx2/lokhelper.hxx> void SmCursor::Move(OutputDevice* pDev, SmMovementDirection direction, bool bMoveAnchor){ SmCaretPosGraphEntry* NewPos = nullptr; @@ -171,6 +174,11 @@ void SmCursor::Draw(OutputDevice& pDev, Point Offset, bool isCaretVisible){ SmCaretDrawingVisitor(pDev, GetPosition(), Offset, isCaretVisible); } +tools::Rectangle SmCursor::GetCaretRectangle(OutputDevice& rOutDev) const +{ + return SmCaretRectanglesVisitor(rOutDev, GetPosition()).getCaret(); +} + void SmCursor::DeletePrev(OutputDevice* pDev){ //Delete only a selection if there's a selection if(HasSelection()){ @@ -1319,7 +1327,11 @@ void SmCursor::EndEdit(){ void SmCursor::RequestRepaint(){ SmViewShell *pViewSh = SmGetActiveView(); if( pViewSh ) { - if ( SfxObjectCreateMode::EMBEDDED == mpDocShell->GetCreateMode() ) + if (comphelper::LibreOfficeKit::isActive()) + { + pViewSh->SendCaretToLOK(); + } + else if ( SfxObjectCreateMode::EMBEDDED == mpDocShell->GetCreateMode() ) mpDocShell->Repaint(); else pViewSh->GetGraphicWidget().Invalidate(); diff --git a/starmath/source/view.cxx b/starmath/source/view.cxx index aee745931ee7..95a175081737 100644 --- a/starmath/source/view.cxx +++ b/starmath/source/view.cxx @@ -40,6 +40,8 @@ #include <sfx2/docinsert.hxx> #include <sfx2/filedlghelper.hxx> #include <sfx2/infobar.hxx> +#include <sfx2/lokcomponenthelpers.hxx> +#include <sfx2/lokhelper.hxx> #include <sfx2/msg.hxx> #include <sfx2/objface.hxx> #include <sfx2/printer.hxx> @@ -365,6 +367,9 @@ bool SmGraphicWidget::MouseButtonDown(const MouseEvent& rMEvt) if (SmViewShell::IsInlineEditEnabled()) { GetCursor().MoveTo(&rDevice, aPos, !rMEvt.IsShift()); + // 'on grab' window events are missing in lok, do it explicitly + if (comphelper::LibreOfficeKit::isActive()) + SetIsCursorVisible(true); return true; } const SmNode *pNode = nullptr; @@ -456,13 +461,15 @@ IMPL_LINK_NOARG(SmGraphicWidget, CaretBlinkTimerHdl, Timer *, void) void SmGraphicWidget::CaretBlinkInit() { + if (comphelper::LibreOfficeKit::isActive()) + return; // No blinking in lok case aCaretBlinkTimer.SetInvokeHandler(LINK(this, SmGraphicWidget, CaretBlinkTimerHdl)); aCaretBlinkTimer.SetTimeout(Application::GetSettings().GetStyleSettings().GetCursorBlinkTime()); } void SmGraphicWidget::CaretBlinkStart() { - if (!SmViewShell::IsInlineEditEnabled()) + if (!SmViewShell::IsInlineEditEnabled() || comphelper::LibreOfficeKit::isActive()) return; if (aCaretBlinkTimer.GetTimeout() != STYLE_CURSOR_NOBLINKTIME) aCaretBlinkTimer.Start(); @@ -470,7 +477,7 @@ void SmGraphicWidget::CaretBlinkStart() void SmGraphicWidget::CaretBlinkStop() { - if (!SmViewShell::IsInlineEditEnabled()) + if (!SmViewShell::IsInlineEditEnabled() || comphelper::LibreOfficeKit::isActive()) return; aCaretBlinkTimer.Stop(); } @@ -496,6 +503,17 @@ void SmGraphicWidget::ShowLine(bool bShow) bIsLineVisible = bShow; } +void SmGraphicWidget::SetIsCursorVisible(bool bVis) +{ + bIsCursorVisible = bVis; + if (comphelper::LibreOfficeKit::isActive()) + { + mrViewShell.SendCaretToLOK(); + mrViewShell.libreOfficeKitViewCallback(LOK_CALLBACK_CURSOR_VISIBLE, + OString::boolean(bVis).getStr()); + } +} + void SmGraphicWidget::SetCursor(const SmNode *pNode) { if (SmViewShell::IsInlineEditEnabled()) @@ -2131,6 +2149,16 @@ public: mpSelectionChangeHandler->selectionChanged({}); // Installs the correct context } + virtual void SAL_CALL dispose() override + { + if (comphelper::LibreOfficeKit::isActive()) + if (auto pViewShell = GetViewShell_Impl()) + pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_CURSOR_VISIBLE, + OString::boolean(false).getStr()); + + SfxBaseController::dispose(); + } + private: static OUString GetContextName() { return "Math"; } // Static constant for now @@ -2282,6 +2310,20 @@ std::optional<OString> SmViewShell::getLOKPayload(int nType, int nViewId) const switch (nType) { case LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR: + { + OString sRectangle; + if (const SmGraphicWidget& widget = GetGraphicWidget(); widget.IsCursorVisible()) + { + SmCursor& rCursor = GetDoc()->GetCursor(); + OutputDevice& rOutDev = const_cast<SmGraphicWidget&>(widget).GetOutputDevice(); + tools::Rectangle aCaret = rCursor.GetCaretRectangle(rOutDev); + LokStarMathHelper helper(SfxViewShell::Current()); + tools::Rectangle aBounds = helper.GetBoundingBox(); + aCaret.Move(aBounds.Left(), aBounds.Top()); + sRectangle = aCaret.toString(); + } + return SfxLokHelper::makeVisCursorInvalidation(nViewId, sRectangle, false, {}); + } case LOK_CALLBACK_INVALIDATE_VIEW_CURSOR: case LOK_CALLBACK_TEXT_SELECTION: case LOK_CALLBACK_TEXT_SELECTION_START: @@ -2292,4 +2334,14 @@ std::optional<OString> SmViewShell::getLOKPayload(int nType, int nViewId) const return SfxViewShell::getLOKPayload(nType, nViewId); // aborts } +void SmViewShell::SendCaretToLOK() const +{ + const int nViewId = sal_Int32(GetViewShellId()); + if (const auto& payload = getLOKPayload(LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR, nViewId)) + { + libreOfficeKitViewCallbackWithViewId(LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR, + payload->getStr(), nViewId); + } +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/starmath/source/visitors.cxx b/starmath/source/visitors.cxx index 980c6346ca80..fdf268b65960 100644 --- a/starmath/source/visitors.cxx +++ b/starmath/source/visitors.cxx @@ -154,19 +154,19 @@ void SmDefaultingVisitor::Visit( SmVerticalBraceNode* pNode ) DefaultVisit( pNode ); } -// SmCaretDrawingVisitor +// SmCaretLinesVisitor -SmCaretDrawingVisitor::SmCaretDrawingVisitor( OutputDevice& rDevice, - SmCaretPos position, - Point offset, - bool caretVisible ) - : mrDev( rDevice ) - , maPos( position ) - , maOffset( offset ) - , mbCaretVisible( caretVisible ) +SmCaretLinesVisitor::SmCaretLinesVisitor(OutputDevice& rDevice, SmCaretPos position, Point offset) + : mrDev(rDevice) + , maPos(position) + , maOffset(offset) +{ +} + +void SmCaretLinesVisitor::DoIt() { - SAL_WARN_IF( !position.IsValid(), "starmath", "Cannot draw invalid position!" ); - if( !position.IsValid( ) ) + SAL_WARN_IF(!maPos.IsValid(), "starmath", "Cannot draw invalid position!"); + if (!maPos.IsValid()) return; //Save device state @@ -177,7 +177,7 @@ SmCaretDrawingVisitor::SmCaretDrawingVisitor( OutputDevice& rDevice, mrDev.Pop( ); } -void SmCaretDrawingVisitor::Visit( SmTextNode* pNode ) +void SmCaretLinesVisitor::Visit( SmTextNode* pNode ) { tools::Long i = maPos.nIndex; @@ -193,23 +193,14 @@ void SmCaretDrawingVisitor::Visit( SmTextNode* pNode ) tools::Long left_line = pLine->GetLeft( ) + maOffset.X( ); tools::Long right_line = pLine->GetRight( ) + maOffset.X( ); - //Set color - mrDev.SetLineColor( COL_BLACK ); - - if ( mbCaretVisible ) { - //Draw vertical line - Point p1( left, top ); - Point p2( left, top + height ); - mrDev.DrawLine( p1, p2 ); - } + // Vertical line + ProcessCaretLine({ left, top }, { left, top + height }); - //Underline the line - Point aLeft( left_line, top + height ); - Point aRight( right_line, top + height ); - mrDev.DrawLine( aLeft, aRight ); + // Underline + ProcessUnderline({ left_line, top + height }, { right_line, top + height }); } -void SmCaretDrawingVisitor::DefaultVisit( SmNode* pNode ) +void SmCaretLinesVisitor::DefaultVisit( SmNode* pNode ) { //Find the line SmNode* pLine = SmCursor::FindTopMostNodeInLine( pNode ); @@ -221,20 +212,52 @@ void SmCaretDrawingVisitor::DefaultVisit( SmNode* pNode ) tools::Long left_line = pLine->GetLeft( ) + maOffset.X( ); tools::Long right_line = pLine->GetRight( ) + maOffset.X( ); - //Set color - mrDev.SetLineColor( COL_BLACK ); + // Vertical line + ProcessCaretLine({ left, top }, { left, top + height }); + + // Underline + ProcessUnderline({ left_line, top + height }, { right_line, top + height }); +} +// SmCaretRectanglesVisitor + +SmCaretRectanglesVisitor::SmCaretRectanglesVisitor(OutputDevice& rDevice, SmCaretPos position) + : SmCaretLinesVisitor(rDevice, position, {}) +{ + DoIt(); +} + +void SmCaretRectanglesVisitor::ProcessCaretLine(Point from, Point to) { maCaret = { from, to }; } +void SmCaretRectanglesVisitor::ProcessUnderline(Point /*from*/, Point /*to*/) {} // No underline + +// SmCaretDrawingVisitor + +SmCaretDrawingVisitor::SmCaretDrawingVisitor( OutputDevice& rDevice, + SmCaretPos position, + Point offset, + bool caretVisible ) + : SmCaretLinesVisitor(rDevice, position, offset) + , mbCaretVisible( caretVisible ) +{ + DoIt(); +} + +void SmCaretDrawingVisitor::ProcessCaretLine(Point from, Point to) +{ if ( mbCaretVisible ) { + //Set color + getDev().SetLineColor(COL_BLACK); //Draw vertical line - Point p1( left, top ); - Point p2( left, top + height ); - mrDev.DrawLine( p1, p2 ); + getDev().DrawLine(from, to); } +} +void SmCaretDrawingVisitor::ProcessUnderline(Point from, Point to) +{ + //Set color + getDev().SetLineColor(COL_BLACK); //Underline the line - Point aLeft( left_line, top + height ); - Point aRight( right_line, top + height ); - mrDev.DrawLine( aLeft, aRight ); + getDev().DrawLine(from, to); } // SmCaretPos2LineVisitor |