desktop/source/lib/init.cxx                  |   54 +++++++++++
 include/LibreOfficeKit/LibreOfficeKitEnums.h |    9 +
 include/vcl/ITiledRenderable.hxx             |   12 ++
 libreofficekit/source/gtk/lokdocview.cxx     |   30 ++++++
 sc/inc/docuno.hxx                            |    6 +
 sc/source/ui/inc/gridwin.hxx                 |   19 ++++
 sc/source/ui/unoobj/docuno.cxx               |   17 +++
 sc/source/ui/view/gridwin.cxx                |  128 ++++++++++++++++++++-------
 sc/source/ui/view/gridwin4.cxx               |    6 -
 9 files changed, 244 insertions(+), 37 deletions(-)

New commits:
commit e7e0d46dba7b1016968a133330bca23a4bf668ec
Author: Andrzej Hunt <andr...@ahunt.org>
Date:   Thu Nov 5 10:31:06 2015 +0100

    sc lok: update parameter syntax for .uno:CellCursor
    
    This follows the syntax for .uno:ViewRowColumnHeaders
    (which was implemented somewhat concurrentl with CellCursor)
    
    Change-Id: I8ef03a969abc1716a0e95d95fb7043d75910c828

diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index f45445c..aaa5492 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -1274,7 +1274,7 @@ static char* doc_getCommandValues(LibreOfficeKitDocument* 
pThis, const char* pCo
         strcpy(pMemory, aString.getStr());
         return pMemory;
     }
