bundled/include/LibreOfficeKit/LibreOfficeKit.h | 3 bundled/include/LibreOfficeKit/LibreOfficeKit.hxx | 8 ++ bundled/include/LibreOfficeKit/LibreOfficeKitEnums.h | 2 kit/ChildSession.cpp | 35 ++++++++++ kit/ChildSession.hpp | 1 loleaflet/css/partsPreviewControl.css | 6 + loleaflet/src/control/Control.PartsPreview.js | 61 +++++++++++++++++++ wsd/ClientSession.cpp | 18 +++++ wsd/protocol.txt | 4 + 9 files changed, 136 insertions(+), 2 deletions(-)
New commits: commit 021d67f1430ff2a554b65c65d7aee752fed0b77f Author: Ashod Nakashian <ashod.nakash...@collabora.co.uk> AuthorDate: Mon Sep 17 07:17:31 2018 -0400 Commit: Ashod Nakashian <ashnak...@gmail.com> CommitDate: Mon Apr 15 04:24:45 2019 +0200 wsd: leaflet: support reordering of slides via drag-and-drop Change-Id: I1b471ba07dd0a1016a0759de729171ae968262cb Reviewed-on: https://gerrit.libreoffice.org/69635 Reviewed-by: Ashod Nakashian <ashnak...@gmail.com> Tested-by: Ashod Nakashian <ashnak...@gmail.com> diff --git a/bundled/include/LibreOfficeKit/LibreOfficeKit.h b/bundled/include/LibreOfficeKit/LibreOfficeKit.h index 763e5311e..510cafcdb 100644 --- a/bundled/include/LibreOfficeKit/LibreOfficeKit.h +++ b/bundled/include/LibreOfficeKit/LibreOfficeKit.h @@ -375,6 +375,9 @@ struct _LibreOfficeKitDocumentClass /// @see lok::Document::selectPart(). void (*selectPart) (LibreOfficeKitDocument* pThis, int nPart, int nSelect); + /// @see lok::Document::moveSelectedParts(). + void (*moveSelectedParts) (LibreOfficeKitDocument* pThis, int nPosition, bool bDuplicate); + #endif // defined LOK_USE_UNSTABLE_API || defined LIBO_INTERNAL_ONLY }; diff --git a/bundled/include/LibreOfficeKit/LibreOfficeKit.hxx b/bundled/include/LibreOfficeKit/LibreOfficeKit.hxx index 36052cd64..4f9ef60d0 100644 --- a/bundled/include/LibreOfficeKit/LibreOfficeKit.hxx +++ b/bundled/include/LibreOfficeKit/LibreOfficeKit.hxx @@ -656,6 +656,14 @@ public: mpDoc->pClass->selectPart(mpDoc, nPart, nSelect); } + /// Moves the selected pages/slides to a new position. + /// nPosition is the new position where the selection + /// should go. bDuplicate when true will copy instead of move. + void moveSelectedParts(int nPosition, bool bDuplicate) + { + mpDoc->pClass->moveSelectedParts(mpDoc, nPosition, bDuplicate); + } + #endif // defined LOK_USE_UNSTABLE_API || defined LIBO_INTERNAL_ONLY }; diff --git a/bundled/include/LibreOfficeKit/LibreOfficeKitEnums.h b/bundled/include/LibreOfficeKit/LibreOfficeKitEnums.h index 26fb2ab74..aae23e319 100644 --- a/bundled/include/LibreOfficeKit/LibreOfficeKitEnums.h +++ b/bundled/include/LibreOfficeKit/LibreOfficeKitEnums.h @@ -563,7 +563,7 @@ typedef enum * "type" tells the type of the window the action is associated with * - "dialog" - window is a dialog * - "child" - window is a floating window (combo boxes, etc.) - * - "panel" - window is a docked panel (i.e. in the sidebar) + * - "deck" - window is a docked/floating deck (i.e. the sidebar) * * "action" can take following values: * - "created" - window is created in the backend, client can render it now diff --git a/kit/ChildSession.cpp b/kit/ChildSession.cpp index ddf7dee8a..ea39697bb 100644 --- a/kit/ChildSession.cpp +++ b/kit/ChildSession.cpp @@ -227,6 +227,10 @@ bool ChildSession::_handleInput(const char *buffer, int length) { return selectClientPart(buffer, length, tokens); } + else if (tokens[0] == "moveselectedclientparts") + { + return moveSelectedClientParts(buffer, length, tokens); + } else if (tokens[0] == "setpage") { return setPage(buffer, length, tokens); @@ -1852,6 +1856,37 @@ bool ChildSession::selectClientPart(const char* /*buffer*/, int /*length*/, cons return true; } +bool ChildSession::moveSelectedClientParts(const char* /*buffer*/, int /*length*/, const std::vector<std::string>& tokens) +{ + int nPosition; + if (tokens.size() < 2 || + !getTokenInteger(tokens[1], "position", nPosition)) + { + sendTextFrame("error: cmd=moveselectedclientparts kind=invalid"); + return false; + } + + std::unique_lock<std::mutex> lock(_docManager.getDocumentMutex()); + + getLOKitDocument()->setView(_viewId); + + if (getLOKitDocument()->getDocumentType() != LOK_DOCTYPE_TEXT) + { + getLOKitDocument()->moveSelectedParts(nPosition, false); // Move, don't duplicate. + + // Get the status to recreate the previews and correctly order parts. + const std::string status = LOKitHelper::documentStatus(getLOKitDocument()->get()); + if (!status.empty()) + return sendTextFrame("statusupdate: " + status); + } + else + { + LOG_WRN("ChildSession::moveSelectedClientParts[" << getName() << "]: error moving parts on text documents."); + } + + return true; // Non-fatal to fail. +} + bool ChildSession::setPage(const char* /*buffer*/, int /*length*/, const std::vector<std::string>& tokens) { int page; diff --git a/kit/ChildSession.hpp b/kit/ChildSession.hpp index d37ab14a5..2cddff005 100644 --- a/kit/ChildSession.hpp +++ b/kit/ChildSession.hpp @@ -264,6 +264,7 @@ private: bool saveAs(const char* buffer, int length, const std::vector<std::string>& tokens); bool setClientPart(const char* buffer, int length, const std::vector<std::string>& tokens); bool selectClientPart(const char* buffer, int length, const std::vector<std::string>& tokens); + bool moveSelectedClientParts(const char* buffer, int length, const std::vector<std::string>& tokens); bool setPage(const char* buffer, int length, const std::vector<std::string>& tokens); bool sendWindowCommand(const char* buffer, int length, const std::vector<std::string>& tokens); bool signDocumentContent(const char* buffer, int length, const std::vector<std::string>& tokens); diff --git a/loleaflet/css/partsPreviewControl.css b/loleaflet/css/partsPreviewControl.css index 438b137d3..66e47c9bb 100644 --- a/loleaflet/css/partsPreviewControl.css +++ b/loleaflet/css/partsPreviewControl.css @@ -20,7 +20,7 @@ .preview-img { /* In draw docs, the width of previews are small, but we want a min of 180px to align it with document's left edge */ - min-width: 180px; + min-width: 180px; vertical-align: middle; max-width: 184px; cursor: pointer; @@ -30,3 +30,7 @@ .preview-img-selected { border-color: #000000; } + +.preview-img-dropsite { + border-bottom: 2px solid red; +} diff --git a/loleaflet/src/control/Control.PartsPreview.js b/loleaflet/src/control/Control.PartsPreview.js index dc978f39f..78834a6d8 100644 --- a/loleaflet/src/control/Control.PartsPreview.js +++ b/loleaflet/src/control/Control.PartsPreview.js @@ -105,6 +105,7 @@ L.Control.PartsPreview = L.Control.extend({ _createPreview: function (i, hashCode, bottomBound) { var frame = L.DomUtil.create('div', 'preview-frame', this._scrollContainer); + this._addDnDHandlers(frame); L.DomUtil.create('span', 'preview-helper', frame); var imgClassName = 'preview-img'; @@ -259,6 +260,7 @@ L.Control.PartsPreview = L.Control.extend({ for (it = 0; it < parts; it++) { if (this._previewTiles[it].hash !== e.partNames[it]) { this._previewTiles[it].hash = e.partNames[it]; + this._map.getPreview(it, it, 180, 180, {autoUpdate: this.options.autoUpdate}); } } } @@ -326,7 +328,66 @@ L.Control.PartsPreview = L.Control.extend({ } } } + }, + + _addDnDHandlers: function (elem) { + if (elem) { + elem.setAttribute('draggable', true); + elem.addEventListener('dragstart', this._handleDragStart, false); + elem.addEventListener('dragenter', this._handleDragEnter, false) + elem.addEventListener('dragover', this._handleDragOver, false); + elem.addEventListener('dragleave', this._handleDragLeave, false); + elem.addEventListener('drop', this._handleDrop, false); + elem.addEventListener('dragend', this._handleDragEnd, false); + elem.partsPreview = this; + } + }, + + _handleDragStart: function (e) { + // By default we move when dragging, but can + // support duplication with ctrl in the future. + e.dataTransfer.effectAllowed = 'move'; + }, + + _handleDragOver: function (e) { + if (e.preventDefault) { + e.preventDefault(); + } + + // By default we move when dragging, but can + // support duplication with ctrl in the future. + e.dataTransfer.dropEffect = 'move'; + + this.classList.add('preview-img-dropsite'); + return false; + }, + + _handleDragEnter: function () { + }, + + _handleDragLeave: function () { + this.classList.remove('preview-img-dropsite'); + }, + + _handleDrop: function (e) { + if (e.stopPropagation) { + e.stopPropagation(); + } + + var part = $('#slide-sorter .mCSB_container .preview-frame').index(e.target.parentNode); + if (part !== null) { + var partId = parseInt(part); + this.partsPreview._map._socket.sendMessage('moveselectedclientparts position=' + partId); + } + + this.classList.remove('preview-img-dropsite'); + return false; + }, + + _handleDragEnd: function () { + this.classList.remove('preview-img-dropsite'); } + }); L.control.partsPreview = function (options) { diff --git a/wsd/ClientSession.cpp b/wsd/ClientSession.cpp index c2fbee956..108eb300b 100644 --- a/wsd/ClientSession.cpp +++ b/wsd/ClientSession.cpp @@ -165,6 +165,7 @@ bool ClientSession::_handleInput(const char *buffer, int length) tokens[0] != "selecttext" && tokens[0] != "setclientpart" && tokens[0] != "selectclientpart" && + tokens[0] != "moveselectedclientparts" && tokens[0] != "setpage" && tokens[0] != "status" && tokens[0] != "statusupdate" && @@ -340,6 +341,23 @@ bool ClientSession::_handleInput(const char *buffer, int length) } } } + else if (tokens[0] == "moveselectedclientparts") + { + if(!_isTextDocument) + { + int nPosition; + if (tokens.size() != 2 || + !getTokenInteger(tokens[1], "position", nPosition)) + { + sendTextFrame("error: cmd=moveselectedclientparts kind=syntax"); + return false; + } + else + { + return forwardToChild(std::string(buffer, length), docBroker); + } + } + } else if (tokens[0] == "clientzoom") { int tilePixelWidth, tilePixelHeight, tileTwipWidth, tileTwipHeight; diff --git a/wsd/protocol.txt b/wsd/protocol.txt index cb5554e4c..865d3fd1b 100644 --- a/wsd/protocol.txt +++ b/wsd/protocol.txt @@ -142,6 +142,10 @@ selectclientpart part=<partNumber> Informs the server that the client changed the selection state of <partNumber>. +moveselectedclientparts position=<positionNumber> + + Moves the selected parts to a new position. + setpage page=<pageNumber> Valid only for text documents. _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits