Skip to content

Commit a0403b6

Browse files
committed
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 <[email protected]>
1 parent fe7a34d commit a0403b6

File tree

3 files changed

+105
-12
lines changed

3 files changed

+105
-12
lines changed

sc/inc/cellsuno.hxx

+12
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,9 @@ protected:
227227
SC_DLLPUBLIC virtual void SetOnePropertyValue( const SfxItemPropertyMapEntry* pEntry,
228228
const css::uno::Any& aValue );
229229

230+
ScRangeList& AccessRanges() { return aRanges; }
231+
SC_DLLPUBLIC virtual void AdjustUpdatedRanges(UpdateRefMode mode);
232+
230233
public:
231234
ScCellRangesBase(ScDocShell* pDocSh, const ScRange& rR);
232235
ScCellRangesBase(ScDocShell* pDocSh, ScRangeList aR);
@@ -935,6 +938,9 @@ public:
935938
virtual OUString SAL_CALL getImplementationName() override;
936939
virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override;
937940
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
941+
942+
protected:
943+
void AdjustUpdatedRanges(UpdateRefMode mode) override;
938944
};
939945

940946
using ScTableColumnObj_BASE = cppu::ImplInheritanceHelper<ScCellRangeObj,
@@ -966,6 +972,9 @@ public:
966972
virtual OUString SAL_CALL getImplementationName() override;
967973
virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override;
968974
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
975+
976+
protected:
977+
void AdjustUpdatedRanges(UpdateRefMode mode) override;
969978
};
970979

971980
class ScTableRowObj final : public ScCellRangeObj
@@ -991,6 +1000,9 @@ public:
9911000
virtual OUString SAL_CALL getImplementationName() override;
9921001
virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override;
9931002
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
1003+
1004+
protected:
1005+
void AdjustUpdatedRanges(UpdateRefMode mode) override;
9941006
};
9951007

9961008
class ScCellsObj final : public cppu::WeakImplHelper<

sc/qa/extras/macros-test.cxx

+57
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,11 @@
1717
#include <document.hxx>
1818
#include <scitems.hxx>
1919

20+
#include <com/sun/star/sheet/XCellRangeAddressable.hpp>
21+
#include <com/sun/star/sheet/XCellRangeMovement.hpp>
2022
#include <com/sun/star/sheet/XFunctionAccess.hpp>
2123
#include <com/sun/star/sheet/XSpreadsheet.hpp>
24+
#include <com/sun/star/table/XColumnRowRange.hpp>
2225

2326
#include <com/sun/star/script/XLibraryContainerPassword.hpp>
2427
#include <com/sun/star/drawing/XDrawPageSupplier.hpp>
@@ -919,6 +922,60 @@ CPPUNIT_TEST_FIXTURE(ScMacrosTest, testTdf159412)
919922
CPPUNIT_ASSERT_EQUAL(u"1 Long/2 Double"_ustr, aReturnValue);
920923
}
921924

925+
CPPUNIT_TEST_FIXTURE(ScMacrosTest, testTdf47479)
926+
{
927+
createScDoc();
928+
uno::Reference<sheet::XSpreadsheetDocument> xDoc(mxComponent, UNO_QUERY_THROW);
929+
auto xSheets = xDoc->getSheets().queryThrow<container::XIndexAccess>();
930+
auto xSheet = xSheets->getByIndex(0).queryThrow<sheet::XCellRangeMovement>();
931+
auto xSheetAddressable = xSheet.queryThrow<sheet::XCellRangeAddressable>();
932+
auto xColRowRange = xSheet.queryThrow<table::XColumnRowRange>();
933+
auto xColAddressable
934+
= xColRowRange->getColumns()->getByIndex(1).queryThrow<sheet::XCellRangeAddressable>();
935+
auto xRowAddressable
936+
= xColRowRange->getRows()->getByIndex(1).queryThrow<sheet::XCellRangeAddressable>();
937+
css::table::CellRangeAddress origSheetRange = xSheetAddressable->getRangeAddress();
938+
css::table::CellRangeAddress origColRange = xColAddressable->getRangeAddress();
939+
css::table::CellRangeAddress origRowRange = xRowAddressable->getRangeAddress();
940+
css::table::CellRangeAddress addressToRemove(origSheetRange.Sheet, 1, 1, 1, 1);
941+
942+
xSheet->removeRange(addressToRemove, css::sheet::CellDeleteMode_UP);
943+
944+
auto currentRange = xSheetAddressable->getRangeAddress();
945+
CPPUNIT_ASSERT_EQUAL(origSheetRange.Sheet, currentRange.Sheet);
946+
CPPUNIT_ASSERT_EQUAL(origSheetRange.StartColumn, currentRange.StartColumn);
947+
CPPUNIT_ASSERT_EQUAL(origSheetRange.StartRow, currentRange.StartRow);
948+
CPPUNIT_ASSERT_EQUAL(origSheetRange.EndColumn, currentRange.EndColumn);
949+
// Without the fix, this would fail with
950+
// - Expected: 1048575
951+
// - Actual : 0
952+
CPPUNIT_ASSERT_EQUAL(origSheetRange.EndRow, currentRange.EndRow);
953+
954+
xSheet->removeRange(addressToRemove, css::sheet::CellDeleteMode_LEFT);
955+
956+
currentRange = xColAddressable->getRangeAddress();
957+
CPPUNIT_ASSERT_EQUAL(origColRange.Sheet, currentRange.Sheet);
958+
CPPUNIT_ASSERT_EQUAL(origColRange.StartColumn, currentRange.StartColumn);
959+
// Without the fix, this would fail with
960+
// - Expected: 0
961+
// - Actual : 2
962+
CPPUNIT_ASSERT_EQUAL(origColRange.StartRow, currentRange.StartRow);
963+
CPPUNIT_ASSERT_EQUAL(origColRange.EndColumn, currentRange.EndColumn);
964+
CPPUNIT_ASSERT_EQUAL(origColRange.EndRow, currentRange.EndRow);
965+
966+
xSheet->removeRange(origColRange, css::sheet::CellDeleteMode_UP);
967+
968+
currentRange = xRowAddressable->getRangeAddress();
969+
CPPUNIT_ASSERT_EQUAL(origRowRange.Sheet, currentRange.Sheet);
970+
// Without the fix, this would fail with
971+
// - Expected: 0
972+
// - Actual : 2
973+
CPPUNIT_ASSERT_EQUAL(origRowRange.StartColumn, currentRange.StartColumn);
974+
CPPUNIT_ASSERT_EQUAL(origRowRange.StartRow, currentRange.StartRow);
975+
CPPUNIT_ASSERT_EQUAL(origRowRange.EndColumn, currentRange.EndColumn);
976+
CPPUNIT_ASSERT_EQUAL(origRowRange.EndRow, currentRange.EndRow);
977+
}
978+
922979
ScMacrosTest::ScMacrosTest()
923980
: ScModelTestBase(u"/sc/qa/extras/testdocuments"_ustr)
924981
{

sc/source/ui/unoobj/cellsuno.cxx

+36-12
Original file line numberDiff line numberDiff line change
@@ -1475,6 +1475,8 @@ const ScMarkData* ScCellRangesBase::GetMarkData()
14751475
return pMarkData.get();
14761476
}
14771477

