[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

2017-06-22 Thread Pranav Kant
 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 Kant 
Date:   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

2017-06-22 Thread Pranav Kant
 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 Kant 
Date:   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

2017-06-22 Thread Pranav Kant
 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 Kant 
Date:   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() -