-    else if (aCommand.startsWith(aCellCursor)
+    else if (aCommand.startsWith(aCellCursor))
     {
         ITiledRenderable* pDoc = getTiledRenderable(pThis);
         if (!pDoc)
@@ -1283,29 +1283,40 @@ static char* 
doc_getCommandValues(LibreOfficeKitDocument* pThis, const char* pCo
             return 0;
         }
 
-        OString aString;
-        OString aParams = 
aCommand.copy(OString(".uno:CellCursor:").getLength());
-
-        sal_Int32 nIndex = 0;
-        OString aOutputWidth = aParams.getToken(0,  ',',  nIndex);
-        OString aOutputHeight = aParams.getToken(0,  ',',  nIndex);
-        OString aTileWidth = aParams.getToken(0,  ',',  nIndex);
-        OString aTileHeight = aParams.getToken(0,  ',',  nIndex);
-
-        int nOutputWidth, nOutputHeight;
-        long nTileWidth, nTileHeight;
-        if (!(comphelper::string::getTokenCount(aParams, ',') == 4
-              && !aOutputWidth.isEmpty()
-              && (nOutputWidth = aOutputWidth.toInt32()) != 0
-              && !aOutputHeight.isEmpty()
-              && (nOutputHeight = aOutputHeight.toInt32()) != 0
-              && !aTileWidth.isEmpty()
-              && (nTileWidth = aTileWidth.toInt64()) != 0
-              && !aTileHeight.isEmpty()
-              && (nTileHeight = aTileHeight.toInt64()) != 0))
+        // Command has parameters.
+        int nOutputWidth = 0;
+        int nOutputHeight = 0;
+        long nTileWidth = 0;
+        long nTileHeight = 0;
+        if (aCommand.getLength() > aCellCursor.getLength())
         {
-            gImpl->maLastExceptionMsg = "Can't parse arguments for 
.uno:CellCursor, no cursor returned";
-            return NULL;
+            OString aArguments = aCommand.copy(aCellCursor.getLength() + 1);
+            sal_Int32 nParamIndex = 0;
+            do
+            {
+                OString aParamToken = aArguments.getToken(0, '&', nParamIndex);
+                sal_Int32 nIndex = 0;
+                OString aKey;
+                OString aValue;
+                do
+                {
+                    OString aToken = aParamToken.getToken(0, '=', nIndex);
+                    if (!aKey.getLength())
+                        aKey = aToken;
+                    else
+                        aValue = aToken;
+                }
+                while (nIndex >= 0);
+                if (aKey == "outputWidth")
+                    nOutputWidth = aValue.toInt32();
+                else if (aKey == "outputHeight")
+                    nOutputHeight = aValue.toInt32();
+                else if (aKey == "tileWidth")
+                    nTileWidth = aValue.toInt64();
+                else if (aKey == "tileHeight")
+                    nTileHeight = aValue.toInt64();
+            }
+            while (nParamIndex >= 0);
         }
 
         OString aString = pDoc->getCellCursor(nOutputWidth, nOutputHeight, 
nTileWidth, nTileHeight);
commit 2bcaffd12263e8f3c2a2fbf8ccc4b9bba2642146
Author: Andrzej Hunt <andr...@ahunt.org>
Date:   Wed Nov 4 17:24:15 2015 +0100

    sc lok: tdf#94605 introduce uno:CellCursor
    
    This allows the client to rerequest the current cursor position,
    which is necessary e.g. on zoom-level changes.
    
    Conflicts:
        desktop/source/lib/init.cxx
        sc/inc/docuno.hxx
    
    Change-Id: I10d81e220a56a36e2ec0c59005cd1d4f134857d5

diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index bcc215b..f45445c 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -32,6 +32,7 @@
 #include <comphelper/dispatchcommand.hxx>
 #include <comphelper/lok.hxx>
 #include <comphelper/processfactory.hxx>
+#include <comphelper/string.hxx>
 
 #include <com/sun/star/beans/XPropertySet.hpp>
 #include <com/sun/star/container/XNameAccess.hpp>
@@ -1209,6 +1210,7 @@ static char* doc_getCommandValues(LibreOfficeKitDocument* 
pThis, const char* pCo
 {
     OString aCommand(pCommand);
     static const OString aViewRowColumnHeaders(".uno:ViewRowColumnHeaders");
+    static const OString aCellCursor(".uno:CellCursor");
 
     if (!strcmp(pCommand, ".uno:CharFontName"))
     {
@@ -1267,6 +1269,47 @@ static char* 
doc_getCommandValues(LibreOfficeKitDocument* pThis, const char* pCo
 
         OUString aHeaders = pDoc->getRowColumnHeaders(aRectangle);
         OString aString = OUStringToOString(aHeaders, RTL_TEXTENCODING_UTF8);
+
+        char* pMemory = static_cast<char*>(malloc(aString.getLength() + 1));
+        strcpy(pMemory, aString.getStr());
+        return pMemory;
+    }
+    else if (aCommand.startsWith(aCellCursor)
+    {
+        ITiledRenderable* pDoc = getTiledRenderable(pThis);
+        if (!pDoc)
+        {
+            gImpl->maLastExceptionMsg = "Document doesn't support tiled 
rendering";
+            return 0;
+        }
+
+        OString aString;
+        OString aParams = 
aCommand.copy(OString(".uno:CellCursor:").getLength());
+
+        sal_Int32 nIndex = 0;
+        OString aOutputWidth = aParams.getToken(0,  ',',  nIndex);
+        OString aOutputHeight = aParams.getToken(0,  ',',  nIndex);
+        OString aTileWidth = aParams.getToken(0,  ',',  nIndex);
+        OString aTileHeight = aParams.getToken(0,  ',',  nIndex);
+
+        int nOutputWidth, nOutputHeight;
+        long nTileWidth, nTileHeight;
+        if (!(comphelper::string::getTokenCount(aParams, ',') == 4
+              && !aOutputWidth.isEmpty()
+              && (nOutputWidth = aOutputWidth.toInt32()) != 0
+              && !aOutputHeight.isEmpty()
+              && (nOutputHeight = aOutputHeight.toInt32()) != 0
+              && !aTileWidth.isEmpty()
+              && (nTileWidth = aTileWidth.toInt64()) != 0
+              && !aTileHeight.isEmpty()
+              && (nTileHeight = aTileHeight.toInt64()) != 0))
+        {
+            gImpl->maLastExceptionMsg = "Can't parse arguments for 
.uno:CellCursor, no cursor returned";
+            return NULL;
+        }
+
+        OString aString = pDoc->getCellCursor(nOutputWidth, nOutputHeight, 
nTileWidth, nTileHeight);
+
         char* pMemory = static_cast<char*>(malloc(aString.getLength() + 1));
         strcpy(pMemory, aString.getStr());
         return pMemory;
diff --git a/include/vcl/ITiledRenderable.hxx b/include/vcl/ITiledRenderable.hxx
index efa9bc2..963f1fc 100644
--- a/include/vcl/ITiledRenderable.hxx
+++ b/include/vcl/ITiledRenderable.hxx
@@ -159,6 +159,18 @@ public:
         return OUString();
     }
 
+    /**
+     * Get position and size of cell cursor in Calc.
+     * (This could maybe also be used for tables in Writer/Impress in future?)
+     */
+    virtual OString getCellCursor(int /*nOutputWidth*/,
+                                  int /*nOutputHeight*/,
+                                  long /*nTileWidth*/,
+                                  long /*nTileHeight*/)
+    {
+        return OString();
+    }
+
     /// Sets the clipboard of the component.
     virtual void setClipboard(const 
css::uno::Reference<css::datatransfer::clipboard::XClipboard>& xClipboard) = 0;
 
diff --git a/sc/inc/docuno.hxx b/sc/inc/docuno.hxx
index 45fd943..49059f0 100644
--- a/sc/inc/docuno.hxx
+++ b/sc/inc/docuno.hxx
@@ -407,6 +407,12 @@ public:
 
     /// @see vcl::ITiledRenderable::getRowColumnHeaders().
     virtual OUString getRowColumnHeaders(const Rectangle& rRectangle) override;
+
+    /// @see vcl::ITiledRenderable::getCellCursor().
+    virtual OString getCellCursor( int nOutputWidth,
+                                   int nOutputHeight,
+                                   long nTileWidth,
+                                   long nTileHeight ) override;
 };
 
 class ScDrawPagesObj : public cppu::WeakImplHelper<
diff --git a/sc/source/ui/inc/gridwin.hxx b/sc/source/ui/inc/gridwin.hxx
index a6dcdf7..f02d09a 100644
--- a/sc/source/ui/inc/gridwin.hxx
+++ b/sc/source/ui/inc/gridwin.hxx
@@ -300,6 +300,7 @@ class ScGridWindow : public vcl::Window, public 
DropTargetHelper, public DragSou
 
     void            GetSelectionRects( ::std::vector< Rectangle >& rPixelRects 
);
 
+
     void            updateLibreOfficeKitCellCursor();
 protected:
     virtual void    PrePaint(vcl::RenderContext& rRenderContext) override;
@@ -439,6 +440,14 @@ public:
     void            UpdateShrinkOverlay();
     void            UpdateAllOverlays();
 
+    /// @see ScModelObj::getCellCursor().
+    OString         getCellCursor(const Fraction& rZoomX,
+                                  const Fraction& rZoomY);
+    OString         getCellCursor(int nOutputWidth,
+                                  int nOutputHeight,
+                                  long nTileWidth,
+                                  long nTileHeight);
+
 protected:
     void ImpCreateOverlayObjects();
     void ImpDestroyOverlayObjects();
diff --git a/sc/source/ui/unoobj/docuno.cxx b/sc/source/ui/unoobj/docuno.cxx
index f8e85de..69a5cb3 100644
--- a/sc/source/ui/unoobj/docuno.cxx
+++ b/sc/source/ui/unoobj/docuno.cxx
@@ -885,6 +885,23 @@ OUString ScModelObj::getRowColumnHeaders(const Rectangle& 
rRectangle)
     return pTabView->getRowColumnHeaders(rRectangle);
 }
 
+OString ScModelObj::getCellCursor( int nOutputWidth, int nOutputHeight,
+                                   long nTileWidth, long nTileHeight )
+{
+    SolarMutexGuard aGuard;
+
+    ScViewData* pViewData = ScDocShell::GetViewData();
+
+    if (!pViewData)
+        return OString();
+
+    ScGridWindow* pGridWindow = pViewData->GetActiveWin();
+    if (!pGridWindow)
+        return OString();
+
+    return "{ \"commandName\": \".uno:CellCursor\", \"commandValues\": \"" + 
pGridWindow->getCellCursor( nOutputWidth, nOutputHeight, nTileWidth, 
nTileHeight ) + "\" }";
+}
+
 void ScModelObj::initializeForTiledRendering()
 {
     SolarMutexGuard aGuard;
diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx
index a3bed46..1636a34 100644
--- a/sc/source/ui/view/gridwin.cxx
+++ b/sc/source/ui/view/gridwin.cxx
@@ -5777,19 +5777,36 @@ bool ScGridWindow::InsideVisibleRange( SCCOL nPosX, 
SCROW nPosY )
     return maVisibleRange.isInside(nPosX, nPosY);
 }
 
-void ScGridWindow::updateLibreOfficeKitCellCursor() {
+// Use the same zoom calculations as in paintTile - this
+// means the client can ensure they can get the correct
+// cursor corresponding to their current tile sizings.
+OString ScGridWindow::getCellCursor( int nOutputWidth, int nOutputHeight,
+                                     long nTileWidth, long nTileHeight )
+{
+    Fraction zoomX = Fraction(long(nOutputWidth * TWIPS_PER_PIXEL), 
nTileWidth);
+    Fraction zoomY = Fraction(long(nOutputHeight * TWIPS_PER_PIXEL), 
nTileHeight);
+    return getCellCursor(zoomX, zoomY);
+}
+
+OString ScGridWindow::getCellCursor(const Fraction& rZoomX, const Fraction& 
rZoomY) {
     ScDocument* pDoc = pViewData->GetDocument();
     ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer();
 
-    if (!pDrawLayer->isTiledRendering())
-        return;
+    // GridWindows stores a shown cell cursor in mpOOCursors, hence
+    // we can use that to determine whether we would want to be showing
+    // one (client-side) for tiled rendering too.
+    if (!pDrawLayer->isTiledRendering() || !mpOOCursors.get())
+    {
+        return OString("EMPTY");
+    }
 
     SCCOL nX = pViewData->GetCurX();
     SCROW nY = pViewData->GetCurY();
 
     Fraction defaultZoomX = pViewData->GetZoomX();
     Fraction defaultZoomY = pViewData->GetZoomX();
-    pViewData->SetZoom(mTiledZoomX, mTiledZoomY, true);
+
+    pViewData->SetZoom(rZoomX, rZoomY, true);
 
     Point aScrPos = pViewData->GetScrPos( nX, nY, eWhich, true );
     long nSizeXPix;
@@ -5803,7 +5820,15 @@ void ScGridWindow::updateLibreOfficeKitCellCursor() {
 
     pViewData->SetZoom(defaultZoomX, defaultZoomY, true);
 
-    pDrawLayer->libreOfficeKitCallback(LOK_CALLBACK_CELL_CURSOR, 
aRect.toString().getStr());
+    return aRect.toString();
+}
+
+void ScGridWindow::updateLibreOfficeKitCellCursor()
+{
+    ScDocument* pDoc = pViewData->GetDocument();
+    ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer();
+    OString aCursor = getCellCursor(mTiledZoomX, mTiledZoomY);
+    pDrawLayer->libreOfficeKitCallback(LOK_CALLBACK_CELL_CURSOR, 
aCursor.getStr());
 }
 
 void ScGridWindow::CursorChanged()
@@ -6089,6 +6114,7 @@ void ScGridWindow::UpdateCursorOverlay()
     if ( !aPixelRects.empty() )
     {
         if (pDrawLayer->isTiledRendering()) {
+            mpOOCursors.reset(new sdr::overlay::OverlayObjectList);
             updateLibreOfficeKitCellCursor();
         }
         else
commit f859dac52e40759fb8202d891df4e1442bc35803
Author: Andrzej Hunt <andr...@ahunt.org>
Date:   Tue Nov 3 10:14:02 2015 +0100

    sc lok: make cell cursor behaviour consistent with desktop
    
    I.e. single click selects cell, typing activates the EditView
    (and hides the cell cursor). (Previously: single click activates
    the edit view, text cursor is shown, and no clean way of hiding
    the cell cursor again.)
    
    Change-Id: I184630277e8935e9f8a97a856191497ec5d62111

diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx
index cdc12ca..a3bed46 100644
--- a/sc/source/ui/view/gridwin.cxx
+++ b/sc/source/ui/view/gridwin.cxx
@@ -2404,7 +2404,9 @@ void ScGridWindow::MouseButtonUp( const MouseEvent& rMEvt 
)
                 bEditAllowed = false;
         }
 
-        if ( bEditAllowed )
+        // We don't want to activate the edit view for a single click in tiled 
rendering
+        // (but we should probably keep the same behaviour for double clicks).
+        if ( bEditAllowed && (!bIsTiledRendering || bDouble) )
         {
             // don't forward the event to an empty cell, causes deselection in
             // case we used the double-click to select the empty cell
@@ -5802,7 +5804,6 @@ void ScGridWindow::updateLibreOfficeKitCellCursor() {
     pViewData->SetZoom(defaultZoomX, defaultZoomY, true);
 
     pDrawLayer->libreOfficeKitCallback(LOK_CALLBACK_CELL_CURSOR, 
aRect.toString().getStr());
-
 }
 
 void ScGridWindow::CursorChanged()
@@ -5811,8 +5812,6 @@ void ScGridWindow::CursorChanged()
     // now, just re-create them
 
     UpdateCursorOverlay();
-
-    updateLibreOfficeKitCellCursor();
 }
 
 void ScGridWindow::ImpCreateOverlayObjects()
@@ -5847,6 +5846,9 @@ void ScGridWindow::UpdateAllOverlays()
 
 void ScGridWindow::DeleteCursorOverlay()
 {
+    ScDocument* pDoc = pViewData->GetDocument();
+    ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer();
+    pDrawLayer->libreOfficeKitCallback(LOK_CALLBACK_CELL_CURSOR, "EMPTY");
     mpOOCursors.reset();
 }
 
@@ -5964,11 +5966,6 @@ void ScGridWindow::UpdateCursorOverlay()
 {
     ScDocument* pDoc = pViewData->GetDocument();
 
-    // The cursor is rendered client-side in tiled rendering -
-    // see updateLibreOfficeKitCellCursor.
-    if (pDoc->GetDrawLayer()->isTiledRendering())
-        return;
-
     MapMode aDrawMode = GetDrawMapMode();
     MapMode aOldMode = GetMapMode();
     if ( aOldMode != aDrawMode )
@@ -6087,40 +6084,48 @@ void ScGridWindow::UpdateCursorOverlay()
         }
     }
 
+    ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer();
+
     if ( !aPixelRects.empty() )
     {
-        // #i70788# get the OverlayManager safely
-        rtl::Reference<sdr::overlay::OverlayManager> xOverlayManager = 
getOverlayManager();
-
-        if (xOverlayManager.is())
+        if (pDrawLayer->isTiledRendering()) {
+            updateLibreOfficeKitCellCursor();
+        }
+        else
         {
-            Color aCursorColor( 
SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor );
-            if (pViewData->GetActivePart() != eWhich)
-                // non-active pane uses a different color.
-                aCursorColor = 
SC_MOD()->GetColorConfig().GetColorValue(svtools::CALCPAGEBREAKAUTOMATIC).nColor;
-            std::vector< basegfx::B2DRange > aRanges;
-            const basegfx::B2DHomMatrix 
aTransform(GetInverseViewTransformation());
+            // #i70788# get the OverlayManager safely
+            rtl::Reference<sdr::overlay::OverlayManager> xOverlayManager = 
getOverlayManager();
 
-            for(size_t a(0); a < aPixelRects.size(); a++)
+            if (xOverlayManager.is())
             {
-                const Rectangle aRA(aPixelRects[a]);
-                basegfx::B2DRange aRB(aRA.Left(), aRA.Top(), aRA.Right() + 1, 
aRA.Bottom() + 1);
-                aRB.transform(aTransform);
-                aRanges.push_back(aRB);
-            }
+                Color aCursorColor( 
SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor );
+                if (pViewData->GetActivePart() != eWhich)
+                    // non-active pane uses a different color.
+                    aCursorColor = 
SC_MOD()->GetColorConfig().GetColorValue(svtools::CALCPAGEBREAKAUTOMATIC).nColor;
+                std::vector< basegfx::B2DRange > aRanges;
+                const basegfx::B2DHomMatrix 
aTransform(GetInverseViewTransformation());
+
+                for(size_t a(0); a < aPixelRects.size(); a++)
+                {
+                    const Rectangle aRA(aPixelRects[a]);
+                    basegfx::B2DRange aRB(aRA.Left(), aRA.Top(), aRA.Right() + 
1, aRA.Bottom() + 1);
+                    aRB.transform(aTransform);
+                    aRanges.push_back(aRB);
+                }
 
-            sdr::overlay::OverlayObject* pOverlay = new 
sdr::overlay::OverlaySelection(
-                sdr::overlay::OVERLAY_SOLID,
-                aCursorColor,
-                aRanges,
-                false);
+                sdr::overlay::OverlayObject* pOverlay = new 
sdr::overlay::OverlaySelection(
+                    sdr::overlay::OVERLAY_SOLID,
+                    aCursorColor,
+                    aRanges,
+                    false);
 
-            xOverlayManager->add(*pOverlay);
-            mpOOCursors.reset(new sdr::overlay::OverlayObjectList);
-            mpOOCursors->append(*pOverlay);
+                xOverlayManager->add(*pOverlay);
+                mpOOCursors.reset(new sdr::overlay::OverlayObjectList);
+                mpOOCursors->append(*pOverlay);
 
-            // notify the LibreOfficeKit too
-            updateLibreOfficeKitSelection(pViewData, pDoc->GetDrawLayer(), 
aPixelRects);
+                // notify the LibreOfficeKit too
+                updateLibreOfficeKitSelection(pViewData, pDoc->GetDrawLayer(), 
aPixelRects);
+            }
         }
     }
 
commit fab3c48a0cd5a0517025993502a04358308fe5ef
Author: Andrzej Hunt <andr...@ahunt.org>
Date:   Mon Nov 2 13:24:12 2015 +0100

    sc lok: Cache viewdata zoom and reuse for cursor callback
    
    As of a1605d6860e3c4510177c42ab6d2fda569506f57 we reset the zoom
    level to the default when processing LOK mouse events. The exact
    cell cursor position is dependent on the zoom level (due to the
    rounding in the cell position summing calculations), hence we need
    to make sure we have the correct zoom level for those calculations
    (or else the rounding errors will result in incorrect cell cursor
    positions). Caching the zoom level and reusing it only here seems
    to be the most efficient way of solving this for now.
    
    (An alternative would be to only send the cell ID in the callback,
     and have the frontend then request the pixel positions together
     with the current frontend zoom level - however especially for
     LOOL minimising the number of trips is probably wise.)
    
    Change-Id: Iae3aabfd7ea9bec7057be7b63670885766870c4f

diff --git a/sc/source/ui/inc/gridwin.hxx b/sc/source/ui/inc/gridwin.hxx
index c5db4f1..a6dcdf7 100644
--- a/sc/source/ui/inc/gridwin.hxx
+++ b/sc/source/ui/inc/gridwin.hxx
@@ -199,6 +199,15 @@ class ScGridWindow : public vcl::Window, public 
DropTargetHelper, public DragSou
     bool                    bAutoMarkVisible:1;
     bool                    bListValButton:1;
 
+    // We cache the tiled rendering zoom level in order to be able to
+    // calculate the correct cell cursor position (which is dependent
+    // on the zoom level). The caching is necessary since
+    // ScModelObj::postMouseEvent resets the zoom level to the default,
+    // which means we have the default zoom level set during the
+    // cell cursor position calculations in updateLibreOfficeKitCellCursor().
+    Fraction                mTiledZoomX;
+    Fraction                mTiledZoomY;
+
     DECL_LINK_TYPED( PopupModeEndHdl, FloatingWindow*, void );
     DECL_LINK_TYPED( PopupSpellingHdl, SpellCallbackInfo&, void );
 
@@ -291,6 +300,7 @@ class ScGridWindow : public vcl::Window, public 
DropTargetHelper, public DragSou
 
     void            GetSelectionRects( ::std::vector< Rectangle >& rPixelRects 
);
 
+    void            updateLibreOfficeKitCellCursor();
 protected:
     virtual void    PrePaint(vcl::RenderContext& rRenderContext) override;
     virtual void    Paint(vcl::RenderContext& rRenderContext, const Rectangle& 
rRect) override;
diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx
index 59bf9e0..cdc12ca 100644
--- a/sc/source/ui/view/gridwin.cxx
+++ b/sc/source/ui/view/gridwin.cxx
@@ -5775,7 +5775,7 @@ bool ScGridWindow::InsideVisibleRange( SCCOL nPosX, SCROW 
nPosY )
     return maVisibleRange.isInside(nPosX, nPosY);
 }
 
-static void updateLibreOfficeKitCellCursor(ScViewData* pViewData, ScSplitPos 
eWhich) {
+void ScGridWindow::updateLibreOfficeKitCellCursor() {
     ScDocument* pDoc = pViewData->GetDocument();
     ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer();
 
@@ -5784,8 +5784,12 @@ static void updateLibreOfficeKitCellCursor(ScViewData* 
pViewData, ScSplitPos eWh
 
     SCCOL nX = pViewData->GetCurX();
     SCROW nY = pViewData->GetCurY();
-    Point aScrPos = pViewData->GetScrPos( nX, nY, eWhich, true );
 
+    Fraction defaultZoomX = pViewData->GetZoomX();
+    Fraction defaultZoomY = pViewData->GetZoomX();
+    pViewData->SetZoom(mTiledZoomX, mTiledZoomY, true);
+
+    Point aScrPos = pViewData->GetScrPos( nX, nY, eWhich, true );
     long nSizeXPix;
     long nSizeYPix;
     pViewData->GetMergeSizePixel( nX, nY, nSizeXPix, nSizeYPix );
@@ -5795,6 +5799,8 @@ static void updateLibreOfficeKitCellCursor(ScViewData* 
pViewData, ScSplitPos eWh
     Rectangle aRect(Point(aScrPos.getX() / fPPTX, aScrPos.getY() / fPPTY),
                     Size(nSizeXPix / fPPTX, nSizeYPix / fPPTY));
 
+    pViewData->SetZoom(defaultZoomX, defaultZoomY, true);
+
     pDrawLayer->libreOfficeKitCallback(LOK_CALLBACK_CELL_CURSOR, 
aRect.toString().getStr());
 
 }
@@ -5806,7 +5812,7 @@ void ScGridWindow::CursorChanged()
 
     UpdateCursorOverlay();
 
-    updateLibreOfficeKitCellCursor(pViewData, eWhich);
+    updateLibreOfficeKitCellCursor();
 }
 
 void ScGridWindow::ImpCreateOverlayObjects()
diff --git a/sc/source/ui/view/gridwin4.cxx b/sc/source/ui/view/gridwin4.cxx
index 51ae5fd..e0f0a51 100644
--- a/sc/source/ui/view/gridwin4.cxx
+++ b/sc/source/ui/view/gridwin4.cxx
@@ -953,11 +953,11 @@ void ScGridWindow::PaintTile( VirtualDevice& rDevice,
     // Similarly to Writer, we should set the mapmode once on the rDevice, and
     // not care about any zoom settings.
 
-    Fraction aFracX(long(nOutputWidth * TWIPS_PER_PIXEL), nTileWidth);
-    Fraction aFracY(long(nOutputHeight * TWIPS_PER_PIXEL), nTileHeight);
+    mTiledZoomX = Fraction(long(nOutputWidth * TWIPS_PER_PIXEL), nTileWidth);
+    mTiledZoomY = Fraction(long(nOutputHeight * TWIPS_PER_PIXEL), nTileHeight);
 
     // page break zoom, and aLogicMode in ScViewData
-    pViewData->SetZoom(aFracX, aFracY, true);
+    pViewData->SetZoom(mTiledZoomX, mTiledZoomY, true);
 
     double fTilePosXPixel = static_cast<double>(nTilePosX) * nOutputWidth / 
nTileWidth;
     double fTilePosYPixel = static_cast<double>(nTilePosY) * nOutputHeight / 
nTileHeight;
commit 799406068d34bb69a077fcc0548bfed002f05641
Author: Andrzej Hunt <andr...@ahunt.org>
Date:   Mon Nov 2 11:43:05 2015 +0100

    sc lok: Cell Cursor callback
    
    This only works correctly for the default zoom level - since
    the updateLibreOfficeKitCellCursor call happens during the
    internal / hidden rendering, it uses the internal zoom values,
    which can differ from the tiled-rendering zoom values.
    
    Conflicts:
        include/LibreOfficeKit/LibreOfficeKitEnums.h
    
    Change-Id: Ie4f344fe771078fca10ad9d6f7a93e88fb93880a

diff --git a/include/LibreOfficeKit/LibreOfficeKitEnums.h 
b/include/LibreOfficeKit/LibreOfficeKitEnums.h
index 86d9e6b..bf62675 100644
--- a/include/LibreOfficeKit/LibreOfficeKitEnums.h
+++ b/include/LibreOfficeKit/LibreOfficeKitEnums.h
@@ -195,7 +195,14 @@ typedef enum
      *     // TODO "result": "..."  // UNO Any converted to JSON (not 
implemented yet)
      * }
      */
-    LOK_CALLBACK_UNO_COMMAND_RESULT
+    LOK_CALLBACK_UNO_COMMAND_RESULT,
+
+    /**
+     * The size and/or the position of the cell cursor changed.
+     *
+     * Rectangle format is the same as LOK_CALLBACK_INVALIDATE_TILES.
+     */
+    LOK_CALLBACK_CELL_CURSOR
 }
 LibreOfficeKitCallbackType;
 
diff --git a/libreofficekit/source/gtk/lokdocview.cxx 
b/libreofficekit/source/gtk/lokdocview.cxx
index dcf6d5f..9aaa5ef 100644
--- a/libreofficekit/source/gtk/lokdocview.cxx
+++ b/libreofficekit/source/gtk/lokdocview.cxx
@@ -79,6 +79,7 @@ struct LOKDocViewPrivateImpl
     /// Position and size of the selection end.
     GdkRectangle m_aTextSelectionEnd;
     GdkRectangle m_aGraphicSelection;
+    GdkRectangle m_aCellCursor;
     gboolean m_bInDragGraphicSelection;
 
     /// @name Start/middle/end handle.
@@ -140,6 +141,7 @@ struct LOKDocViewPrivateImpl
         m_aTextSelectionStart({0, 0, 0, 0}),
         m_aTextSelectionEnd({0, 0, 0, 0}),
         m_aGraphicSelection({0, 0, 0, 0}),
+        m_aCellCursor({0, 0, 0, 0}),
         m_bInDragGraphicSelection(false),
         m_pHandleStart(0),
         m_aHandleStartRect({0, 0, 0, 0}),
@@ -275,6 +277,8 @@ callbackTypeToString (int nType)
         return "LOK_CALLBACK_CURSOR_VISIBLE";
     case LOK_CALLBACK_GRAPHIC_SELECTION:
         return "LOK_CALLBACK_GRAPHIC_SELECTION";
+    case LOK_CALLBACK_CELL_CURSOR:
+        return "LOK_CALLBACK_CELL_CURSOR";
     case LOK_CALLBACK_HYPERLINK_CLICKED:
         return "LOK_CALLBACK_HYPERLINK_CLICKED";
     case LOK_CALLBACK_STATE_CHANGED:
@@ -719,6 +723,15 @@ callback (gpointer pData)
         gtk_widget_queue_draw(GTK_WIDGET(pDocView));
     }
     break;
+    case LOK_CALLBACK_CELL_CURSOR:
+    {
+        if (pCallback->m_aPayload != "EMPTY")
+            priv->m_aCellCursor = payloadToRectangle(pDocView, 
pCallback->m_aPayload.c_str());
+        else
+            memset(&priv->m_aCellCursor, 0, sizeof(priv->m_aCellCursor));
+        gtk_widget_queue_draw(GTK_WIDGET(pDocView));
+    }
+    break;
     case LOK_CALLBACK_HYPERLINK_CLICKED:
     {
         hyperlinkClicked(pDocView, pCallback->m_aPayload);
@@ -1074,6 +1087,22 @@ renderOverlay(LOKDocView* pDocView, cairo_t* pCairo)
         g_free (handleGraphicPath);
     }
 
+    if (!isEmptyRectangle(priv->m_aCellCursor))
+    {
+        cairo_set_source_rgb(pCairo, 0, 0, 0);
+        cairo_rectangle(pCairo,
+                        twipToPixel(priv->m_aCellCursor.x, priv->m_fZoom),
+                        twipToPixel(priv->m_aCellCursor.y, priv->m_fZoom),
+                        twipToPixel(priv->m_aCellCursor.width, priv->m_fZoom),
+                        twipToPixel(priv->m_aCellCursor.height, 
priv->m_fZoom));
+                        // priv->m_aCellCursor.x - 1,
+                        // priv->m_aCellCursor.y - 1,
+                        // priv->m_aCellCursor.width + 2,
+                        // priv->m_aCellCursor.height + 2);
+        cairo_set_line_width(pCairo, 2.0);
+        cairo_stroke(pCairo);
+    }
+
     return FALSE;
 }
 
@@ -2331,6 +2360,7 @@ lok_doc_view_reset_view(LOKDocView* pDocView)
     memset(&priv->m_aTextSelectionEnd, 0, sizeof(priv->m_aTextSelectionEnd));
     memset(&priv->m_aGraphicSelection, 0, sizeof(priv->m_aGraphicSelection));
     priv->m_bInDragGraphicSelection = false;
+    memset(&priv->m_aCellCursor, 0, sizeof(priv->m_aCellCursor));
 
     cairo_surface_destroy(priv->m_pHandleStart);
     priv->m_pHandleStart = 0;
diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx
index 0c37ab9..59bf9e0 100644
--- a/sc/source/ui/view/gridwin.cxx
+++ b/sc/source/ui/view/gridwin.cxx
@@ -5775,12 +5775,38 @@ bool ScGridWindow::InsideVisibleRange( SCCOL nPosX, 
SCROW nPosY )
     return maVisibleRange.isInside(nPosX, nPosY);
 }
 
