[Libreoffice-commits] online.git: Branch 'distro/collabora/collabora-online-2-1' - loleaflet/src wsd/ClientSession.cpp wsd/DocumentBroker.cpp wsd/DocumentBroker.hpp wsd/protocol.txt
loleaflet/src/core/Socket.js | 12 wsd/ClientSession.cpp|5 - wsd/DocumentBroker.cpp | 18 +- wsd/DocumentBroker.hpp |3 +++ wsd/protocol.txt | 14 +- 5 files changed, 41 insertions(+), 11 deletions(-) New commits: commit 2491146606b92db70529e2f6255c767d4daa8b32 Author: Pranav KantDate: Thu Jun 1 21:41:11 2017 +0530 Broadcast command result back to clients This is required to tell the clients if the command they issued was successfull or not. In this case 'savetostorage' is the command that we are interested in knowing the success status of. With this, now if the user commands to overwrite the document, dialog boxes of all other users are automatically closed. Can easily more commands in future for this kind of thing. Its similar to unocommandresult, except its not a uno command, but our internal command. Change-Id: I2e7e1fd5edbd55c13ee4bf9bce24284483d6507f (cherry picked from commit f4b22bbb3c82c1e841934f98280f5deb2256f326) Reviewed-on: https://gerrit.libreoffice.org/38533 Reviewed-by: Jan Holesovsky Tested-by: Jan Holesovsky diff --git a/loleaflet/src/core/Socket.js b/loleaflet/src/core/Socket.js index 8abb1898..fa03820a 100644 --- a/loleaflet/src/core/Socket.js +++ b/loleaflet/src/core/Socket.js @@ -223,6 +223,18 @@ L.Socket = L.Class.extend({ this._map.fire('wopiprops', wopiInfo); return; } + else if (textMsg.startsWith('commandresult: ')) { + var commandresult = JSON.parse(textMsg.substring(textMsg.indexOf('{'))); + if (commandresult['command'] === 'savetostorage' && commandresult['success']) { + // Close any open confirmation dialogs + if (vex.dialogID > 0) { + var id = vex.dialogID; + vex.dialogID = -1; + vex.close(id); + } + } + return; + } else if (textMsg.startsWith('close: ')) { textMsg = textMsg.substring('close: '.length); msg = ''; diff --git a/wsd/ClientSession.cpp b/wsd/ClientSession.cpp index 5dd4c278..64e7ea94 100644 --- a/wsd/ClientSession.cpp +++ b/wsd/ClientSession.cpp @@ -224,7 +224,10 @@ bool ClientSession::_handleInput(const char *buffer, int length) { int force = 0; getTokenInteger(tokens[1], "force", force); -docBroker->saveToStorage(getId(), true, "" /* This is irrelevant when success is true*/, true); +if (docBroker->saveToStorage(getId(), true, "" /* This is irrelevant when success is true*/, true)) +{ +docBroker->broadcastMessage("commandresult: { \"command\": \"savetostorage\", \"success\": true }"); +} } else { diff --git a/wsd/DocumentBroker.cpp b/wsd/DocumentBroker.cpp index d1ad267b..850baf66 100644 --- a/wsd/DocumentBroker.cpp +++ b/wsd/DocumentBroker.cpp @@ -626,6 +626,7 @@ bool DocumentBroker::saveToStorageInternal(const std::string& sessionId, // So set _documentLastModifiedTime then _documentLastModifiedTime = _storage->getFileInfo()._modifiedTime; + // After a successful save, we are sure that document in the storage is same as ours _documentChangedInStorage = false; @@ -661,11 +662,7 @@ bool DocumentBroker::saveToStorageInternal(const std::string& sessionId, { LOG_ERR("PutFile says that Document changed in storage"); _documentChangedInStorage = true; -// Inform all clients -for (const auto& sessionIt : _sessions) -{ -sessionIt.second->sendTextFrame("error: cmd=storage kind=documentconflict"); -} +broadcastMessage("error: cmd=storage kind=documentconflict"); } return false; @@ -1416,6 +1413,17 @@ void DocumentBroker::closeDocument(const std::string& reason) terminateChild(reason, false); } +void DocumentBroker::broadcastMessage(const std::string& message) +{ +assertCorrectThread(); + +LOG_DBG("Broadcasting message [" << message << "] to all sessions."); +for (const auto& sessionIt : _sessions) +{ +sessionIt.second->sendTextFrame(message); +} +} + void DocumentBroker::updateLastActivityTime() { _lastActivityTime = std::chrono::steady_clock::now(); diff --git a/wsd/DocumentBroker.hpp b/wsd/DocumentBroker.hpp index 92de36c2..03bca722 100644 --- a/wsd/DocumentBroker.hpp +++ b/wsd/DocumentBroker.hpp @@ -340,6 +340,9 @@ public: /// Sends the .uno:Save command to LoKit. bool sendUnoSave(const std::string& sessionId, bool
[Libreoffice-commits] online.git: Branch 'distro/collabora/collabora-online-2-1' - loleaflet/src wsd/ClientSession.cpp wsd/DocumentBroker.cpp wsd/DocumentBroker.hpp wsd/protocol.txt wsd/Storage.cpp ws
loleaflet/src/control/Toolbar.js |4 +++- loleaflet/src/core/Socket.js |2 +- wsd/ClientSession.cpp|7 +++ wsd/DocumentBroker.cpp |7 ++- wsd/DocumentBroker.hpp |2 +- wsd/Storage.cpp |7 ++- wsd/Storage.hpp |6 +++--- wsd/protocol.txt |8 8 files changed, 35 insertions(+), 8 deletions(-) New commits: commit 3528fdc925fd98c7ec9f74c9b7187b73c35aecd9 Author: Pranav KantDate: Thu Jun 1 19:46:03 2017 +0530 If user permits, save to storage force-fully in case of doc conflict There is one known problem still - after any user decides to overwrite the file to storage, other users are not informed, so their dialog keeps hanging on the screen until they press the cancel or reload button. Change-Id: I6dad1585e4c53eeed79cd38316892a7f239d44ef (cherry picked from commit 41234773e3b57e1695951bddaedb4f61ad44026d) Reviewed-on: https://gerrit.libreoffice.org/38530 Reviewed-by: Jan Holesovsky Tested-by: Jan Holesovsky diff --git a/loleaflet/src/control/Toolbar.js b/loleaflet/src/control/Toolbar.js index 681a8ecc..b5f68749 100644 --- a/loleaflet/src/control/Toolbar.js +++ b/loleaflet/src/control/Toolbar.js @@ -131,7 +131,9 @@ L.Map.include({ }, save: function(dontTerminateEdit, dontSaveIfUnmodified) { - this._socket.sendMessage('save dontTerminateEdit=' + (dontTerminateEdit ? 1 : 0) + ' dontSaveIfUnmodified=' + (dontSaveIfUnmodified ? 1 : 0)); + this._socket.sendMessage('save' + +' dontTerminateEdit=' + (dontTerminateEdit ? 1 : 0) + +' dontSaveIfUnmodified=' + (dontSaveIfUnmodified ? 1 : 0)); }, sendUnoCommand: function (command, json) { diff --git a/loleaflet/src/core/Socket.js b/loleaflet/src/core/Socket.js index 17d73b04..cbb9f523 100644 --- a/loleaflet/src/core/Socket.js +++ b/loleaflet/src/core/Socket.js @@ -369,7 +369,7 @@ L.Socket = L.Class.extend({ this.sendMessage('closedocument'); } else { // They want to overwrite - this.sendMessage('documentconflict.overwrite'); + this.sendMessage('savetostorage force=1'); } }, this) }); diff --git a/wsd/ClientSession.cpp b/wsd/ClientSession.cpp index 84558297..5dd4c278 100644 --- a/wsd/ClientSession.cpp +++ b/wsd/ClientSession.cpp @@ -134,6 +134,7 @@ bool ClientSession::_handleInput(const char *buffer, int length) tokens[0] != "resetselection" && tokens[0] != "save" && tokens[0] != "saveas" && + tokens[0] != "savetostorage" && tokens[0] != "selectgraphic" && tokens[0] != "selecttext" && tokens[0] != "setclientpart" && @@ -219,6 +220,12 @@ bool ClientSession::_handleInput(const char *buffer, int length) getTokenInteger(tokens[2], "dontSaveIfUnmodified", dontSaveIfUnmodified); docBroker->sendUnoSave(getId(), dontTerminateEdit != 0, dontSaveIfUnmodified != 0); } +else if (tokens[0] == "savetostorage") +{ +int force = 0; +getTokenInteger(tokens[1], "force", force); +docBroker->saveToStorage(getId(), true, "" /* This is irrelevant when success is true*/, true); +} else { if (!filterMessage(firstLine)) diff --git a/wsd/DocumentBroker.cpp b/wsd/DocumentBroker.cpp index 2dc938ac..fe01c979 100644 --- a/wsd/DocumentBroker.cpp +++ b/wsd/DocumentBroker.cpp @@ -542,10 +542,15 @@ bool DocumentBroker::load(const std::shared_ptr& session, const s } bool DocumentBroker::saveToStorage(const std::string& sessionId, - bool success, const std::string& result) + bool success, const std::string& result, bool force) { assertCorrectThread(); +if (force) +{ +LOG_TRC("Document will be saved forcefully to storage."); +_storage->forceSave(); +} const bool res = saveToStorageInternal(sessionId, success, result); // If marked to destroy, or session is disconnected, remove. diff --git a/wsd/DocumentBroker.hpp b/wsd/DocumentBroker.hpp index 5b9b1730..92de36c2 100644 --- a/wsd/DocumentBroker.hpp +++ b/wsd/DocumentBroker.hpp @@ -240,7 +240,7 @@ public: bool isDocumentChangedInStorage() { return _documentChangedInStorage; } /// Save the document to Storage if it needs persisting. -bool saveToStorage(const
[Libreoffice-commits] online.git: Branch 'distro/collabora/collabora-online-2-1' - loleaflet/src wsd/ClientSession.cpp wsd/DocumentBroker.cpp wsd/DocumentBroker.hpp wsd/protocol.txt wsd/Storage.cpp ws
loleaflet/src/core/Socket.js | 30 ++ wsd/ClientSession.cpp|7 +++ wsd/DocumentBroker.cpp |8 +--- wsd/DocumentBroker.hpp |6 ++ wsd/Storage.cpp | 10 +++--- wsd/Storage.hpp |8 +++- wsd/protocol.txt |4 7 files changed, 66 insertions(+), 7 deletions(-) New commits: commit 8f02d4b49d699d37ff979b2cb553564d8f11358b Author: Pranav KantDate: Thu Jun 1 18:26:54 2017 +0530 If user commands, refresh the document for all in case of doc conflict Change-Id: I42c61fb8099b0bcc60f942e602561cc97486a918 (cherry picked from commit 4d61cae4c8b6ecc7890fb0426c9600e1cf77bbdb) Reviewed-on: https://gerrit.libreoffice.org/38529 Reviewed-by: Jan Holesovsky Tested-by: Jan Holesovsky diff --git a/loleaflet/src/core/Socket.js b/loleaflet/src/core/Socket.js index 894725aa..17d73b04 100644 --- a/loleaflet/src/core/Socket.js +++ b/loleaflet/src/core/Socket.js @@ -269,6 +269,21 @@ L.Socket = L.Class.extend({ } }, timeoutMs); } + else if (textMsg.startsWith('documentconflict')) { + var username = textMsg.substring('documentconflict '.length); + msg = _('%user asked to refresh the document. Document will now refresh automatically.').replace('%user', username); + + // Reload the document + this._map._active = false; + map = this._map; + vex.timer = setInterval(function() { + try { + // Activate and cancel timer and dialogs. + map._activate(); + } catch (error) { + } + }, 3000); + } // Close any open dialogs first. if (vex.dialogID > 0) { @@ -346,6 +361,21 @@ L.Socket = L.Class.extend({ else if (command.errorKind === 'documentconflict') { storageError = errorMessages.storage.documentconflict; + vex.dialog.confirm({ + message: _('Document has been changed in storage. Do you want to refresh the page to load the new document ? Cancelling will continue editing and overwrite.'), + callback: L.bind(function(value) { + if (value) { + // They want to refresh the page and load document again for all + this.sendMessage('closedocument'); + } else { + // They want to overwrite + this.sendMessage('documentconflict.overwrite'); + } + }, this) + }); + vex.dialogID = vex.globalID - 1; + + return; } // Parse the storage url as link diff --git a/wsd/ClientSession.cpp b/wsd/ClientSession.cpp index 7c22b04d..84558297 100644 --- a/wsd/ClientSession.cpp +++ b/wsd/ClientSession.cpp @@ -171,6 +171,13 @@ bool ClientSession::_handleInput(const char *buffer, int length) LOG_DBG("Session [" << getId() << "] requested owner termination"); docBroker->closeDocument("ownertermination"); } +else if (docBroker->isDocumentChangedInStorage()) +{ +LOG_DBG("Document marked as changed in storage and user [" +<< getUserId() << ", " << getUserName() +<< "] wants to refresh the document for all."); +docBroker->closeDocument("documentconflict " + getUserName()); +} return true; } diff --git a/wsd/DocumentBroker.cpp b/wsd/DocumentBroker.cpp index 2157e191..2dc938ac 100644 --- a/wsd/DocumentBroker.cpp +++ b/wsd/DocumentBroker.cpp @@ -145,6 +145,7 @@ DocumentBroker::DocumentBroker(const std::string& uri, _docId(Util::encodeId(DocBrokerId++, 3)), _childRoot(childRoot), _cacheRoot(getCachePath(uriPublic.toString())), +_documentChangedInStorage(false), _lastSaveTime(std::chrono::steady_clock::now()), _lastSaveRequestTime(std::chrono::steady_clock::now() -