From e076820bb7a9537a2427f1e4f1d4d35812ef9aae Mon Sep 17 00:00:00 2001 From: Andrzej Hunt Date: Wed, 4 Nov 2015 15:54:36 +0100 Subject: 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. Change-Id: I10d81e220a56a36e2ec0c59005cd1d4f134857d5 --- desktop/source/lib/init.cxx | 39 ++++++++++++++++++++++++++++++++++++--- include/vcl/ITiledRenderable.hxx | 12 ++++++++++++ sc/inc/docuno.hxx | 6 ++++++ sc/source/ui/inc/gridwin.hxx | 9 +++++++++ sc/source/ui/unoobj/docuno.cxx | 17 +++++++++++++++++ sc/source/ui/view/gridwin.cxx | 36 +++++++++++++++++++++++++++++++----- 6 files changed, 111 insertions(+), 8 deletions(-) diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx index 9999acd93fb1..16c4379b229a 100644 --- a/desktop/source/lib/init.cxx +++ b/desktop/source/lib/init.cxx @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -1141,6 +1142,7 @@ static char* getStyles(LibreOfficeKitDocument* pThis, const char* pCommand) static char* doc_getCommandValues(LibreOfficeKitDocument* pThis, const char* pCommand) { + OString aCommand(pCommand); if (!strcmp(pCommand, ".uno:CharFontName")) { return getFonts(pCommand); @@ -1149,7 +1151,7 @@ static char* doc_getCommandValues(LibreOfficeKitDocument* pThis, const char* pCo { return getStyles(pThis, pCommand); } - else if (OString(pCommand) == ".uno:ViewRowColumnHeaders") + else if (aCommand == ".uno:ViewRowColumnHeaders" || aCommand.startsWith(".uno:CellCursor")) { ITiledRenderable* pDoc = getTiledRenderable(pThis); if (!pDoc) @@ -1158,8 +1160,39 @@ static char* doc_getCommandValues(LibreOfficeKitDocument* pThis, const char* pCo return 0; } - OUString aHeaders = pDoc->getRowColumnHeaders(); - OString aString = OUStringToOString(aHeaders, RTL_TEXTENCODING_UTF8); + OString aString; + if (aCommand == ".uno:ViewRowColumnHeaders") + { + OUString aValue = pDoc->getRowColumnHeaders(); + aString = OUStringToOString(aValue, RTL_TEXTENCODING_UTF8); + } + else if (aCommand.startsWith(".uno:CellCursor:")) + { + 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; + } + aString = pDoc->getCellCursor(nOutputWidth, nOutputHeight, nTileWidth, nTileHeight); + } char* pMemory = static_cast(malloc(aString.getLength() + 1)); strcpy(pMemory, aString.getStr()); return pMemory; diff --git a/include/vcl/ITiledRenderable.hxx b/include/vcl/ITiledRenderable.hxx index 48a13ffc1275..01c0dd20f9ed 100644 --- a/include/vcl/ITiledRenderable.hxx +++ b/include/vcl/ITiledRenderable.hxx @@ -156,6 +156,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& xClipboard) = 0; diff --git a/sc/inc/docuno.hxx b/sc/inc/docuno.hxx index e2a2dbc13349..2c168a1d89b0 100644 --- a/sc/inc/docuno.hxx +++ b/sc/inc/docuno.hxx @@ -407,6 +407,12 @@ public: /// @see vcl::ITiledRenderable::getRowColumnHeaders(). virtual OUString getRowColumnHeaders() 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 d248c3c00e23..97d2c8efd68e 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(); void updateLibreOfficeKitSelection(const std::vector& rRectangles, std::vector* pLogicRects = 0); protected: @@ -440,6 +441,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 2e4bb66be317..337e17fc67b2 100644 --- a/sc/source/ui/unoobj/docuno.cxx +++ b/sc/source/ui/unoobj/docuno.cxx @@ -885,6 +885,23 @@ OUString ScModelObj::getRowColumnHeaders() return pTabView->getRowColumnHeaders(); } +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 8212976c1617..5486cf75feef 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() @@ -6098,6 +6123,7 @@ void ScGridWindow::UpdateCursorOverlay() if ( !aPixelRects.empty() ) { if (pDrawLayer->isTiledRendering()) { + mpOOCursors.reset(new sdr::overlay::OverlayObjectList); updateLibreOfficeKitCellCursor(); } else -- cgit