[Libreoffice-commits] online.git: kit/ChildSession.cpp kit/ChildSession.hpp loleaflet/css loleaflet/src wsd/ClientSession.cpp wsd/protocol.txt

Ashod Nakashian (via logerrit) logerrit at kemper.freedesktop.org
Sat Aug 17 02:33:22 UTC 2019


 kit/ChildSession.cpp                          |   33 ++++++++++++++
 kit/ChildSession.hpp                          |    1 
 loleaflet/css/partsPreviewControl.css         |    6 ++
 loleaflet/src/control/Control.PartsPreview.js |   61 ++++++++++++++++++++++++++
 wsd/ClientSession.cpp                         |   18 +++++++
 wsd/protocol.txt                              |    4 +
 6 files changed, 122 insertions(+), 1 deletion(-)

New commits:
commit 2eab5cea763d037ed7d11f0ba88b8299edc592ff
Author:     Ashod Nakashian <ashod.nakashian at collabora.co.uk>
AuthorDate: Mon Sep 17 07:17:31 2018 -0400
Commit:     Ashod Nakashian <ashnakash at gmail.com>
CommitDate: Sat Aug 17 04:33:04 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 <ashnakash at gmail.com>
    Tested-by: Ashod Nakashian <ashnakash at gmail.com>
    Reviewed-on: https://gerrit.libreoffice.org/71099

diff --git a/kit/ChildSession.cpp b/kit/ChildSession.cpp
index fc41597e5..be169fc6f 100644
--- a/kit/ChildSession.cpp
+++ b/kit/ChildSession.cpp
@@ -232,6 +232,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);
@@ -1964,6 +1968,35 @@ 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;
+    }
+
+    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 cc5ff6a15..1d2cd3fdd 100644
--- a/kit/ChildSession.hpp
+++ b/kit/ChildSession.hpp
@@ -269,6 +269,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 3ebe4baaa..8f0629957 100644
--- a/loleaflet/src/control/Control.PartsPreview.js
+++ b/loleaflet/src/control/Control.PartsPreview.js
@@ -85,6 +85,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';
@@ -209,6 +210,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});
 				}
 			}
 		}
@@ -276,7 +278,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 f10f08724..5dbcaa7d0 100644
--- a/wsd/ClientSession.cpp
+++ b/wsd/ClientSession.cpp
@@ -402,6 +402,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" &&
@@ -580,6 +581,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 a1bdb39cb..bf11deafd 100644
--- a/wsd/protocol.txt
+++ b/wsd/protocol.txt
@@ -144,6 +144,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.


More information about the Libreoffice-commits mailing list