From 9971b1602d2a526dd8f2cc8255794515bb4e2168 Mon Sep 17 00:00:00 2001 From: Tibor Nagy Date: Mon, 5 Oct 2020 20:47:14 +0200 Subject: tdf#125462 sc: remove red (invalid data) circle MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit around the cell after typing valid data in it. This mark wasn't removed when correct data is entered in the cell, giving the impression that the entered value is incorrect. Note: This fixes only the directly modified cell, not the other cells with red circles which refer the modified cell. Testing: Tools->Detective->Mark Invalid Data adds these red circles around the cells with invalid content, according to their validation added by Data->Validity... Co-authored-by: Attila Szűcs (NISZ) Change-Id: Ib7ca3c453a930669a7c58e89b91654de36b8bb3b Reviewed-on: https://gerrit.libreoffice.org/c/core/+/103995 Tested-by: László Németh Reviewed-by: László Németh --- sc/inc/detfunc.hxx | 1 + sc/qa/unit/data/xlsx/testDeleteCircles.xlsx | Bin 0 -> 8420 bytes sc/qa/unit/subsequent_filters-test.cxx | 42 +++++++++++++++++++++ sc/source/core/tool/detfunc.cxx | 55 ++++++++++++++++++++++++++++ sc/source/ui/docshell/docfunc.cxx | 10 +++++ 5 files changed, 108 insertions(+) create mode 100644 sc/qa/unit/data/xlsx/testDeleteCircles.xlsx (limited to 'sc') diff --git a/sc/inc/detfunc.hxx b/sc/inc/detfunc.hxx index 38de23a954ae..623f1e5c3442 100644 --- a/sc/inc/detfunc.hxx +++ b/sc/inc/detfunc.hxx @@ -126,6 +126,7 @@ public: bool DeleteSucc( SCCOL nCol, SCROW nRow ); bool DeletePred( SCCOL nCol, SCROW nRow ); bool DeleteAll( ScDetectiveDelete eWhat ); + bool DeleteCirclesAt( SCCOL nCol, SCROW nRow ); bool MarkInvalid(bool& rOverflow); diff --git a/sc/qa/unit/data/xlsx/testDeleteCircles.xlsx b/sc/qa/unit/data/xlsx/testDeleteCircles.xlsx new file mode 100644 index 000000000000..1f544957fcd9 Binary files /dev/null and b/sc/qa/unit/data/xlsx/testDeleteCircles.xlsx differ diff --git a/sc/qa/unit/subsequent_filters-test.cxx b/sc/qa/unit/subsequent_filters-test.cxx index 1f4906a1803f..3f2b354a4efe 100644 --- a/sc/qa/unit/subsequent_filters-test.cxx +++ b/sc/qa/unit/subsequent_filters-test.cxx @@ -65,6 +65,7 @@ #include #include #include +#include #include #include @@ -284,6 +285,7 @@ public: void testShapeDisplacementOnRotationImport(); void testTextBoxBodyUpright(); void testTextLengthDataValidityXLSX(); + void testDeleteCircles(); CPPUNIT_TEST_SUITE(ScFiltersTest); CPPUNIT_TEST(testBooleanFormatXLSX); @@ -456,6 +458,7 @@ public: CPPUNIT_TEST(testShapeDisplacementOnRotationImport); CPPUNIT_TEST(testTextBoxBodyUpright); CPPUNIT_TEST(testTextLengthDataValidityXLSX); + CPPUNIT_TEST(testDeleteCircles); CPPUNIT_TEST_SUITE_END(); @@ -5021,6 +5024,45 @@ void ScFiltersTest::testTextLengthDataValidityXLSX() xDocSh->DoClose(); } +void ScFiltersTest::testDeleteCircles() +{ + ScDocShellRef xDocSh = loadDoc("testDeleteCircles.", FORMAT_XLSX); + CPPUNIT_ASSERT_MESSAGE("Failed to load testDeleteCircles.xlsx", xDocSh.is()); + + ScDocument& rDoc = xDocSh->GetDocument(); + + ScDrawLayer* pDrawLayer = rDoc.GetDrawLayer(); + SdrPage* pPage = pDrawLayer->GetPage(0); + CPPUNIT_ASSERT_MESSAGE("draw page for sheet 1 should exist.", pPage); + + ScRefCellValue aCellA1; // A1 = "Hello" + ScAddress aPosA1(0, 0, 0); + aCellA1.assign(rDoc, aPosA1); + + // Mark invalid value + bool bOverflow; + bool bMarkInvalid = ScDetectiveFunc(rDoc, 0).MarkInvalid(bOverflow); + CPPUNIT_ASSERT_EQUAL(true, bMarkInvalid); + + // There should be a circle object! + CPPUNIT_ASSERT_EQUAL(static_cast(1), pPage->GetObjCount()); + + // The value of A1 change to Hello1. + rDoc.SetString(0, 0, 0, "Hello1"); + + // Check that the data is valid.(True if text length = 6) + const ScValidationData* pData = rDoc.GetValidationEntry(1); + bool bValidA1 = pData->IsDataValid(aCellA1, aPosA1); + // if valid, delete circle. + if (bValidA1) + ScDetectiveFunc(rDoc, 0).DeleteCirclesAt(aPosA1.Col(), aPosA1.Row()); + + // There should not be a circle object! + CPPUNIT_ASSERT_EQUAL(static_cast(0), pPage->GetObjCount()); + + xDocSh->DoClose(); +} + ScFiltersTest::ScFiltersTest() : ScBootstrapFixture( "sc/qa/unit/data" ) { diff --git a/sc/source/core/tool/detfunc.cxx b/sc/source/core/tool/detfunc.cxx index d4c1ab66ec2e..813345b5e46d 100644 --- a/sc/source/core/tool/detfunc.cxx +++ b/sc/source/core/tool/detfunc.cxx @@ -1238,6 +1238,61 @@ bool ScDetectiveFunc::DeletePred( SCCOL nCol, SCROW nRow ) return ( nLevelCount != 0 ); } +bool ScDetectiveFunc::DeleteCirclesAt( SCCOL nCol, SCROW nRow ) +{ + tools::Rectangle aRect = GetDrawRect(nCol, nRow); + aRect.AdjustLeft(-250); + aRect.AdjustRight(250); + aRect.AdjustTop(-70); + aRect.AdjustBottom(70); + + Point aStartCorner = aRect.TopLeft(); + Point aEndCorner = aRect.BottomRight(); + + ScDrawLayer* pModel = rDoc.GetDrawLayer(); + if (!pModel) + return false; + + SdrPage* pPage = pModel->GetPage(static_cast(nTab)); + OSL_ENSURE(pPage, "Page ?"); + + pPage->RecalcObjOrdNums(); + + const size_t nObjCount = pPage->GetObjCount(); + size_t nDelCount = 0; + if (nObjCount) + { + std::unique_ptr ppObj(new SdrObject*[nObjCount]); + + SdrObjListIter aIter(pPage, SdrIterMode::Flat); + SdrObject* pObject = aIter.Next(); + while (pObject) + { + if (pObject->GetLayer() == SC_LAYER_INTERN + && dynamic_cast(pObject) != nullptr) + { + tools::Rectangle aObjRect = static_cast(pObject)->GetLogicRect(); + if (RectIsPoints(aObjRect, aStartCorner, aEndCorner)) + ppObj[nDelCount++] = pObject; + } + + pObject = aIter.Next(); + } + + for (size_t i = 1; i <= nDelCount; ++i) + pModel->AddCalcUndo(std::make_unique(*ppObj[nDelCount - i])); + + for (size_t i = 1; i <= nDelCount; ++i) + pPage->RemoveObject(ppObj[nDelCount - i]->GetOrdNum()); + + ppObj.reset(); + + Modified(); + } + + return (nDelCount != 0); +} + bool ScDetectiveFunc::DeleteAll( ScDetectiveDelete eWhat ) { ScDrawLayer* pModel = rDoc.GetDrawLayer(); diff --git a/sc/source/ui/docshell/docfunc.cxx b/sc/source/ui/docshell/docfunc.cxx index b0229c4c20f6..358fb135d17c 100644 --- a/sc/source/ui/docshell/docfunc.cxx +++ b/sc/source/ui/docshell/docfunc.cxx @@ -92,6 +92,7 @@ #include #include #include +#include #include #include @@ -839,6 +840,15 @@ bool ScDocFunc::SetNormalString( bool& o_rbNumFmtSet, const ScAddress& rPos, con if (bApi) NotifyInputHandler( rPos ); + const SfxUInt32Item* pItem = rDoc.GetAttr(rPos, ATTR_VALIDDATA); + const ScValidationData* pData = rDoc.GetValidationEntry(pItem->GetValue()); + if (pData) + { + ScRefCellValue aCell(rDoc, rPos); + if (pData->IsDataValid(aCell, rPos)) + ScDetectiveFunc(rDoc, rPos.Tab()).DeleteCirclesAt(rPos.Col(), rPos.Row()); + } + return true; } -- cgit