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.nakash...@collabora.co.uk>
AuthorDate: Mon Sep 17 07:17:31 2018 -0400
Commit:     Ashod Nakashian <ashnak...@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 <ashnak...@gmail.com>
    Tested-by: Ashod Nakashian <ashnak...@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.
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to