loleaflet/Makefile | 2 loleaflet/README | 3 loleaflet/reference.html | 25 ++ loleaflet/src/control/Parts.js | 19 ++ loleaflet/src/core/Socket.js | 1 loleaflet/src/layer/tile/GridLayer.js | 28 +++ loleaflet/src/layer/tile/TileLayer.js | 96 ++++++++++- loleaflet/src/map/handler/Map.Keyboard.js | 70 +++++++- loleaflet/src/map/handler/Map.Mouse.js | 33 ++- loolwsd/LOKitClient.cpp | 6 loolwsd/LOOLSession.cpp | 54 +++++- loolwsd/LOOLSession.hpp | 6 loolwsd/Makefile.am | 4 loolwsd/TileCache.cpp | 2 loolwsd/bundled/include/LibreOfficeKit/LibreOfficeKit.h | 29 ++- loolwsd/bundled/include/LibreOfficeKit/LibreOfficeKitEnums.h | 4 loolwsd/protocol.txt | 7 17 files changed, 360 insertions(+), 29 deletions(-)
New commits: commit 4fa63063d2dc957fd830cb3f27356a83e7fc985c Author: Mihai Varga <mihai.va...@collabora.com> Date: Thu Oct 8 16:40:19 2015 +0300 loleaflet: bump version after tarball diff --git a/loleaflet/Makefile b/loleaflet/Makefile index 444fc81..a77191f 100644 --- a/loleaflet/Makefile +++ b/loleaflet/Makefile @@ -3,7 +3,7 @@ # ("micro") part: Between releases odd, even for releases (no other # changes inbetween). -VERSION=1.2.6 +VERSION=1.2.7 # Version number of the bundled 'draw' thing DRAW_VERSION=0.2.4 commit b433d066ce3f01b5e6ee28d60a4227771efc608c Author: Mihai Varga <mihai.va...@collabora.com> Date: Thu Oct 8 16:39:47 2015 +0300 loleaflet: bump version before tarball diff --git a/loleaflet/Makefile b/loleaflet/Makefile index aa96ef8..444fc81 100644 --- a/loleaflet/Makefile +++ b/loleaflet/Makefile @@ -3,7 +3,7 @@ # ("micro") part: Between releases odd, even for releases (no other # changes inbetween). -VERSION=1.2.5 +VERSION=1.2.6 # Version number of the bundled 'draw' thing DRAW_VERSION=0.2.4 commit 1cf0c7299236734fc07950fac4fe5c2f145ab3de Author: Mihai Varga <mihai.va...@collabora.com> Date: Tue Oct 6 17:33:22 2015 +0300 handle LOK_CALLBACK_SEARCH_RESULT_SELECTION callback diff --git a/loleaflet/reference.html b/loleaflet/reference.html index d45f019..057c2d5 100644 --- a/loleaflet/reference.html +++ b/loleaflet/reference.html @@ -6823,6 +6823,11 @@ map.addControl(new MyControl()); <td><code>Number</code></td> <td>Number of search results</td> </tr> + <tr> + <td><code><b>results</b></code></td> + <td><code><a href="#bounds">Bounds[]</a></code></td> + <td>An array of bounds representing the selections of the search results in the document.</td> + </tr> </table> <h3 id="partpagerectangles-event">PartPageRectangles</h3> diff --git a/loleaflet/src/layer/tile/TileLayer.js b/loleaflet/src/layer/tile/TileLayer.js index 5eaab4d..6be61de 100644 --- a/loleaflet/src/layer/tile/TileLayer.js +++ b/loleaflet/src/layer/tile/TileLayer.js @@ -214,8 +214,8 @@ L.TileLayer = L.GridLayer.extend({ else if (textMsg.startsWith('searchnotfound:')) { this._onSearchNotFoundMsg(textMsg); } - else if (textMsg.startsWith('searchresultcount:')) { - this._onSearchResultCount(textMsg); + else if (textMsg.startsWith('searchresultselection:')) { + this._onSearchResultSelection(textMsg); } else if (textMsg.startsWith('setpart:')) { this._onSetPartMsg(textMsg); @@ -336,11 +336,16 @@ L.TileLayer = L.GridLayer.extend({ this._map.fire('search', {originalPhrase: originalPhrase, count: 0}); }, - _onSearchResultCount: function (textMsg) { - textMsg = textMsg.substring(19); - var count = parseInt(textMsg.substring(0, textMsg.indexOf(';'))); - var originalPhrase = textMsg.substring(textMsg.indexOf(';') + 1); - this._map.fire('search', {originalPhrase: originalPhrase, count: count}); + _onSearchResultSelection: function (textMsg) { + textMsg = textMsg.substring(23); + var obj = JSON.parse(textMsg); + var originalPhrase = obj.searchString; + var count = obj.searchResultSelection.length; + var results = []; + for (var i = 0; i < obj.searchResultSelection.length; i++) { + results.push(this._twipsRectangleToPixelBounds(obj.searchResultSelection[i])); + } + this._map.fire('search', {originalPhrase: originalPhrase, count: count, results: results}); }, _onStateChangedMsg: function (textMsg) { diff --git a/loolwsd/LOKitClient.cpp b/loolwsd/LOKitClient.cpp index 57f0e03..8e3f546 100644 --- a/loolwsd/LOKitClient.cpp +++ b/loolwsd/LOKitClient.cpp @@ -58,6 +58,7 @@ extern "C" CASE(STATUS_INDICATOR_FINISH); CASE(SEARCH_NOT_FOUND); CASE(SEARCH_RESULT_COUNT); + CASE(SEARCH_RESULT_SELECTION); CASE(DOCUMENT_SIZE_CHANGED); CASE(SET_PART); #undef CASE diff --git a/loolwsd/LOOLSession.cpp b/loolwsd/LOOLSession.cpp index ef1f1d8..d8b7dd0 100644 --- a/loolwsd/LOOLSession.cpp +++ b/loolwsd/LOOLSession.cpp @@ -826,6 +826,9 @@ extern "C" case LOK_CALLBACK_SEARCH_NOT_FOUND: srv->sendTextFrame("searchnotfound: " + std::string(pPayload)); break; + case LOK_CALLBACK_SEARCH_RESULT_SELECTION: + srv->sendTextFrame("searchresultselection: " + std::string(pPayload)); + break; case LOK_CALLBACK_DOCUMENT_SIZE_CHANGED: srv->getStatus("", 0); srv->getPartPageRectangles("", 0); commit 68398735302d6866461f52f948a09351d6a2b879 Author: Mihai Varga <mihai.va...@collabora.com> Date: Tue Oct 6 17:32:39 2015 +0300 loleaflet: twips rectangle to pixel bounds method diff --git a/loleaflet/src/layer/tile/GridLayer.js b/loleaflet/src/layer/tile/GridLayer.js index 9c89f7c..0e1fded 100644 --- a/loleaflet/src/layer/tile/GridLayer.js +++ b/loleaflet/src/layer/tile/GridLayer.js @@ -758,6 +758,21 @@ L.GridLayer = L.Layer.extend({ pixels.y * this._tileHeightTwips / this._tileSize); }, + _twipsRectangleToPixelBounds: function (strRectangle) { + // TODO use this more + // strRectangle = x, y, width, height + var strTwips = strRectangle.match(/\d+/g); + if (!strTwips) { + return null; + } + var topLeftTwips = new L.Point(parseInt(strTwips[0]), parseInt(strTwips[1])); + var offset = new L.Point(parseInt(strTwips[2]), parseInt(strTwips[3])); + var bottomRightTwips = topLeftTwips.add(offset); + return new L.Bounds( + this._twipsToPixels(topLeftTwips), + this._twipsToPixels(bottomRightTwips)); + }, + _noTilesToLoad: function () { for (var key in this._tiles) { if (!this._tiles[key].loaded) { return false; } commit be67ec80650293c40135e63eeaf518aacd5c7134 Author: Mihai Varga <mihai.va...@collabora.com> Date: Mon Oct 5 20:02:35 2015 +0300 loleaflet: some ctrl+key shortcuts #tdf94608 diff --git a/loleaflet/src/map/handler/Map.Keyboard.js b/loleaflet/src/map/handler/Map.Keyboard.js index 98c722d..93490e4 100644 --- a/loleaflet/src/map/handler/Map.Keyboard.js +++ b/loleaflet/src/map/handler/Map.Keyboard.js @@ -187,10 +187,7 @@ L.Map.Keyboard = L.Handler.extend({ var alt = e.originalEvent.altKey ? this.keyModifier.alt : 0; this.modifier = shift | ctrl | alt; if (e.originalEvent.ctrlKey) { - // we prepare for a copy event - docLayer._textArea.value = 'dummy text'; - docLayer._textArea.focus(); - docLayer._textArea.select(); + this._handleCtrlCommand(e); return; } @@ -244,6 +241,65 @@ L.Map.Keyboard = L.Handler.extend({ } } L.DomEvent.stopPropagation(e.originalEvent); + }, + + _handleCtrlCommand: function (e) { + if (e.type !== 'keydown') { + e.originalEvent.preventDefault(); + return; + }; + + switch (e.originalEvent.keyCode) { + case 13: // enter + L.Socket.sendMessage('uno .uno:InsertPagebreak'); + break; + case 37: // left arrow + L.Socket.sendMessage('uno .uno:GoToPrevWord'); + break; + case 39: // right arrow + L.Socket.sendMessage('uno .uno:GoToNextWord'); + break; + case 65: // a + L.Socket.sendMessage('uno .uno:Selectall'); + break; + case 66: // b + L.Socket.sendMessage('uno .uno:Bold'); + break; + case 67: // c + // we prepare for a copy event + this._map._docLayer._textArea.value = 'dummy text'; + this._map._docLayer._textArea.focus(); + this._map._docLayer._textArea.select(); + break; + case 69: // e + L.Socket.sendMessage('uno .uno:CenterPara'); + break; + case 73: // i + L.Socket.sendMessage('uno .uno:Italic'); + break; + case 74: // j + L.Socket.sendMessage('uno .uno:JustifyPara'); + break; + case 76: // l + L.Socket.sendMessage('uno .uno:LeftPara'); + break; + case 82: // r + L.Socket.sendMessage('uno .uno:RightPara'); + break; + case 85: // u + L.Socket.sendMessage('uno .uno:Underline'); + break; + case 90: // z + L.Socket.sendMessage('uno .uno:Undo'); + break; + case 189: // - + L.Socket.sendMessage('uno .uno:InsertSoftHyphen'); + break; + } + if (e.originalEvent.keyCode !== 67 && e.originalEvent.keyCode !== 86) { + // not copy or paste + e.originalEvent.preventDefault(); + } } }); commit f68c3907477ffd4829b0216f75db72d872fae60d Author: Mihai Varga <mihai.va...@collabora.com> Date: Mon Oct 5 16:44:40 2015 +0300 search result count callback handler diff --git a/loleaflet/src/layer/tile/TileLayer.js b/loleaflet/src/layer/tile/TileLayer.js index cfe686a..5eaab4d 100644 --- a/loleaflet/src/layer/tile/TileLayer.js +++ b/loleaflet/src/layer/tile/TileLayer.js @@ -214,6 +214,9 @@ L.TileLayer = L.GridLayer.extend({ else if (textMsg.startsWith('searchnotfound:')) { this._onSearchNotFoundMsg(textMsg); } + else if (textMsg.startsWith('searchresultcount:')) { + this._onSearchResultCount(textMsg); + } else if (textMsg.startsWith('setpart:')) { this._onSetPartMsg(textMsg); } @@ -333,6 +336,13 @@ L.TileLayer = L.GridLayer.extend({ this._map.fire('search', {originalPhrase: originalPhrase, count: 0}); }, + _onSearchResultCount: function (textMsg) { + textMsg = textMsg.substring(19); + var count = parseInt(textMsg.substring(0, textMsg.indexOf(';'))); + var originalPhrase = textMsg.substring(textMsg.indexOf(';') + 1); + this._map.fire('search', {originalPhrase: originalPhrase, count: count}); + }, + _onStateChangedMsg: function (textMsg) { var unoMsg = textMsg.substr(14).split('='); var commandName = '', diff --git a/loolwsd/LOKitClient.cpp b/loolwsd/LOKitClient.cpp index 97d42da..57f0e03 100644 --- a/loolwsd/LOKitClient.cpp +++ b/loolwsd/LOKitClient.cpp @@ -57,6 +57,7 @@ extern "C" CASE(STATUS_INDICATOR_SET_VALUE); CASE(STATUS_INDICATOR_FINISH); CASE(SEARCH_NOT_FOUND); + CASE(SEARCH_RESULT_COUNT); CASE(DOCUMENT_SIZE_CHANGED); CASE(SET_PART); #undef CASE @@ -117,7 +118,7 @@ protected: if (tokens[0] == "?" || tokens[0] == "help") { - std::cout << + std::cout << "Commands mimic LOOL protocol but we talk directly to LOKit:" << std::endl << " status" << std::endl << " calls LibreOfficeKitDocument::getDocumentType, getParts, getPartName, getDocumentSize" << std::endl << @@ -152,7 +153,7 @@ protected: int tilePosY(std::stoi(tokens[5])); int tileWidth(std::stoi(tokens[6])); int tileHeight(std::stoi(tokens[7])); - + std::vector<unsigned char> pixmap(canvasWidth*canvasHeight*4); loKitDocument->pClass->setPart(loKitDocument, partNumber); loKitDocument->pClass->paintTile(loKitDocument, pixmap.data(), canvasWidth, canvasHeight, tilePosX, tilePosY, tileWidth, tileHeight); diff --git a/loolwsd/LOOLSession.cpp b/loolwsd/LOOLSession.cpp index a293cde..ef1f1d8 100644 --- a/loolwsd/LOOLSession.cpp +++ b/loolwsd/LOOLSession.cpp @@ -808,6 +808,9 @@ extern "C" case LOK_CALLBACK_HYPERLINK_CLICKED: srv->sendTextFrame("hyperlinkclicked: " + std::string(pPayload)); break; + case LOK_CALLBACK_SEARCH_RESULT_COUNT: + srv->sendTextFrame("searchresultcount: " + std::string(pPayload)); + break; case LOK_CALLBACK_STATE_CHANGED: srv->sendTextFrame("statechanged: " + std::string(pPayload)); break; diff --git a/loolwsd/bundled/include/LibreOfficeKit/LibreOfficeKitEnums.h b/loolwsd/bundled/include/LibreOfficeKit/LibreOfficeKitEnums.h index 7038e5f..dc3e0f9 100644 --- a/loolwsd/bundled/include/LibreOfficeKit/LibreOfficeKitEnums.h +++ b/loolwsd/bundled/include/LibreOfficeKit/LibreOfficeKitEnums.h @@ -155,7 +155,9 @@ typedef enum * * Payload is a single 0-based integer. */ - LOK_CALLBACK_SET_PART + LOK_CALLBACK_SET_PART, + /// Number of search results, in case something is found. + LOK_CALLBACK_SEARCH_RESULT_COUNT } LibreOfficeKitCallbackType; commit f3af51450ac43c16594d04a9bbb49391a6a493b9 Author: Mihai Varga <mihai.va...@collabora.com> Date: Mon Oct 5 15:04:19 2015 +0300 We now send the mouse button that has been pressed and also they key modifiers for actions such as ctrl+click or shift+click diff --git a/loleaflet/src/layer/tile/TileLayer.js b/loleaflet/src/layer/tile/TileLayer.js index 86d7f2b..cfe686a 100644 --- a/loleaflet/src/layer/tile/TileLayer.js +++ b/loleaflet/src/layer/tile/TileLayer.js @@ -191,6 +191,9 @@ L.TileLayer = L.GridLayer.extend({ else if (textMsg.startsWith('graphicselection:')) { this._onGraphicSelectionMsg(textMsg); } + else if (textMsg.startsWith('hyperlinkclicked:')) { + this._onHyperlinkClickedMsg(textMsg); + } else if (textMsg.startsWith('invalidatecursor:')) { this._onInvalidateCursorMsg(textMsg); } @@ -280,6 +283,11 @@ L.TileLayer = L.GridLayer.extend({ this._onUpdateGraphicSelection(); }, + _onHyperlinkClickedMsg: function (textMsg) { + var link = textMsg.substring(18); + window.open(link, '_blank'); + }, + _onInvalidateCursorMsg: function (textMsg) { var strTwips = textMsg.match(/\d+/g); var topLeftTwips = new L.Point(parseInt(strTwips[0]), parseInt(strTwips[1])); @@ -503,9 +511,10 @@ L.TileLayer = L.GridLayer.extend({ this._onUpdateGraphicSelection(); }, - _postMouseEvent: function(type, x, y, count) { + _postMouseEvent: function(type, x, y, count, buttons, modifier) { L.Socket.sendMessage('mouse type=' + type + - ' x=' + x + ' y=' + y + ' count=' + count); + ' x=' + x + ' y=' + y + ' count=' + count + + ' buttons=' + buttons + ' modifier=' + modifier); }, _postKeyboardEvent: function(type, charcode, keycode) { diff --git a/loleaflet/src/map/handler/Map.Keyboard.js b/loleaflet/src/map/handler/Map.Keyboard.js index 987d2b4..98c722d 100644 --- a/loleaflet/src/map/handler/Map.Keyboard.js +++ b/loleaflet/src/map/handler/Map.Keyboard.js @@ -115,6 +115,7 @@ L.Map.Keyboard = L.Handler.extend({ this._map = map; this._setPanOffset(map.options.keyboardPanOffset); this._setZoomOffset(map.options.keyboardZoomOffset); + this.modifier = 0; }, addHooks: function () { @@ -180,6 +181,11 @@ L.Map.Keyboard = L.Handler.extend({ _onKeyDown: function (e) { var docLayer = this._map._docLayer; + this.modifier = 0; + var shift = e.originalEvent.shiftKey ? this.keyModifier.shift : 0; + var ctrl = e.originalEvent.ctrlKey ? this.keyModifier.ctrl : 0; + var alt = e.originalEvent.altKey ? this.keyModifier.alt : 0; + this.modifier = shift | ctrl | alt; if (e.originalEvent.ctrlKey) { // we prepare for a copy event docLayer._textArea.value = 'dummy text'; diff --git a/loleaflet/src/map/handler/Map.Mouse.js b/loleaflet/src/map/handler/Map.Mouse.js index ac731a8..9fd8ba8 100644 --- a/loleaflet/src/map/handler/Map.Mouse.js +++ b/loleaflet/src/map/handler/Map.Mouse.js @@ -23,6 +23,18 @@ L.Map.Mouse = L.Handler.extend({ this._onMouseEvent, this); }, + LOButtons: { + left: 1, + middle: 2, + right: 4 + }, + + JSButtons: { + left: 0, + middle: 1, + right: 2 + }, + _onMouseEvent: function (e) { var docLayer = this._map._docLayer; if (!docLayer) { @@ -39,6 +51,12 @@ L.Map.Mouse = L.Handler.extend({ } } + var modifier = this._map.keyboard.modifier; + var buttons = 0; + buttons |= e.originalEvent.button === this.JSButtons.left ? this.LOButtons.left : 0; + buttons |= e.originalEvent.button === this.JSButtons.middle ? this.LOButtons.middle : 0; + buttons |= e.originalEvent.button === this.JSButtons.right ? this.LOButtons.right : 0; + if (e.type === 'mousedown') { docLayer._resetPreFetching(); this._mouseDown = true; @@ -47,7 +65,8 @@ L.Map.Mouse = L.Handler.extend({ } var mousePos = docLayer._latLngToTwips(e.latlng); this._mouseEventsQueue.push(L.bind(function() { - this._postMouseEvent('buttondown', mousePos.x, mousePos.y, 1);}, docLayer)); + this._postMouseEvent('buttondown', mousePos.x, mousePos.y, 1, buttons, modifier); + }, docLayer)); this._holdMouseEvent = setTimeout(L.bind(this._executeMouseEvents, this), 500); } else if (e.type === 'mouseup') { @@ -82,7 +101,7 @@ L.Map.Mouse = L.Handler.extend({ } } this._mouseEventsQueue = []; - docLayer._postMouseEvent('buttonup', mousePos.x, mousePos.y, 1); + docLayer._postMouseEvent('buttonup', mousePos.x, mousePos.y, 1, buttons, modifier); docLayer._textArea.focus(); }, this)); this._holdMouseEvent = setTimeout(L.bind(this._executeMouseEvents, this), timeOut); @@ -113,7 +132,7 @@ L.Map.Mouse = L.Handler.extend({ } if (!this._map.dragging.enabled()) { mousePos = docLayer._latLngToTwips(e.latlng); - docLayer._postMouseEvent('move', mousePos.x, mousePos.y, 1); + docLayer._postMouseEvent('move', mousePos.x, mousePos.y, 1, buttons, modifier); for (key in docLayer._selectionHandles) { handle = docLayer._selectionHandles[key]; if (handle._icon) { @@ -124,10 +143,10 @@ L.Map.Mouse = L.Handler.extend({ } else if (e.type === 'dblclick') { mousePos = docLayer._latLngToTwips(e.latlng); - docLayer._postMouseEvent('buttondown', mousePos.x, mousePos.y, 1); - docLayer._postMouseEvent('buttondown', mousePos.x, mousePos.y, 2); - docLayer._postMouseEvent('buttonup', mousePos.x, mousePos.y, 2); - docLayer._postMouseEvent('buttonup', mousePos.x, mousePos.y, 1); + docLayer._postMouseEvent('buttondown', mousePos.x, mousePos.y, 1, buttons, modifier); + docLayer._postMouseEvent('buttondown', mousePos.x, mousePos.y, 2, buttons, modifier); + docLayer._postMouseEvent('buttonup', mousePos.x, mousePos.y, 2, 1, buttons, modifier); + docLayer._postMouseEvent('buttonup', mousePos.x, mousePos.y, 1, 1, buttons, modifier); } }, diff --git a/loolwsd/LOOLSession.cpp b/loolwsd/LOOLSession.cpp index 5f5d12e..a293cde 100644 --- a/loolwsd/LOOLSession.cpp +++ b/loolwsd/LOOLSession.cpp @@ -1025,9 +1025,9 @@ bool ChildProcessSession::keyEvent(const char *buffer, int length, StringTokeniz bool ChildProcessSession::mouseEvent(const char *buffer, int length, StringTokenizer& tokens) { - int type, x, y, count; + int type, x, y, count, buttons, modifier; - if (tokens.count() != 5 || + if (tokens.count() != 7 || !getTokenKeyword(tokens[1], "type", {{"buttondown", LOK_MOUSEEVENT_MOUSEBUTTONDOWN}, {"buttonup", LOK_MOUSEEVENT_MOUSEBUTTONUP}, @@ -1035,13 +1035,15 @@ bool ChildProcessSession::mouseEvent(const char *buffer, int length, StringToken type) || !getTokenInteger(tokens[2], "x", x) || !getTokenInteger(tokens[3], "y", y) || - !getTokenInteger(tokens[4], "count", count)) + !getTokenInteger(tokens[4], "count", count), + !getTokenInteger(tokens[5], "buttons", buttons), + !getTokenInteger(tokens[6], "modifier", modifier)) { sendTextFrame("error: cmd=mouse kind=syntax"); return false; } - _loKitDocument->pClass->postMouseEvent(_loKitDocument, type, x, y, count); + _loKitDocument->pClass->postMouseEvent(_loKitDocument, type, x, y, count, buttons, modifier); return true; } diff --git a/loolwsd/bundled/include/LibreOfficeKit/LibreOfficeKit.h b/loolwsd/bundled/include/LibreOfficeKit/LibreOfficeKit.h index d83dd49..83dcc98 100644 --- a/loolwsd/bundled/include/LibreOfficeKit/LibreOfficeKit.h +++ b/loolwsd/bundled/include/LibreOfficeKit/LibreOfficeKit.h @@ -137,7 +137,9 @@ struct _LibreOfficeKitDocumentClass int nType, int nX, int nY, - int nCount); + int nCount, + int nButtons, + int nModifier); /// @see lok::Document::postUnoCommand void (*postUnoCommand) (LibreOfficeKitDocument* pThis, commit d92c8903adb565d8ac4040cdacac4ad7b94d5099 Author: Mihai Varga <mihai.va...@collabora.com> Date: Wed Sep 30 17:22:00 2015 +0300 loolwsd: update page sizes when the doc size changes diff --git a/loolwsd/LOOLSession.cpp b/loolwsd/LOOLSession.cpp index 313e76f..5f5d12e 100644 --- a/loolwsd/LOOLSession.cpp +++ b/loolwsd/LOOLSession.cpp @@ -825,6 +825,7 @@ extern "C" break; case LOK_CALLBACK_DOCUMENT_SIZE_CHANGED: srv->getStatus("", 0); + srv->getPartPageRectangles("", 0); break; case LOK_CALLBACK_SET_PART: srv->sendTextFrame("setpart: " + std::string(pPayload)); commit 0557bc170a179393a6e237d0a596f8fdb98eafd2 Author: Mihai Varga <mihai.va...@collabora.com> Date: Wed Sep 30 17:17:03 2015 +0300 loolwsd: switch to editing dir when invalidating the cursor diff --git a/loolwsd/LOOLSession.cpp b/loolwsd/LOOLSession.cpp index 4b00dea..313e76f 100644 --- a/loolwsd/LOOLSession.cpp +++ b/loolwsd/LOOLSession.cpp @@ -218,6 +218,9 @@ bool MasterProcessSession::handleInput(const char *buffer, int length) { peer->_tileCache->saveTextFile(std::string(buffer, length), "partpagerectangles.txt"); } + else if (tokens[0] == "invalidatecursor:") { + peer->_tileCache->setEditing(true); + } else if (tokens[0] == "invalidatetiles:") { // FIXME temporarily, set the editing on the 1st invalidate, TODO extend diff --git a/loolwsd/TileCache.cpp b/loolwsd/TileCache.cpp index 76ca730..cbd0278 100644 --- a/loolwsd/TileCache.cpp +++ b/loolwsd/TileCache.cpp @@ -172,7 +172,7 @@ void TileCache::setEditing(bool editing) void TileCache::saveTextFile(const std::string& text, std::string fileName) { - std::string dirName = cacheDirName(_hasUnsavedChanges); + std::string dirName = cacheDirName(_isEditing); File(dirName).createDirectories(); commit 0219c1877a8f6c6276ee8808f7e90264e4f7ec15 Author: Mihai Varga <mihai.va...@collabora.com> Date: Wed Sep 30 13:43:12 2015 +0300 loleaflet: goToPage without having a LOK instance Knowing the page dimension, we can scroll to the desired page without requesting sending the 'setpage' command to the server diff --git a/loleaflet/src/control/Parts.js b/loleaflet/src/control/Parts.js index 1ae0825..d710d47 100644 --- a/loleaflet/src/control/Parts.js +++ b/loleaflet/src/control/Parts.js @@ -122,7 +122,19 @@ L.Map.include({ else if (typeof (page) === 'number' && page >= 0 && page < docLayer._pages) { docLayer._currentPage = page; } - L.Socket.sendMessage('setpage page=' + docLayer._currentPage); + if (docLayer._permission !== 'edit' && docLayer._partPageRectanglesPixels.length > docLayer._currentPage) { + // we can scroll to the desired page without having a LOK instance + var pageBounds = docLayer._partPageRectanglesPixels[docLayer._currentPage]; + var pos = new L.Point( + pageBounds.min.x + (pageBounds.max.x - pageBounds.min.x) / 2, + pageBounds.min.y); + pos.y -= this.getSize().y / 4; // offset by a quater of the viewing area so that the previous page is visible + this.scrollTop(pos.y, {update: true}); + this.scrollLeft(pos.x, {update: true}); + } + else { + L.Socket.sendMessage('setpage page=' + docLayer._currentPage); + } this.fire('pagenumberchanged', { currentPage: docLayer._currentPage, pages: docLayer._pages, commit 771ae08cb682aa163b770ad736ad21d696bee259 Author: Mihai Varga <mihai.va...@collabora.com> Date: Wed Sep 30 13:17:43 2015 +0300 loleaflet: partpagerectangles command integration An event is fired with the page dimensions. Also the current page number is updated based on which page contains the current view's center diff --git a/loleaflet/README b/loleaflet/README index 4a32d13..8cc2739 100644 --- a/loleaflet/README +++ b/loleaflet/README @@ -193,6 +193,9 @@ Writer pages: + e.docType = document type, should be 'text' map.on('invalidatepreview', function (e) {}) + e.id = the preview's id + map.on('partpagerectangles', function (e) {}) where: + + e.pixelRectangles = An array of bounds representing each page's dimension in pixels on the current zoom level + + e.twipsRectangles = An array of bounds representing each page's dimension in twips. Error: - events diff --git a/loleaflet/reference.html b/loleaflet/reference.html index 595dd62..d45f019 100644 --- a/loleaflet/reference.html +++ b/loleaflet/reference.html @@ -6825,6 +6825,26 @@ map.addControl(new MyControl()); </tr> </table> +<h3 id="partpagerectangles-event">PartPageRectangles</h3> + +<table data-id='events'> + <tr> + <th class="width100">property</th> + <th>type</th> + <th>description</th> + </tr> + <tr> + <td><code><b>pixelRectangles</b></code></td> + <td><code><a href="#bounds">Bounds[]</a></code></td> + <td>An array of bounds representing each page's dimension in pixels on the current zoom level.</td> + </tr> + <tr> + <td><code><b>twipsRectangles</b></code></td> + <td><code><a href="#bounds">Bounds[]</a></code></td> + <td>An array of bounds representing each page's dimension in twips.</td> + </tr> +</table> + <h3 id="permission-event">PermissionEvent</h3> <table data-id='events'> diff --git a/loleaflet/src/control/Parts.js b/loleaflet/src/control/Parts.js index 55d4c9b..1ae0825 100644 --- a/loleaflet/src/control/Parts.js +++ b/loleaflet/src/control/Parts.js @@ -123,6 +123,11 @@ L.Map.include({ docLayer._currentPage = page; } L.Socket.sendMessage('setpage page=' + docLayer._currentPage); + this.fire('pagenumberchanged', { + currentPage: docLayer._currentPage, + pages: docLayer._pages, + docType: docLayer._docType + }); }, getNumberOfPages: function () { diff --git a/loleaflet/src/core/Socket.js b/loleaflet/src/core/Socket.js index ba93c2b..99a8c19 100644 --- a/loleaflet/src/core/Socket.js +++ b/loleaflet/src/core/Socket.js @@ -52,6 +52,7 @@ L.Socket = { } this.socket.send(msg); this.socket.send('status'); + this.socket.send('partpagerectangles'); for (var i = 0; i < this._msgQueue.length; i++) { this.socket.send(this._msgQueue[i].msg); L.Log.log(this._msgQueue[i].msg, this._msgQueue[i].coords); diff --git a/loleaflet/src/layer/tile/GridLayer.js b/loleaflet/src/layer/tile/GridLayer.js index 2922d7e..9c89f7c 100644 --- a/loleaflet/src/layer/tile/GridLayer.js +++ b/loleaflet/src/layer/tile/GridLayer.js @@ -444,6 +444,7 @@ L.GridLayer = L.Layer.extend({ _move: function () { this._update(); this._resetPreFetching(true); + this._onCurrentPageUpdate(); }, _update: function (center, zoom) { diff --git a/loleaflet/src/layer/tile/TileLayer.js b/loleaflet/src/layer/tile/TileLayer.js index 0bf5474..86d7f2b 100644 --- a/loleaflet/src/layer/tile/TileLayer.js +++ b/loleaflet/src/layer/tile/TileLayer.js @@ -102,6 +102,7 @@ L.TileLayer = L.GridLayer.extend({ map.on('drag resize zoomend', this._updateScrollOffset, this); map.on('copy', this._onCopy, this); map.on('zoomend', this._onUpdateCursor, this); + map.on('zoomend', this._onUpdatePartPageRectangles, this); map.on('dragstart', this._onDragStart, this); map.on('requestloksession', this._onRequestLOKSession, this); map.on('error', this._mapOnError, this); @@ -204,6 +205,9 @@ L.TileLayer = L.GridLayer.extend({ msg += 'height=' + this._docHeightTwips; this._onInvalidateTilesMsg(msg); } + else if (textMsg.startsWith('partpagerectangles:')) { + this._onPartPageRectanglesMsg(textMsg); + } else if (textMsg.startsWith('searchnotfound:')) { this._onSearchNotFoundMsg(textMsg); } @@ -288,6 +292,34 @@ L.TileLayer = L.GridLayer.extend({ this._onUpdateCursor(); }, + _onPartPageRectanglesMsg: function (textMsg) { + textMsg = textMsg.substring(19); + var pages = textMsg.split(';'); + this._partPageRectanglesTwips = []; + this._partPageRectanglesPixels = []; + for (var i = 0; i < pages.length; i++) { + var strTwips = pages[i].match(/\d+/g); + if (!strTwips) { + // probably not a text file + return; + } + var topLeftTwips = new L.Point(parseInt(strTwips[0]), parseInt(strTwips[1])); + var offset = new L.Point(parseInt(strTwips[2]), parseInt(strTwips[3])); + var bottomRightTwips = topLeftTwips.add(offset); + var pageBoundsTwips = new L.Bounds(topLeftTwips, bottomRightTwips); + this._partPageRectanglesTwips.push(pageBoundsTwips); + var pageBoundsPixels = new L.Bounds( + this._twipsToPixels(topLeftTwips), + this._twipsToPixels(bottomRightTwips)); + this._partPageRectanglesPixels.push(pageBoundsPixels); + } + this._map.fire('partpagerectangles', { + pixelRectangles: this._partPageRectanglesPixels, + twipsRectangles: this._partPageRectanglesTwips + }); + this._onCurrentPageUpdate(); + }, + _onSearchNotFoundMsg: function (textMsg) { var originalPhrase = textMsg.substring(16); this._map.fire('search', {originalPhrase: originalPhrase, count: 0}); @@ -689,6 +721,42 @@ L.TileLayer = L.GridLayer.extend({ this._map.setZoom(Math.min(10, this._map.getZoom() + zoomDelta), {animate: false}); } } + }, + + _onCurrentPageUpdate: function () { + var mapCenter = this._map.project(this._map.getCenter()); + if (!this._partPageRectanglesPixels || !(this._currentPage >= 0) || + this._partPageRectanglesPixels[this._currentPage].contains(mapCenter)) { + // page number has not changed + return; + } + for (var i = 0; i < this._partPageRectanglesPixels.length; i++) { + if (this._partPageRectanglesPixels[i].contains(mapCenter)) { + this._currentPage = i; + this._map.fire('pagenumberchanged', { + currentPage: this._currentPage, + pages: this._pages, + docType: this._docType + }); + return; + } + } + }, + + _onUpdatePartPageRectangles: function () { + if (this._partPageRectanglesPixels.length > 0) { + this._partPageRectanglesPixels = []; + for (var i = 0; i < this._partPageRectanglesTwips.length; i++) { + var pageBounds = new L.Bounds( + this._twipsToPixels(this._partPageRectanglesTwips[i].min), + this._twipsToPixels(this._partPageRectanglesTwips[i].max)); + this._partPageRectanglesPixels.push(pageBounds); + } + this._map.fire('partpagerectangles', { + pixelRectangles: this._partPageRectanglesPixels, + twipsRectangles: this._partPageRectanglesTwips + }); + } } }); commit 32e89553b8a4a281d721e3a6b1fe7eb3300567ef Author: Mihai Varga <mihai.va...@collabora.com> Date: Wed Sep 30 13:10:48 2015 +0300 loleaflet: twipsToPixels and back methods diff --git a/loleaflet/src/layer/tile/GridLayer.js b/loleaflet/src/layer/tile/GridLayer.js index e010aa3..2922d7e 100644 --- a/loleaflet/src/layer/tile/GridLayer.js +++ b/loleaflet/src/layer/tile/GridLayer.js @@ -745,6 +745,18 @@ L.GridLayer = L.Layer.extend({ Math.round(pixels.y / this._tileSize * this._tileHeightTwips)); }, + _twipsToPixels: function (twips) { + return new L.Point( + twips.x / this._tileWidthTwips * this._tileSize, + twips.y / this._tileHeightTwips * this._tileSize); + }, + + _pixelsToTwips: function (pixels) { + return new L.Point( + pixels.x * this._tileWidthTwips / this._tileSize, + pixels.y * this._tileHeightTwips / this._tileSize); + }, + _noTilesToLoad: function () { for (var key in this._tiles) { if (!this._tiles[key].loaded) { return false; } commit afe2a71692bf4cfaf9f3c3e1c17b9e5b9cb0a979 Author: Miklos Vajna <vmik...@collabora.co.uk> Date: Tue Sep 29 12:55:21 2015 +0200 loolwsd: document partpagerectangles command on both directions diff --git a/loolwsd/protocol.txt b/loolwsd/protocol.txt index 369bb69..88cc062 100644 --- a/loolwsd/protocol.txt +++ b/loolwsd/protocol.txt @@ -75,6 +75,9 @@ uno <command> <command> is a line of text. +partpagerectangles + + Invokes lok::Document::getPartPageRectangles(). server -> client ================ @@ -117,6 +120,10 @@ status: type=<typeName> parts=<numberOfParts> current=<currentPartNumber> width= styles: {"styleFamily": ["styles in family"], etc. } +partpagerectangles: <payload> + + Payload format is the same as LOK_CALLBACK_TEXT_SELECTION. + textselectioncontent: <content> Current selection's content commit c543d3d740be636caee43de1e72ba248e5503fce Author: Miklos Vajna <vmik...@collabora.co.uk> Date: Tue Sep 29 12:27:45 2015 +0200 loolwsd: parse the partpagerectangles command and cache the values diff --git a/loolwsd/LOOLSession.cpp b/loolwsd/LOOLSession.cpp index 233e999..4b00dea 100644 --- a/loolwsd/LOOLSession.cpp +++ b/loolwsd/LOOLSession.cpp @@ -214,6 +214,10 @@ bool MasterProcessSession::handleInput(const char *buffer, int length) std::string commandName = object->get("commandName").toString(); peer->_tileCache->saveTextFile(std::string(buffer, length), "cmdValues" + commandName + ".txt"); } + else if (tokens[0] == "partpagerectangles:") + { + peer->_tileCache->saveTextFile(std::string(buffer, length), "partpagerectangles.txt"); + } else if (tokens[0] == "invalidatetiles:") { // FIXME temporarily, set the editing on the 1st invalidate, TODO extend @@ -283,6 +287,7 @@ bool MasterProcessSession::handleInput(const char *buffer, int length) } else if (tokens[0] != "canceltiles" && tokens[0] != "commandvalues" && + tokens[0] != "partpagerectangles" && tokens[0] != "gettextselection" && tokens[0] != "invalidatetiles" && tokens[0] != "key" && @@ -315,6 +320,10 @@ bool MasterProcessSession::handleInput(const char *buffer, int length) { return getCommandValues(buffer, length, tokens); } + else if (tokens[0] == "partpagerectangles") + { + return getPartPageRectangles(buffer, length); + } else if (tokens[0] == "invalidatetiles") { return invalidateTiles(buffer, length, tokens); @@ -454,6 +463,21 @@ bool MasterProcessSession::getCommandValues(const char *buffer, int length, Stri return true; } +bool MasterProcessSession::getPartPageRectangles(const char *buffer, int length) +{ + std::string partPageRectangles = _tileCache->getTextFile("partpagerectangles.txt"); + if (partPageRectangles.size() > 0) + { + sendTextFrame(partPageRectangles); + return true; + } + + if (_peer.expired()) + dispatchChild(); + forwardToPeer(buffer, length); + return true; +} + void MasterProcessSession::sendTile(const char *buffer, int length, StringTokenizer& tokens) { int part, width, height, tilePosX, tilePosY, tileWidth, tileHeight; @@ -633,6 +657,10 @@ bool ChildProcessSession::handleInput(const char *buffer, int length) { return getCommandValues(buffer, length, tokens); } + if (tokens[0] == "partpagerectangles") + { + return getPartPageRectangles(buffer, length); + } if (tokens[0] == "load") { if (_docURL != "") @@ -895,6 +923,12 @@ bool ChildProcessSession::getCommandValues(const char *buffer, int length, Strin return true; } +bool ChildProcessSession::getPartPageRectangles(const char* /*buffer*/, int /*length*/) +{ + sendTextFrame("partpagerectangles: " + std::string(_loKitDocument->pClass->getPartPageRectangles(_loKitDocument))); + return true; +} + void ChildProcessSession::sendTile(const char *buffer, int length, StringTokenizer& tokens) { int part, width, height, tilePosX, tilePosY, tileWidth, tileHeight; diff --git a/loolwsd/LOOLSession.hpp b/loolwsd/LOOLSession.hpp index 247012c..13970c6 100644 --- a/loolwsd/LOOLSession.hpp +++ b/loolwsd/LOOLSession.hpp @@ -47,6 +47,8 @@ public: virtual bool getCommandValues(const char *buffer, int length, Poco::StringTokenizer& tokens) = 0; + virtual bool getPartPageRectangles(const char *buffer, int length) = 0; + virtual bool handleInput(const char *buffer, int length) = 0; protected: @@ -113,6 +115,8 @@ public: virtual bool getCommandValues(const char *buffer, int length, Poco::StringTokenizer& tokens); + virtual bool getPartPageRectangles(const char *buffer, int length) override; + protected: bool invalidateTiles(const char *buffer, int length, Poco::StringTokenizer& tokens); @@ -161,6 +165,8 @@ public: virtual bool getCommandValues(const char *buffer, int length, Poco::StringTokenizer& tokens); + virtual bool getPartPageRectangles(const char *buffer, int length) override; + LibreOfficeKitDocument *_loKitDocument; std::string _docType; commit d8a4499567712ae5dd9cda99e18ff5124404e05f Author: Miklos Vajna <vmik...@collabora.co.uk> Date: Tue Sep 29 12:27:27 2015 +0200 loolwsd: update bundled LOK headers diff --git a/loolwsd/bundled/include/LibreOfficeKit/LibreOfficeKit.h b/loolwsd/bundled/include/LibreOfficeKit/LibreOfficeKit.h index 8060f0e..d83dd49 100644 --- a/loolwsd/bundled/include/LibreOfficeKit/LibreOfficeKit.h +++ b/loolwsd/bundled/include/LibreOfficeKit/LibreOfficeKit.h @@ -54,6 +54,9 @@ struct _LibreOfficeKitClass void (*registerCallback) (LibreOfficeKit* pThis, LibreOfficeKitCallback pCallback, void* pData); + + /// @see lok::Office::getFilterTypes(). + char* (*getFilterTypes) (LibreOfficeKit* pThis); #endif }; @@ -82,6 +85,9 @@ struct _LibreOfficeKitDocumentClass /// @see lok::Document::getParts(). int (*getParts) (LibreOfficeKitDocument* pThis); + /// @see lok::Document::getPartPageRectangles(). + char* (*getPartPageRectangles) (LibreOfficeKitDocument* pThis); + /// @see lok::Document::getPart(). int (*getPart) (LibreOfficeKitDocument* pThis); @@ -93,10 +99,7 @@ struct _LibreOfficeKitDocumentClass char* (*getPartName) (LibreOfficeKitDocument* pThis, int nPart); - /** Sets mode of the current part. - * - * @param nMode - element from the LibreOfficeKitPartMode enum. - */ + /// @see lok::Document::setPartMode(). void (*setPartMode) (LibreOfficeKitDocument* pThis, int nMode); @@ -118,6 +121,7 @@ struct _LibreOfficeKitDocumentClass /// @see lok::Document::initializeForRendering(). void (*initializeForRendering) (LibreOfficeKitDocument* pThis); + /// @see lok::Document::registerCallback(). void (*registerCallback) (LibreOfficeKitDocument* pThis, LibreOfficeKitCallback pCallback, void* pData); @@ -160,8 +164,19 @@ struct _LibreOfficeKitDocumentClass /// @see lok::Document::resetSelection void (*resetSelection) (LibreOfficeKitDocument* pThis); - /// @see lok::Document:getStyles + /// @see lok::Document::getCommandValues(). char* (*getCommandValues) (LibreOfficeKitDocument* pThis, const char* pCommand); + + /// @see lok::Document::createView(). + int (*createView) (LibreOfficeKitDocument* pThis); + /// @see lok::Document::destroyView(). + void (*destroyView) (LibreOfficeKitDocument* pThis, int nId); + /// @see lok::Document::setView(). + void (*setView) (LibreOfficeKitDocument* pThis, int nId); + /// @see lok::Document::getView(). + int (*getView) (LibreOfficeKitDocument* pThis); + /// @see lok::Document::getViews(). + int (*getViews) (LibreOfficeKitDocument* pThis); #endif // LOK_USE_UNSTABLE_API }; commit fdc739d85732ccec3b176c8cd279517b15dffb5b Author: Miklos Vajna <vmik...@collabora.co.uk> Date: Tue Sep 29 11:15:02 2015 +0200 loolwsd: implement a 'make tags' diff --git a/loolwsd/Makefile.am b/loolwsd/Makefile.am index 07b68ca..9e1f143 100644 --- a/loolwsd/Makefile.am +++ b/loolwsd/Makefile.am @@ -34,3 +34,7 @@ all-local: loolwsd sudo chown root loolwsd && sudo chmod u+s loolwsd; \ fi; \ fi + +tags: + ctags --c++-kinds=+p --fields=+iaS --extra=+q -R --totals=yes \ + --exclude=jails * _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits