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@gmail.com>
Tested-by: Jenkins
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
This commit is contained in:
Mike Kaganski 2020-07-14 22:19:14 +03:00
parent 0c99f6830b
commit a1fafe27f4
6 changed files with 92 additions and 16 deletions

View file

@ -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 ""

View file

@ -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;
vex.dialog.alert({ message: alertMsg });
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
},
// 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) {

View file

@ -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;

View file

@ -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;

View file

@ -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)
{

View file

@ -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.