/* -*- 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/.
*/
// Add a conditional format to B2:B4. auto pFormat = std::make_unique<ScConditionalFormat>(1, *m_pDoc);
pFormat->SetRange(ScRange(1,1,0,1,3,0));
auto pFormatTmp = pFormat.get();
sal_uInt32 nKey = m_pDoc->AddCondFormat(std::move(pFormat), 0);
// Add condition in which if the value equals 2, set the "Result" style.
ScCondFormatEntry* pEntry = new ScCondFormatEntry(
ScConditionMode::Equal, u"=2"_ustr, u""_ustr , *m_pDoc, ScAddress(0,0,0), ScResId(STR_STYLENAME_RESULT));
pFormatTmp->AddEntry(pEntry);
// Apply the format to the range.
m_pDoc->AddCondFormatData(pFormatTmp->GetRange(), 0, nKey);
// Make sure this conditional format entry is really there.
ScConditionalFormatList* pList = m_pDoc->GetCondFormList(0);
CPPUNIT_ASSERT(pList); const ScConditionalFormat* pCheck = pList->GetFormat(nKey);
CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong conditional format instance.", pCheck, const_cast<const ScConditionalFormat*>(pFormatTmp));
// ... and its range is B2:B4.
ScRangeList aCheckRange = pCheck->GetRange();
CPPUNIT_ASSERT_EQUAL_MESSAGE("This should be a single range.", size_t(1), aCheckRange.size()); const ScRange* pRange = &aCheckRange[0];
CPPUNIT_ASSERT(pRange);
CPPUNIT_ASSERT_EQUAL_MESSAGE("Format should be applied to B2:B4.", ScRange(1,1,0,1,3,0), *pRange);
ScDocFunc& rFunc = m_xDocShell->GetDocFunc();
// Insert a new sheet at the left. bool bInserted = rFunc.InsertTable(0, u"Inserted"_ustr, true, true);
CPPUNIT_ASSERT(bInserted);
// Make sure the range also got shifted.
aCheckRange = pCheck->GetRange();
CPPUNIT_ASSERT_EQUAL_MESSAGE("This should be a single range.", size_t(1), aCheckRange.size());
pRange = &aCheckRange[0];
CPPUNIT_ASSERT(pRange);
CPPUNIT_ASSERT_EQUAL_MESSAGE("Format should be applied to B2:B4 on the 2nd sheet after the sheet insertion.", ScRange(1,1,1,1,3,1), *pRange);
// Delete the sheet to the left. bool bDeleted = rFunc.DeleteTable(0, true);
CPPUNIT_ASSERT(bDeleted);
// Make sure the range got shifted back.
aCheckRange = pCheck->GetRange();
CPPUNIT_ASSERT_EQUAL_MESSAGE("This should be a single range.", size_t(1), aCheckRange.size());
pRange = &aCheckRange[0];
CPPUNIT_ASSERT(pRange);
CPPUNIT_ASSERT_EQUAL_MESSAGE("Format should be applied to B2:B4 on the 1st sheet after the sheet removal.", ScRange(1,1,0,1,3,0), *pRange);
aCheckRange = pCheck->GetRange();
CPPUNIT_ASSERT_EQUAL_MESSAGE("This should be a single range.", size_t(1), aCheckRange.size());
pRange = &aCheckRange[0];
CPPUNIT_ASSERT(pRange);
CPPUNIT_ASSERT_EQUAL_MESSAGE("Format should be applied to B2:B4 on the 2nd sheet after the undo of the sheet removal.", ScRange(1,1,1,1,3,1), *pRange);
#if 0 // TODO : Undo of sheet insertion currently depends on the presence of // view shell, and crashes when executed during cppunit run.
// Make sure the range got shifted back.
aCheckRange = pCheck->GetRange();
CPPUNIT_ASSERT_MESSAGE("This should be a single range.", aCheckRange.size() == 1);
pRange = aCheckRange[0];
CPPUNIT_ASSERT(pRange);
CPPUNIT_ASSERT_MESSAGE("Format should be applied to B2:B4 on the 1st sheet after the undo of sheet insertion.", *pRange == ScRange(1,1,0,1,3,0)); #else
m_pDoc->DeleteTab(1); #endif
// Pasting the same conditional databar format into a non-adjacent range must create a new // format.
sal_uInt32 nIndex1 = m_pDoc->GetCondFormat(0, 3, 0)->GetKey();
CPPUNIT_ASSERT_EQUAL(size_t(2), m_pDoc->GetCondFormList(0)->size());
aRangeList = aTargetRange; for (SCCOL nCol = 0; nCol < 3; ++nCol)
{
ScConditionalFormat* pPastedFormat = m_pDoc->GetCondFormat(nCol, 3, 0);
CPPUNIT_ASSERT(pPastedFormat);
CPPUNIT_ASSERT_EQUAL(aRangeList, pPastedFormat->GetRange());
// Now paste next to the previous range (immediately below)
aTargetRange = ScRange(0, 4, 0, 2, 4, 0);
pasteFromClip(m_pDoc, aTargetRange, &aClipDoc);
// Pasting the same conditional databar format into an adjacent range (not continuing the row) // must create a new format.
sal_uInt32 nIndex2 = m_pDoc->GetCondFormat(0, 4, 0)->GetKey();
CPPUNIT_ASSERT_EQUAL(size_t(3), m_pDoc->GetCondFormList(0)->size());
aRangeList = aTargetRange; for (SCCOL nCol = 0; nCol < 3; ++nCol)
{
ScConditionalFormat* pPastedFormat = m_pDoc->GetCondFormat(nCol, 4, 0);
CPPUNIT_ASSERT(pPastedFormat);
CPPUNIT_ASSERT_EQUAL(aRangeList, pPastedFormat->GetRange());
// Now paste next to the previous range (immediately to the right)
aTargetRange = ScRange(3, 4, 0, 5, 4, 0);
pasteFromClip(m_pDoc, aTargetRange, &aClipDoc);
// Pasting the same conditional databar format into an adjacent range (continuing the row) must // modify existing format, making its range combined of previous range and newly pasted range // having the conditional format. No new conditional formats must be created.
CPPUNIT_ASSERT_EQUAL(size_t(3), m_pDoc->GetCondFormList(0)->size());
aRangeList.Join(aTargetRange); for (SCCOL nCol = 3; nCol < 6; ++nCol)
{
ScConditionalFormat* pPastedFormat = m_pDoc->GetCondFormat(nCol, 4, 0);
CPPUNIT_ASSERT(pPastedFormat);
CPPUNIT_ASSERT_EQUAL(aRangeList, pPastedFormat->GetRange());
// Add a conditional format to A1. auto pFormat = std::make_unique<ScConditionalFormat>(1, *m_pDoc);
pFormat->SetRange(ScRange(0, 0, 0, 0, 0, 0)); auto pFormatTmp = pFormat.get();
sal_uInt32 nKey = m_pDoc->AddCondFormat(std::move(pFormat), 0);
// Add color scale entries. // The coloring is based on the value. (BLUE (x <= 0), GREEN (x == 1), RED (x >= 2))
ScColorScaleFormat* pColorScaleFormat = new ScColorScaleFormat(*m_pDoc);
ScColorScaleEntry* pEntryBlue = new ScColorScaleEntry(0, COL_BLUE);
ScColorScaleEntry* pEntryGreen = new ScColorScaleEntry(1, COL_GREEN);
ScColorScaleEntry* pEntryRed = new ScColorScaleEntry(2, COL_RED);
pColorScaleFormat->AddEntry(pEntryBlue);
pColorScaleFormat->AddEntry(pEntryGreen);
pColorScaleFormat->AddEntry(pEntryRed);
pFormatTmp->AddEntry(pColorScaleFormat);
// Apply the format to the range.
m_pDoc->AddCondFormatData(pFormatTmp->GetRange(), 0, nKey);
RowInfo* pRowInfoA1 = &pRowInfo[1];
ScCellInfo* pCellInfoA1 = &pRowInfoA1->cellInfo(0); // Check if there is a color scale in A1.
CPPUNIT_ASSERT_EQUAL_MESSAGE("There is no color scale in cell A1!", true,
pCellInfoA1->mxColorScale.has_value());
RowInfo* pRowInfoA2 = &pRowInfo[2];
ScCellInfo* pCellInfoA2 = &pRowInfoA2->cellInfo(0); // Check if there is a color scale in A2.
CPPUNIT_ASSERT_EQUAL_MESSAGE("There is no color scale in cell A2!", true,
pCellInfoA2->mxColorScale.has_value());
// Check that cells A1 and A2 have the same color scale. (GREEN)
CPPUNIT_ASSERT(pCellInfoA1->mxColorScale.value().IsRGBEqual(pCellInfoA2->mxColorScale.value()));
// Pasting the same conditional databar format into a non-adjacent range must create a new // format.
sal_uInt32 nIndex1 = m_pDoc->GetCondFormat(0, 3, 0)->GetKey();
CPPUNIT_ASSERT_EQUAL(size_t(2), m_pDoc->GetCondFormList(0)->size());
aRangeList = aTargetRange; for (SCCOL nCol = 0; nCol < 3; ++nCol)
{
ScConditionalFormat* pPastedFormat = m_pDoc->GetCondFormat(nCol, 3, 0);
CPPUNIT_ASSERT(pPastedFormat);
CPPUNIT_ASSERT_EQUAL(aRangeList, pPastedFormat->GetRange());
// Now paste next to the previous range (immediately below)
aTargetRange = ScRange(0, 4, 0, 2, 4, 0);
pasteFromClip(m_pDoc, aTargetRange, &aClipDoc);
// Pasting the same conditional databar format into an adjacent range (not continuing the row) // must create a new format.
sal_uInt32 nIndex2 = m_pDoc->GetCondFormat(0, 4, 0)->GetKey();
CPPUNIT_ASSERT_EQUAL(size_t(3), m_pDoc->GetCondFormList(0)->size());
aRangeList = aTargetRange; for (SCCOL nCol = 0; nCol < 3; ++nCol)
{
ScConditionalFormat* pPastedFormat = m_pDoc->GetCondFormat(nCol, 4, 0);
CPPUNIT_ASSERT(pPastedFormat);
CPPUNIT_ASSERT_EQUAL(aRangeList, pPastedFormat->GetRange());
// Now paste next to the previous range (immediately to the right)
aTargetRange = ScRange(3, 4, 0, 5, 4, 0);
pasteFromClip(m_pDoc, aTargetRange, &aClipDoc);
// Pasting the same conditional databar format into an adjacent range (continuing the row) must // modify existing format, making its range combined of previous range and newly pasted range // having the conditional format. No new conditional formats must be created.
CPPUNIT_ASSERT_EQUAL(size_t(3), m_pDoc->GetCondFormList(0)->size());
aRangeList.Join(aTargetRange); for (SCCOL nCol = 3; nCol < 6; ++nCol)
{
ScConditionalFormat* pPastedFormat = m_pDoc->GetCondFormat(nCol, 4, 0);
CPPUNIT_ASSERT(pPastedFormat);
CPPUNIT_ASSERT_EQUAL(aRangeList, pPastedFormat->GetRange());
// Pasting the same conditional format must modify existing format, making its range // combined of previous range and newly pasted range having the conditional format. // No new conditional formats must be created.
CPPUNIT_ASSERT_EQUAL(size_t(1), m_pDoc->GetCondFormList(0)->size());
aRangeList.Join(aTargetRange);
CPPUNIT_ASSERT_EQUAL(aRangeList, pPastedFormat->GetRange());
CPPUNIT_ASSERT_EQUAL(nIndex, pPastedFormat->GetKey()); const SfxPoolItem* pItem = m_pDoc->GetAttr( 7, 7, 0, ATTR_CONDITIONAL ); const ScCondFormatItem* pCondFormatItem = static_cast<const ScCondFormatItem*>(pItem);
// Pasting the same conditional format must modify existing format, making its range // combined of previous range and newly pasted range having the conditional format. // No new conditional formats must be created.
CPPUNIT_ASSERT_EQUAL(size_t(1), m_pDoc->GetCondFormList(0)->size());
aRangeList.Join(aTargetRange);
CPPUNIT_ASSERT_EQUAL(aRangeList, pPastedFormat->GetRange());
CPPUNIT_ASSERT_EQUAL(nIndex, pPastedFormat->GetKey()); const SfxPoolItem* pItem = m_pDoc->GetAttr( 4, 4, 0, ATTR_CONDITIONAL ); const ScCondFormatItem* pCondFormatItem = static_cast<const ScCondFormatItem*>(pItem);
// Pasting the same conditional format must modify existing format, making its range // combined of previous range and newly pasted range having the conditional format. // No new conditional formats must be created.
CPPUNIT_ASSERT_EQUAL(size_t(1), m_pDoc->GetCondFormList(0)->size());
aRangeList.Join(aTargetRange); for(SCROW nRow = 4; nRow <= 8; ++nRow)
{ for (SCCOL nCol = 4; nCol <= 5; ++nCol)
{
ScConditionalFormat* pPastedFormat = m_pDoc->GetCondFormat(nCol, nRow, 0);
CPPUNIT_ASSERT(pPastedFormat);
// Pasting the same conditional format into the same range must not modify existing format, // since it already covers the pasted range. No new conditional formats must be created.
CPPUNIT_ASSERT_EQUAL(size_t(1), m_pDoc->GetCondFormList(0)->size());
CPPUNIT_ASSERT_EQUAL(aRangeList, pPastedFormat->GetRange());
CPPUNIT_ASSERT_EQUAL(nIndex, pPastedFormat->GetKey()); const SfxPoolItem* pItem = m_pDoc->GetAttr(2, 2, 0, ATTR_CONDITIONAL); const ScCondFormatItem* pCondFormatItem = static_cast<const ScCondFormatItem*>(pItem);
auto pFormat = std::make_unique<ScConditionalFormat>(0, *m_pDoc);
pFormat->SetRange(ScRange(10, 10, 0, 10, 12, 0)); auto pFormatTmp = pFormat.get();
m_pDoc->AddCondFormat(std::move(pFormat), 0);
pFormatTmp->AddEntry(pEntry);
// the conditional format should listen to A1:A3 for (SCROW nRow = 0; nRow < 3; ++nRow)
{
m_pDoc->SetValue(ScAddress(0, nRow, 0), 1.0);
CPPUNIT_ASSERT(pEntry->NeedsRepaint());
}
m_pDoc->MoveTab(0, 1);
// the conditional format should listen to A1:A3 on the second sheet for (SCROW nRow = 0; nRow < 3; ++nRow)
{
m_pDoc->SetValue(ScAddress(0, nRow, 1), 1.0);
CPPUNIT_ASSERT(pEntry->NeedsRepaint());
auto pFormat = std::make_unique<ScConditionalFormat>(0, *m_pDoc);
pFormat->SetRange(ScRange(10, 10, 0, 10, 12, 0)); auto pFormatTmp = pFormat.get();
m_pDoc->AddCondFormat(std::move(pFormat), 0);
pFormatTmp->AddEntry(pEntry);
// the conditional format should listen to A1:A3 for (SCROW nRow = 0; nRow < 3; ++nRow)
{
m_pDoc->SetValue(ScAddress(0, nRow, 0), 1.0);
CPPUNIT_ASSERT(pEntry->NeedsRepaint());
// the conditional format should listen to A1:A3 on the second sheet for (SCROW nRow = 0; nRow < 3; ++nRow)
{
m_pDoc->SetValue(ScAddress(0, nRow, 1), 1.0);
CPPUNIT_ASSERT(pEntry->NeedsRepaint());
auto pFormat = std::make_unique<ScConditionalFormat>(0, *m_pDoc);
pFormat->SetRange(ScRange(10, 10, 1, 10, 12, 1)); auto pFormatTmp = pFormat.get();
m_pDoc->AddCondFormat(std::move(pFormat), 1);
pFormatTmp->AddEntry(pEntry);
// the conditional format should listen to A1:A3 on the second sheet for (SCROW nRow = 0; nRow < 3; ++nRow)
{
m_pDoc->SetValue(ScAddress(0, nRow, 1), 1.0);
CPPUNIT_ASSERT(pEntry->NeedsRepaint());
}
m_pDoc->DeleteTab(0);
// the conditional format should listen to A1:A3 on the second sheet for (SCROW nRow = 0; nRow < 3; ++nRow)
{
m_pDoc->SetValue(ScAddress(0, nRow, 0), 1.0);
CPPUNIT_ASSERT(pEntry->NeedsRepaint());
}
auto pFormat = std::make_unique<ScConditionalFormat>(0, *m_pDoc);
pFormat->SetRange(ScRange(10, 10, 0, 10, 12, 0)); auto pFormatTmp = pFormat.get();
m_pDoc->AddCondFormat(std::move(pFormat), 0);
pFormatTmp->AddEntry(pEntry);
// the conditional format should listen to A1:A3 for (SCROW nRow = 0; nRow < 3; ++nRow)
{
m_pDoc->SetValue(ScAddress(0, nRow, 0), 1.0);
CPPUNIT_ASSERT(pEntry->NeedsRepaint());
}
bool bNewValid = bValid; // chance of a random failure is 0.5^100, anyone hitting that will get a beer from me for (size_t i = 0; i < 100; ++i)
{
pFormatTmp->CalcAll();
bNewValid = pEntry->IsCellValid(aCell, ScAddress(0, 0, 0));
// Add a conditional format. auto pFormat = std::make_unique<ScConditionalFormat>(1, *m_pDoc);
pFormat->SetRange(ScRange(0, 0, 0, 0, 0, 0));
// Add condition in which if the value equals 1, set the "Good" style.
ScCondFormatEntry* pEntry = new ScCondFormatEntry(
ScConditionMode::Equal, u"=1"_ustr, u""_ustr, *m_pDoc, ScAddress(0, 0, 0), ScResId(STR_STYLENAME_GOOD));
pFormat->AddEntry(pEntry);
// Apply the format to the range.
m_pDoc->AddCondFormatData(pFormat->GetRange(), 0, 1);
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.