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

Mike Kaganski (via logerrit) logerrit at kemper.freedesktop.org
Mon Jul 20 13:49:28 UTC 2020


 loleaflet/po/templates/loleaflet-ui.pot |    8 +++-
 loleaflet/src/control/Permission.js     |   61 +++++++++++++++++++++++++-------
 wsd/ClientSession.cpp                   |   22 +++++++++++
 wsd/ClientSession.hpp                   |    3 +
 wsd/DocumentBroker.cpp                  |    9 ++++
 wsd/DocumentBroker.hpp                  |    3 +
 6 files changed, 91 insertions(+), 15 deletions(-)

New commits:
commit a1fafe27f410e422c0bd559bb3d7fd3d06937c7e
Author:     Mike Kaganski <mike.kaganski at collabora.com>
AuthorDate: Tue Jul 14 22:19:14 2020 +0300
Commit:     Mike Kaganski <mike.kaganski at collabora.com>
CommitDate: Mon Jul 20 15:49:09 2020 +0200

    Allow user to try to lock the document for edit
    
    Use mobile-edit-button for that is permitted.
    
    Change-Id: I4d4c3f21d574abae033bacc69def96aaf6b51567
    Reviewed-on: https://gerrit.libreoffice.org/c/online/+/98786
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice at gmail.com>
    Tested-by: Jenkins
    Reviewed-by: Mike Kaganski <mike.kaganski at collabora.com>

diff --git a/loleaflet/po/templates/loleaflet-ui.pot b/loleaflet/po/templates/loleaflet-ui.pot
index d715eca95..55a4f192f 100644
--- a/loleaflet/po/templates/loleaflet-ui.pot
+++ b/loleaflet/po/templates/loleaflet-ui.pot
@@ -898,16 +898,20 @@ msgstr ""
 msgid "Start Presentation"
 msgstr ""
 
-#: src/control/Permission.js:42
+#: src/control/Permission.js:45
 msgid "The document could not be locked, and is opened in read-only mode."
 msgstr ""
 
-#: src/control/Permission.js:44
+#: src/control/Permission.js:47 src/control/Permission.js:65
 msgid ""
 "\n"
 "Server returned this reason: \""
 msgstr ""
 
+#: src/control/Permission.js:63
+msgid "The document could not be locked."
+msgstr ""
+
 #: src/control/Ruler.js:366
 msgid "Left Margin"
 msgstr ""
