[Libreoffice-commits] online.git: Branch 'distro/collabora/collabora-online-2-1' - loleaflet/dist loleaflet/src wsd/ClientSession.cpp wsd/DocumentBroker.cpp wsd/DocumentBroker.hpp wsd/protocol.txt

Pranav Kant pranavk at collabora.co.uk
Tue May 16 14:52:55 UTC 2017


 loleaflet/dist/toolbar/toolbar.js        |    5 +-
 loleaflet/src/control/Control.Menubar.js |   10 ++--
 loleaflet/src/control/Toolbar.js         |   12 -----
 wsd/ClientSession.cpp                    |    8 +++
 wsd/DocumentBroker.cpp                   |   70 ++++++++++++++++---------------
 wsd/DocumentBroker.hpp                   |    6 +-
 wsd/protocol.txt                         |   10 +++-
 7 files changed, 67 insertions(+), 54 deletions(-)

New commits:
commit 41942b923cde9adfea679288f8a818e9e87b825f
Author: Pranav Kant <pranavk at collabora.co.uk>
Date:   Mon May 15 11:29:04 2017 +0530

    wsd: Save wrapper over .uno:Save
    
    Document broker needs to know when the save request is sent and when the
    save finished. It uses these parameters to avoid shutting down document,
    in the document broker main polling loop, if save is already going on.
    But direct .uno:Save commands issued from
    loleaflet precludes document broker to keep track of it - in this case a
    .uno:Save command issued from loleaflet followed by shutting-down the
    wsd will prevent saving the document to storage, if document is huge
    enough and LO core takes a bit of time to save it. A save wrapper
    command, 'save', ensures that document broker is aware of all such save
    requests (_saveRequestTime member variable) and doesn't close the
    document until we completely save it (to storage and other cleanups).
    
    Change-Id: I5ec73d45adff23b2e7543e93dfd0624a5e5af46d
    (cherry picked from commit 1cb75cbcb8c87481bf341c5ac058a36c13529dc8)
    Reviewed-on: https://gerrit.libreoffice.org/37643
    Reviewed-by: Jan Holesovsky <kendy at collabora.com>
    Tested-by: Jan Holesovsky <kendy at collabora.com>

diff --git a/loleaflet/dist/toolbar/toolbar.js b/loleaflet/dist/toolbar/toolbar.js
index bc2d9cd0..11ad3244 100644
--- a/loleaflet/dist/toolbar/toolbar.js
+++ b/loleaflet/dist/toolbar/toolbar.js
@@ -218,6 +218,9 @@ function onClick(id, item, subItem) {
 			map.toggleCommandState(item.uno);
 		}
 	}
+	else if (id === 'save') {
+		map.save(true, true);
+	}
 	else if (id === 'repair') {
 		map._socket.sendMessage('commandvalues command=.uno:DocumentRepair');
 	}
