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 <[email protected]> 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>"} - - _______________________________________________ Libreoffice-commits mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
