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.kagan...@collabora.com>
AuthorDate: Tue Jul 14 22:19:14 2020 +0300
Commit:     Mike Kaganski <mike.kagan...@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 <jenkinscollaboraoff...@gmail.com>
    Tested-by: Jenkins
    Reviewed-by: Mike Kaganski <mike.kagan...@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.
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to