@@ -451,7 +454,7 @@ $(function () {
 		name: 'toolbar-up',
 		items: [
 			{type: 'html', id: 'left'},
-			{type: 'button',  id: 'save', img: 'save', hint: _('Save'), uno: 'Save'},
+			{type: 'button',  id: 'save', img: 'save', hint: _('Save')},
 			{type: 'break', id: 'savebreak'},
 			{type: 'button',  id: 'undo',  img: 'undo', hint: _('Undo'), uno: 'Undo'},
 			{type: 'button',  id: 'redo',  img: 'redo', hint: _('Redo'), uno: 'Redo'},
diff --git a/loleaflet/src/control/Control.Menubar.js b/loleaflet/src/control/Control.Menubar.js
index 89048a3b..8206ab5c 100644
--- a/loleaflet/src/control/Control.Menubar.js
+++ b/loleaflet/src/control/Control.Menubar.js
@@ -8,7 +8,7 @@ L.Control.Menubar = L.Control.extend({
 	options: {
 		text:  [
 			{name: _('File'), id: 'file', type: 'menu', menu: [
-				{name: _('Save'), id: 'save', type: 'unocommand', uno: '.uno:Save'},
+				{name: _('Save'), id: 'save', type: 'action'},
 				{name: _('Print'), id: 'print', type: 'action'},
 				{name: _('See revision history'), id: 'rev-history', type: 'action'},
 				{name: _('Download as'), id: 'downloadas', type: 'menu', menu: [
@@ -172,7 +172,7 @@ L.Control.Menubar = L.Control.extend({
 
 		presentation: [
 			{name: _('File'), id: 'file', type: 'menu', menu: [
-				{name: _('Save'), id: 'save', type: 'unocommand', uno: '.uno:Save'},
+				{name: _('Save'), id: 'save', type: 'action'},
 				{name: _('Print'), id: 'print', type: 'action'},
 				{name: _('See revision history'), id: 'rev-history', type: 'action'},
 				{name: _('Download as'), id: 'downloadas', type: 'menu', menu: [
@@ -232,7 +232,7 @@ L.Control.Menubar = L.Control.extend({
 
 		spreadsheet: [
 			{name: _('File'), id: 'file', type: 'menu', menu: [
-				{name: _('Save'), id: 'save', type: 'unocommand', uno: '.uno:Save'},
+				{name: _('Save'), id: 'save', type: 'action'},
 				{name: _('Print'), id: 'print', type: 'action'},
 				{name: _('See revision history'), id: 'rev-history', type: 'action'},
 				{name: _('Download as'), id:'downloadas', type: 'menu', menu: [
@@ -417,7 +417,9 @@ L.Control.Menubar = L.Control.extend({
 	},
 
 	_executeAction: function(id) {
-		if (id === 'print') {
+		if (id === 'save') {
+			map.save(true, true);
+		} else if (id === 'print') {
 			map.print();
 		} else if (id.startsWith('downloadas-')) {
 			var format = id.substring('downloadas-'.length);
diff --git a/loleaflet/src/control/Toolbar.js b/loleaflet/src/control/Toolbar.js
index 8d229f53..681a8ecc 100644
--- a/loleaflet/src/control/Toolbar.js
+++ b/loleaflet/src/control/Toolbar.js
@@ -131,17 +131,7 @@ L.Map.include({
 	},
 
 	save: function(dontTerminateEdit, dontSaveIfUnmodified) {
-		var args = {
-			DontTerminateEdit: {
-				type: 'boolean',
-				value: !!dontTerminateEdit
-			},
-			DontSaveIfUnmodified: {
-				type: 'boolean',
-				value: !!dontSaveIfUnmodified
-			}
-		};
-		this.sendUnoCommand('.uno:Save', args);
+		this._socket.sendMessage('save dontTerminateEdit=' + (dontTerminateEdit ? 1 : 0) + ' dontSaveIfUnmodified=' + (dontSaveIfUnmodified ? 1 : 0));
 	},
 
 	sendUnoCommand: function (command, json) {
diff --git a/wsd/ClientSession.cpp b/wsd/ClientSession.cpp
index c1693c60..90a21aa2 100644
--- a/wsd/ClientSession.cpp
+++ b/wsd/ClientSession.cpp
@@ -203,6 +203,14 @@ bool ClientSession::_handleInput(const char *buffer, int length)
     {
         return sendCombinedTiles(buffer, length, tokens, docBroker);
     }
+    else if (tokens[0] == "save")
+    {
+        int dontTerminateEdit = 1;
+        int dontSaveIfUnmodified = 1;
+        getTokenInteger(tokens[1], "dontTerminateEdit", dontTerminateEdit);
+        getTokenInteger(tokens[2], "dontSaveIfUnmodified", dontSaveIfUnmodified);
+        docBroker->sendUnoSave(getId(), dontTerminateEdit != 0, dontSaveIfUnmodified != 0);
+    }
     else
     {
         if (!filterMessage(firstLine))
diff --git a/wsd/DocumentBroker.cpp b/wsd/DocumentBroker.cpp
index 0dac41b5..2c66154e 100644
--- a/wsd/DocumentBroker.cpp
+++ b/wsd/DocumentBroker.cpp
@@ -700,11 +700,29 @@ bool DocumentBroker::autoSave(const bool force)
     // Remember the last save time, since this is the predicate.
     LOG_TRC("Checking to autosave [" << _docKey << "].");
 
+    // Which session to use when auto saving ?
+    std::string savingSessionId;
+    for (auto& sessionIt : _sessions)
+    {
+        // Save the document using first session available ...
+        if (savingSessionId.empty())
+        {
+            savingSessionId = sessionIt.second->getId();
+        }
+
+        // or if any of the sessions is document owner, use that.
+        if (sessionIt.second->isDocumentOwner())
+        {
+            savingSessionId = sessionIt.second->getId();
+            break;
+        }
+    }
+
     bool sent = false;
     if (force)
     {
         LOG_TRC("Sending forced save command for [" << _docKey << "].");
-        sent = sendUnoSave(true);
+        sent = sendUnoSave(savingSessionId);
     }
     else if (_isModified)
     {
@@ -719,37 +737,20 @@ bool DocumentBroker::autoSave(const bool force)
             timeSinceLastSaveMs >= AutoSaveDurationMs)
         {
             LOG_TRC("Sending timed save command for [" << _docKey << "].");
-            sent = sendUnoSave(true);
+            sent = sendUnoSave(savingSessionId);
         }
     }
 
     return sent;
 }
 
-bool DocumentBroker::sendUnoSave(const bool dontSaveIfUnmodified)
+bool DocumentBroker::sendUnoSave(const std::string& sessionId, bool dontTerminateEdit, bool dontSaveIfUnmodified)
 {
     assertCorrectThread();
 
-    LOG_INF("Autosave triggered for doc [" << _docKey << "].");
+    LOG_INF("Saving doc [" << _docKey << "].");
 
-    std::shared_ptr<ClientSession> savingSession;
-    for (auto& sessionIt : _sessions)
-    {
-        // Save the document using first session available ...
-        if (!savingSession)
-        {
-            savingSession = sessionIt.second;
-        }
-
-        // or if any of the sessions is document owner, use that.
-        if (sessionIt.second->isDocumentOwner())
-        {
-            savingSession = sessionIt.second;
-            break;
-        }
-    }
-
-    if (savingSession)
+    if (_sessions.find(sessionId) != _sessions.end())
     {
         // Invalidate the timestamp to force persisting.
         _lastFileModifiedTime = Poco::Timestamp::fromEpochTime(0);
@@ -760,18 +761,21 @@ bool DocumentBroker::sendUnoSave(const bool dontSaveIfUnmodified)
         // arguments init
         oss << "{";
 
-        // Mention DontTerminateEdit always
-        oss << "\"DontTerminateEdit\":"
-            << "{"
-            << "\"type\":\"boolean\","
-            << "\"value\":true"
-            << "}";
+        if (dontTerminateEdit)
+        {
+            oss << "\"DontTerminateEdit\":"
+                << "{"
+                << "\"type\":\"boolean\","
+                << "\"value\":true"
+                << "}";
+        }
 
-        // Mention DontSaveIfUnmodified
         if (dontSaveIfUnmodified)
         {
-            oss << ","
-                << "\"DontSaveIfUnmodified\":"
+            if (dontTerminateEdit)
+                oss << ",";
+
+            oss << "\"DontSaveIfUnmodified\":"
                 << "{"
                 << "\"type\":\"boolean\","
                 << "\"value\":true"
@@ -784,12 +788,12 @@ bool DocumentBroker::sendUnoSave(const bool dontSaveIfUnmodified)
         const auto saveArgs = oss.str();
         LOG_TRC(".uno:Save arguments: " << saveArgs);
         const auto command = "uno .uno:Save " + saveArgs;
-        forwardToChild(savingSession->getId(), command);
+        forwardToChild(sessionId, command);
         _lastSaveRequestTime = std::chrono::steady_clock::now();
         return true;
     }
 
-    LOG_ERR("Failed to auto-save doc [" << _docKey << "]: No valid sessions.");
+    LOG_ERR("Failed to save doc [" << _docKey << "]: No valid sessions.");
     return false;
 }
 
diff --git a/wsd/DocumentBroker.hpp b/wsd/DocumentBroker.hpp
index 3f7ebc67..46481cba 100644
--- a/wsd/DocumentBroker.hpp
+++ b/wsd/DocumentBroker.hpp
@@ -335,14 +335,14 @@ public:
         return std::chrono::duration_cast<std::chrono::seconds>(duration).count();
     }
 
+    /// Sends the .uno:Save command to LoKit.
+    bool sendUnoSave(const std::string& sessionId, bool dontTerminateEdit = true, bool dontSaveIfUnmodified = true);
+
 private:
     /// This gracefully terminates the connection
     /// with the child and cleans up ChildProcess etc.
     void terminateChild(const std::string& closeReason, const bool rude);
 
-    /// Sends the .uno:Save command to LoKit.
-    bool sendUnoSave(const bool dontSaveIfUnmodified);
-
     /// Saves the doc to the storage.
     bool saveToStorageInternal(const std::string& sesionId, bool success, const std::string& result = "");
 
diff --git a/wsd/protocol.txt b/wsd/protocol.txt
index 0c13bca7..d1de4ab3 100644
--- a/wsd/protocol.txt
+++ b/wsd/protocol.txt
@@ -152,6 +152,14 @@ uno <command>
 
     <command> is a line of text.
 
+save dontTerminateEdit=<value> dontSaveIfUnmodified=<value>
+
+    A wrapper over UNO save command. A non-zero <value> is considered true.
+    'dontTerminateEdit' means not terminating the edit session in
+    spreadsheets when saving the document. In most cases, you should set it to
+    non-zero. 'dontSaveIfUnmodified' when set to non-zero skips saving the document when it is
+    unmodified.
+
 clientvisiblearea x=<x> y=<y> width=<width> height=<height>
 
     Invokes lok::Document::setClientVisibleArea().
@@ -626,5 +634,3 @@ lokitversion <JSON string>
          "ProductVersion": "5.3",
          "ProductExtension": ".0.0.alpha0",
          "BuildId": "<full 40 char git hash>"}
-
-


More information about the Libreoffice-commits mailing list