sc/inc/cellsuno.hxx | 11 +++++ sc/qa/extras/macros-test.cxx | 57 +++++++++++++++++++++++++++++++ sc/source/ui/unoobj/cellsuno.cxx | 48 +++++++++++++++++++------- sw/qa/uitest/writer_tests3/pageNumber.py | 9 ++-- sw/source/uibase/shells/textfld.cxx | 4 ++ 5 files changed, 113 insertions(+), 16 deletions(-)
New commits: commit 1f3b872e8c4901ff36e07bb973e008f6849af21c Author: Mike Kaganski <mike.kagan...@collabora.com> AuthorDate: Fri May 2 09:55:27 2025 +0200 Commit: Xisco Fauli <xiscofa...@libreoffice.org> CommitDate: Fri May 2 20:18:53 2025 +0200 tdf#47479: Do not modify range of sheet / column / row in notifications Change-Id: I2c5afa5397e3a98806908a2f73f8d654e83fb890 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/184889 Tested-by: Jenkins Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com> Signed-off-by: Xisco Fauli <xiscofa...@libreoffice.org> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/184908 diff --git a/sc/inc/cellsuno.hxx b/sc/inc/cellsuno.hxx index 9f7709631778..259571901721 100644 --- a/sc/inc/cellsuno.hxx +++ b/sc/inc/cellsuno.hxx @@ -226,6 +226,9 @@ protected: SC_DLLPUBLIC virtual void SetOnePropertyValue( const SfxItemPropertyMapEntry* pEntry, const css::uno::Any& aValue ); + ScRangeList& AccessRanges() { return aRanges; } + SC_DLLPUBLIC virtual void AdjustUpdatedRanges(UpdateRefMode mode); + public: ScCellRangesBase(ScDocShell* pDocSh, const ScRange& rR); ScCellRangesBase(ScDocShell* pDocSh, ScRangeList aR); @@ -956,6 +959,9 @@ public: // XTypeProvider virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes() override; virtual css::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId() override; + +protected: + void AdjustUpdatedRanges(UpdateRefMode mode) override; }; class ScTableColumnObj final : public ScCellRangeObj, @@ -995,6 +1001,8 @@ public: // XTypeProvider virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes() override; virtual css::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId() override; +protected: + void AdjustUpdatedRanges(UpdateRefMode mode) override; }; class ScTableRowObj final : public ScCellRangeObj @@ -1020,6 +1028,9 @@ public: virtual OUString SAL_CALL getImplementationName() override; virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override; virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override; + +protected: + void AdjustUpdatedRanges(UpdateRefMode mode) override; }; class ScCellsObj final : public cppu::WeakImplHelper< diff --git a/sc/qa/extras/macros-test.cxx b/sc/qa/extras/macros-test.cxx index 6e2b81a01ecd..c9148f64854d 100644 --- a/sc/qa/extras/macros-test.cxx +++ b/sc/qa/extras/macros-test.cxx @@ -17,8 +17,11 @@ #include <document.hxx> #include <scitems.hxx> +#include <com/sun/star/sheet/XCellRangeAddressable.hpp> +#include <com/sun/star/sheet/XCellRangeMovement.hpp> #include <com/sun/star/sheet/XFunctionAccess.hpp> #include <com/sun/star/sheet/XSpreadsheet.hpp> +#include <com/sun/star/table/XColumnRowRange.hpp> #include <com/sun/star/script/XLibraryContainerPassword.hpp> #include <com/sun/star/drawing/XDrawPageSupplier.hpp> @@ -919,6 +922,60 @@ CPPUNIT_TEST_FIXTURE(ScMacrosTest, testTdf159412) CPPUNIT_ASSERT_EQUAL(u"1 Long/2 Double"_ustr, aReturnValue); } +CPPUNIT_TEST_FIXTURE(ScMacrosTest, testTdf47479) +{ + createScDoc(); + uno::Reference<sheet::XSpreadsheetDocument> xDoc(mxComponent, UNO_QUERY_THROW); + auto xSheets = xDoc->getSheets().queryThrow<container::XIndexAccess>(); + auto xSheet = xSheets->getByIndex(0).queryThrow<sheet::XCellRangeMovement>(); + auto xSheetAddressable = xSheet.queryThrow<sheet::XCellRangeAddressable>(); + auto xColRowRange = xSheet.queryThrow<table::XColumnRowRange>(); + auto xColAddressable + = xColRowRange->getColumns()->getByIndex(1).queryThrow<sheet::XCellRangeAddressable>(); + auto xRowAddressable + = xColRowRange->getRows()->getByIndex(1).queryThrow<sheet::XCellRangeAddressable>(); + css::table::CellRangeAddress origSheetRange = xSheetAddressable->getRangeAddress(); + css::table::CellRangeAddress origColRange = xColAddressable->getRangeAddress(); + css::table::CellRangeAddress origRowRange = xRowAddressable->getRangeAddress(); + css::table::CellRangeAddress addressToRemove(origSheetRange.Sheet, 1, 1, 1, 1); + + xSheet->removeRange(addressToRemove, css::sheet::CellDeleteMode_UP); + + auto currentRange = xSheetAddressable->getRangeAddress(); + CPPUNIT_ASSERT_EQUAL(origSheetRange.Sheet, currentRange.Sheet); + CPPUNIT_ASSERT_EQUAL(origSheetRange.StartColumn, currentRange.StartColumn); + CPPUNIT_ASSERT_EQUAL(origSheetRange.StartRow, currentRange.StartRow); + CPPUNIT_ASSERT_EQUAL(origSheetRange.EndColumn, currentRange.EndColumn); + // Without the fix, this would fail with + // - Expected: 1048575 + // - Actual : 0 + CPPUNIT_ASSERT_EQUAL(origSheetRange.EndRow, currentRange.EndRow); + + xSheet->removeRange(addressToRemove, css::sheet::CellDeleteMode_LEFT); + + currentRange = xColAddressable->getRangeAddress(); + CPPUNIT_ASSERT_EQUAL(origColRange.Sheet, currentRange.Sheet); + CPPUNIT_ASSERT_EQUAL(origColRange.StartColumn, currentRange.StartColumn); + // Without the fix, this would fail with + // - Expected: 0 + // - Actual : 2 + CPPUNIT_ASSERT_EQUAL(origColRange.StartRow, currentRange.StartRow); + CPPUNIT_ASSERT_EQUAL(origColRange.EndColumn, currentRange.EndColumn); + CPPUNIT_ASSERT_EQUAL(origColRange.EndRow, currentRange.EndRow); + + xSheet->removeRange(origColRange, css::sheet::CellDeleteMode_UP); + + currentRange = xRowAddressable->getRangeAddress(); + CPPUNIT_ASSERT_EQUAL(origRowRange.Sheet, currentRange.Sheet); + // Without the fix, this would fail with + // - Expected: 0 + // - Actual : 2 + CPPUNIT_ASSERT_EQUAL(origRowRange.StartColumn, currentRange.StartColumn); + CPPUNIT_ASSERT_EQUAL(origRowRange.StartRow, currentRange.StartRow); + CPPUNIT_ASSERT_EQUAL(origRowRange.EndColumn, currentRange.EndColumn); + CPPUNIT_ASSERT_EQUAL(origRowRange.EndRow, currentRange.EndRow); +} + ScMacrosTest::ScMacrosTest() : ScModelTestBase(u"/sc/qa/extras/testdocuments"_ustr) { diff --git a/sc/source/ui/unoobj/cellsuno.cxx b/sc/source/ui/unoobj/cellsuno.cxx index 29f437e77529..2e5e6b60be14 100644 --- a/sc/source/ui/unoobj/cellsuno.cxx +++ b/sc/source/ui/unoobj/cellsuno.cxx @@ -1475,6 +1475,8 @@ const ScMarkData* ScCellRangesBase::GetMarkData() return pMarkData.get(); } +void ScCellRangesBase::AdjustUpdatedRanges(UpdateRefMode) {} + void ScCellRangesBase::Notify( SfxBroadcaster&, const SfxHint& rHint ) { const SfxHintId nId = rHint.GetId(); @@ -1546,18 +1548,7 @@ void ScCellRangesBase::Notify( SfxBroadcaster&, const SfxHint& rHint ) if ( aRanges.UpdateReference( pRefHint->GetMode(), &rDoc, pRefHint->GetRange(), pRefHint->GetDx(), pRefHint->GetDy(), pRefHint->GetDz() ) ) { - if ( pRefHint->GetMode() == URM_INSDEL - && aRanges.size() == 1 - && dynamic_cast<ScTableSheetObj*>(this) - ) - { - // #101755#; the range size of a sheet does not change - ScRange & rR = aRanges.front(); - rR.aStart.SetCol(0); - rR.aStart.SetRow(0); - rR.aEnd.SetCol(rDoc.MaxCol()); - rR.aEnd.SetRow(rDoc.MaxRow()); - } + AdjustUpdatedRanges(pRefHint->GetMode()); RefChanged(); // any change of the range address is broadcast to value (modify) listeners @@ -6596,6 +6587,17 @@ SCTAB ScTableSheetObj::GetTab_Impl() const return 0; } +void ScTableSheetObj::AdjustUpdatedRanges(UpdateRefMode mode) +{ + if (mode == URM_INSDEL) + { + ScRangeList& rRanges = AccessRanges(); + // #101755#, tdf#47479: the range of a sheet does not change + rRanges.RemoveAll(); + rRanges.push_back(GetRange()); + } +} + // former XSheet uno::Reference<table::XTableCharts> SAL_CALL ScTableSheetObj::getCharts() @@ -8431,6 +8433,17 @@ const SfxItemPropertyMap& ScTableColumnObj::GetItemPropertyMap() return pColPropSet->getPropertyMap(); } +void ScTableColumnObj::AdjustUpdatedRanges(UpdateRefMode mode) +{ + if (mode == URM_INSDEL) + { + ScRangeList& rRanges = AccessRanges(); + // tdf#47479: the range of a column does not change + rRanges.RemoveAll(); + rRanges.push_back(GetRange()); + } +} + ScTableRowObj::ScTableRowObj(ScDocShell* pDocSh, SCROW nRow, SCTAB nTab) : ScCellRangeObj( pDocSh, ScRange(0,nRow,nTab, pDocSh->GetDocument().MaxCol(),nRow,nTab) ), pRowPropSet(lcl_GetRowPropertySet()) @@ -8580,6 +8593,17 @@ const SfxItemPropertyMap& ScTableRowObj::GetItemPropertyMap() return pRowPropSet->getPropertyMap(); } +void ScTableRowObj::AdjustUpdatedRanges(UpdateRefMode mode) +{ + if (mode == URM_INSDEL) + { + ScRangeList& rRanges = AccessRanges(); + // tdf#47479: the range of a row does not change + rRanges.RemoveAll(); + rRanges.push_back(GetRange()); + } +} + ScCellsObj::ScCellsObj(ScDocShell* pDocSh, ScRangeList aR) : pDocShell( pDocSh ), aRanges(std::move( aR )) commit 260a77ad9b04dd53712ebc061dffa4c1b77a88b1 Author: Justin Luth <jl...@mail.com> AuthorDate: Fri Jul 19 09:50:11 2024 -0400 Commit: Xisco Fauli <xiscofa...@libreoffice.org> CommitDate: Fri May 2 20:18:42 2025 +0200 tdf#164033 tdf#161741 tdf#161705 pgnum wizard: avoid undo crash (sledgehammer) I have zero knowledge of the many intricate pitfalls of undo/redo, so there is no way I could create a "proper" fix. LO 7.6 introduced the page number wizard which has more prominently exposed existing ways to make undo/redo of page style changes to crash. So treat this as pre-LO 7.2 and simply erase the undo stack after running the wizard. ------------------------------------------------------------------ The ability to undo/redo the "Header/footer change" started in bibisect-linux-64-7.2 commit 910d9a081daf11ea53235d227c3dc9623942a824 commit 8d8486f43c1a8a51157bfc3e0b87090b05a9229e Author: Daniel Arato (NISZ) on Mon Feb 22 16:59:38 2021 +0100 tdf#46561 sw: fix lost undo stack setting header/footer - if( bHeaderFooterChanged ) - GetIDocumentUndoRedo().DelAllUndoObj(); Change-Id: I00c529784bfd7b2cd1230474c05eea8516e6c1e3 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/170771 Tested-by: Jenkins Tested-by: Xisco Fauli <xiscofa...@libreoffice.org> Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org> (cherry picked from commit f84369daa125717f3c87fe34abb0b91c6f6ba3d5) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/184903 Reviewed-by: Justin Luth <jl...@mail.com> diff --git a/sw/qa/uitest/writer_tests3/pageNumber.py b/sw/qa/uitest/writer_tests3/pageNumber.py index f148d047b33d..30c6ea4781bc 100644 --- a/sw/qa/uitest/writer_tests3/pageNumber.py +++ b/sw/qa/uitest/writer_tests3/pageNumber.py @@ -40,7 +40,8 @@ class PageNumberWizard(UITestCase): self.xUITest.executeCommand(".uno:Undo") self.assertIsNone(document.StyleFamilies.PageStyles.Standard.HeaderText) - self.assertIsNone(document.StyleFamilies.PageStyles.Standard.FooterText) + # FIXME: tdf#164033: Undo is disabled to avoid the crash + self.assertIsNotNone(document.StyleFamilies.PageStyles.Standard.FooterText) with self.ui_test.execute_dialog_through_command(".uno:PageNumberWizard") as xDialog: xPositionCombo = xDialog.getChild("positionCombo") @@ -50,11 +51,11 @@ class PageNumberWizard(UITestCase): xHeader = document.StyleFamilies.PageStyles.Standard.HeaderText.createEnumeration().nextElement() self.assertEqual("A", xHeader.String) - self.assertIsNone(document.StyleFamilies.PageStyles.Standard.FooterText) + self.assertIsNotNone(document.StyleFamilies.PageStyles.Standard.FooterText) self.xUITest.executeCommand(".uno:Undo") - self.assertIsNone(document.StyleFamilies.PageStyles.Standard.HeaderText) - self.assertIsNone(document.StyleFamilies.PageStyles.Standard.FooterText) + self.assertIsNotNone(document.StyleFamilies.PageStyles.Standard.HeaderText) + self.assertIsNotNone(document.StyleFamilies.PageStyles.Standard.FooterText) # vim: set shiftwidth=4 softtabstop=4 expandtab: diff --git a/sw/source/uibase/shells/textfld.cxx b/sw/source/uibase/shells/textfld.cxx index 42fd111f2684..a3d67d44b073 100644 --- a/sw/source/uibase/shells/textfld.cxx +++ b/sw/source/uibase/shells/textfld.cxx @@ -1459,6 +1459,10 @@ FIELD_INSERT: rSh.EndAllAction(); rSh.LockView(false); rDoc.GetIDocumentUndoRedo().EndUndo(SwUndoId::INSERT_PAGE_NUMBER, nullptr); + + // avoid various ways to crash related to undo of SwPageDesc (tdf#161741, tdf#161705) + if (bChangePageDesc) + rDoc.GetIDocumentUndoRedo().DelAllUndoObj(); } pDlg->disposeOnce(); });