1478+
void ScCellRangesBase::AdjustUpdatedRanges(UpdateRefMode) {}
1479+
14781480
void ScCellRangesBase::Notify( SfxBroadcaster&, const SfxHint& rHint )
14791481
{
14801482
const SfxHintId nId = rHint.GetId();
@@ -1546,18 +1548,7 @@ void ScCellRangesBase::Notify( SfxBroadcaster&, const SfxHint& rHint )
15461548
if ( aRanges.UpdateReference( pRefHint->GetMode(), &rDoc, pRefHint->GetRange(),
15471549
pRefHint->GetDx(), pRefHint->GetDy(), pRefHint->GetDz() ) )
15481550
{
1549-
if ( pRefHint->GetMode() == URM_INSDEL
1550-
&& aRanges.size() == 1
1551-
&& dynamic_cast<ScTableSheetObj*>(this)
1552-
)
1553-
{
1554-
// #101755#; the range size of a sheet does not change
1555-
ScRange & rR = aRanges.front();
1556-
rR.aStart.SetCol(0);
1557-
rR.aStart.SetRow(0);
1558-
rR.aEnd.SetCol(rDoc.MaxCol());
1559-
rR.aEnd.SetRow(rDoc.MaxRow());
1560-
}
1551+
AdjustUpdatedRanges(pRefHint->GetMode());
15611552
RefChanged();
15621553

15631554
// any change of the range address is broadcast to value (modify) listeners
@@ -6392,6 +6383,17 @@ SCTAB ScTableSheetObj::GetTab_Impl() const
63926383
return 0;
63936384
}
63946385

6386+
void ScTableSheetObj::AdjustUpdatedRanges(UpdateRefMode mode)
6387+
{
6388+
if (mode == URM_INSDEL)
6389+
{
6390+
ScRangeList& rRanges = AccessRanges();
6391+
// #101755#, tdf#47479: the range of a sheet does not change
6392+
rRanges.RemoveAll();
6393+
rRanges.push_back(GetRange());
6394+
}
6395+
}
6396+
63956397
// former XSheet
63966398

63976399
uno::Reference<table::XTableCharts> SAL_CALL ScTableSheetObj::getCharts()
@@ -8195,6 +8197,17 @@ const SfxItemPropertyMap& ScTableColumnObj::GetItemPropertyMap()
81958197
return pColPropSet->getPropertyMap();
81968198
}
81978199

8200+
void ScTableColumnObj::AdjustUpdatedRanges(UpdateRefMode mode)
8201+
{
8202+
if (mode == URM_INSDEL)
8203+
{
8204+
ScRangeList& rRanges = AccessRanges();
8205+
// tdf#47479: the range of a column does not change
8206+
rRanges.RemoveAll();
8207+
rRanges.push_back(GetRange());
8208+
}
8209+
}
8210+
81988211
ScTableRowObj::ScTableRowObj(ScDocShell* pDocSh, SCROW nRow, SCTAB nTab) :
81998212
ScCellRangeObj( pDocSh, ScRange(0,nRow,nTab, pDocSh->GetDocument().MaxCol(),nRow,nTab) ),
82008213
pRowPropSet(lcl_GetRowPropertySet())
@@ -8344,6 +8357,17 @@ const SfxItemPropertyMap& ScTableRowObj::GetItemPropertyMap()
83448357
return pRowPropSet->getPropertyMap();
83458358
}
83468359

8360+
void ScTableRowObj::AdjustUpdatedRanges(UpdateRefMode mode)
8361+
{
8362+
if (mode == URM_INSDEL)
8363+
{
8364+
ScRangeList& rRanges = AccessRanges();
8365+
// tdf#47479: the range of a row does not change
8366+
rRanges.RemoveAll();
8367+
rRanges.push_back(GetRange());
8368+
}
8369+
}
8370+
83478371
ScCellsObj::ScCellsObj(ScDocShell* pDocSh, ScRangeList aR) :
83488372
pDocShell( pDocSh ),
83498373
aRanges(std::move( aR ))

0 commit comments

Comments
 (0)