diff --git a/loleaflet/src/control/Permission.js b/loleaflet/src/control/Permission.js
index 1ba08d90b..62b9bb9ad 100644
--- a/loleaflet/src/control/Permission.js
+++ b/loleaflet/src/control/Permission.js
@@ -13,24 +13,22 @@ L.Map.include({
 
 				var that = this;
 				button.on('click', function () {
-					button.hide();
-					that._enterEditMode('edit');
-					that.fire('editorgotfocus');
-					// In the iOS/android app, just clicking the mobile-edit-button is
-					// not reason enough to pop up the on-screen keyboard.
-					if (!(window.ThisIsTheiOSApp || window.ThisIsTheAndroidApp))
-						that.focus();
+					that._switchToEditMode();
 				});
 
 				// temporarily, before the user touches the floating action button
 				this._enterReadOnlyMode('readonly');
 			}
+			else if (this.options.canTryLock) {
+				// This is a success response to an attempt to lock using mobile-edit-button
+				this._switchToEditMode();
+			}
 			else {
 				this._enterEditMode(perm);
 			}
 		}
 		else if (perm === 'view' || perm === 'readonly') {
-			if (window.mode.isMobile() || window.mode.isTablet()) {
+			if (!this.options.canTryLock && (window.mode.isMobile() || window.mode.isTablet())) {
 				$('#mobile-edit-button').hide();
 			}
 
@@ -39,13 +37,50 @@ L.Map.include({
 	},
 
 	onLockFailed: function(reason) {
-		var alertMsg = _('The document could not be locked, and is opened in read-only mode.');
-		if (reason) {
-			alertMsg += _('\nServer returned this reason: "') + reason + '"';
+		if (this.options.canTryLock === undefined) {
+			// This is the initial notification. This status is not permanent.
+			// Allow to try to lock the file for edit again.
+			this.options.canTryLock = true;
+
+			var alertMsg = _('The document could not be locked, and is opened in read-only mode.');
+			if (reason) {
+				alertMsg += _('\nServer returned this reason: "') + reason + '"';
+			}
+			vex.dialog.alert({ message: alertMsg });
+
+			var button = $('#mobile-edit-button');
+			// TODO: modify the icon here
+			button.show();
+			button.off('click');
+
+			var that = this;
+			button.on('click', function () {
+				that._socket.sendMessage('attemptlock');
+			});
+		}
+		else if (this.options.canTryLock) {
+			// This is a failed response to an attempt to lock using mobile-edit-button
+			alertMsg = _('The document could not be locked.');
+			if (reason) {
+				alertMsg += _('\nServer returned this reason: "') + reason + '"';
+			}
+			vex.dialog.alert({ message: alertMsg });
 		}
+		// do nothing if this.options.canTryLock is defined and is false
+	},
 
-		vex.dialog.alert({ message: alertMsg });
-		this.options.canTryLock = true;
+	// from read-only to edit mode
+	_switchToEditMode: function () {
+		this.options.canTryLock = false; // don't respond to lockfailed anymore
+		$('#mobile-edit-button').hide();
+		this._enterEditMode('edit');
+		if (window.mode.isMobile() || window.mode.isTablet()) {
+			this.fire('editorgotfocus');
+			// In the iOS/android app, just clicking the mobile-edit-button is
+			// not reason enough to pop up the on-screen keyboard.
+			if (!(window.ThisIsTheiOSApp || window.ThisIsTheAndroidApp))
+				this.focus();
+		}
 	},
 
 	_enterEditMode: function (perm) {
diff --git a/wsd/ClientSession.cpp b/wsd/ClientSession.cpp
index 6536b08fd..c75a14a8d 100644
--- a/wsd/ClientSession.cpp
+++ b/wsd/ClientSession.cpp
@@ -736,6 +736,10 @@ bool ClientSession::_handleInput(const char *buffer, int length)
             return true;
         }
     }
+    else if (tokens.equals(0, "attemptlock"))
+    {
+        return attemptLock(docBroker);
+    }
     else
     {
         LOG_ERR("Session [" << getId() << "] got unknown command [" << tokens[0] << "].");
@@ -992,6 +996,24 @@ void ClientSession::setLockFailed(const std::string& sReason)
     sendTextFrame("lockfailed:" + sReason);
 }
 
+bool ClientSession::attemptLock(const std::shared_ptr<DocumentBroker>& docBroker)
+{
+    if (!isReadOnly())
+        return true;
+    // We are only allowed to change into edit mode if the read-only mode is because of failed lock
+    if (!_isLockFailed)
+        return false;
+
+    std::string failReason;
+    const bool bResult = docBroker->attemptLock(*this, failReason);
+    if (bResult)
+        setReadOnly(false);
+    else
+        sendTextFrame("lockfailed:" + failReason);
+
+    return bResult;
+}
+
 bool ClientSession::hasQueuedMessages() const
 {
     return _senderQueue.size() > 0;
diff --git a/wsd/ClientSession.hpp b/wsd/ClientSession.hpp
index ab3402935..9c9975c07 100644
--- a/wsd/ClientSession.hpp
+++ b/wsd/ClientSession.hpp
@@ -237,6 +237,9 @@ private:
 
     bool isTileInsideVisibleArea(const TileDesc& tile) const;
 
+    /// If this session is read-only because of failed lock, try to unlock and make it read-write.
+    bool attemptLock(const std::shared_ptr<DocumentBroker>& docBroker);
+
 private:
     std::weak_ptr<DocumentBroker> _docBroker;
 
diff --git a/wsd/DocumentBroker.cpp b/wsd/DocumentBroker.cpp
index 0de4f15f9..623f3418f 100644
--- a/wsd/DocumentBroker.cpp
+++ b/wsd/DocumentBroker.cpp
@@ -910,6 +910,15 @@ bool DocumentBroker::load(const std::shared_ptr<ClientSession>& session, const s
     return true;
 }
 
+bool DocumentBroker::attemptLock(const ClientSession& session, std::string& failReason)
+{
+    const bool bResult = _storage->updateLockState(session.getAuthorization(), session.getCookies(),
+                                                  *_lockCtx, true);
+    if (!bResult)
+        failReason = _lockCtx->_lockFailureReason;
+    return bResult;
+}
+
 bool DocumentBroker::saveToStorage(const std::string& sessionId,
                                    bool success, const std::string& result, bool force)
 {
diff --git a/wsd/DocumentBroker.hpp b/wsd/DocumentBroker.hpp
index 24835ceca..b8e176b3c 100644
--- a/wsd/DocumentBroker.hpp
+++ b/wsd/DocumentBroker.hpp
@@ -170,6 +170,9 @@ public:
     /// Notify that the load has completed
     virtual void setLoaded();
 
+    /// If not yet locked, try to lock
+    bool attemptLock(const ClientSession& session, std::string& failReason);
+
     bool isDocumentChangedInStorage() { return _documentChangedInStorage; }
 
     /// Save the document to Storage if it needs persisting.


More information about the Libreoffice-commits mailing list