+static void updateLibreOfficeKitCellCursor(ScViewData* pViewData, ScSplitPos 
eWhich) {
+    ScDocument* pDoc = pViewData->GetDocument();
+    ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer();
+
+    if (!pDrawLayer->isTiledRendering())
+        return;
+
+    SCCOL nX = pViewData->GetCurX();
+    SCROW nY = pViewData->GetCurY();
+    Point aScrPos = pViewData->GetScrPos( nX, nY, eWhich, true );
+
+    long nSizeXPix;
+    long nSizeYPix;
+    pViewData->GetMergeSizePixel( nX, nY, nSizeXPix, nSizeYPix );
+
+    double fPPTX = pViewData->GetPPTX();
+    double fPPTY = pViewData->GetPPTY();
+    Rectangle aRect(Point(aScrPos.getX() / fPPTX, aScrPos.getY() / fPPTY),
+                    Size(nSizeXPix / fPPTX, nSizeYPix / fPPTY));
+
+    pDrawLayer->libreOfficeKitCallback(LOK_CALLBACK_CELL_CURSOR, 
aRect.toString().getStr());
+
+}
+
 void ScGridWindow::CursorChanged()
 {
     // here the created OverlayObjects may be transformed in later versions. 
For
     // now, just re-create them
 
     UpdateCursorOverlay();
+
+    updateLibreOfficeKitCellCursor(pViewData, eWhich);
 }
 
 void ScGridWindow::ImpCreateOverlayObjects()
@@ -5932,9 +5958,8 @@ void ScGridWindow::UpdateCursorOverlay()
 {
     ScDocument* pDoc = pViewData->GetDocument();
 
-    // never show the cell cursor when the tiled rendering is going on; either
-    // we want to show the editeng selection, or the cell selection, but not
-    // the cell cursor by itself
+    // The cursor is rendered client-side in tiled rendering -
+    // see updateLibreOfficeKitCellCursor.
     if (pDoc->GetDrawLayer()->isTiledRendering())
         return;
 
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to