summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPranav Kant <pranavk@collabora.co.uk>2017-06-01 19:46:03 +0530
committerPranav Kant <pranavk@collabora.co.uk>2017-06-01 19:53:10 +0530
commit41234773e3b57e1695951bddaedb4f61ad44026d (patch)
tree3ad8f9d601913a7460fc6e8b92ae5a4886adabab
parent4d61cae4c8b6ecc7890fb0426c9600e1cf77bbdb (diff)
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
-rw-r--r--loleaflet/src/control/Toolbar.js4
-rw-r--r--loleaflet/src/core/Socket.js2
-rw-r--r--wsd/ClientSession.cpp7
-rw-r--r--wsd/DocumentBroker.cpp7
-rw-r--r--wsd/DocumentBroker.hpp2
-rw-r--r--wsd/Storage.cpp7
-rw-r--r--wsd/Storage.hpp6
-rw-r--r--wsd/protocol.txt8
8 files changed, 35 insertions, 8 deletions
diff --git a/loleaflet/src/control/Toolbar.js b/loleaflet/src/control/Toolbar.js
index 681a8ecc4..b5f687499 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 a65a330a6..1d6b884f3 100644
--- a/loleaflet/src/core/Socket.js
+++ b/loleaflet/src/core/Socket.js
@@ -357,7 +357,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 4ba8988fe..7af580bb5 100644
--- a/wsd/ClientSession.cpp
+++ b/wsd/ClientSession.cpp
@@ -136,6 +136,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" &&
@@ -221,6 +222,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 9b2821657..981834fa6 100644
--- a/wsd/DocumentBroker.cpp
+++ b/wsd/DocumentBroker.cpp
@@ -544,10 +544,15 @@ bool DocumentBroker::load(const std::shared_ptr<ClientSession>& 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 588df3fd6..7f5636476 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 std::string& sesionId, bool success, const std::string& result = "");
+ bool saveToStorage(const std::string& sesionId, bool success, const std::string& result = "", bool force = false);
bool isModified() const { return _isModified; }
void setModified(const bool value);
/// Save the document if the document is modified.
diff --git a/wsd/Storage.cpp b/wsd/Storage.cpp
index 7c677a6d9..af31674e3 100644
--- a/wsd/Storage.cpp
+++ b/wsd/Storage.cpp
@@ -668,13 +668,14 @@ StorageBase::SaveResult WopiStorage::saveLocalFileToStorage(const std::string& a
Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_POST, uriObject.getPathAndQuery(), Poco::Net::HTTPMessage::HTTP_1_1);
request.set("X-WOPI-Override", "PUT");
- if (!_forceOverwrite)
+ if (!_forceSave)
{
// Request WOPI host to not overwrite if timestamps mismatch
request.set("X-LOOL-WOPI-Timestamp",
Poco::DateTimeFormatter::format(Poco::DateTime(_fileInfo._modifiedTime),
Poco::DateTimeFormat::ISO8601_FRAC_FORMAT));
}
+
request.setContentType("application/octet-stream");
request.setContentLength(size);
addStorageDebugCookie(request);
@@ -699,6 +700,10 @@ StorageBase::SaveResult WopiStorage::saveLocalFileToStorage(const std::string& a
const std::string lastModifiedTime = getJSONValue<std::string>(object, "LastModifiedTime");
LOG_TRC("WOPI::PutFile returns LastModifiedTime [" << lastModifiedTime << "].");
_fileInfo._modifiedTime = iso8601ToTimestamp(lastModifiedTime);
+
+ // Reset the force save flag now, if any, since we are done saving
+ // Next saves shouldn't be saved forcefully unless commanded
+ _forceSave = false;
}
else
{
diff --git a/wsd/Storage.hpp b/wsd/Storage.hpp
index bb25a2d7e..60c732757 100644
--- a/wsd/Storage.hpp
+++ b/wsd/Storage.hpp
@@ -78,7 +78,7 @@ public:
_jailPath(jailPath),
_fileInfo("", "lool", Poco::Timestamp::fromEpochTime(0), 0),
_isLoaded(false),
- _forceOverwrite(false)
+ _forceSave(false)
{
LOG_DBG("Storage ctor: " << uri.toString());
}
@@ -92,7 +92,7 @@ public:
/// Asks the storage object to force overwrite to storage upon next save
/// even if document turned out to be changed in storage
- void forceOverwrite() { _forceOverwrite = true; }
+ void forceSave() { _forceSave = true; }
/// Returns the basic information about the file.
FileInfo getFileInfo() { return _fileInfo; }
@@ -125,7 +125,7 @@ protected:
std::string _jailedFilePath;
FileInfo _fileInfo;
bool _isLoaded;
- bool _forceOverwrite;
+ bool _forceSave;
static bool FilesystemEnabled;
static bool WopiEnabled;
diff --git a/wsd/protocol.txt b/wsd/protocol.txt
index b0617b2f7..e3bf12aba 100644
--- a/wsd/protocol.txt
+++ b/wsd/protocol.txt
@@ -160,6 +160,14 @@ save dontTerminateEdit=<value> dontSaveIfUnmodified=<value>
non-zero. 'dontSaveIfUnmodified' when set to non-zero skips saving the document when it is
unmodified.
+savetostorage force=<value>
+
+ Saves the files to storage. A 'save' command automatically saves the file to
+ storage almost always except in the case where there is a document conflict
+ i.e document in the storage is changed behind our back. We might need to do
+ call this command with force=1 in that case to forcefully save it to storage
+ after asking from the user.
+
clientvisiblearea x=<x> y=<y> width=<width> height=<height>
Invokes lok::Document::setClientVisibleArea().