include/sfx2/docfile.hxx | 3 + include/sfx2/strings.hrc | 3 + sfx2/source/doc/docfile.cxx | 74 ++++++++++++++++++++++++++----------------- sfx2/source/view/viewfrm.cxx | 43 +++++++++++++++++++++--- 4 files changed, 86 insertions(+), 37 deletions(-)
New commits: commit 0f9599b687c10f3887c8cc5f419278aa4375889a Author: Mike Kaganski <mike.kagan...@collabora.com> AuthorDate: Fri Jul 5 17:56:38 2019 +1000 Commit: Mike Kaganski <mike.kagan...@collabora.com> CommitDate: Fri Jul 5 11:51:56 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> diff --git a/include/sfx2/docfile.hxx b/include/sfx2/docfile.hxx index 77950a473197..c5fc22c511bb 100644 --- a/include/sfx2/docfile.hxx +++ b/include/sfx2/docfile.hxx @@ -166,7 +166,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 98e547d2b515..96883a2384b0 100644 --- a/include/sfx2/strings.hrc +++ b/include/sfx2/strings.hrc @@ -238,7 +238,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 da295c476991..efb874b67f2a 100644 --- a/sfx2/source/doc/docfile.cxx +++ b/sfx2/source/doc/docfile.cxx @@ -1128,7 +1128,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; @@ -1183,38 +1185,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& ) @@ -1467,6 +1478,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 ed8ffa200ef6..e26587be9cb4 100644 --- a/sfx2/source/view/viewfrm.cxx +++ b/sfx2/source/view/viewfrm.cxx @@ -183,9 +183,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) @@ -194,6 +195,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? @@ -434,6 +461,7 @@ void SfxViewFrame::ExecReload_Impl( SfxRequest& rReq ) bool bRetryIgnoringLock = false; bool bOpenTemplate = false; do { + LockFileEntry aLockData; if ( !pVersionItem ) { if (bRetryIgnoringLock) @@ -455,8 +483,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 @@ -471,7 +501,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