sc/inc/document.hxx | 13 ++++++++ sc/qa/unit/ucalc.hxx | 2 + sc/qa/unit/ucalc_formula.cxx | 62 +++++++++++++++++++++++++++++++++++++++ sc/source/core/data/documen3.cxx | 10 ++++++ sc/source/core/tool/token.cxx | 26 ++++++++++++++++ 5 files changed, 113 insertions(+)
New commits: commit 8582db191b5c88c72e5b16c89a024f897a95a6f1 Author: Kohei Yoshida <kohei.yosh...@collabora.com> Date: Tue Mar 25 12:38:48 2014 -0400 fdo#76402: Handle range reference expansion in named ranges. Change-Id: I8314260fc7588f0a0230ab63cc600fa887a8479d diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx index 75f8bc0..7947827 100644 --- a/sc/source/core/tool/token.cxx +++ b/sc/source/core/tool/token.cxx @@ -2939,6 +2939,19 @@ bool adjustDoubleRefInName( ScComplexRefData& rRef, const sc::RefUpdateContext& rCxt, const ScAddress& rPos ) { bool bRefChanged = false; + if (rCxt.mnRowDelta > 0 && rCxt.mrDoc.IsExpandRefs() && !rRef.Ref1.IsRowRel() && !rRef.Ref2.IsRowRel()) + { + // Check and see if we should expand the range at the top. + ScRange aSelectedRange = getSelectedRange(rCxt); + ScRange aAbs = rRef.toAbs(rPos); + if (aSelectedRange.Intersects(aAbs)) + { + // Selection intersects the referenced range. Only expand the + // bottom position. + rRef.Ref2.IncRow(rCxt.mnRowDelta); + return true; + } + } if (adjustSingleRefInName(rRef.Ref1, rCxt, rPos)) bRefChanged = true; @@ -2994,6 +3007,19 @@ sc::RefUpdateResult ScTokenArray::AdjustReferenceInName( aRes.mbReferenceModified = true; } } + else if (rCxt.mnRowDelta > 0 && rCxt.mrDoc.IsExpandRefs()) + { + // Check if we could expand range reference by the bottom + // edge. For named expressions, we only expand absolute + // references. + if (!rRef.Ref1.IsRowRel() && !rRef.Ref2.IsRowRel() && aAbs.aEnd.Row()+1 == rCxt.maRange.aStart.Row()) + { + // Expand by the bottom edge. + rRef.Ref2.IncRow(rCxt.mnRowDelta); + aRes.mbReferenceModified = true; + } + + } } break; default: commit a603ddf9adef4373940936f785e918a8c0ea560b Author: Kohei Yoshida <kohei.yosh...@collabora.com> Date: Tue Mar 25 10:52:48 2014 -0400 fdo#76402: Write unit test for this first. Change-Id: Ib4fccb0e29d4a21a211de4af2cdeaf956f9b9cc6 diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx index becca93..5b8579b 100644 --- a/sc/inc/document.hxx +++ b/sc/inc/document.hxx @@ -514,6 +514,19 @@ public: SC_DLLPUBLIC ScRangeName* GetRangeName() const; void SetRangeName(SCTAB nTab, ScRangeName* pNew); void SetRangeName( ScRangeName* pNewRangeName ); + + /** + * Insert a new named expression to the global scope. + * + * @param rName name for the expression. + * @param rPos base position. + * @param rExpr formula expression to be associated with the name. The + * current grammer is used to compile this expression. + * + * @return true if inserted successfully, false otherwise. + */ + bool InsertNewRangeName( const OUString& rName, const ScAddress& rPos, const OUString& rExpr ); + SCTAB GetMaxTableNumber() { return static_cast<SCTAB>(maTabs.size()) - 1; } void SetMaxTableNumber(SCTAB nNumber) { nMaxTableNumber = nNumber; } diff --git a/sc/qa/unit/ucalc.hxx b/sc/qa/unit/ucalc.hxx index 39b40d1..7c1c67c 100644 --- a/sc/qa/unit/ucalc.hxx +++ b/sc/qa/unit/ucalc.hxx @@ -121,6 +121,7 @@ public: void testFormulaRefUpdateMove(); void testFormulaRefUpdateMoveUndo(); void testFormulaRefUpdateNamedExpression(); + void testFormulaRefUpdateNamedExpressionExpandRef(); void testMultipleOperations(); void testFuncCOLUMN(); void testFuncCOUNT(); @@ -366,6 +367,7 @@ public: CPPUNIT_TEST(testFormulaRefUpdateMove); CPPUNIT_TEST(testFormulaRefUpdateMoveUndo); CPPUNIT_TEST(testFormulaRefUpdateNamedExpression); + CPPUNIT_TEST(testFormulaRefUpdateNamedExpressionExpandRef); CPPUNIT_TEST(testMultipleOperations); CPPUNIT_TEST(testFuncCOLUMN); CPPUNIT_TEST(testFuncCOUNT); diff --git a/sc/qa/unit/ucalc_formula.cxx b/sc/qa/unit/ucalc_formula.cxx index a03ba89..718ece7 100644 --- a/sc/qa/unit/ucalc_formula.cxx +++ b/sc/qa/unit/ucalc_formula.cxx @@ -1818,6 +1818,68 @@ void Test::testFormulaRefUpdateNamedExpression() m_pDoc->DeleteTab(0); } +void Test::testFormulaRefUpdateNamedExpressionExpandRef() +{ + m_pDoc->InsertTab(0, "Test"); + m_pDoc->SetExpandRefs(true); // turn on automatic range expansion. + + sc::AutoCalcSwitch aACSwitch(*m_pDoc, true); // turn auto calc on. + + bool bInserted = m_pDoc->InsertNewRangeName("MyRange", ScAddress(0,0,0), "$A$1:$A$3"); + CPPUNIT_ASSERT(bInserted); + + // Set values to A1:A3. + m_pDoc->SetValue(ScAddress(0,0,0), 1.0); + m_pDoc->SetValue(ScAddress(0,1,0), 2.0); + m_pDoc->SetValue(ScAddress(0,2,0), 3.0); + + m_pDoc->SetString(ScAddress(0,5,0), "=SUM(MyRange)"); + CPPUNIT_ASSERT_EQUAL(6.0, m_pDoc->GetValue(ScAddress(0,5,0))); + + // Insert a new row at row 4, which should expand the named range to A1:A4. + ScDocFunc& rFunc = getDocShell().GetDocFunc(); + ScMarkData aMark; + aMark.SelectOneTable(0); + rFunc.InsertCells(ScRange(0,3,0,MAXCOL,3,0), &aMark, INS_INSROWS, false, true, false); + ScRangeData* pName = m_pDoc->GetRangeName()->findByUpperName("MYRANGE"); + CPPUNIT_ASSERT(pName); + OUString aSymbol; + pName->GetSymbol(aSymbol, m_pDoc->GetGrammar()); + CPPUNIT_ASSERT_EQUAL(OUString("$A$1:$A$4"), aSymbol); + + // Make sure the listening area has been expanded as well. Note the + // formula cell has been pushed downward by one cell. + m_pDoc->SetValue(ScAddress(0,3,0), 4.0); + CPPUNIT_ASSERT_EQUAL(10.0, m_pDoc->GetValue(ScAddress(0,6,0))); + + // Clear the document and start over. + m_pDoc->GetRangeName()->clear(); + clearSheet(m_pDoc, 0); + + // Set values to B4:B6. + m_pDoc->SetValue(ScAddress(1,3,0), 1.0); + m_pDoc->SetValue(ScAddress(1,4,0), 2.0); + m_pDoc->SetValue(ScAddress(1,5,0), 3.0); + + bInserted = m_pDoc->InsertNewRangeName("MyRange", ScAddress(0,0,0), "$B$4:$B$6"); + CPPUNIT_ASSERT(bInserted); + + // Set formula to A1. + m_pDoc->SetString(ScAddress(0,0,0), "=SUM(MyRange)"); + CPPUNIT_ASSERT_EQUAL(6.0, m_pDoc->GetValue(0,0,0)); + + // Insert rows over 3:5 which should expand the range by 3 rows. + rFunc.InsertCells(ScRange(0,2,0,MAXCOL,4,0), &aMark, INS_INSROWS, false, true, false); + + pName = m_pDoc->GetRangeName()->findByUpperName("MYRANGE"); + CPPUNIT_ASSERT(pName); + + pName->GetSymbol(aSymbol, m_pDoc->GetGrammar()); + CPPUNIT_ASSERT_EQUAL(OUString("$B$4:$B$9"), aSymbol); + + m_pDoc->DeleteTab(0); +} + void Test::testMultipleOperations() { m_pDoc->InsertTab(0, "MultiOp"); diff --git a/sc/source/core/data/documen3.cxx b/sc/source/core/data/documen3.cxx index 4dd1222..051c0d1 100644 --- a/sc/source/core/data/documen3.cxx +++ b/sc/source/core/data/documen3.cxx @@ -207,6 +207,16 @@ void ScDocument::SetRangeName( ScRangeName* pNewRangeName ) pRangeName = pNewRangeName; } +bool ScDocument::InsertNewRangeName( const OUString& rName, const ScAddress& rPos, const OUString& rExpr ) +{ + ScRangeName* pGlobalNames = GetRangeName(); + if (!pGlobalNames) + return false; + + ScRangeData* pName = new ScRangeData(this, rName, rExpr, rPos, RT_NAME, GetGrammar()); + return pGlobalNames->insert(pName); +} + const ScRangeData* ScDocument::GetRangeAtBlock( const ScRange& rBlock, OUString* pName ) const { const ScRangeData* pData = NULL; _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits