[Libreoffice-commits] online.git: loleaflet/dist loleaflet/src wsd/ClientSession.cpp wsd/DocumentBroker.cpp wsd/DocumentBroker.hpp wsd/protocol.txt

Pranav Kant pranavk at collabora.co.uk
Mon May 15 06:38:19 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 1cb75cbcb8c87481bf341c5ac058a36c13529dc8
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 closing the
    session 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

diff --git a/loleaflet/dist/toolbar/toolbar.js b/loleaflet/dist/toolbar/toolbar.js
index bbd4b81e..55d50353 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');
 	}
@@ -465,7 +468,7 @@ $(function () {
 				{ text: _('Right wrap'), id: 'wrap-WrapRight' },
 				{ text: _('Wrap through'), id: 'wrap-WrapThrough' }
 			]},
-			{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 5ef70522..5a0af025 100644
--- a/wsd/ClientSession.cpp
+++ b/wsd/ClientSession.cpp
@@ -204,6 +204,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 bb7b9c5e..e5924f87 100644
--- a/wsd/DocumentBroker.cpp
+++ b/wsd/DocumentBroker.cpp
@@ -696,11 +696,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)
     {
@@ -715,37 +733,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);
@@ -756,18 +757,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"
@@ -780,12 +784,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 1d136eb7..89c2ce43 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().
@@ -660,5 +668,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