include/sfx2/docfile.hxx | 17 + include/svl/documentlockfile.hxx | 3 l10ntools/source/gRun.sh | 2 offapi/UnoApi_offapi.mk | 1 offapi/com/sun/star/document/LockFileCorruptRequest.idl | 43 +++ oox/source/export/shapes.cxx | 2 sd/qa/unit/data/odp/group_rotation.odp |binary sd/qa/unit/export-tests-ooxml2.cxx | 15 + sfx2/source/doc/docfile.cxx | 205 ++++++++++----- sfx2/source/doc/new.cxx | 2 sfx2/source/doc/objcont.cxx | 2 sfx2/source/view/view.hrc | 7 sfx2/source/view/view.src | 12 sfx2/source/view/viewfrm.cxx | 133 +++++++-- svl/source/misc/documentlockfile.cxx | 7 sw/qa/extras/ooxmlimport/data/tdf114217.docx |binary sw/qa/extras/ooxmlimport/ooxmlimport.cxx | 8 uui/AllLangResTarget_uui.mk | 1 uui/Library_uui.mk | 1 uui/source/iahndl-locking.cxx | 55 +++- uui/source/iahndl.cxx | 11 uui/source/iahndl.hxx | 2 uui/source/ids.hrc | 66 ++-- uui/source/lockcorrupt.cxx | 44 +++ uui/source/lockcorrupt.hxx | 33 ++ uui/source/lockcorrupt.src | 37 ++ uui/source/lockfailed.cxx | 5 uui/source/lockfailed.src | 6 uui/source/openlocked.cxx | 22 - uui/source/openlocked.hxx | 2 uui/source/openlocked.src | 6 writerfilter/source/dmapper/DomainMapperTableHandler.cxx | 5 writerfilter/source/dmapper/DomainMapper_Impl.hxx | 6 writerfilter/source/dmapper/PropertyMap.cxx | 5 34 files changed, 588 insertions(+), 178 deletions(-)
New commits: commit 999df3e27d6ab582a67bd7c47a6e4ebb123bdcf3 Author: Paul Trojahn <paul.troj...@gmail.com> Date: Sat Sep 23 15:17:13 2017 +0200 PPTX Fix export of rotated group shapes The rotation is already applied to the child shapes and must not be added to the group. Reviewed-on: https://gerrit.libreoffice.org/42765 Tested-by: Jenkins <c...@libreoffice.org> Reviewed-by: Tamás Zolnai <tamas.zol...@collabora.com> (cherry picked from commit 465092047d5fa6ec6dd369372e712d76554570ff) Change-Id: Ic564cbcf31a81a248878f0179fdd21144f076b61 (cherry picked from commit b24c5ad7997de08b9da0c928f87df922b9f9797d) diff --git a/oox/source/export/shapes.cxx b/oox/source/export/shapes.cxx index 871873c968b1..05502d693722 100644 --- a/oox/source/export/shapes.cxx +++ b/oox/source/export/shapes.cxx @@ -525,7 +525,7 @@ ShapeExport& ShapeExport::WriteGroupShape(const uno::Reference<drawing::XShape>& // visual properties pFS->startElementNS(mnXmlNamespace, XML_grpSpPr, FSEND); - WriteShapeTransformation(xShape, XML_a); + WriteShapeTransformation(xShape, XML_a, false, false, true); pFS->endElementNS(mnXmlNamespace, XML_grpSpPr); uno::Reference<drawing::XShapes> xGroupShape(xShape, uno::UNO_QUERY_THROW); diff --git a/sd/qa/unit/data/odp/group_rotation.odp b/sd/qa/unit/data/odp/group_rotation.odp new file mode 100644 index 000000000000..92568c1500d9 Binary files /dev/null and b/sd/qa/unit/data/odp/group_rotation.odp differ diff --git a/sd/qa/unit/export-tests-ooxml2.cxx b/sd/qa/unit/export-tests-ooxml2.cxx index 38bf2980746a..3d1ad4f28b78 100644 --- a/sd/qa/unit/export-tests-ooxml2.cxx +++ b/sd/qa/unit/export-tests-ooxml2.cxx @@ -118,6 +118,7 @@ public: void testTdf112334(); void testTdf112647(); void testTdf112086(); + void testGroupRotation(); void testTdf104788(); void testSmartartRotation2(); void testGroupsPosition(); @@ -163,6 +164,7 @@ public: CPPUNIT_TEST(testTdf112334); CPPUNIT_TEST(testTdf112647); CPPUNIT_TEST(testTdf112086); + CPPUNIT_TEST(testGroupRotation); CPPUNIT_TEST(testTdf104788); CPPUNIT_TEST(testSmartartRotation2); CPPUNIT_TEST(testGroupsPosition); @@ -1115,6 +1117,19 @@ void SdOOXMLExportTest2::testTdf114848() assertXPath(pXmlDocTheme2, "/a:theme/a:themeElements/a:clrScheme/a:dk2/a:srgbClr", "val", "1f497d"); } +void SdOOXMLExportTest2::testGroupRotation() +{ + ::sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/odp/group_rotation.odp"), ODP); + utl::TempFile tempFile; + xDocShRef = saveAndReload(xDocShRef.get(), PPTX, &tempFile); + xDocShRef->DoClose(); + + xmlDocPtr pXmlDocContent = parseExport(tempFile, "ppt/slides/slide1.xml"); + assertXPathNoAttribute(pXmlDocContent, "/p:sld/p:cSld/p:spTree/p:grpSp/p:grpSpPr/a:xfrm", "rot"); + assertXPath(pXmlDocContent, "/p:sld/p:cSld/p:spTree/p:grpSp/p:sp[1]/p:spPr/a:xfrm", "rot", "20400000"); + assertXPath(pXmlDocContent, "/p:sld/p:cSld/p:spTree/p:grpSp/p:sp[2]/p:spPr/a:xfrm", "rot", "20400000"); +} + CPPUNIT_TEST_SUITE_REGISTRATION(SdOOXMLExportTest2); CPPUNIT_PLUGIN_IMPLEMENT(); commit 804c52e5e4412880639d816a688f284afd85cfcf Author: Stephan Bergmann <sberg...@redhat.com> Date: Fri Jan 27 15:46:47 2017 +0100 -Werror=int-in-bool-context (GCC 7) Change-Id: I69f31a94f3e57b3488c576f8d8e0569f459a2117 (cherry picked from commit c65d6e9e5dc4f7d13be582bfb5206caeb7b51ba4) (cherry picked from commit c82ef1dadaa3571524eaf5c474d745ce24ba5803) diff --git a/sfx2/source/doc/new.cxx b/sfx2/source/doc/new.cxx index 0a7f60b219e0..667e002e5bb1 100644 --- a/sfx2/source/doc/new.cxx +++ b/sfx2/source/doc/new.cxx @@ -73,7 +73,7 @@ void SfxPreviewWin_Impl::ImpPaint(vcl::RenderContext& rRenderContext, const Rect rRenderContext.DrawRect(Rectangle(Point(0,0), rRenderContext.GetOutputSize())); Size aTmpSize = pFile ? pFile->GetPrefSize() : Size(1, 1); - DBG_ASSERT(aTmpSize.Height() * aTmpSize.Width(), "size of first page is 0, override GetFirstPageSize or set vis-area!"); + DBG_ASSERT(aTmpSize.Height() != 0 && aTmpSize.Width() != 0, "size of first page is 0, override GetFirstPageSize or set vis-area!"); #define FRAME 4 diff --git a/sfx2/source/doc/objcont.cxx b/sfx2/source/doc/objcont.cxx index fc25b5f9ae65..890a87a4d752 100644 --- a/sfx2/source/doc/objcont.cxx +++ b/sfx2/source/doc/objcont.cxx @@ -151,7 +151,7 @@ SfxObjectShell::CreatePreviewMetaFile_Impl( bool bFullContent ) const } xFile->SetPrefSize( aTmpSize ); - DBG_ASSERT( aTmpSize.Height()*aTmpSize.Width(), + DBG_ASSERT( aTmpSize.Height() != 0 && aTmpSize.Width() != 0, "size of first page is 0, override GetFirstPageSize or set vis-area!" ); xFile->Record( pDevice ); commit 04901aeeb521aa576a741a89f080f6ac76acf071 Author: Mike Kaganski <mike.kagan...@collabora.com> Date: Thu Feb 8 18:06:06 2018 +0300 tdf#108210: Allow to ignore a lock file if there's no filesystem lock Two cases are handled: when a file is being opened, and when it was opened read-only already, and one tries to reopen it in edit mode. The option to ignore locking and open the file anyway is only offered when there is no filesystem lock present on the file. Change-Id: I377d3cae4c949ae64d449634acea8fb3f68a5700 Reviewed-on: https://gerrit.libreoffice.org/49448 Tested-by: Jenkins <c...@libreoffice.org> Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com> Reviewed-on: https://gerrit.libreoffice.org/49470 Reviewed-by: Aron Budea <aron.bu...@collabora.com> Tested-by: Aron Budea <aron.bu...@collabora.com> (cherry picked from commit e189dd061bb0817e1f9e872c9b8dc82b72bfffc5) diff --git a/include/sfx2/docfile.hxx b/include/sfx2/docfile.hxx index 8710498c7808..02beb2138e38 100644 --- a/include/sfx2/docfile.hxx +++ b/include/sfx2/docfile.hxx @@ -163,11 +163,13 @@ public: bool Commit(); bool IsStorage(); - enum class ShowLockResult { NoLock, Succeeded,Try }; - ShowLockResult ShowLockedDocumentDialog( const LockFileEntry& aData, bool bIsLoading, bool bOwnLock, bool bHandleSysLocked); - void LockOrigFileOnDemand( bool bLoading, bool bNoUI ); - enum class MessageDlg { LockFileIgnore, LockFileCorrupt }; - bool ShowLockFileProblemDialog(MessageDlg nWhichDlg); + enum class LockFileResult + { + Failed, + FailedLockFile, // there was only lock file that prevented success - no syslock or IO error + Succeeded, + }; + LockFileResult LockOrigFileOnDemand( bool bLoading, bool bNoUI, bool bTryIgnoreLockFile = false ); void DisableUnlockWebDAV( bool bDisableUnlockWebDAV = true ); void UnlockFile( bool bReleaseLockStream ); @@ -273,6 +275,13 @@ public: static bool SetWritableForUserOnly( const OUString& aURL ); static sal_uInt32 CreatePasswordToModifyHash( const OUString& aPasswd, bool bWriter ); + +private: + enum class ShowLockResult { NoLock, Succeeded, Try }; + ShowLockResult ShowLockedDocumentDialog(const LockFileEntry& aData, bool bIsLoading, bool bOwnLock, bool bHandleSysLocked); + enum class MessageDlg { LockFileIgnore, LockFileCorrupt }; + bool ShowLockFileProblemDialog(MessageDlg nWhichDlg); + }; #endif diff --git a/sfx2/source/doc/docfile.cxx b/sfx2/source/doc/docfile.cxx index b1ce8b84655b..a7b8af14c13a 100644 --- a/sfx2/source/doc/docfile.cxx +++ b/sfx2/source/doc/docfile.cxx @@ -864,6 +864,8 @@ SfxMedium::ShowLockResult SfxMedium::ShowLockedDocumentDialog( const LockFileEnt OUString aInfo; ::rtl::Reference< ::ucbhelper::InteractionRequest > xInteractionRequestImpl; + sal_Int32 nContinuations = 3; + if ( bOwnLock ) { aInfo = aData[LockFileComponent::EDITTIME]; @@ -887,12 +889,23 @@ SfxMedium::ShowLockResult SfxMedium::ShowLockedDocumentDialog( const LockFileEnt xInteractionRequestImpl = new ::ucbhelper::InteractionRequest( uno::makeAny( document::LockedDocumentRequest( OUString(), uno::Reference< uno::XInterface >(), aDocumentURL, aInfo ) ) ); + + // Use a fourth continuation in case there's no filesystem lock: + // "Ignore lock file and open the document" + if (!bHandleSysLocked) + nContinuations = 4; } - uno::Sequence< uno::Reference< task::XInteractionContinuation > > aContinuations( 3 ); + uno::Sequence< uno::Reference< task::XInteractionContinuation > > aContinuations(nContinuations); aContinuations[0] = new ::ucbhelper::InteractionAbort( xInteractionRequestImpl.get() ); aContinuations[1] = new ::ucbhelper::InteractionApprove( xInteractionRequestImpl.get() ); aContinuations[2] = new ::ucbhelper::InteractionDisapprove( xInteractionRequestImpl.get() ); + if (nContinuations > 3) + { + // We use InteractionRetry to reflect that user wants to + // ignore the (stale?) alien lock file and open the document + aContinuations[3] = new ::ucbhelper::InteractionRetry(xInteractionRequestImpl.get()); + } xInteractionRequestImpl->setContinuations( aContinuations ); xHandler->handle( xInteractionRequestImpl.get() ); @@ -908,14 +921,19 @@ SfxMedium::ShowLockResult SfxMedium::ShowLockedDocumentDialog( const LockFileEnt // own lock on saving, user has selected to ignore the lock // alien lock on loading, user has selected to edit a copy of document // TODO/LATER: alien lock on saving, user has selected to do SaveAs to different location - if ( bIsLoading && !bOwnLock ) + if ( !bOwnLock ) // bIsLoading implied from outermost condition { // means that a copy of the document should be opened GetItemSet()->Put( SfxBoolItem( SID_TEMPLATE, true ) ); } - else if ( bOwnLock ) + else nResult = ShowLockResult::Succeeded; } + else if (uno::Reference< task::XInteractionRetry >(xSelected.get(), uno::UNO_QUERY).is()) + { + // User decided to ignore the alien (stale?) lock file without filesystem lock + nResult = ShowLockResult::Succeeded; + } else // if ( XSelected == aContinuations[1] ) { // own lock on loading, user has selected to open readonly @@ -1010,12 +1028,16 @@ namespace // sets SID_DOC_READONLY if the document cannot be opened for editing // if user cancel the loading the ERROR_ABORT is set -void SfxMedium::LockOrigFileOnDemand( bool bLoading, bool bNoUI ) +SfxMedium::LockFileResult SfxMedium::LockOrigFileOnDemand( bool bLoading, bool bNoUI, bool bTryIgnoreLockFile ) { #if !HAVE_FEATURE_MULTIUSER_ENVIRONMENT (void) bLoading; (void) bNoUI; + (void) bTryIgnoreLockFile; + return LockFileResult::Succeeded; #else + LockFileResult eResult = LockFileResult::Failed; + // check if path scheme is http:// or https:// // may be this is better if used always, in Android and iOS as well? // if this code should be always there, remember to move the relevant code in UnlockFile method as well ! @@ -1086,7 +1108,7 @@ void SfxMedium::LockOrigFileOnDemand( bool bLoading, bool bNoUI ) if ( !bResult && !bNoUI ) { - bUIStatus = ShowLockedDocumentDialog( aLockData, bLoading, false , false ); + bUIStatus = ShowLockedDocumentDialog( aLockData, bLoading, false , true ); } } catch( ucb::InteractiveNetworkWriteException& ) @@ -1125,23 +1147,28 @@ void SfxMedium::LockOrigFileOnDemand( bool bLoading, bool bNoUI ) // when the file is locked, get the current file date if ( bResult && DocNeedsFileDateCheck() ) GetInitFileDate( true ); + + if ( bResult ) + eResult = LockFileResult::Succeeded; } catch ( const uno::Exception& ) { SAL_WARN( "sfx.doc", "Locking exception: WebDAV while trying to lock the file" ); } - return; + return eResult; } - if (!IsLockingUsed() || GetURLObject().HasError()) - return; + if (!IsLockingUsed()) + return LockFileResult::Succeeded; + if (GetURLObject().HasError()) + return eResult; try { if ( pImpl->m_bLocked && bLoading && GetURLObject().GetProtocol() == INetProtocol::File ) { - // if the document is already locked the system locking might be temporarely off after storing + // if the document is already locked the system locking might be temporarily off after storing // check whether the system file locking should be taken again GetLockingStream_Impl(); } @@ -1209,7 +1236,7 @@ void SfxMedium::LockOrigFileOnDemand( bool bLoading, bool bNoUI ) // let the stream be opened to check the system file locking GetMedium_Impl(); if (GetError() != ERRCODE_NONE) { - return; + return eResult; } } @@ -1235,15 +1262,6 @@ void SfxMedium::LockOrigFileOnDemand( bool bLoading, bool bNoUI ) { bResult = aLockFile.CreateOwnLockFile(); } - catch (const ucb::InteractiveIOException&) - { - if (bLoading && !bNoUI) - { - bIoErr = true; - ShowLockFileProblemDialog(MessageDlg::LockFileIgnore); - bResult = true; // always delete the defect lock-file - } - } catch (const uno::Exception&) { if (bLoading && !bNoUI) @@ -1303,14 +1321,20 @@ void SfxMedium::LockOrigFileOnDemand( bool bLoading, bool bNoUI ) } } - if ( !bResult && !bNoUI && !bIoErr) + if ( !bResult && !bIoErr) { - bUIStatus = ShowLockedDocumentDialog( aData, bLoading, bOwnLock, bHandleSysLocked ); + if (!bNoUI) + bUIStatus = ShowLockedDocumentDialog(aData, bLoading, bOwnLock, bHandleSysLocked); + else if (bLoading && bTryIgnoreLockFile && !bHandleSysLocked) + bUIStatus = ShowLockResult::Succeeded; + if ( bUIStatus == ShowLockResult::Succeeded ) { // take the ownership over the lock file bResult = aLockFile.OverwriteOwnLockFile(); } + else if (bLoading && !bHandleSysLocked) + eResult = LockFileResult::FailedLockFile; } } } @@ -1344,11 +1368,16 @@ void SfxMedium::LockOrigFileOnDemand( bool bLoading, bool bNoUI ) // when the file is locked, get the current file date if ( bResult && DocNeedsFileDateCheck() ) GetInitFileDate( true ); + + if ( bResult ) + eResult = LockFileResult::Succeeded; } catch( const uno::Exception& ) { SAL_WARN( "sfx.doc", "Locking exception: high probability, that the content has not been created" ); } + + return eResult; #endif } diff --git a/sfx2/source/view/view.hrc b/sfx2/source/view/view.hrc index 548c43592561..af4c02fe59f1 100644 --- a/sfx2/source/view/view.hrc +++ b/sfx2/source/view/view.hrc @@ -35,8 +35,11 @@ #define STR_ERROR_SAVE_TEMPLATE (RID_SFX_VIEW_START+33) -#define STR_QUERY_OPENASTEMPLATE (RID_SFX_VIEW_START+41) -#define STR_CANT_CLOSE (RID_SFX_VIEW_START+42) +#define STR_QUERY_OPENASTEMPLATE (RID_SFX_VIEW_START+41) +#define STR_QUERY_OPENASTEMPLATE_ALLOW_IGNORE (RID_SFX_VIEW_START+42) +#define STR_QUERY_OPENASTEMPLATE_OPENCOPY_BTN (RID_SFX_VIEW_START+43) +#define STR_QUERY_OPENASTEMPLATE_OPEN_BTN (RID_SFX_VIEW_START+44) +#define STR_CANT_CLOSE (RID_SFX_VIEW_START+45) #endif diff --git a/sfx2/source/view/view.src b/sfx2/source/view/view.src index 0826609e5339..47caed97e475 100644 --- a/sfx2/source/view/view.src +++ b/sfx2/source/view/view.src @@ -77,6 +77,18 @@ String STR_QUERY_OPENASTEMPLATE { Text [ en-US ] = "This document cannot be edited, possibly due to missing access rights. Do you want to edit a copy of the document?" ; }; +String STR_QUERY_OPENASTEMPLATE_ALLOW_IGNORE +{ + Text [ en-US ] = "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." ; +}; +String STR_QUERY_OPENASTEMPLATE_OPENCOPY_BTN +{ + Text [ en-US ] = "Open ~Copy" ; +}; +String STR_QUERY_OPENASTEMPLATE_OPEN_BTN +{ + Text [ en-US ] = "~Open" ; +}; String STR_REPAIREDDOCUMENT { Text [ en-US ] = " (repaired document)" ; diff --git a/sfx2/source/view/viewfrm.cxx b/sfx2/source/view/viewfrm.cxx index 840ba418e3e7..8d0fb19f3faf 100644 --- a/sfx2/source/view/viewfrm.cxx +++ b/sfx2/source/view/viewfrm.cxx @@ -137,6 +137,7 @@ using ::com::sun::star::container::XIndexContainer; #include <sfx2/minfitem.hxx> #include "../appl/app.hrc" #include "impviewframe.hxx" +#include <vcl/msgbox.hxx> #define SfxViewFrame #include "sfxslots.hxx" @@ -154,6 +155,7 @@ void SfxViewFrame::InitInterface_Impl() #endif } +namespace { /// Asks the user if editing a read-only document is really wanted. class SfxEditDocumentDialog : public MessageDialog { @@ -186,8 +188,31 @@ void SfxEditDocumentDialog::dispose() MessageDialog::dispose(); } +class SfxQueryOpenAsTemplate : public QueryBox +{ +public: + SfxQueryOpenAsTemplate(vcl::Window* pParent, WinBits nStyle, bool bAllowIgnoreLock); +}; + +SfxQueryOpenAsTemplate::SfxQueryOpenAsTemplate(vcl::Window* pParent, WinBits nStyle, bool bAllowIgnoreLock) + : QueryBox(pParent, nStyle, SfxResId(bAllowIgnoreLock ? STR_QUERY_OPENASTEMPLATE_ALLOW_IGNORE : STR_QUERY_OPENASTEMPLATE)) +{ + AddButton(SfxResId(STR_QUERY_OPENASTEMPLATE_OPENCOPY_BTN), RET_YES, + ButtonDialogFlags::Default | ButtonDialogFlags::OK | ButtonDialogFlags::Focus); + SetButtonHelpText(RET_YES, OUString()); + + if (bAllowIgnoreLock) + { + AddButton(SfxResId(STR_QUERY_OPENASTEMPLATE_OPEN_BTN), RET_IGNORE); + SetButtonHelpText(RET_IGNORE, OUString()); + } + + AddButton(StandardButtonType::Cancel, RET_CANCEL); + SetButtonHelpText(RET_CANCEL, OUString()); +} + /// Is this read-only object shell opened via .uno:SignPDF? -static bool IsSignPDF(SfxObjectShellRef xObjSh) +bool IsSignPDF(SfxObjectShellRef xObjSh) { if (!xObjSh.Is()) return false; @@ -203,7 +228,7 @@ static bool IsSignPDF(SfxObjectShellRef xObjSh) return false; } -static bool AskPasswordToModify_Impl( const uno::Reference< task::XInteractionHandler >& xHandler, const OUString& aPath, const std::shared_ptr<const SfxFilter>& pFilter, sal_uInt32 nPasswordHash, const uno::Sequence< beans::PropertyValue >& aInfo ) +bool AskPasswordToModify_Impl( const uno::Reference< task::XInteractionHandler >& xHandler, const OUString& aPath, const std::shared_ptr<const SfxFilter>& pFilter, sal_uInt32 nPasswordHash, const uno::Sequence< beans::PropertyValue >& aInfo ) { // TODO/LATER: In future the info should replace the direct hash completely bool bResult = ( !nPasswordHash && !aInfo.getLength() ); @@ -251,6 +276,7 @@ static bool AskPasswordToModify_Impl( const uno::Reference< task::XInteractionHa return bResult; } +} void SfxViewFrame::ExecReload_Impl( SfxRequest& rReq ) { @@ -283,6 +309,23 @@ void SfxViewFrame::ExecReload_Impl( SfxRequest& rReq ) if( !pSh || !pSh->HasName() || !(pSh->Get_Impl()->nLoadedFlags & SfxLoadedFlags::MAINDOCUMENT )) break; + // Only change read-only UI and remove info bar when we succeed + struct ReadOnlyUIGuard + { + SfxViewFrame* m_pFrame; + SfxObjectShell* m_pSh; + bool m_bSetRO; + ~ReadOnlyUIGuard() + { + if (m_bSetRO != m_pSh->IsReadOnlyUI()) + { + m_pSh->SetReadOnlyUI(m_bSetRO); + if (!m_bSetRO) + m_pFrame->RemoveInfoBar("readonly"); + } + } + } aReadOnlyUIGuard{ this, pSh, pSh->IsReadOnlyUI() }; + SfxMedium* pMed = pSh->GetMedium(); const SfxBoolItem* pItem = SfxItemSet::GetItem<SfxBoolItem>(pSh->GetMedium()->GetItemSet(), SID_VIEWONLY, false); @@ -332,7 +375,7 @@ void SfxViewFrame::ExecReload_Impl( SfxRequest& rReq ) } } nOpenMode = SFX_STREAM_READONLY; - pSh->SetReadOnlyUI(); + aReadOnlyUIGuard.m_bSetRO = true; } else { @@ -352,10 +395,8 @@ void SfxViewFrame::ExecReload_Impl( SfxRequest& rReq ) pSh->SetModifyPasswordEntered(); } - // Remove infobar if document was read-only (after password check) - RemoveInfoBar("readonly"); - nOpenMode = pSh->IsOriginallyReadOnlyMedium() ? SFX_STREAM_READONLY : SFX_STREAM_READWRITE; + aReadOnlyUIGuard.m_bSetRO = false; // if only the view was in the readonly mode then there is no need to do the reload if ( !pSh->IsReadOnlyMedium() ) @@ -364,12 +405,8 @@ void SfxViewFrame::ExecReload_Impl( SfxRequest& rReq ) // open mode among other things, so call SetOpenMode before // SetReadOnlyUI: pMed->SetOpenMode( nOpenMode ); - pSh->SetReadOnlyUI( false ); return; } - - - pSh->SetReadOnlyUI( false ); } if ( rReq.IsAPI() ) @@ -416,31 +453,58 @@ void SfxViewFrame::ExecReload_Impl( SfxRequest& rReq ) // <- tdf#82744 { bool bOK = false; - if ( !pVersionItem ) - { - bool bHasStorage = pMed->HasStorage_Impl(); - // switching edit mode could be possible without reload - if ( bHasStorage && pMed->GetStorage() == pSh->GetStorage() ) + bool bRetryIgnoringLock = false; + bool bOpenTemplate = false; + do { + if ( !pVersionItem ) { - // TODO/LATER: faster creation of copy - if ( !pSh->ConnectTmpStorage_Impl( pMed->GetStorage(), pMed ) ) - return; - } + if (bRetryIgnoringLock) + pMed->ResetError(); - pMed->CloseAndRelease(); - pMed->GetItemSet()->Put( SfxBoolItem( SID_DOC_READONLY, !( nOpenMode & StreamMode::WRITE ) ) ); - pMed->SetOpenMode( nOpenMode ); + bool bHasStorage = pMed->HasStorage_Impl(); + // switching edit mode could be possible without reload + if ( bHasStorage && pMed->GetStorage() == pSh->GetStorage() ) + { + // TODO/LATER: faster creation of copy + if ( !pSh->ConnectTmpStorage_Impl( pMed->GetStorage(), pMed ) ) + return; + } + + pMed->CloseAndRelease(); + pMed->GetItemSet()->Put( SfxBoolItem( SID_DOC_READONLY, !( nOpenMode & StreamMode::WRITE ) ) ); + pMed->SetOpenMode( nOpenMode ); + + pMed->CompleteReOpen(); + if ( nOpenMode & StreamMode::WRITE ) + { + auto eResult = pMed->LockOrigFileOnDemand( true, true, bRetryIgnoringLock ); + bRetryIgnoringLock = eResult == SfxMedium::LockFileResult::FailedLockFile; + } + + // LockOrigFileOnDemand might set the readonly flag itself, it should be set back + pMed->GetItemSet()->Put( SfxBoolItem( SID_DOC_READONLY, !( nOpenMode & StreamMode::WRITE ) ) ); - pMed->CompleteReOpen(); - if ( nOpenMode & StreamMode::WRITE ) - pMed->LockOrigFileOnDemand( false, true ); + if ( !pMed->GetErrorCode() ) + bOK = true; + } - // LockOrigFileOnDemand might set the readonly flag itself, it should be set back - pMed->GetItemSet()->Put( SfxBoolItem( SID_DOC_READONLY, !( nOpenMode & StreamMode::WRITE ) ) ); + if( !bOK ) + { + if (nOpenMode == SFX_STREAM_READWRITE && !rReq.IsAPI()) + { + // css::sdbcx::User offering to open it as a template + ScopedVclPtrInstance<SfxQueryOpenAsTemplate> aBox(&GetWindow(), 0, bRetryIgnoringLock); - if ( !pMed->GetErrorCode() ) - bOK = true; + short nUserAnswer = aBox->Execute(); + bOpenTemplate = RET_YES == nUserAnswer; + // Always reset this here to avoid infinite loop + bRetryIgnoringLock = RET_IGNORE == nUserAnswer; + } + else + bRetryIgnoringLock = false; + } } + while ( !bOK && bRetryIgnoringLock ); if( !bOK ) { @@ -460,10 +524,7 @@ void SfxViewFrame::ExecReload_Impl( SfxRequest& rReq ) if ( nOpenMode == SFX_STREAM_READWRITE && !rReq.IsAPI() ) { - // css::sdbcx::User offering to open it as a template - ScopedVclPtrInstance<MessageDialog> aBox(&GetWindow(), SfxResId(STR_QUERY_OPENASTEMPLATE), - VclMessageType::Question, VCL_BUTTONS_YES_NO); - if ( RET_YES == aBox->Execute() ) + if ( bOpenTemplate ) { SfxApplication* pApp = SfxGetpApp(); SfxAllItemSet aSet( pApp->GetPool() ); @@ -486,10 +547,12 @@ void SfxViewFrame::ExecReload_Impl( SfxRequest& rReq ) GetDispatcher()->Execute( SID_OPENDOC, SfxCallMode::ASYNCHRON, aSet ); return; } - else - nErr = 0; + nErr = 0; } + // Keep the read-only UI + aReadOnlyUIGuard.m_bSetRO = true; + ErrorHandler::HandleError( nErr ); rReq.SetReturnValue( SfxBoolItem( rReq.GetSlot(), false ) ); diff --git a/uui/source/iahndl-locking.cxx b/uui/source/iahndl-locking.cxx index 48312637bb21..d1c00706d769 100644 --- a/uui/source/iahndl-locking.cxx +++ b/uui/source/iahndl-locking.cxx @@ -29,6 +29,7 @@ #include <com/sun/star/task/XInteractionDisapprove.hpp> #include <com/sun/star/task/XInteractionAbort.hpp> #include <com/sun/star/task/XInteractionRequest.hpp> +#include <com/sun/star/task/XInteractionRetry.hpp> #include <osl/mutex.hxx> #include <vcl/svapp.hxx> @@ -68,7 +69,9 @@ handleLockedDocumentRequest_( uno::Reference< task::XInteractionApprove > xApprove; uno::Reference< task::XInteractionDisapprove > xDisapprove; uno::Reference< task::XInteractionAbort > xAbort; - getContinuations(rContinuations, &xApprove, &xDisapprove, &xAbort); + // In case an option to ignore lock and open the file is available + uno::Reference< task::XInteractionRetry > xRetry; + getContinuations(rContinuations, &xApprove, &xDisapprove, &xAbort, &xRetry); if ( !xApprove.is() || !xDisapprove.is() || !xAbort.is() ) return; @@ -91,11 +94,15 @@ handleLockedDocumentRequest_( ? aInfo : ResId( STR_UNKNOWNUSER, *xManager.get() ).toString() ); + aArguments.push_back( xRetry.is() + ? ResId( STR_OPENLOCKED_ALLOWIGNORE_MSG, + *xManager.get() ).toString() + : "" ); aMessage = ResId(STR_OPENLOCKED_MSG, *xManager.get()).toString(); aMessage = UUIInteractionHelper::replaceMessageWithArguments( aMessage, aArguments ); - ScopedVclPtrInstance< OpenLockedQueryBox > xDialog(pParent, xManager.get(), aMessage); + ScopedVclPtrInstance< OpenLockedQueryBox > xDialog(pParent, xManager.get(), aMessage, xRetry.is()); nResult = xDialog->Execute(); } else if ( nMode == UUI_DOC_SAVE_LOCK ) @@ -133,6 +140,8 @@ handleLockedDocumentRequest_( xApprove->select(); else if ( nResult == RET_NO ) xDisapprove->select(); + else if ( nResult == RET_IGNORE && xRetry.is() ) + xRetry->select(); else xAbort->select(); } diff --git a/uui/source/iahndl.cxx b/uui/source/iahndl.cxx index 57ed634b24c1..f98757d89fd2 100644 --- a/uui/source/iahndl.cxx +++ b/uui/source/iahndl.cxx @@ -244,10 +244,11 @@ UUIInteractionHelper::replaceMessageWithArguments( OUString aMessage = _aMessage; SAL_WARN_IF(rArguments.size() == 0, "uui", "replaceMessageWithArguments: No arguments passed!"); - if (rArguments.size() > 0) - aMessage = aMessage.replaceAll("$(ARG1)", rArguments[0]); - if (rArguments.size() > 1) - aMessage = aMessage.replaceAll("$(ARG2)", rArguments[1]); + for (size_t i = 0; i < rArguments.size(); ++i) + { + const OUString sReplaceTemplate = "$(ARG" + OUString::number(i+1) + ")"; + aMessage = aMessage.replaceAll(sReplaceTemplate, rArguments[i]); + } return aMessage; } diff --git a/uui/source/ids.hrc b/uui/source/ids.hrc index d06457dbcbe2..d3f2a80f2d59 100644 --- a/uui/source/ids.hrc +++ b/uui/source/ids.hrc @@ -36,41 +36,42 @@ #define STR_UNKNOWNUSER (RID_UUI_START + 31) #define STR_OPENLOCKED_TITLE (RID_UUI_START + 32) #define STR_OPENLOCKED_MSG (RID_UUI_START + 33) -#define STR_OPENLOCKED_OPENREADONLY_BTN (RID_UUI_START + 34) -#define STR_OPENLOCKED_OPENCOPY_BTN (RID_UUI_START + 35) -#define STR_FILECHANGED_TITLE (RID_UUI_START + 36) -#define STR_FILECHANGED_MSG (RID_UUI_START + 37) -#define STR_FILECHANGED_SAVEANYWAY_BTN (RID_UUI_START + 38) -#define STR_ALREADYOPEN_TITLE (RID_UUI_START + 39) -#define STR_ALREADYOPEN_MSG (RID_UUI_START + 40) -#define STR_ALREADYOPEN_READONLY_BTN (RID_UUI_START + 41) -#define STR_ALREADYOPEN_OPEN_BTN (RID_UUI_START + 42) -#define STR_LOCKFAILED_TITLE (RID_UUI_START + 43) -#define STR_LOCKFAILED_MSG (RID_UUI_START + 44) -#define STR_LOCKFAILED_OPENREADONLY_BTN (RID_UUI_START + 45) -#define STR_LOCKCORRUPT_TITLE (RID_UUI_START + 46) -#define STR_LOCKCORRUPT_MSG (RID_UUI_START + 47) -#define STR_LOCKCORRUPT_OPENREADONLY_BTN (RID_UUI_START + 48) -#define STR_TRYLATER_TITLE (RID_UUI_START + 49) -#define STR_TRYLATER_MSG (RID_UUI_START + 50) -#define STR_TRYLATER_RETRYSAVING_BTN (RID_UUI_START + 51) -#define STR_TRYLATER_SAVEAS_BTN (RID_UUI_START + 52) -#define STR_ALREADYOPEN_SAVE_MSG (RID_UUI_START + 53) -#define STR_ALREADYOPEN_RETRY_SAVE_BTN (RID_UUI_START + 54) -#define STR_ALREADYOPEN_SAVE_BTN (RID_UUI_START + 55) +#define STR_OPENLOCKED_ALLOWIGNORE_MSG (RID_UUI_START + 34) +#define STR_OPENLOCKED_OPENREADONLY_BTN (RID_UUI_START + 35) +#define STR_OPENLOCKED_OPENCOPY_BTN (RID_UUI_START + 36) +#define STR_FILECHANGED_TITLE (RID_UUI_START + 37) +#define STR_FILECHANGED_MSG (RID_UUI_START + 38) +#define STR_FILECHANGED_SAVEANYWAY_BTN (RID_UUI_START + 39) +#define STR_ALREADYOPEN_TITLE (RID_UUI_START + 40) +#define STR_ALREADYOPEN_MSG (RID_UUI_START + 41) +#define STR_ALREADYOPEN_READONLY_BTN (RID_UUI_START + 42) +#define STR_ALREADYOPEN_OPEN_BTN (RID_UUI_START + 43) +#define STR_LOCKFAILED_TITLE (RID_UUI_START + 44) +#define STR_LOCKFAILED_MSG (RID_UUI_START + 45) +#define STR_LOCKFAILED_OPENREADONLY_BTN (RID_UUI_START + 46) +#define STR_LOCKCORRUPT_TITLE (RID_UUI_START + 47) +#define STR_LOCKCORRUPT_MSG (RID_UUI_START + 48) +#define STR_LOCKCORRUPT_OPENREADONLY_BTN (RID_UUI_START + 49) +#define STR_TRYLATER_TITLE (RID_UUI_START + 50) +#define STR_TRYLATER_MSG (RID_UUI_START + 51) +#define STR_TRYLATER_RETRYSAVING_BTN (RID_UUI_START + 52) +#define STR_TRYLATER_SAVEAS_BTN (RID_UUI_START + 53) +#define STR_ALREADYOPEN_SAVE_MSG (RID_UUI_START + 54) +#define STR_ALREADYOPEN_RETRY_SAVE_BTN (RID_UUI_START + 55) +#define STR_ALREADYOPEN_SAVE_BTN (RID_UUI_START + 56) -#define STR_WARNING_INCOMPLETE_ENCRYPTION_TITLE (RID_UUI_START + 56) -#define STR_WARNING_BROKENSIGNATURE_TITLE (RID_UUI_START + 57) -#define STR_ENTER_PASSWORD_TO_OPEN (RID_UUI_START + 58) -#define STR_ENTER_PASSWORD_TO_MODIFY (RID_UUI_START + 59) -#define STR_RENAME_OR_REPLACE (RID_UUI_START + 60) -#define STR_NAME_CLASH_RENAME_ONLY (RID_UUI_START + 61) -#define STR_SAME_NAME_USED (RID_UUI_START + 62) -#define STR_ENTER_SIMPLE_PASSWORD (RID_UUI_START + 63) -#define STR_CONFIRM_SIMPLE_PASSWORD (RID_UUI_START + 64) -#define STR_TITLE_CREATE_PASSWORD (RID_UUI_START + 65) -#define STR_TITLE_ENTER_PASSWORD (RID_UUI_START + 66) -#define STR_PASSWORD_MISMATCH (RID_UUI_START + 67) +#define STR_WARNING_INCOMPLETE_ENCRYPTION_TITLE (RID_UUI_START + 57) +#define STR_WARNING_BROKENSIGNATURE_TITLE (RID_UUI_START + 58) +#define STR_ENTER_PASSWORD_TO_OPEN (RID_UUI_START + 59) +#define STR_ENTER_PASSWORD_TO_MODIFY (RID_UUI_START + 60) +#define STR_RENAME_OR_REPLACE (RID_UUI_START + 61) +#define STR_NAME_CLASH_RENAME_ONLY (RID_UUI_START + 62) +#define STR_SAME_NAME_USED (RID_UUI_START + 63) +#define STR_ENTER_SIMPLE_PASSWORD (RID_UUI_START + 64) +#define STR_CONFIRM_SIMPLE_PASSWORD (RID_UUI_START + 65) +#define STR_TITLE_CREATE_PASSWORD (RID_UUI_START + 66) +#define STR_TITLE_ENTER_PASSWORD (RID_UUI_START + 67) +#define STR_PASSWORD_MISMATCH (RID_UUI_START + 68) #define ERRCODE_UUI_IO_ABORT (ERRCODE_AREA_UUI + 0) #define ERRCODE_UUI_IO_ACCESSDENIED (ERRCODE_AREA_UUI + 1) diff --git a/uui/source/openlocked.cxx b/uui/source/openlocked.cxx index 4de71b54c2ca..90d7ad8bff68 100644 --- a/uui/source/openlocked.cxx +++ b/uui/source/openlocked.cxx @@ -20,7 +20,7 @@ #include "ids.hrc" #include "openlocked.hxx" -OpenLockedQueryBox::OpenLockedQueryBox( vcl::Window* pParent, ResMgr* pResMgr, const OUString& aMessage ) : +OpenLockedQueryBox::OpenLockedQueryBox( vcl::Window* pParent, ResMgr* pResMgr, const OUString& aMessage, bool bEnableOverride ) : MessBox(pParent, 0, ResId(STR_OPENLOCKED_TITLE, *pResMgr).toString(), aMessage ) @@ -29,21 +29,19 @@ OpenLockedQueryBox::OpenLockedQueryBox( vcl::Window* pParent, ResMgr* pResMgr, c AddButton(ResId(STR_OPENLOCKED_OPENREADONLY_BTN, *pResMgr).toString(), RET_YES, ButtonDialogFlags::Default | ButtonDialogFlags::OK | ButtonDialogFlags::Focus); + SetButtonHelpText(RET_YES, OUString()); AddButton(ResId(STR_OPENLOCKED_OPENCOPY_BTN, *pResMgr).toString(), RET_NO); + SetButtonHelpText(RET_NO, OUString()); + + if (bEnableOverride) + { + // Present option to ignore the (stale?) lock file and open the document + AddButton(ResId(STR_ALREADYOPEN_OPEN_BTN, *pResMgr).toString(), RET_IGNORE); + SetButtonHelpText(RET_IGNORE, OUString()); + } AddButton( StandardButtonType::Cancel, RET_CANCEL, ButtonDialogFlags::Cancel ); - SetButtonHelpText( RET_YES, OUString() ); - SetButtonHelpText( RET_NO, OUString() ); - -#ifdef _WIN32 - // bnc#656566 - // Yes, it is silly to do this only for this dialog but not the - // other similar ones. But hey, it was about this dialog that the - // customer complained. You who read this and feel the itch, feel - // free to fix the problem in a better way. - EnableAlwaysOnTop(); -#endif } OpenLockedQueryBox::~OpenLockedQueryBox() diff --git a/uui/source/openlocked.hxx b/uui/source/openlocked.hxx index 40c50e403e00..73c435fa6c11 100644 --- a/uui/source/openlocked.hxx +++ b/uui/source/openlocked.hxx @@ -24,7 +24,7 @@ class OpenLockedQueryBox : public MessBox { public: - OpenLockedQueryBox( vcl::Window* pParent, ResMgr* pResMgr, const OUString& aMessage ); + OpenLockedQueryBox( vcl::Window* pParent, ResMgr* pResMgr, const OUString& aMessage, bool bEnableOverride ); virtual ~OpenLockedQueryBox() override; }; diff --git a/uui/source/openlocked.src b/uui/source/openlocked.src index 8aee0a643bf9..d0069ce97ee6 100644 --- a/uui/source/openlocked.src +++ b/uui/source/openlocked.src @@ -27,7 +27,11 @@ String STR_OPENLOCKED_TITLE }; String STR_OPENLOCKED_MSG { - Text [ en-US ] = "Document file '$(ARG1)' is locked for editing by:\n\n$(ARG2)\n\nOpen document read-only or open a copy of the document for editing.\n\n"; + Text [ en-US ] = "Document file '$(ARG1)' is locked for editing by:\n\n$(ARG2)\n\nOpen document read-only or open a copy of the document for editing.\n\n$(ARG3)"; +}; +String STR_OPENLOCKED_ALLOWIGNORE_MSG +{ + Text [ en-US ] = "You may also ignore the file locking and open the document for editing.\n\n"; }; String STR_OPENLOCKED_OPENREADONLY_BTN { commit 95994da7e162a972b25c69023c42756735cc9d8d Author: Juergen Funk <juergen.funk...@cib.de> Date: Wed Jun 21 14:41:49 2017 +0200 Improve tdf#106942: always erase empty/corrupt lockfile also when we could not create lockfile, not only when open as readonly Change-Id: Ied53bbfe47669f62553d97d81f0bed156ae58887 Reviewed-on: https://gerrit.libreoffice.org/39054 Reviewed-by: Katarina Behrens <katarina.behr...@cib.de> Tested-by: Katarina Behrens <katarina.behr...@cib.de> Reviewed-on: https://gerrit.libreoffice.org/49469 Reviewed-by: Aron Budea <aron.bu...@collabora.com> Tested-by: Aron Budea <aron.bu...@collabora.com> (cherry picked from commit 6c5af47fc25aecc624e68af174c7e1d9ca2392f9) diff --git a/sfx2/source/doc/docfile.cxx b/sfx2/source/doc/docfile.cxx index 7e2bbc973443..b1ce8b84655b 100644 --- a/sfx2/source/doc/docfile.cxx +++ b/sfx2/source/doc/docfile.cxx @@ -1240,7 +1240,8 @@ void SfxMedium::LockOrigFileOnDemand( bool bLoading, bool bNoUI ) if (bLoading && !bNoUI) { bIoErr = true; - bResult = ShowLockFileProblemDialog(MessageDlg::LockFileIgnore); + ShowLockFileProblemDialog(MessageDlg::LockFileIgnore); + bResult = true; // always delete the defect lock-file } } catch (const uno::Exception&) @@ -1248,7 +1249,8 @@ void SfxMedium::LockOrigFileOnDemand( bool bLoading, bool bNoUI ) if (bLoading && !bNoUI) { bIoErr = true; - bResult = ShowLockFileProblemDialog(MessageDlg::LockFileIgnore); + ShowLockFileProblemDialog(MessageDlg::LockFileIgnore); + bResult = true; // always delete the defect lock-file } } commit 748abfdd6104b0023fe545f8ea380f8af4fc892d Author: Juergen Funk <juergen.funk...@cib.de> Date: Wed Apr 12 11:26:10 2017 +0200 tdf#106942 Wrong message when lock file is empty or corrupt 1. Erase empty or corrupt lockfile, when reading it fails and skip "Locked Document Dialog" in that case 2. Show Dialog (use LockFileIgnoreRequest -> LockFailedQueryBox) when create lock file is not possible. Two Dialogs: "lock file create error" and "empty lockfile is present" Set the document to read-only when creating lockfile is not possible. If lockfile is corrupt or empty, inform the user. They can interrupt loading the document or open it read-only, which also erases the corrupt lock file after closing the document 3. Handling for the two Dialogs Use LockFileIgnoreRequst for create lockfile error and add a new LockFileCorruptRequest, (lock file is corrupt). Change and generate new messages for both dialogs in english Change-Id: I35c377f85b5113e8ffb89d83b9544b8ebc81d89f Reviewed-on: https://gerrit.libreoffice.org/36658 Tested-by: Jenkins <c...@libreoffice.org> Reviewed-by: Katarina Behrens <katarina.behr...@cib.de> Reviewed-on: https://gerrit.libreoffice.org/49468 Reviewed-by: Aron Budea <aron.bu...@collabora.com> Tested-by: Aron Budea <aron.bu...@collabora.com> (cherry picked from commit e5dc12d37bfea357aeb6f71e876dd4f93833d1c9) diff --git a/include/sfx2/docfile.hxx b/include/sfx2/docfile.hxx index 07cfbe119c5b..8710498c7808 100644 --- a/include/sfx2/docfile.hxx +++ b/include/sfx2/docfile.hxx @@ -164,8 +164,10 @@ public: bool IsStorage(); enum class ShowLockResult { NoLock, Succeeded,Try }; - ShowLockResult ShowLockedDocumentDialog( const LockFileEntry& aData, bool bIsLoading, bool bOwnLock ); + ShowLockResult ShowLockedDocumentDialog( const LockFileEntry& aData, bool bIsLoading, bool bOwnLock, bool bHandleSysLocked); void LockOrigFileOnDemand( bool bLoading, bool bNoUI ); + enum class MessageDlg { LockFileIgnore, LockFileCorrupt }; + bool ShowLockFileProblemDialog(MessageDlg nWhichDlg); void DisableUnlockWebDAV( bool bDisableUnlockWebDAV = true ); void UnlockFile( bool bReleaseLockStream ); diff --git a/include/svl/documentlockfile.hxx b/include/svl/documentlockfile.hxx index 98dde757cf7b..ec94f1f22dde 100644 --- a/include/svl/documentlockfile.hxx +++ b/include/svl/documentlockfile.hxx @@ -48,7 +48,10 @@ public: bool CreateOwnLockFile(); LockFileEntry GetLockData(); bool OverwriteOwnLockFile(); + /// Delete the Lockfile, if current user is the owner void RemoveFile(); + /// Only delete lockfile, disregarding ownership + void RemoveFileDirectly(); static bool IsInteractionAllowed() { return m_bAllowInteraction; } }; diff --git a/l10ntools/source/gRun.sh b/l10ntools/source/gRun.sh index e8a622cf9903..bf7ef98a27d7 100755 --- a/l10ntools/source/gRun.sh +++ b/l10ntools/source/gRun.sh @@ -490,7 +490,7 @@ ${MYCMD} --base sw/source/uibase/utlui --files attrdesc.src initui.src navipi.sr ${MYCMD} --files sw/source/uibase/wrtsh/wrtsh.src -${MYCMD} --base uui/source --files alreadyopen.src filechanged.src ids.src lockfailed.src nameclashdlg.src openlocked.src passworddlg.src passworderrs.src trylater.src +${MYCMD} --base uui/source --files alreadyopen.src filechanged.src ids.src lockfailed.src lockcorrupt.src nameclashdlg.src openlocked.src passworddlg.src passworderrs.src trylater.src ${MYCMD} --files vcl/source/edit/textundo.src diff --git a/offapi/UnoApi_offapi.mk b/offapi/UnoApi_offapi.mk index c53b2d938392..416d64faca88 100644 --- a/offapi/UnoApi_offapi.mk +++ b/offapi/UnoApi_offapi.mk @@ -2199,6 +2199,7 @@ $(eval $(call gb_UnoApi_add_idlfiles,offapi,com/sun/star/document,\ FilterOptionsRequest \ LinkUpdateModes \ LockFileIgnoreRequest \ + LockFileCorruptRequest \ LockedDocumentRequest \ LockedOnSavingRequest \ MacroExecMode \ diff --git a/offapi/com/sun/star/document/LockFileCorruptRequest.idl b/offapi/com/sun/star/document/LockFileCorruptRequest.idl new file mode 100644 index 000000000000..7780414723e2 --- /dev/null +++ b/offapi/com/sun/star/document/LockFileCorruptRequest.idl @@ -0,0 +1,43 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef __com_sun_star_document_LockFileCorruptRequest_idl__ +#define __com_sun_star_document_LockFileCorruptRequest_idl__ + +#include <com/sun/star/io/IOException.idl> +#include <com/sun/star/beans/PropertyValue.idl> +#include <com/sun/star/frame/XModel.idl> + + +module com { module sun { module star { module document { + +/** Is used for interaction handle to query user's decision + when the lock file is corrupt. + + @since OOo 5.5 +*/ +exception LockFileCorruptRequest : ::com::sun::star::io::IOException +{ +}; + + +}; }; }; }; + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sfx2/source/doc/docfile.cxx b/sfx2/source/doc/docfile.cxx index d9a090d7c4db..7e2bbc973443 100644 --- a/sfx2/source/doc/docfile.cxx +++ b/sfx2/source/doc/docfile.cxx @@ -31,6 +31,7 @@ #include <com/sun/star/document/LockedDocumentRequest.hpp> #include <com/sun/star/document/OwnLockOnDocumentRequest.hpp> #include <com/sun/star/document/LockFileIgnoreRequest.hpp> +#include <com/sun/star/document/LockFileCorruptRequest.hpp> #include <com/sun/star/document/ChangedByOthersRequest.hpp> #include <com/sun/star/beans/XPropertySet.hpp> #include <com/sun/star/embed/XTransactedObject.hpp> @@ -122,6 +123,8 @@ #include "sfxacldetect.hxx" #include <officecfg/Office/Common.hxx> +#include <com/sun/star/io/WrongFormatException.hpp> + #include <memory> using namespace ::com::sun::star; @@ -844,12 +847,12 @@ void SfxMedium::SetEncryptionDataToStorage_Impl() // not for some URL scheme belongs in UCB, not here. -SfxMedium::ShowLockResult SfxMedium::ShowLockedDocumentDialog( const LockFileEntry& aData, bool bIsLoading, bool bOwnLock ) +SfxMedium::ShowLockResult SfxMedium::ShowLockedDocumentDialog( const LockFileEntry& aData, bool bIsLoading, bool bOwnLock, bool bHandleSysLocked ) { ShowLockResult nResult = ShowLockResult::NoLock; - // tdf#92817: Simple check for empty lock file that needs to be deleted - if( aData[LockFileComponent::OOOUSERNAME].isEmpty() && aData[LockFileComponent::SYSUSERNAME].isEmpty() ) + // tdf#92817: Simple check for empty lock file that needs to be deleted, when system locking is enabled + if( aData[LockFileComponent::OOOUSERNAME].isEmpty() && aData[LockFileComponent::SYSUSERNAME].isEmpty() && !bHandleSysLocked ) bOwnLock=true; // show the interaction regarding the document opening @@ -943,6 +946,51 @@ SfxMedium::ShowLockResult SfxMedium::ShowLockedDocumentDialog( const LockFileEnt return nResult; } + +bool SfxMedium::ShowLockFileProblemDialog(MessageDlg nWhichDlg) +{ + // system file locking is not active, ask user whether he wants to open the document without any locking + uno::Reference< task::XInteractionHandler > xHandler = GetInteractionHandler(); + + if (xHandler.is()) + { + ::rtl::Reference< ::ucbhelper::InteractionRequest > xIgnoreRequestImpl; + + switch (nWhichDlg) + { + case MessageDlg::LockFileIgnore: + xIgnoreRequestImpl = new ::ucbhelper::InteractionRequest(uno::makeAny( document::LockFileIgnoreRequest() )); + break; + case MessageDlg::LockFileCorrupt: + xIgnoreRequestImpl = new ::ucbhelper::InteractionRequest(uno::makeAny( document::LockFileCorruptRequest() )); + break; + } + + uno::Sequence< uno::Reference< task::XInteractionContinuation > > aContinuations(2); + aContinuations[0] = new ::ucbhelper::InteractionAbort(xIgnoreRequestImpl.get()); + aContinuations[1] = new ::ucbhelper::InteractionApprove(xIgnoreRequestImpl.get()); + xIgnoreRequestImpl->setContinuations(aContinuations); + + xHandler->handle(xIgnoreRequestImpl.get()); + + ::rtl::Reference< ::ucbhelper::InteractionContinuation > xSelected = xIgnoreRequestImpl->getSelection(); + bool bReadOnly = uno::Reference< task::XInteractionApprove >(xSelected.get(), uno::UNO_QUERY).is(); + + if (bReadOnly) + { + GetItemSet()->Put(SfxBoolItem(SID_DOC_READONLY, true)); + } + else + { + SetError( ERRCODE_ABORT, OSL_LOG_PREFIX ); + } + + return bReadOnly; + } + + return false; +} + namespace { bool isSuitableProtocolForLocking(const OUString & rLogicName) @@ -1038,7 +1086,7 @@ void SfxMedium::LockOrigFileOnDemand( bool bLoading, bool bNoUI ) if ( !bResult && !bNoUI ) { - bUIStatus = ShowLockedDocumentDialog( aLockData, bLoading, false ); + bUIStatus = ShowLockedDocumentDialog( aLockData, bLoading, false , false ); } } catch( ucb::InteractiveNetworkWriteException& ) @@ -1179,59 +1227,34 @@ void SfxMedium::LockOrigFileOnDemand( bool bLoading, bool bNoUI ) try { ::svt::DocumentLockFile aLockFile( pImpl->m_aLogicName ); - if ( !bHandleSysLocked ) + bool bIoErr = false; + + if (!bHandleSysLocked) { try { bResult = aLockFile.CreateOwnLockFile(); } - catch ( const ucb::InteractiveIOException& e ) + catch (const ucb::InteractiveIOException&) { - // exception means that the lock file can not be successfully accessed - // in this case it should be ignored if system file locking is anyway active - if ( bUseSystemLock || !IsOOoLockFileUsed() ) + if (bLoading && !bNoUI) { - bResult = true; - // take the ownership over the lock file - aLockFile.OverwriteOwnLockFile(); - } - else if ( e.Code == IOErrorCode_INVALID_PARAMETER ) - { - // system file locking is not active, ask user whether he wants to open the document without any locking - uno::Reference< task::XInteractionHandler > xHandler = GetInteractionHandler(); - - if ( xHandler.is() ) - { - ::rtl::Reference< ::ucbhelper::InteractionRequest > xIgnoreRequestImpl - = new ::ucbhelper::InteractionRequest( uno::makeAny( document::LockFileIgnoreRequest() ) ); - - uno::Sequence< uno::Reference< task::XInteractionContinuation > > aContinuations( 2 ); - aContinuations[0] = new ::ucbhelper::InteractionAbort( xIgnoreRequestImpl.get() ); - aContinuations[1] = new ::ucbhelper::InteractionApprove( xIgnoreRequestImpl.get() ); - xIgnoreRequestImpl->setContinuations( aContinuations ); - - xHandler->handle( xIgnoreRequestImpl.get() ); - - ::rtl::Reference< ::ucbhelper::InteractionContinuation > xSelected = xIgnoreRequestImpl->getSelection(); - bResult = uno::Reference< task::XInteractionApprove >( xSelected.get(), uno::UNO_QUERY ).is(); - } + bIoErr = true; + bResult = ShowLockFileProblemDialog(MessageDlg::LockFileIgnore); } } - catch ( const uno::Exception& ) + catch (const uno::Exception&) { - // exception means that the lock file can not be successfully accessed - // in this case it should be ignored if system file locking is anyway active - if ( bUseSystemLock || !IsOOoLockFileUsed() ) + if (bLoading && !bNoUI) { - bResult = true; - // take the ownership over the lock file - aLockFile.OverwriteOwnLockFile(); + bIoErr = true; + bResult = ShowLockFileProblemDialog(MessageDlg::LockFileIgnore); } } // in case OOo locking is turned off the lock file is still written if possible // but it is ignored while deciding whether the document should be opened for editing or not - if ( !bResult && !IsOOoLockFileUsed() ) + if (!bResult && !IsOOoLockFileUsed() && !bIoErr) { bResult = true; // take the ownership over the lock file @@ -1239,46 +1262,54 @@ void SfxMedium::LockOrigFileOnDemand( bool bLoading, bool bNoUI ) } } - if ( !bResult ) { LockFileEntry aData; try { - // impossibility to get data is no real problem aData = aLockFile.GetLockData(); } + catch (const io::WrongFormatException&) + { + // we get empty or corrupt data + // info to the user + if (!bIoErr && bLoading && !bNoUI ) + bResult = ShowLockFileProblemDialog(MessageDlg::LockFileCorrupt); + + // not show the Lock Document Dialog + bIoErr = true; + } catch( const uno::Exception& ) { + // show the Lock Document Dialog, when locked from other app + bIoErr = !bHandleSysLocked; } bool bOwnLock = false; - if ( !bHandleSysLocked ) + if (!bHandleSysLocked) { LockFileEntry aOwnData = svt::LockFileCommon::GenerateOwnEntry(); - bOwnLock = aOwnData[LockFileComponent::SYSUSERNAME].equals( aData[LockFileComponent::SYSUSERNAME] ); + bOwnLock = aOwnData[LockFileComponent::SYSUSERNAME].equals(aData[LockFileComponent::SYSUSERNAME]); - if ( bOwnLock - && aOwnData[LockFileComponent::LOCALHOST].equals( aData[LockFileComponent::LOCALHOST] ) - && aOwnData[LockFileComponent::USERURL].equals( aData[LockFileComponent::USERURL] ) ) + if (bOwnLock + && aOwnData[LockFileComponent::LOCALHOST].equals(aData[LockFileComponent::LOCALHOST]) + && aOwnData[LockFileComponent::USERURL].equals(aData[LockFileComponent::USERURL])) { // this is own lock from the same installation, it could remain because of crash bResult = true; } } - if ( !bResult && !bNoUI ) + if ( !bResult && !bNoUI && !bIoErr) { - bUIStatus = ShowLockedDocumentDialog( aData, bLoading, bOwnLock ); + bUIStatus = ShowLockedDocumentDialog( aData, bLoading, bOwnLock, bHandleSysLocked ); if ( bUIStatus == ShowLockResult::Succeeded ) { // take the ownership over the lock file bResult = aLockFile.OverwriteOwnLockFile(); } } - - bHandleSysLocked = false; } } catch( const uno::Exception& ) @@ -2780,13 +2811,24 @@ void SfxMedium::UnlockFile( bool bReleaseLockStream ) if ( pImpl->m_bLocked ) { + ::svt::DocumentLockFile aLockFile( pImpl->m_aLogicName ); + try { pImpl->m_bLocked = false; - ::svt::DocumentLockFile aLockFile( pImpl->m_aLogicName ); // TODO/LATER: A warning could be shown in case the file is not the own one aLockFile.RemoveFile(); } + catch( const io::WrongFormatException& ) + { + try + { + // erase the empty or corrupt file + aLockFile.RemoveFileDirectly(); + } + catch( const uno::Exception& ) + {} + } catch( const uno::Exception& ) {} } diff --git a/svl/source/misc/documentlockfile.cxx b/svl/source/misc/documentlockfile.cxx index 6dcd09b0ca62..d8c3fe1cd9c3 100644 --- a/svl/source/misc/documentlockfile.cxx +++ b/svl/source/misc/documentlockfile.cxx @@ -207,12 +207,19 @@ void DocumentLockFile::RemoveFile() || !aFileData[LockFileComponent::USERURL].equals( aNewEntry[LockFileComponent::USERURL] ) ) throw io::IOException(); // not the owner, access denied + RemoveFileDirectly(); +} + +void DocumentLockFile::RemoveFileDirectly() +{ uno::Reference < css::ucb::XCommandEnvironment > xEnv; ::ucbhelper::Content aCnt(m_aURL, xEnv, comphelper::getProcessComponentContext()); aCnt.executeCommand("delete", uno::makeAny(true)); } + + } // namespace svt /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/uui/AllLangResTarget_uui.mk b/uui/AllLangResTarget_uui.mk index 2cd36571b0e8..fe59c93c6201 100644 --- a/uui/AllLangResTarget_uui.mk +++ b/uui/AllLangResTarget_uui.mk @@ -25,6 +25,7 @@ $(eval $(call gb_SrsTarget_add_files,uui/res,\ uui/source/filechanged.src \ uui/source/ids.src \ uui/source/lockfailed.src \ + uui/source/lockcorrupt.src \ uui/source/nameclashdlg.src \ uui/source/openlocked.src \ uui/source/passworddlg.src \ diff --git a/uui/Library_uui.mk b/uui/Library_uui.mk index c1054aa47a81..80eadf84cf1f 100644 --- a/uui/Library_uui.mk +++ b/uui/Library_uui.mk @@ -50,6 +50,7 @@ $(eval $(call gb_Library_add_exception_objects,uui,\ uui/source/iahndl-ssl \ uui/source/interactionhandler \ uui/source/lockfailed \ + uui/source/lockcorrupt \ uui/source/logindlg \ uui/source/masterpasscrtdlg \ uui/source/masterpassworddlg \ diff --git a/uui/source/iahndl-locking.cxx b/uui/source/iahndl-locking.cxx index f3793819471a..48312637bb21 100644 --- a/uui/source/iahndl-locking.cxx +++ b/uui/source/iahndl-locking.cxx @@ -23,6 +23,7 @@ #include <com/sun/star/document/LockedDocumentRequest.hpp> #include <com/sun/star/document/LockedOnSavingRequest.hpp> #include <com/sun/star/document/LockFileIgnoreRequest.hpp> +#include <com/sun/star/document/LockFileCorruptRequest.hpp> #include <com/sun/star/document/OwnLockOnDocumentRequest.hpp> #include <com/sun/star/task/XInteractionApprove.hpp> #include <com/sun/star/task/XInteractionDisapprove.hpp> @@ -40,6 +41,7 @@ #include "alreadyopen.hxx" #include "filechanged.hxx" #include "lockfailed.hxx" +#include "lockcorrupt.hxx" #include "iahndl.hxx" @@ -174,11 +176,16 @@ handleChangedByOthersRequest_( } } +const sal_uInt16 UUI_DOC_CreateErrDlg = 0; +const sal_uInt16 UUI_DOC_CorruptErrDlg = 1; + + + void -handleLockFileIgnoreRequest_( +handleLockFileProblemRequest_( vcl::Window * pParent, uno::Sequence< uno::Reference< task::XInteractionContinuation > > const & - rContinuations ) + rContinuations, sal_uInt16 nWhichDlg ) { uno::Reference< task::XInteractionApprove > xApprove; uno::Reference< task::XInteractionAbort > xAbort; @@ -194,8 +201,19 @@ handleLockFileIgnoreRequest_( if (!xManager.get()) return; - ScopedVclPtrInstance< LockFailedQueryBox > xDialog(pParent, xManager.get()); - sal_Int32 nResult = xDialog->Execute(); + sal_Int32 nResult; + + if (nWhichDlg == UUI_DOC_CreateErrDlg) + { + ScopedVclPtrInstance< LockFailedQueryBox > xDialog(pParent, xManager.get()); + nResult = xDialog->Execute(); + } + else + { + ScopedVclPtrInstance< LockCorruptQueryBox > xDialog(pParent, xManager.get()); + nResult = xDialog->Execute(); + } + if ( nResult == RET_OK ) xApprove->select(); @@ -269,8 +287,9 @@ UUIInteractionHelper::handleChangedByOthersRequest( return false; } + bool -UUIInteractionHelper::handleLockFileIgnoreRequest( +UUIInteractionHelper::handleLockFileProblemRequest( uno::Reference< task::XInteractionRequest > const & rRequest) { uno::Any aAnyRequest(rRequest->getRequest()); @@ -278,10 +297,19 @@ UUIInteractionHelper::handleLockFileIgnoreRequest( document::LockFileIgnoreRequest aLockFileIgnoreRequest; if (aAnyRequest >>= aLockFileIgnoreRequest ) { - handleLockFileIgnoreRequest_( getParentProperty(), - rRequest->getContinuations() ); + handleLockFileProblemRequest_( getParentProperty(), + rRequest->getContinuations(), UUI_DOC_CreateErrDlg ); return true; } + + document::LockFileCorruptRequest aLockFileCorruptRequest; + if (aAnyRequest >>= aLockFileCorruptRequest ) + { + handleLockFileProblemRequest_( getParentProperty(), + rRequest->getContinuations(), UUI_DOC_CorruptErrDlg ); + return true; + } + return false; } diff --git a/uui/source/iahndl.cxx b/uui/source/iahndl.cxx index e587a831e457..57ed634b24c1 100644 --- a/uui/source/iahndl.cxx +++ b/uui/source/iahndl.cxx @@ -822,7 +822,7 @@ UUIInteractionHelper::handleRequest_impl( if ( handleChangedByOthersRequest( rRequest ) ) return true; - if ( handleLockFileIgnoreRequest( rRequest ) ) + if ( handleLockFileProblemRequest( rRequest ) ) return true; task::DocumentMacroConfirmationRequest aMacroConfirmRequest; diff --git a/uui/source/iahndl.hxx b/uui/source/iahndl.hxx index 6543b345247f..1f4801314065 100644 --- a/uui/source/iahndl.hxx +++ b/uui/source/iahndl.hxx @@ -232,7 +232,7 @@ private: css::uno::Reference< css::task::XInteractionRequest > const & rRequest); - bool handleLockFileIgnoreRequest( + bool handleLockFileProblemRequest( css::uno::Reference< css::task::XInteractionRequest > const & rRequest); bool handleCustomRequest( diff --git a/uui/source/ids.hrc b/uui/source/ids.hrc index e70c7a84300d..d06457dbcbe2 100644 --- a/uui/source/ids.hrc +++ b/uui/source/ids.hrc @@ -47,27 +47,30 @@ #define STR_ALREADYOPEN_OPEN_BTN (RID_UUI_START + 42) #define STR_LOCKFAILED_TITLE (RID_UUI_START + 43) #define STR_LOCKFAILED_MSG (RID_UUI_START + 44) -#define STR_LOCKFAILED_DONTSHOWAGAIN (RID_UUI_START + 45) -#define STR_TRYLATER_TITLE (RID_UUI_START + 46) -#define STR_TRYLATER_MSG (RID_UUI_START + 47) -#define STR_TRYLATER_RETRYSAVING_BTN (RID_UUI_START + 48) -#define STR_TRYLATER_SAVEAS_BTN (RID_UUI_START + 49) -#define STR_ALREADYOPEN_SAVE_MSG (RID_UUI_START + 50) -#define STR_ALREADYOPEN_RETRY_SAVE_BTN (RID_UUI_START + 51) -#define STR_ALREADYOPEN_SAVE_BTN (RID_UUI_START + 52) +#define STR_LOCKFAILED_OPENREADONLY_BTN (RID_UUI_START + 45) +#define STR_LOCKCORRUPT_TITLE (RID_UUI_START + 46) +#define STR_LOCKCORRUPT_MSG (RID_UUI_START + 47) +#define STR_LOCKCORRUPT_OPENREADONLY_BTN (RID_UUI_START + 48) +#define STR_TRYLATER_TITLE (RID_UUI_START + 49) +#define STR_TRYLATER_MSG (RID_UUI_START + 50) +#define STR_TRYLATER_RETRYSAVING_BTN (RID_UUI_START + 51) +#define STR_TRYLATER_SAVEAS_BTN (RID_UUI_START + 52) +#define STR_ALREADYOPEN_SAVE_MSG (RID_UUI_START + 53) +#define STR_ALREADYOPEN_RETRY_SAVE_BTN (RID_UUI_START + 54) +#define STR_ALREADYOPEN_SAVE_BTN (RID_UUI_START + 55) -#define STR_WARNING_INCOMPLETE_ENCRYPTION_TITLE (RID_UUI_START + 54) -#define STR_WARNING_BROKENSIGNATURE_TITLE (RID_UUI_START + 55) -#define STR_ENTER_PASSWORD_TO_OPEN (RID_UUI_START + 56) -#define STR_ENTER_PASSWORD_TO_MODIFY (RID_UUI_START + 57) -#define STR_RENAME_OR_REPLACE (RID_UUI_START + 58) -#define STR_NAME_CLASH_RENAME_ONLY (RID_UUI_START + 59) -#define STR_SAME_NAME_USED (RID_UUI_START + 60) -#define STR_ENTER_SIMPLE_PASSWORD (RID_UUI_START + 61) -#define STR_CONFIRM_SIMPLE_PASSWORD (RID_UUI_START + 62) -#define STR_TITLE_CREATE_PASSWORD (RID_UUI_START + 63) -#define STR_TITLE_ENTER_PASSWORD (RID_UUI_START + 64) -#define STR_PASSWORD_MISMATCH (RID_UUI_START + 65) +#define STR_WARNING_INCOMPLETE_ENCRYPTION_TITLE (RID_UUI_START + 56) +#define STR_WARNING_BROKENSIGNATURE_TITLE (RID_UUI_START + 57) +#define STR_ENTER_PASSWORD_TO_OPEN (RID_UUI_START + 58) +#define STR_ENTER_PASSWORD_TO_MODIFY (RID_UUI_START + 59) +#define STR_RENAME_OR_REPLACE (RID_UUI_START + 60) +#define STR_NAME_CLASH_RENAME_ONLY (RID_UUI_START + 61) +#define STR_SAME_NAME_USED (RID_UUI_START + 62) +#define STR_ENTER_SIMPLE_PASSWORD (RID_UUI_START + 63) +#define STR_CONFIRM_SIMPLE_PASSWORD (RID_UUI_START + 64) +#define STR_TITLE_CREATE_PASSWORD (RID_UUI_START + 65) +#define STR_TITLE_ENTER_PASSWORD (RID_UUI_START + 66) +#define STR_PASSWORD_MISMATCH (RID_UUI_START + 67) #define ERRCODE_UUI_IO_ABORT (ERRCODE_AREA_UUI + 0) #define ERRCODE_UUI_IO_ACCESSDENIED (ERRCODE_AREA_UUI + 1) diff --git a/uui/source/lockcorrupt.cxx b/uui/source/lockcorrupt.cxx new file mode 100644 index 000000000000..a22ad863ccc0 --- /dev/null +++ b/uui/source/lockcorrupt.cxx @@ -0,0 +1,44 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include "ids.hrc" +#include "lockcorrupt.hxx" + +#include <vcl/button.hxx> + +LockCorruptQueryBox::LockCorruptQueryBox( vcl::Window* pParent, ResMgr* pResMgr ) : + MessBox(pParent, 0, + ResId(STR_LOCKCORRUPT_TITLE, *pResMgr).toString(), + OUString() ) +{ + SetImage( ErrorBox::GetStandardImage() ); + + AddButton(ResId(STR_LOCKCORRUPT_OPENREADONLY_BTN, *pResMgr).toString(), RET_OK, + ButtonDialogFlags::Default | ButtonDialogFlags::OK | ButtonDialogFlags::Focus); + + AddButton( StandardButtonType::Cancel, RET_CANCEL, ButtonDialogFlags::Cancel ); + + SetMessText(ResId(STR_LOCKCORRUPT_MSG, *pResMgr ).toString()); +} + +LockCorruptQueryBox::~LockCorruptQueryBox() +{ +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/uui/source/lockcorrupt.hxx b/uui/source/lockcorrupt.hxx new file mode 100644 index 000000000000..b83d94084d8c --- /dev/null +++ b/uui/source/lockcorrupt.hxx @@ -0,0 +1,33 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#ifndef INCLUDED_UUI_SOURCE_LOCKCORRUPT_HXX +#define INCLUDED_UUI_SOURCE_LOCKCORRUPT_HXX + +#include <vcl/msgbox.hxx> + +class LockCorruptQueryBox : public MessBox +{ +public: + LockCorruptQueryBox( vcl::Window* pParent, ResMgr* pResMgr ); + virtual ~LockCorruptQueryBox() override; +}; + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/uui/source/lockcorrupt.src b/uui/source/lockcorrupt.src new file mode 100644 index 000000000000..e26535f3f925 --- /dev/null +++ b/uui/source/lockcorrupt.src @@ -0,0 +1,37 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#define __RSC + +#include "ids.hrc" + +String STR_LOCKCORRUPT_TITLE +{ + Text [ en-US ] = "Lock file is corrupted"; +}; +String STR_LOCKCORRUPT_MSG +{ + Text [ en-US ] = "The lock file is corrupted and probably empty. Opening the document read-only and closing it again removes the corrupted lock file."; +}; +String STR_LOCKCORRUPT_OPENREADONLY_BTN +{ + Text [ en-US ] = "Open ~Read-Only"; +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/uui/source/lockfailed.cxx b/uui/source/lockfailed.cxx index 77ceb7e8d625..63ad3a76f2a0 100644 --- a/uui/source/lockfailed.cxx +++ b/uui/source/lockfailed.cxx @@ -29,11 +29,12 @@ LockFailedQueryBox::LockFailedQueryBox( vcl::Window* pParent, ResMgr* pResMgr ) { SetImage( ErrorBox::GetStandardImage() ); - AddButton( StandardButtonType::OK, RET_OK, ButtonDialogFlags::OK ); + AddButton(ResId(STR_LOCKFAILED_OPENREADONLY_BTN, *pResMgr).toString(), RET_OK, + ButtonDialogFlags::Default | ButtonDialogFlags::OK | ButtonDialogFlags::Focus); + AddButton( StandardButtonType::Cancel, RET_CANCEL, ButtonDialogFlags::Cancel ); SetMessText(ResId(STR_LOCKFAILED_MSG, *pResMgr ).toString()); - SetCheckBoxText(ResId(STR_LOCKFAILED_DONTSHOWAGAIN, *pResMgr).toString()); } LockFailedQueryBox::~LockFailedQueryBox() diff --git a/uui/source/lockfailed.src b/uui/source/lockfailed.src index 2384e43e0ed7..5eeba410e23f 100644 --- a/uui/source/lockfailed.src +++ b/uui/source/lockfailed.src @@ -27,11 +27,11 @@ String STR_LOCKFAILED_TITLE }; String STR_LOCKFAILED_MSG { - Text [ en-US ] = "The file could not be locked for exclusive access by %PRODUCTNAME, due to missing permission to create a lock file on that file location."; + Text [ en-US ] = "The lock file could not be created for exclusive access by %PRODUCTNAME, due to missing permission to create a lock file on that file location or lack of free disk space."; }; -String STR_LOCKFAILED_DONTSHOWAGAIN +String STR_LOCKFAILED_OPENREADONLY_BTN { - Text [ en-US ] = "~Do not show this message again"; + Text [ en-US ] = "Open ~Read-Only"; }; /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ commit 1dca41d2ff8d5f23738b061fd5f02fec785e21bd Author: Mike Kaganski <mike.kagan...@collabora.com> Date: Wed Feb 7 01:03:32 2018 +0300 tdf#114217: Consider relative width when importing floating table Unit test included Change-Id: I8e3338d7df431bd016caa4e06e684fbd189127c4 Reviewed-on: https://gerrit.libreoffice.org/49324 Tested-by: Jenkins <c...@libreoffice.org> Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com> Reviewed-on: https://gerrit.libreoffice.org/49335 Reviewed-by: Aron Budea <aron.bu...@collabora.com> Tested-by: Aron Budea <aron.bu...@collabora.com> (cherry picked from commit 561f2a32966ff68bdf0d30a33b90fe95ee7e48cb) diff --git a/sw/qa/extras/ooxmlimport/data/tdf114217.docx b/sw/qa/extras/ooxmlimport/data/tdf114217.docx new file mode 100644 index 000000000000..49f1ce164cbe Binary files /dev/null and b/sw/qa/extras/ooxmlimport/data/tdf114217.docx differ diff --git a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx index a45d1c8469e3..b8920caf2976 100644 --- a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx +++ b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx @@ -1587,6 +1587,14 @@ DECLARE_OOXMLIMPORT_TEST(testTdf111550, "tdf111550.docx") getCell(innerTable, "A1", "[outer:A2]\n[inner:A1]"); } +DECLARE_OOXMLIMPORT_TEST(testTdf114217, "tdf114217.docx") +{ + uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference<drawing::XDrawPage> xDrawPage = xDrawPageSupplier->getDrawPage(); + // This was 1, multi-page table was imported as a floating one. + CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), xDrawPage->getCount()); +} + // tests should only be added to ooxmlIMPORT *if* they fail round-tripping in ooxmlEXPORT CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/writerfilter/source/dmapper/DomainMapperTableHandler.cxx b/writerfilter/source/dmapper/DomainMapperTableHandler.cxx index 4c8365f0ad6f..a872ecb16c6a 100644 --- a/writerfilter/source/dmapper/DomainMapperTableHandler.cxx +++ b/writerfilter/source/dmapper/DomainMapperTableHandler.cxx @@ -1136,8 +1136,11 @@ void DomainMapperTableHandler::endTable(unsigned int nestedTableLevel, bool bTab // table is not in the body text. sal_Int32 nTableWidth = 0; m_aTableProperties->getValue(TablePropertyMap::TABLE_WIDTH, nTableWidth); + sal_Int32 nTableWidthType = text::SizeType::FIX; + m_aTableProperties->getValue(TablePropertyMap::TABLE_WIDTH_TYPE, nTableWidthType); if (m_rDMapper_Impl.GetSectionContext() && nestedTableLevel <= 1 && !m_rDMapper_Impl.IsInHeaderFooter()) - m_rDMapper_Impl.m_aPendingFloatingTables.push_back(FloatingTableInfo(xStart, xEnd, comphelper::containerToSequence(aFrameProperties), nTableWidth)); + m_rDMapper_Impl.m_aPendingFloatingTables.push_back( + FloatingTableInfo(xStart, xEnd, comphelper::containerToSequence(aFrameProperties), nTableWidth, nTableWidthType)); else { // m_xText points to the body text, get the current xText from m_rDMapper_Impl, in case e.g. we would be in a header. diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.hxx b/writerfilter/source/dmapper/DomainMapper_Impl.hxx index 44a2be003c30..9d51754bd1ef 100644 --- a/writerfilter/source/dmapper/DomainMapper_Impl.hxx +++ b/writerfilter/source/dmapper/DomainMapper_Impl.hxx @@ -310,17 +310,19 @@ struct FloatingTableInfo css::uno::Reference<css::text::XTextRange> m_xEnd; css::uno::Sequence<css::beans::PropertyValue> m_aFrameProperties; sal_Int32 m_nTableWidth; + sal_Int32 m_nTableWidthType; /// Break type of the section that contains this table. sal_Int32 m_nBreakType = -1; FloatingTableInfo(css::uno::Reference<css::text::XTextRange> const& xStart, css::uno::Reference<css::text::XTextRange> const& xEnd, const css::uno::Sequence<css::beans::PropertyValue>& aFrameProperties, - sal_Int32 nTableWidth) + sal_Int32 nTableWidth, sal_Int32 nTableWidthType) : m_xStart(xStart), m_xEnd(xEnd), m_aFrameProperties(aFrameProperties), - m_nTableWidth(nTableWidth) + m_nTableWidth(nTableWidth), + m_nTableWidthType(nTableWidthType) { } css::uno::Any getPropertyValue(const OUString &propertyName); diff --git a/writerfilter/source/dmapper/PropertyMap.cxx b/writerfilter/source/dmapper/PropertyMap.cxx index 91528c7967ce..70d9c3fcbf32 100644 --- a/writerfilter/source/dmapper/PropertyMap.cxx +++ b/writerfilter/source/dmapper/PropertyMap.cxx @@ -37,6 +37,7 @@ #include <com/sun/star/table/ShadowFormat.hpp> #include <com/sun/star/text/RelOrientation.hpp> #include <com/sun/star/text/HoriOrientation.hpp> +#include <com/sun/star/text/SizeType.hpp> #include <com/sun/star/text/VertOrientation.hpp> #include <com/sun/star/text/WritingMode.hpp> #include <com/sun/star/text/XTextColumns.hpp> @@ -1074,6 +1075,10 @@ bool SectionPropertyMap::FloatingTableConversion(DomainMapper_Impl& rDM_Impl, Fl sal_Int32 nTextAreaWidth = nPageWidth - GetLeftMargin() - GetRightMargin(); // Count the layout width of the table. sal_Int32 nTableWidth = rInfo.m_nTableWidth; + if (rInfo.m_nTableWidthType == text::SizeType::VARIABLE) + { + nTableWidth *= nTextAreaWidth / 100.0; + } sal_Int32 nLeftMargin = 0; if (rInfo.getPropertyValue("LeftMargin") >>= nLeftMargin) nTableWidth += nLeftMargin; _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits