/* -*- 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/.
*/
// Undo the new row
m_pDoc->GetUndoManager()->Undo();
// Check patterns // Failed if row 3 is not blue all the way through
pItem = nullptr;
m_pDoc->GetPattern(ScAddress(1000, 3, 0))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
CPPUNIT_ASSERT(pItem);
CPPUNIT_ASSERT_EQUAL(COL_BLUE, static_cast<const SvxBrushItem*>(pItem)->GetColor());
// Undo the new column
m_pDoc->GetUndoManager()->Undo();
// Check patterns // Failed if column 3 is not blue all the way through
pItem = nullptr;
m_pDoc->GetPattern(ScAddress(3, 1000, 0))->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem);
CPPUNIT_ASSERT(pItem);
CPPUNIT_ASSERT_EQUAL(COL_BLUE, static_cast<const SvxBrushItem*>(pItem)->GetColor());
{ // These two shared string objects must go out of scope before the purge test.
svl::SharedString aSS1 = m_pDoc->GetSharedString(ScAddress(0,0,0));
svl::SharedString aSS2 = m_pDoc->GetSharedString(ScAddress(0,1,0));
CPPUNIT_ASSERT_MESSAGE("Failed to get a valid shared string.", aSS1.isValid());
CPPUNIT_ASSERT_MESSAGE("Failed to get a valid shared string.", aSS2.isValid());
CPPUNIT_ASSERT_EQUAL(aSS1.getData(), aSS2.getData());
aSS2 = m_pDoc->GetSharedString(ScAddress(0,2,0));
CPPUNIT_ASSERT_MESSAGE("They must differ", aSS1.getData() != aSS2.getData());
aSS2 = m_pDoc->GetSharedString(ScAddress(0,3,0));
CPPUNIT_ASSERT_MESSAGE("They must differ", aSS1.getData() != aSS2.getData());
aSS2 = m_pDoc->GetSharedString(ScAddress(0,4,0));
CPPUNIT_ASSERT_MESSAGE("They must differ", aSS1.getData() != aSS2.getData());
// A3 and A5 should differ but should be equal case-insensitively.
aSS1 = m_pDoc->GetSharedString(ScAddress(0,2,0));
aSS2 = m_pDoc->GetSharedString(ScAddress(0,4,0));
CPPUNIT_ASSERT_MESSAGE("They must differ", aSS1.getData() != aSS2.getData());
CPPUNIT_ASSERT_EQUAL_MESSAGE("They must be equal when cases are ignored.", aSS1.getDataIgnoreCase(), aSS2.getDataIgnoreCase());
// A2 and A4 should be equal when ignoring cases.
aSS1 = m_pDoc->GetSharedString(ScAddress(0,1,0));
aSS2 = m_pDoc->GetSharedString(ScAddress(0,3,0));
CPPUNIT_ASSERT_EQUAL_MESSAGE("They must be equal when cases are ignored.", aSS1.getDataIgnoreCase(), aSS2.getDataIgnoreCase());
}
// Check the string counts after purging. Purging shouldn't remove any strings in this case.
rPool.purge();
CPPUNIT_ASSERT_EQUAL(5+extraCount, rPool.getCount());
CPPUNIT_ASSERT_EQUAL(2+extraCountIgnoreCase, rPool.getCountIgnoreCase());
// Clear A1
clearRange(m_pDoc, ScRange(ScAddress(0,0,0))); // Clear A2
clearRange(m_pDoc, ScRange(ScAddress(0,1,0))); // Clear A3
clearRange(m_pDoc, ScRange(ScAddress(0,2,0))); // Clear A4
clearRange(m_pDoc, ScRange(ScAddress(0,3,0))); // Clear A5 and the pool should be completely empty.
clearRange(m_pDoc, ScRange(ScAddress(0,4,0)));
rPool.purge();
CPPUNIT_ASSERT_EQUAL(extraCount, rPool.getCount());
CPPUNIT_ASSERT_EQUAL(extraCountIgnoreCase, rPool.getCountIgnoreCase());
// Now, compare string and edit text cells.
m_pDoc->SetString(ScAddress(0,0,0), "Andy and Bruce"); // A1 // [-loplugin:ostr]
ScFieldEditEngine& rEE = m_pDoc->GetEditEngine();
rEE.SetTextCurrentDefaults(u"Andy and Bruce"_ustr);
// These two should be equal.
svl::SharedString aSS1 = m_pDoc->GetSharedString(ScAddress(0,0,0));
svl::SharedString aSS2 = m_pDoc->GetSharedString(ScAddress(1,0,0));
CPPUNIT_ASSERT_MESSAGE("Failed to get a valid string ID.", aSS1.isValid());
CPPUNIT_ASSERT_MESSAGE("Failed to get a valid string ID.", aSS2.isValid());
CPPUNIT_ASSERT_EQUAL(aSS1.getData(), aSS2.getData());
rEE.SetTextCurrentDefaults(u"ANDY and BRUCE"_ustr);
m_pDoc->SetEditText(ScAddress(2,0,0), rEE.CreateTextObject()); // C1
aSS2 = m_pDoc->GetSharedString(ScAddress(2,0,0));
CPPUNIT_ASSERT_MESSAGE("Failed to get a valid string ID.", aSS2.isValid());
CPPUNIT_ASSERT_MESSAGE("These two should be different when cases are considered.", aSS1.getData() != aSS2.getData());
// But they should be considered equal when cases are ignored.
aSS1 = m_pDoc->GetSharedString(ScAddress(0,0,0));
aSS2 = m_pDoc->GetSharedString(ScAddress(2,0,0));
CPPUNIT_ASSERT_MESSAGE("Failed to get a valid string ID.", aSS1.isValid());
CPPUNIT_ASSERT_MESSAGE("Failed to get a valid string ID.", aSS2.isValid());
CPPUNIT_ASSERT_EQUAL(aSS1.getDataIgnoreCase(), aSS2.getDataIgnoreCase());
ScRangeList aRL;
aRL.push_back(ScRange(1,1,0,3,10,0));
CPPUNIT_ASSERT_EQUAL_MESSAGE("List should have one range.", size_t(1), aRL.size()); const ScRange* p = &aRL[0];
CPPUNIT_ASSERT_MESSAGE("Failed to get the range object.", p);
CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong range.", ScAddress(1,1,0), p->aStart);
CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong range.", ScAddress(3,10,0), p->aEnd);
// Empty mark. Nothing is selected.
std::vector<sc::ColRowSpan> aSpans = aMarkData.GetMarkedRowSpans();
CPPUNIT_ASSERT_MESSAGE("Span should be empty.", aSpans.empty());
aSpans = aMarkData.GetMarkedColSpans();
CPPUNIT_ASSERT_MESSAGE("Span should be empty.", aSpans.empty());
// Select B3:F7.
aMarkData.SetMarkArea(ScRange(1,2,0,5,6,0));
aSpans = aMarkData.GetMarkedRowSpans();
CPPUNIT_ASSERT_EQUAL_MESSAGE("There should be one selected row span.", size_t(1), aSpans.size());
CPPUNIT_ASSERT_EQUAL(static_cast<SCCOLROW>(2), aSpans[0].mnStart);
CPPUNIT_ASSERT_EQUAL(static_cast<SCCOLROW>(6), aSpans[0].mnEnd);
aSpans = aMarkData.GetMarkedColSpans();
CPPUNIT_ASSERT_EQUAL_MESSAGE("There should be one selected column span.", size_t(1), aSpans.size());
CPPUNIT_ASSERT_EQUAL(static_cast<SCCOLROW>(1), aSpans[0].mnStart);
CPPUNIT_ASSERT_EQUAL(static_cast<SCCOLROW>(5), aSpans[0].mnEnd);
aSpans = aMarkData.GetMarkedColSpans();
CPPUNIT_ASSERT_EQUAL_MESSAGE("There should be one selected column span.", size_t(1), aSpans.size());
CPPUNIT_ASSERT_EQUAL(static_cast<SCCOLROW>(0), aSpans[0].mnStart);
CPPUNIT_ASSERT_EQUAL(static_cast<SCCOLROW>(5), aSpans[0].mnEnd);
// Select C8:C10.
aMarkData.SetMultiMarkArea(ScRange(2,7,0,2,9,0));
aSpans = aMarkData.GetMarkedRowSpans();
CPPUNIT_ASSERT_EQUAL_MESSAGE("There should be one selected row span.", size_t(1), aSpans.size());
CPPUNIT_ASSERT_EQUAL(static_cast<SCCOLROW>(2), aSpans[0].mnStart);
CPPUNIT_ASSERT_EQUAL(static_cast<SCCOLROW>(12), aSpans[0].mnEnd);
aSpans = aMarkData.GetMarkedColSpans();
CPPUNIT_ASSERT_EQUAL_MESSAGE("There should be one selected column span.", size_t(1), aSpans.size());
CPPUNIT_ASSERT_EQUAL(static_cast<SCCOLROW>(0), aSpans[0].mnStart);
CPPUNIT_ASSERT_EQUAL(static_cast<SCCOLROW>(5), aSpans[0].mnEnd);
}
CPPUNIT_TEST_FIXTURE(Test, testInput)
{
CPPUNIT_ASSERT_MESSAGE ("failed to insert sheet",
m_pDoc->InsertTab (0, u"foo"_ustr));
OUString test;
m_pDoc->SetString(0, 0, 0, u"'10.5"_ustr);
test = m_pDoc->GetString(0, 0, 0); bool bTest = test == "10.5";
CPPUNIT_ASSERT_MESSAGE("String number should have the first apostrophe stripped.", bTest);
m_pDoc->SetString(0, 0, 0, u"'apple'"_ustr);
test = m_pDoc->GetString(0, 0, 0);
bTest = test == "apple'";
CPPUNIT_ASSERT_MESSAGE("Text content should have the first apostrophe stripped.", bTest);
// Customized string handling policy.
ScSetStringParam aParam;
aParam.setTextInput();
m_pDoc->SetString(0, 0, 0, u"000123"_ustr, &aParam);
test = m_pDoc->GetString(0, 0, 0);
CPPUNIT_ASSERT_EQUAL_MESSAGE("Text content should have been treated as string, not number.", u"000123"_ustr, test);
// Transfer generated tabs to a new document with different order
ScDocument aScDocument;
aScDocument.TransferTab(*m_pDoc, nSecondTab, nFirstTab);
aScDocument.TransferTab(*m_pDoc, nFirstTab, nSecondTab);
// Check the number of print ranges in both documents
CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16>(1), m_pDoc->GetPrintRangeCount(nFirstTab));
CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16>(1), m_pDoc->GetPrintRangeCount(nSecondTab));
CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16>(1), aScDocument.GetPrintRangeCount(nFirstTab));
CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16>(1), aScDocument.GetPrintRangeCount(nSecondTab));
// Check the print ranges and col/row repetitions in both documents
CPPUNIT_ASSERT_EQUAL(aFirstPrintRange, *m_pDoc->GetPrintRange(nFirstTab, 0));
CPPUNIT_ASSERT_EQUAL(aFirstRepeatColRange, *m_pDoc->GetRepeatColRange(nFirstTab));
CPPUNIT_ASSERT_EQUAL(aFirstRepeatRowRange, *m_pDoc->GetRepeatRowRange(nFirstTab));
CPPUNIT_ASSERT_EQUAL(aSecondPrintRange, *m_pDoc->GetPrintRange(nSecondTab, 0));
CPPUNIT_ASSERT_EQUAL(aSecondRepeatColRange, *m_pDoc->GetRepeatColRange(nSecondTab));
CPPUNIT_ASSERT_EQUAL(aSecondRepeatRowRange, *m_pDoc->GetRepeatRowRange(nSecondTab));
// Tabs have to be adjusted since the order of the tabs is inverted in the new document
std::vector<ScRange*> aScRanges
= { &aFirstPrintRange, &aFirstRepeatColRange, &aFirstRepeatRowRange,
&aSecondPrintRange, &aSecondRepeatColRange, &aSecondRepeatRowRange }; for (size_t i = 0; i < aScRanges.size(); i++)
{ const SCTAB nTab = i >= 3 ? nFirstTab : nSecondTab;
aScRanges[i]->aStart.SetTab(nTab);
aScRanges[i]->aEnd.SetTab(nTab);
}
// Without the fix in place, no print ranges and col/row repetitions would be present
CPPUNIT_ASSERT_EQUAL(aFirstPrintRange, *aScDocument.GetPrintRange(nSecondTab, 0));
CPPUNIT_ASSERT_EQUAL(aFirstRepeatColRange, *aScDocument.GetRepeatColRange(nSecondTab));
CPPUNIT_ASSERT_EQUAL(aFirstRepeatRowRange, *aScDocument.GetRepeatRowRange(nSecondTab));
CPPUNIT_ASSERT_EQUAL(aSecondPrintRange, *aScDocument.GetPrintRange(nFirstTab, 0));
CPPUNIT_ASSERT_EQUAL(aSecondRepeatColRange, *aScDocument.GetRepeatColRange(nFirstTab));
CPPUNIT_ASSERT_EQUAL(aSecondRepeatRowRange, *aScDocument.GetRepeatRowRange(nFirstTab));
CPPUNIT_TEST_FIXTURE(Test, testTdf113027)
{ // Insert some sheets including a whitespace in their name and switch the grammar to R1C1
CPPUNIT_ASSERT(m_pDoc->InsertTab(0, u"Sheet 1"_ustr));
CPPUNIT_ASSERT(m_pDoc->InsertTab(1, u"Sheet 2"_ustr));
FormulaGrammarSwitch aFGSwitch(m_pDoc, formula::FormulaGrammar::GRAM_ENGLISH_XL_R1C1);
// Add a formula containing a remote reference, i.e., to another sheet const ScAddress aScAddress(0, 0, 0); static constexpr OUString aFormula = u"='Sheet 2'!RC"_ustr;
m_pDoc->SetString(aScAddress, aFormula);
// Switch from relative to absolute cell reference
ScRefFinder aFinder(aFormula, aScAddress, *m_pDoc, m_pDoc->GetAddressConvention());
aFinder.ToggleRel(0, aFormula.getLength());
// Without the fix in place, this test would have failed with // - Expected: ='Sheet 2'!R1C1 // - Actual : ='Sheet 2'!RC // i.e. the cell reference was not changed from relative to absolute
CPPUNIT_ASSERT_EQUAL(u"='Sheet 2'!R1C1"_ustr, aFinder.GetText());
// Without the fix in place, this would have failed with // - Expected: =(1;2) // - Actual : =(1~2)
OUString aFormula = m_pDoc->GetFormula(0,0,0);
CPPUNIT_ASSERT_EQUAL(u"=(1;2)"_ustr, aFormula);
// Without the fix in place, this would have failed with // - Expected: =A1/100% // - Actual : =A1/1
OUString aFormula = m_pDoc->GetFormula(1,0,0);
CPPUNIT_ASSERT_EQUAL(u"=A1/100%"_ustr, aFormula);
// Without the fix in place, this test would have failed with // - Expected: --1 // - Actual : -1
CPPUNIT_ASSERT_EQUAL(u"--1"_ustr, m_pDoc->GetString(ScAddress(0,0,0)));
CPPUNIT_ASSERT_EQUAL(u"---1"_ustr, m_pDoc->GetString(ScAddress(0,1,0)));
CPPUNIT_ASSERT_EQUAL(u"+-1"_ustr, m_pDoc->GetString(ScAddress(0,2,0)));
CPPUNIT_ASSERT_EQUAL(u"+--1"_ustr, m_pDoc->GetString(ScAddress(0,3,0)));
// These are not valid duration inputs
CPPUNIT_ASSERT_EQUAL(u"1:60"_ustr, m_pDoc->GetString(ScAddress(0,0,0)));
CPPUNIT_ASSERT_EQUAL(u"1:123"_ustr, m_pDoc->GetString(ScAddress(0,1,0)));
CPPUNIT_ASSERT_EQUAL(u"1:1:123"_ustr, m_pDoc->GetString(ScAddress(0,2,0)));
// These are valid duration inputs // Without the fix in place, this test would have failed with // - Expected: 02:03:00 AM // - Actual : 0:123
CPPUNIT_ASSERT_EQUAL(u"02:03:00 AM"_ustr, m_pDoc->GetString(ScAddress(0,3,0)));
CPPUNIT_ASSERT_EQUAL(u"12:02:03 AM"_ustr, m_pDoc->GetString(ScAddress(0,4,0)));
CPPUNIT_ASSERT_EQUAL(u"02:03:59 AM"_ustr, m_pDoc->GetString(ScAddress(0,5,0)));
m_pDoc->DeleteTab(1);
CPPUNIT_ASSERT_EQUAL_MESSAGE("Failed to decrement sheet count.", static_cast<SCTAB>(nStartTabs+1), m_pDoc->GetTableCount());
m_pDoc->DeleteTab(0); // This may fail in case there is only one sheet in the document.
}
CPPUNIT_TEST_FIXTURE(Test, testDataEntries)
{ /** * The 'data entries' data is a list of strings used for suggestions as * the user types in new cell value.
*/
m_pDoc->InsertTab(0, u"Test"_ustr);
std::vector<ScTypedStrData> aEntries;
m_pDoc->GetDataEntries(0, 0, 0, aEntries); // Try at the very top.
// Entries are supposed to be sorted in ascending order, and are all unique.
CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(3), aEntries.size());
std::vector<ScTypedStrData>::const_iterator it = aEntries.begin();
CPPUNIT_ASSERT_EQUAL(u"Andy"_ustr, it->GetString());
++it;
CPPUNIT_ASSERT_EQUAL(u"Bruce"_ustr, it->GetString());
++it;
CPPUNIT_ASSERT_EQUAL(u"Charlie"_ustr, it->GetString());
++it;
CPPUNIT_ASSERT_MESSAGE("The entries should have ended here.", bool(it == aEntries.end()));
aEntries.clear();
m_pDoc->GetDataEntries(0, m_pDoc->MaxRow(), 0, aEntries); // Try at the very bottom.
CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(3), aEntries.size());
// Make sure we get the same set of suggestions.
it = aEntries.begin();
CPPUNIT_ASSERT_EQUAL(u"Andy"_ustr, it->GetString());
++it;
CPPUNIT_ASSERT_EQUAL(u"Bruce"_ustr, it->GetString());
++it;
CPPUNIT_ASSERT_EQUAL(u"Charlie"_ustr, it->GetString());
++it;
CPPUNIT_ASSERT_MESSAGE("The entries should have ended here.", bool(it == aEntries.end()));
m_pDoc->DeleteTab(0);
}
CPPUNIT_TEST_FIXTURE(Test, testSelectionFunction)
{ /** * Selection function is responsible for displaying quick calculation * results in the status bar.
*/
m_pDoc->InsertTab(0, u"Test"_ustr);
// Insert values into B2:B4.
m_pDoc->SetString(ScAddress(1,1,0), u"=1"_ustr); // formula
m_pDoc->SetValue(ScAddress(1,2,0), 2.0);
m_pDoc->SetValue(ScAddress(1,3,0), 3.0);
// Insert strings into B5:B8.
m_pDoc->SetString(ScAddress(1,4,0), u"A"_ustr);
m_pDoc->SetString(ScAddress(1,5,0), u"B"_ustr);
m_pDoc->SetString(ScAddress(1,6,0), u"=\"C\""_ustr); // formula
m_pDoc->SetString(ScAddress(1,7,0), u"D"_ustr);
for (constauto& rCheck : aChecks)
{ double fRes = 0.0; bool bRes = m_pDoc->GetSelectionFunction(rCheck.meFunc, aPos, aEmpty, fRes);
CPPUNIT_ASSERT_MESSAGE("Failed to fetch selection function result.", bRes);
CPPUNIT_ASSERT_EQUAL(rCheck.mfExpected, fRes);
}
}
// Calculate function across selected sheets.
clearSheet(m_pDoc, 0);
m_pDoc->InsertTab(1, u"Test2"_ustr);
m_pDoc->InsertTab(2, u"Test3"_ustr);
// Set values at B2 and C3 on each sheet.
m_pDoc->SetValue(ScAddress(1,1,0), 1.0);
m_pDoc->SetValue(ScAddress(2,2,0), 2.0);
m_pDoc->SetValue(ScAddress(1,1,1), 4.0);
m_pDoc->SetValue(ScAddress(2,2,1), 8.0);
m_pDoc->SetValue(ScAddress(1,1,2), 16.0);
m_pDoc->SetValue(ScAddress(2,2,2), 32.0);
// Mark B2 and C3 on first sheet.
aRanges.RemoveAll();
aRanges.push_back(ScRange(1,1,0)); // B2
aRanges.push_back(ScRange(2,2,0)); // C3
aMark.MarkFromRangeList(aRanges, true); // Additionally select third sheet.
aMark.SelectTable(2, true);
// Insert cells to A1, A5, B2 and C3.
m_pDoc->SetString(ScAddress(0,0,0), u"California"_ustr);
m_pDoc->SetValue(ScAddress(0,4,0), 1.2);
m_pDoc->SetEditText(ScAddress(1,1,0), u"Boston"_ustr);
m_pDoc->SetFormula(ScAddress(2,2,0), u"=SUM(1,2,3)"_ustr, m_pDoc->GetGrammar());
// Select A1:C5.
ScMarkData aMarkData(m_pDoc->GetSheetLimits());
aMarkData.SetMarkArea(ScRange(0,0,0,2,4,0));
aMarkData.MarkToMulti(); // TODO : we shouldn't have to do this.
// verify note
CPPUNIT_ASSERT_MESSAGE("There should be a note in A1 destDocument", pDestDoc->HasNote(ScAddress(0, 0, 0)));
CPPUNIT_ASSERT_EQUAL_MESSAGE("The notes content should be the same on both documents",
m_pDoc->GetNote(ScAddress(0, 0, 0))->GetText(), pDestDoc->GetNote(ScAddress(0, 0, 0))->GetText());
SCCOL nCol;
SCROW nRow;
size_t i = 0; for (ScRefCellValue* pCell = aIter.GetNext(nCol, nRow); pCell; pCell = aIter.GetNext(nCol, nRow), ++i)
{ if (i >= nCheckCount)
{
cerr << "hit invalid check " << i << " of " << nCheckCount << endl;
CPPUNIT_FAIL("Iterator claims there is more data than there should be."); returnfalse;
}
// Set values in first two columns, to ensure allocation of those columns.
m_pDoc->SetValue(ScAddress(0,1,0), 1);
m_pDoc->SetValue(ScAddress(1,1,0), 2);
constexpr SCCOL allocatedColsCount = 2;
assert( allocatedColsCount >= INITIALCOLCOUNT );
CPPUNIT_ASSERT_EQUAL(allocatedColsCount, m_pDoc->GetAllocatedColumnsCount(0));
// Make entire second row and third row bold.
ScPatternAttr boldAttr(m_pDoc->getCellAttributeHelper());
boldAttr.GetItemSet().Put(SvxWeightItem(WEIGHT_BOLD, ATTR_FONT_WEIGHT));
m_pDoc->ApplyPatternAreaTab(0, 1, m_pDoc->MaxCol(), 2, 0, boldAttr);
// That shouldn't need allocating more columns, just changing the default attribute.
CPPUNIT_ASSERT_EQUAL(allocatedColsCount, m_pDoc->GetAllocatedColumnsCount(0));
vcl::Font aFont; const ScPatternAttr* pattern = m_pDoc->GetPattern(m_pDoc->MaxCol(), 1, 0);
pattern->fillFontOnly(aFont);
CPPUNIT_ASSERT_EQUAL_MESSAGE("font should be bold", WEIGHT_BOLD, aFont.GetWeightMaybeAskConfig());
// The default pattern is the default style, which can be edited by the user. // As such iterators should not ignore it by default, because it might contain // some attributes set.
// That shouldn't need allocating more columns, just changing column flags.
CPPUNIT_ASSERT_EQUAL(INITIALCOLCOUNT, m_pDoc->GetAllocatedColumnsCount(0)); // But the flags are changed.
CPPUNIT_ASSERT_EQUAL(m_pDoc->MaxCol(), m_pDoc->GetLastChangedColFlagsWidth(0));
ScSingleRefData& rRef = *pToken->GetSingleRef(); if (!rRef.IsDeleted())
{
cerr << "Deleted reference is expected, but it's still a valid reference." << endl; returnfalse;
}
returntrue;
}
}
CPPUNIT_TEST_FIXTURE(Test, testCellBroadcaster)
{ /** * More direct test for cell broadcaster management, used to track formula * dependencies.
*/
CPPUNIT_ASSERT_MESSAGE ("failed to insert sheet", m_pDoc->InsertTab (0, u"foo"_ustr));
sc::AutoCalcSwitch aACSwitch(*m_pDoc, true); // turn on auto calculation.
m_pDoc->SetString(ScAddress(1,0,0), u"=A1"_ustr); // B1 depends on A1. double val = m_pDoc->GetValue(ScAddress(1,0,0)); // A1 is empty, so the result should be 0.
CPPUNIT_ASSERT_EQUAL(0.0, val);
const SvtBroadcaster* pBC = m_pDoc->GetBroadcaster(ScAddress(0,0,0));
CPPUNIT_ASSERT_MESSAGE("Cell A1 should have a broadcaster.", pBC);
// Change the value of A1 and make sure that B1 follows.
m_pDoc->SetValue(ScAddress(0,0,0), 1.23);
val = m_pDoc->GetValue(ScAddress(1,0,0));
CPPUNIT_ASSERT_EQUAL(1.23, val);
// Move column A down 5 cells. Make sure B1 now references A6, not A1.
m_pDoc->InsertRow(0, 0, 0, 0, 0, 5);
CPPUNIT_ASSERT_MESSAGE("Relative reference check failed.",
checkRelativeRefToken(*m_pDoc, ScAddress(1,0,0), -1, 5));
// Make sure the broadcaster has also moved.
CPPUNIT_ASSERT_MESSAGE("Broadcaster relocation failed.",
broadcasterShifted(*m_pDoc, ScAddress(0,0,0), ScAddress(0,5,0)));
// Set new value to A6 and make sure B1 gets updated.
m_pDoc->SetValue(ScAddress(0,5,0), 45.6);
val = m_pDoc->GetValue(ScAddress(1,0,0));
CPPUNIT_ASSERT_EQUAL(45.6, val);
// Move column A up 3 cells, and make sure B1 now references A3, not A6.
m_pDoc->DeleteRow(0, 0, 0, 0, 0, 3);
CPPUNIT_ASSERT_MESSAGE("Relative reference check failed.",
checkRelativeRefToken(*m_pDoc, ScAddress(1,0,0), -1, 2));
// The broadcaster should also have been relocated from A6 to A3.
CPPUNIT_ASSERT_MESSAGE("Broadcaster relocation failed.",
broadcasterShifted(*m_pDoc, ScAddress(0,5,0), ScAddress(0,2,0)));
// Insert cells over A1:A10 and shift cells to right.
m_pDoc->InsertCol(ScRange(0, 0, 0, 0, 10, 0));
CPPUNIT_ASSERT_MESSAGE("Relative reference check failed.",
checkRelativeRefToken(*m_pDoc, ScAddress(2,0,0), -1, 2));
CPPUNIT_ASSERT_MESSAGE("Broadcaster relocation failed.",
broadcasterShifted(*m_pDoc, ScAddress(0,2,0), ScAddress(1,2,0)));
// Delete formula in C2, which should remove the broadcaster in B3.
pBC = m_pDoc->GetBroadcaster(ScAddress(1,2,0));
CPPUNIT_ASSERT_MESSAGE("Broadcaster in B3 should still exist.", pBC);
clearRange(m_pDoc, ScRange(ScAddress(2,0,0)));
CPPUNIT_ASSERT_EQUAL(CELLTYPE_NONE, m_pDoc->GetCellType(ScAddress(2,0,0))); // C2 should be empty.
pBC = m_pDoc->GetBroadcaster(ScAddress(1,2,0));
CPPUNIT_ASSERT_MESSAGE("Broadcaster in B3 should have been removed.", !pBC);
// Clear everything and start over.
clearRange(m_pDoc, ScRange(0,0,0,10,100,0));
m_pDoc->SetString(ScAddress(1,0,0), u"=A1"_ustr); // B1 depends on A1.
pBC = m_pDoc->GetBroadcaster(ScAddress(0,0,0));
CPPUNIT_ASSERT_MESSAGE("Broadcaster should exist in A1.", pBC);
// While column A is still empty, move column A down 2 cells. This should // move the broadcaster from A1 to A3.
m_pDoc->InsertRow(0, 0, 0, 0, 0, 2);
CPPUNIT_ASSERT_MESSAGE("Broadcaster relocation failed.",
broadcasterShifted(*m_pDoc, ScAddress(0,0,0), ScAddress(0,2,0)));
// Move it back while column A is still empty.
m_pDoc->DeleteRow(0, 0, 0, 0, 0, 2);
CPPUNIT_ASSERT_MESSAGE("Broadcaster relocation failed.",
broadcasterShifted(*m_pDoc, ScAddress(0,2,0), ScAddress(0,0,0)));
// Clear everything again
clearRange(m_pDoc, ScRange(0,0,0,10,100,0));
// B1:B3 depends on A1:A3
m_pDoc->SetString(ScAddress(1,0,0), u"=A1"_ustr);
m_pDoc->SetString(ScAddress(1,1,0), u"=A2"_ustr);
m_pDoc->SetString(ScAddress(1,2,0), u"=A3"_ustr);
CPPUNIT_ASSERT_MESSAGE("Relative reference check in B1 failed.",
checkRelativeRefToken(*m_pDoc, ScAddress(1,0,0), -1, 0));
CPPUNIT_ASSERT_MESSAGE("Relative reference check in B2 failed.",
checkRelativeRefToken(*m_pDoc, ScAddress(1,1,0), -1, 0));
CPPUNIT_ASSERT_MESSAGE("Relative reference check in B3 failed.",
checkRelativeRefToken(*m_pDoc, ScAddress(1,2,0), -1, 0));
CPPUNIT_ASSERT_MESSAGE("Broadcaster should exist in A1.", m_pDoc->GetBroadcaster(ScAddress(0,0,0)));
CPPUNIT_ASSERT_MESSAGE("Broadcaster should exist in A2.", m_pDoc->GetBroadcaster(ScAddress(0,1,0)));
CPPUNIT_ASSERT_MESSAGE("Broadcaster should exist in A3.", m_pDoc->GetBroadcaster(ScAddress(0,2,0)));
// Insert Rows at row 2, down 5 rows.
m_pDoc->InsertRow(0, 0, 0, 0, 1, 5);
CPPUNIT_ASSERT_MESSAGE("Broadcaster should exist in A1.", m_pDoc->GetBroadcaster(ScAddress(0,0,0)));
CPPUNIT_ASSERT_MESSAGE("Relative reference check in B1 failed.",
checkRelativeRefToken(*m_pDoc, ScAddress(1,0,0), -1, 0));
// Broadcasters in A2 and A3 should shift down by 5 rows.
CPPUNIT_ASSERT_MESSAGE("Broadcaster relocation failed.",
broadcasterShifted(*m_pDoc, ScAddress(0,1,0), ScAddress(0,6,0)));
CPPUNIT_ASSERT_MESSAGE("Broadcaster relocation failed.",
broadcasterShifted(*m_pDoc, ScAddress(0,2,0), ScAddress(0,7,0)));
// B2 and B3 should reference shifted cells.
--> --------------------
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.