include/sfx2/docfile.hxx | 3 + include/sfx2/strings.hrc | 3 + sfx2/source/doc/docfile.cxx | 73 ++++++++++++++++++++++++++----------------- sfx2/source/view/viewfrm.cxx | 43 +++++++++++++++++++++---- 4 files changed, 86 insertions(+), 36 deletions(-)
New commits: commit 7943a3b4b7ab5891e0be61bcfedd7c55a1ef8bf4 Author: Mike Kaganski <mike.kagan...@collabora.com> AuthorDate: Fri Jul 5 17:56:38 2019 +1000 Commit: Mike Kaganski <mike.kagan...@collabora.com> CommitDate: Mon Jul 8 04:47:48 2019 +0200 Show who has locked the document when reopening a read-only document Pass the locking data from SfxMedium::LockOrigFileOnDemand, to allow clients to show it themselves when required. Change-Id: I6afe46a1896e1b60771c080efa2f58794dbed8a6 Reviewed-on: https://gerrit.libreoffice.org/75113 Tested-by: Jenkins Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com> Reviewed-on: https://gerrit.libreoffice.org/75137 Tested-by: Mike Kaganski <mike.kagan...@collabora.com> diff --git a/include/sfx2/docfile.hxx b/include/sfx2/docfile.hxx index 2f7d9454c1e5..482c1e4ba3ce 100644 --- a/include/sfx2/docfile.hxx +++ b/include/sfx2/docfile.hxx @@ -169,7 +169,8 @@ public: FailedLockFile, // there was only lock file that prevented success - no syslock or IO error Succeeded, }; - LockFileResult LockOrigFileOnDemand( bool bLoading, bool bNoUI, bool bTryIgnoreLockFile = false ); + LockFileResult LockOrigFileOnDemand(bool bLoading, bool bNoUI, bool bTryIgnoreLockFile = false, + LockFileEntry* pLockData = nullptr); void DisableUnlockWebDAV( bool bDisableUnlockWebDAV = true ); void UnlockFile( bool bReleaseLockStream ); /// Lets Transfer_Impl() not fsync the output file. diff --git a/include/sfx2/strings.hrc b/include/sfx2/strings.hrc index a77dbc86d77d..373ca649fa48 100644 --- a/include/sfx2/strings.hrc +++ b/include/sfx2/strings.hrc @@ -239,7 +239,8 @@ #define STR_ERROR_SEND_MAIL_CODE NC_("STR_ERROR_SEND_MAIL_CODE", "An error occurred in sending the message. Possible errors could be a missing user account or a defective setup.\n\nError code is $1") #define STR_ERROR_SEND_MAIL_HEADER NC_("STR_ERROR_SEND_MAIL_HEADER", "Error sending mail") #define STR_QUERY_OPENASTEMPLATE NC_("STR_QUERY_OPENASTEMPLATE", "This document cannot be edited, possibly due to missing access rights. Do you want to edit a copy of the document?") -#define STR_QUERY_OPENASTEMPLATE_ALLOW_IGNORE NC_("STR_QUERY_OPENASTEMPLATE_ALLOW_IGNORE", "This document cannot be edited, because it is locked in another session. Do you want to edit a copy of the document?\n\nYou can also try to ignore the lock and open the file for editing.") +#define STR_QUERY_OPENASTEMPLATE_LOCKED NC_("STR_QUERY_OPENASTEMPLATE_LOCKED", "This document cannot be edited, because it is locked in another session.%LOCKINFO\nDo you want to edit a copy of the document?") +#define STR_QUERY_OPENASTEMPLATE_ALLOW_IGNORE NC_("STR_QUERY_OPENASTEMPLATE_ALLOW_IGNORE", "You can also try to ignore the lock and open the file for editing.") #define STR_QUERY_OPENASTEMPLATE_OPENCOPY_BTN NC_("STR_QUERY_OPENASTEMPLATE_OPENCOPY_BTN", "Open ~Copy") #define STR_QUERY_OPENASTEMPLATE_OPEN_BTN NC_("STR_QUERY_OPENASTEMPLATE_OPEN_BTN", "~Open") #define STR_REPAIREDDOCUMENT NC_("STR_REPAIREDDOCUMENT", " (repaired document)") diff --git a/sfx2/source/doc/docfile.cxx b/sfx2/source/doc/docfile.cxx index bb153e5badb5..789f3b8b8dae 100644 --- a/sfx2/source/doc/docfile.cxx +++ b/sfx2/source/doc/docfile.cxx @@ -1117,7 +1117,9 @@ namespace // sets SID_DOC_READONLY if the document cannot be opened for editing // if user cancel the loading the ERROR_ABORT is set -SfxMedium::LockFileResult SfxMedium::LockOrigFileOnDemand( bool bLoading, bool bNoUI, bool bTryIgnoreLockFile ) +SfxMedium::LockFileResult SfxMedium::LockOrigFileOnDemand(bool bLoading, bool bNoUI, + bool bTryIgnoreLockFile, + LockFileEntry* pLockData) { #if !HAVE_FEATURE_MULTIUSER_ENVIRONMENT (void) bLoading; @@ -1168,37 +1170,47 @@ SfxMedium::LockFileResult SfxMedium::LockOrigFileOnDemand( bool bLoading, bool b catch ( ucb::InteractiveLockingLockedException& ) { // received when the resource is already locked - // get the lock owner, using a special ucb.webdav property - // the owner property retrieved here is what the other principal send the server - // when activating the lock. - // See http://tools.ietf.org/html/rfc4918#section-14.17 for details - LockFileEntry aLockData; - aLockData[LockFileComponent::OOOUSERNAME] = "Unknown user"; - // This solution works right when the LO user name and the WebDAV user - // name are the same. - // A better thing to do would be to obtain the 'real' WebDAV user name, - // but that's not possible from a WebDAV UCP provider client. - LockFileEntry aOwnData = svt::LockFileCommon::GenerateOwnEntry(); - // use the current LO user name as the system name - aLockData[LockFileComponent::SYSUSERNAME] = aOwnData[LockFileComponent::SYSUSERNAME]; - - uno::Sequence< css::ucb::Lock > aLocks; - // getting the property, send a PROPFIND to the server over the net - if( aContentToLock.getPropertyValue( "DAV:lockdiscovery" ) >>= aLocks ) + if (!bNoUI || pLockData) { - // got at least a lock, show the owner of the first lock returned - css::ucb::Lock aLock = aLocks[0]; - OUString aOwner; - if(aLock.Owner >>= aOwner) + // get the lock owner, using a special ucb.webdav property + // the owner property retrieved here is what the other principal send the server + // when activating the lock. + // See http://tools.ietf.org/html/rfc4918#section-14.17 for details + LockFileEntry aLockData; + aLockData[LockFileComponent::OOOUSERNAME] = "Unknown user"; + // This solution works right when the LO user name and the WebDAV user + // name are the same. + // A better thing to do would be to obtain the 'real' WebDAV user name, + // but that's not possible from a WebDAV UCP provider client. + LockFileEntry aOwnData = svt::LockFileCommon::GenerateOwnEntry(); + // use the current LO user name as the system name + aLockData[LockFileComponent::SYSUSERNAME] + = aOwnData[LockFileComponent::SYSUSERNAME]; + + uno::Sequence<css::ucb::Lock> aLocks; + // getting the property, send a PROPFIND to the server over the net + if (aContentToLock.getPropertyValue("DAV:lockdiscovery") >>= aLocks) { - // we need to display the WebDAV user name owning the lock, not the local one - aLockData[LockFileComponent::OOOUSERNAME] = aOwner; + // got at least a lock, show the owner of the first lock returned + css::ucb::Lock aLock = aLocks[0]; + OUString aOwner; + if (aLock.Owner >>= aOwner) + { + // we need to display the WebDAV user name owning the lock, not the local one + aLockData[LockFileComponent::OOOUSERNAME] = aOwner; + } } - } - if ( !bResult && !bNoUI ) - { - bUIStatus = ShowLockedDocumentDialog("", aLockData, bLoading, false , true ); + if (!bNoUI) + { + bUIStatus = ShowLockedDocumentDialog("", aLockData, bLoading, false, + true); + } + + if (pLockData) + { + std::copy(aLockData.begin(), aLockData.end(), pLockData->begin()); + } } } catch( ucb::InteractiveNetworkWriteException& ) @@ -1451,6 +1463,11 @@ SfxMedium::LockFileResult SfxMedium::LockOrigFileOnDemand( bool bLoading, bool b } else if (bLoading && !bHandleSysLocked) eResult = LockFileResult::FailedLockFile; + + if (!bResult && pLockData) + { + std::copy(aData.begin(), aData.end(), pLockData->begin()); + } } } } diff --git a/sfx2/source/view/viewfrm.cxx b/sfx2/source/view/viewfrm.cxx index 814a45f42b6f..42a4fa7ec3c7 100644 --- a/sfx2/source/view/viewfrm.cxx +++ b/sfx2/source/view/viewfrm.cxx @@ -182,9 +182,10 @@ class SfxQueryOpenAsTemplate private: std::unique_ptr<weld::MessageDialog> m_xQueryBox; public: - SfxQueryOpenAsTemplate(weld::Window* pParent, bool bAllowIgnoreLock) - : m_xQueryBox(Application::CreateMessageDialog(pParent, VclMessageType::Question, VclButtonsType::NONE, - SfxResId(bAllowIgnoreLock ? STR_QUERY_OPENASTEMPLATE_ALLOW_IGNORE : STR_QUERY_OPENASTEMPLATE))) + SfxQueryOpenAsTemplate(weld::Window* pParent, bool bAllowIgnoreLock, LockFileEntry& rLockData) + : m_xQueryBox(Application::CreateMessageDialog(pParent, VclMessageType::Question, + VclButtonsType::NONE, + QueryString(bAllowIgnoreLock, rLockData))) { m_xQueryBox->add_button(SfxResId(STR_QUERY_OPENASTEMPLATE_OPENCOPY_BTN), RET_YES); if (bAllowIgnoreLock) @@ -193,6 +194,32 @@ public: m_xQueryBox->set_default_response(RET_YES); } short run() { return m_xQueryBox->run(); } + +private: + static OUString QueryString(bool bAllowIgnoreLock, LockFileEntry& rLockData) + { + OUString sLockUserData; + if (!rLockData[LockFileComponent::OOOUSERNAME].isEmpty()) + sLockUserData = rLockData[LockFileComponent::OOOUSERNAME]; + else + sLockUserData = rLockData[LockFileComponent::SYSUSERNAME]; + + if (!sLockUserData.isEmpty() && !rLockData[LockFileComponent::EDITTIME].isEmpty()) + sLockUserData += " ( " + rLockData[LockFileComponent::EDITTIME] + " )"; + + if (!sLockUserData.isEmpty()) + sLockUserData = "\n\n" + sLockUserData + "\n"; + + const bool bUseLockStr = bAllowIgnoreLock || !sLockUserData.isEmpty(); + + OUString sMsg( + SfxResId(bUseLockStr ? STR_QUERY_OPENASTEMPLATE_LOCKED : STR_QUERY_OPENASTEMPLATE)); + + if (bAllowIgnoreLock) + sMsg += "\n\n" + SfxResId(STR_QUERY_OPENASTEMPLATE_ALLOW_IGNORE); + + return sMsg.replaceFirst("%LOCKINFO", sLockUserData); + } }; /// Is this read-only object shell opened via .uno:SignPDF? @@ -433,6 +460,7 @@ void SfxViewFrame::ExecReload_Impl( SfxRequest& rReq ) bool bRetryIgnoringLock = false; bool bOpenTemplate = false; do { + LockFileEntry aLockData; if ( !pVersionItem ) { if (bRetryIgnoringLock) @@ -454,8 +482,10 @@ void SfxViewFrame::ExecReload_Impl( SfxRequest& rReq ) pMed->CompleteReOpen(); if ( nOpenMode & StreamMode::WRITE ) { - auto eResult = pMed->LockOrigFileOnDemand( true, true, bRetryIgnoringLock ); - bRetryIgnoringLock = eResult == SfxMedium::LockFileResult::FailedLockFile; + auto eResult = pMed->LockOrigFileOnDemand( + true, true, bRetryIgnoringLock, &aLockData); + bRetryIgnoringLock + = eResult == SfxMedium::LockFileResult::FailedLockFile; } // LockOrigFileOnDemand might set the readonly flag itself, it should be set back @@ -470,7 +500,8 @@ void SfxViewFrame::ExecReload_Impl( SfxRequest& rReq ) if (nOpenMode == SFX_STREAM_READWRITE && !rReq.IsAPI()) { // css::sdbcx::User offering to open it as a template - SfxQueryOpenAsTemplate aBox(GetWindow().GetFrameWeld(), bRetryIgnoringLock); + SfxQueryOpenAsTemplate aBox(GetWindow().GetFrameWeld(), + bRetryIgnoringLock, aLockData); short nUserAnswer = aBox.run(); bOpenTemplate = RET_YES == nUserAnswer; _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits