1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
10 #include "helper/qahelper.hxx"
12 #include <conditio.hxx>
13 #include <colorscale.hxx>
15 #include <globstr.hrc>
16 #include <scresid.hxx>
17 #include <docfunc.hxx>
18 #include <scitems.hxx>
20 #include <fillinfo.hxx>
21 #include <compiler.hxx>
22 #include <undomanager.hxx>
24 #include <svl/sharedstringpool.hxx>
28 struct ScDataBarLengthData
34 void testDataBarLengthImpl(ScDocument
* pDoc
, const ScDataBarLengthData
* pData
, const ScRange
& rRange
,
35 double nMinVal
, ScColorScaleEntryType eMinType
,
36 double nMaxVal
, ScColorScaleEntryType eMaxType
,
37 double nZeroPos
, databar::ScAxisPosition eAxisPos
)
39 std::unique_ptr
<ScConditionalFormat
> pFormat(new ScConditionalFormat(1, pDoc
));
40 ScRangeList
aRangeList(rRange
);
41 pFormat
->SetRange(aRangeList
);
43 SCCOL nCol
= rRange
.aStart
.Col();
45 ScDataBarFormat
* pDatabar
= new ScDataBarFormat(pDoc
);
46 pFormat
->AddEntry(pDatabar
);
48 ScDataBarFormatData
* pFormatData
= new ScDataBarFormatData();
49 pFormatData
->meAxisPosition
= eAxisPos
;
51 pFormatData
->mpLowerLimit
.reset(new ScColorScaleEntry());
52 pFormatData
->mpLowerLimit
->SetValue(nMinVal
);
53 pFormatData
->mpLowerLimit
->SetType(eMinType
);
54 pFormatData
->mpUpperLimit
.reset(new ScColorScaleEntry());
55 pFormatData
->mpUpperLimit
->SetValue(nMaxVal
);
56 pFormatData
->mpUpperLimit
->SetType(eMaxType
);
57 pDatabar
->SetDataBarData(pFormatData
);
59 for (size_t i
= 0; pData
[i
].nLength
!= -200; ++i
)
61 pDoc
->SetValue(nCol
, i
, 0, pData
[i
].nVal
);
64 for (size_t i
= 0; pData
[i
].nLength
!= -200; ++i
)
66 std::unique_ptr
<ScDataBarInfo
> xInfo(pDatabar
->GetDataBarInfo(ScAddress(nCol
, i
, 0)));
67 CPPUNIT_ASSERT(xInfo
);
68 ASSERT_DOUBLES_EQUAL(pData
[i
].nLength
, xInfo
->mnLength
);
69 ASSERT_DOUBLES_EQUAL(nZeroPos
, xInfo
->mnZero
);
73 sal_uInt32
addSingleCellCondFormat(ScDocument
* pDoc
, const ScAddress
& rAddr
, sal_uInt32 nKey
, const OUString
& rCondition
)
75 auto pFormat
= std::make_unique
<ScConditionalFormat
>(nKey
, pDoc
);
76 ScRange
aCondFormatRange(rAddr
);
77 ScRangeList
aRangeList(aCondFormatRange
);
78 pFormat
->SetRange(aRangeList
);
80 ScCondFormatEntry
* pEntry
= new ScCondFormatEntry(ScConditionMode::Direct
, rCondition
, "",
81 *pDoc
, ScAddress(0,0,0), ScResId(STR_STYLENAME_RESULT
));
82 pFormat
->AddEntry(pEntry
);
83 return pDoc
->AddCondFormat(std::move(pFormat
), 0);
89 class TestCondformat
: public ScUcalcTestBase
92 void testCondFormatINSDEL();
93 void testCondFormatInsertRow();
94 void testCondFormatInsertCol();
95 void testCondFormatInsertDeleteSheets();
96 void testCondCopyPaste();
97 void testCondCopyPasteSingleCell(); //e.g. fdo#82503
98 void testCondCopyPasteSingleCellToRange(); //e.g. fdo#82503
99 void testCondCopyPasteSingleCellIntoSameFormatRange(); // e.g., tdf#95295
100 void testCondCopyPasteSingleRowToRange(); //e.g. tdf#106242
101 void testCondCopyPasteSingleRowToRange2();
102 void testCondCopyPasteSheetBetweenDoc();
103 void testCondCopyPasteSheet();
106 void testDataBarLengthAutomaticAxis();
107 void testDataBarLengthMiddleAxis();
109 // Tests for the ScFormulaListener class
110 void testFormulaListenerSingleCellToSingleCell();
111 void testFormulaListenerMultipleCellsToSingleCell();
112 void testFormulaListenerSingleCellToMultipleCells();
113 void testFormulaListenerMultipleCellsToMultipleCells();
114 void testFormulaListenerUpdateInsertTab();
115 void testFormulaListenerUpdateDeleteTab();
117 // Check that the Listeners are correctly updated when we
119 void testCondFormatUpdateMoveTab();
120 void testCondFormatUpdateDeleteTab();
121 void testCondFormatUpdateInsertTab();
122 void testCondFormatUpdateReference();
123 void testCondFormatUpdateReferenceDelRow();
124 void testCondFormatUpdateReferenceInsRow();
126 void testCondFormatEndsWithStr();
127 void testCondFormatEndsWithVal();
129 void testCondFormatUndoList();
130 void testMultipleSingleCellCondFormatCopyPaste();
131 void testDeduplicateMultipleCondFormats();
132 void testCondFormatListenToOwnRange();
133 void testCondFormatVolatileFunctionRecalc();
135 CPPUNIT_TEST_SUITE(TestCondformat
);
137 CPPUNIT_TEST(testCondFormatINSDEL
);
138 CPPUNIT_TEST(testCondFormatInsertRow
);
139 CPPUNIT_TEST(testCondFormatInsertCol
);
140 CPPUNIT_TEST(testCondFormatInsertDeleteSheets
);
141 CPPUNIT_TEST(testCondCopyPaste
);
142 CPPUNIT_TEST(testCondCopyPasteSingleCell
);
143 CPPUNIT_TEST(testCondCopyPasteSingleCellToRange
);
144 CPPUNIT_TEST(testCondCopyPasteSingleCellIntoSameFormatRange
);
145 CPPUNIT_TEST(testCondCopyPasteSingleRowToRange
);
146 CPPUNIT_TEST(testCondCopyPasteSingleRowToRange2
);
147 CPPUNIT_TEST(testCondCopyPasteSheetBetweenDoc
);
148 CPPUNIT_TEST(testCondCopyPasteSheet
);
149 CPPUNIT_TEST(testCondFormatEndsWithStr
);
150 CPPUNIT_TEST(testCondFormatEndsWithVal
);
151 CPPUNIT_TEST(testCondFormatUpdateMoveTab
);
152 CPPUNIT_TEST(testCondFormatUpdateDeleteTab
);
153 CPPUNIT_TEST(testCondFormatUpdateInsertTab
);
154 CPPUNIT_TEST(testCondFormatUpdateReference
);
155 CPPUNIT_TEST(testCondFormatUpdateReferenceDelRow
);
156 CPPUNIT_TEST(testCondFormatUpdateReferenceInsRow
);
157 CPPUNIT_TEST(testCondFormatUndoList
);
158 CPPUNIT_TEST(testMultipleSingleCellCondFormatCopyPaste
);
159 CPPUNIT_TEST(testDeduplicateMultipleCondFormats
);
160 CPPUNIT_TEST(testCondFormatListenToOwnRange
);
161 CPPUNIT_TEST(testCondFormatVolatileFunctionRecalc
);
162 CPPUNIT_TEST(testIconSet
);
163 CPPUNIT_TEST(testDataBarLengthAutomaticAxis
);
164 CPPUNIT_TEST(testDataBarLengthMiddleAxis
);
165 CPPUNIT_TEST(testFormulaListenerSingleCellToSingleCell
);
166 CPPUNIT_TEST(testFormulaListenerSingleCellToMultipleCells
);
167 CPPUNIT_TEST(testFormulaListenerMultipleCellsToSingleCell
);
168 CPPUNIT_TEST(testFormulaListenerMultipleCellsToMultipleCells
);
169 CPPUNIT_TEST(testFormulaListenerUpdateInsertTab
);
170 CPPUNIT_TEST(testFormulaListenerUpdateDeleteTab
);
172 CPPUNIT_TEST_SUITE_END();
175 void TestCondformat::testCondFormatINSDEL()
178 m_pDoc
->InsertTab(0, "Test");
179 ScConditionalFormatList
* pList
= m_pDoc
->GetCondFormList(0);
181 auto pFormat
= std::make_unique
<ScConditionalFormat
>(1, m_pDoc
);
182 ScRangeList
aRangeList(ScRange(0,0,0,0,3,0));
183 pFormat
->SetRange(aRangeList
);
184 ScCondFormatEntry
* pEntry
= new ScCondFormatEntry(ScConditionMode::Direct
,"=B2","",*m_pDoc
,ScAddress(0,0,0),ScResId(STR_STYLENAME_RESULT
));
185 pFormat
->AddEntry(pEntry
);
187 m_pDoc
->AddCondFormatData(pFormat
->GetRange(), 0, 1);
188 auto pFormatTmp
= pFormat
.get();
189 pList
->InsertNew(std::move(pFormat
));
191 m_pDoc
->InsertCol(0,0,m_pDoc
->MaxRow(),0,0,2);
192 const ScRangeList
& rRange
= pFormatTmp
->GetRange();
193 CPPUNIT_ASSERT_EQUAL(static_cast<const ScRangeList
&>(ScRange(2,0,0,2,3,0)), rRange
);
195 OUString aExpr
= pEntry
->GetExpression(ScAddress(2,0,0), 0);
196 CPPUNIT_ASSERT_EQUAL(OUString("D2"), aExpr
);
198 m_pDoc
->DeleteTab(0);
201 void TestCondformat::testCondFormatInsertCol()
203 m_pDoc
->InsertTab(0, "Test");
204 ScConditionalFormatList
* pList
= m_pDoc
->GetCondFormList(0);
206 auto pFormat
= std::make_unique
<ScConditionalFormat
>(1, m_pDoc
);
207 ScRangeList
aRangeList(ScRange(0,0,0,3,3,0));
208 pFormat
->SetRange(aRangeList
);
210 ScCondFormatEntry
* pEntry
= new ScCondFormatEntry(ScConditionMode::Direct
,"=B2","",*m_pDoc
,ScAddress(0,0,0),ScResId(STR_STYLENAME_RESULT
));
211 pFormat
->AddEntry(pEntry
);
213 m_pDoc
->AddCondFormatData(pFormat
->GetRange(), 0, 1);
214 auto pFormatTmp
= pFormat
.get();
215 pList
->InsertNew(std::move(pFormat
));
217 m_pDoc
->InsertCol(0,0,m_pDoc
->MaxRow(),0,4,2);
218 const ScRangeList
& rRange
= pFormatTmp
->GetRange();
219 CPPUNIT_ASSERT_EQUAL(ScRangeList(ScRange(0,0,0,5,3,0)), rRange
);
221 m_pDoc
->DeleteTab(0);
224 void TestCondformat::testCondFormatInsertRow()
226 m_pDoc
->InsertTab(0, "Test");
227 ScConditionalFormatList
* pList
= m_pDoc
->GetCondFormList(0);
229 auto pFormat
= std::make_unique
<ScConditionalFormat
>(1, m_pDoc
);
230 ScRangeList
aRangeList(ScRange(0,0,0,3,3,0));
231 pFormat
->SetRange(aRangeList
);
233 ScCondFormatEntry
* pEntry
= new ScCondFormatEntry(ScConditionMode::Direct
,"=B2","",*m_pDoc
,ScAddress(0,0,0),ScResId(STR_STYLENAME_RESULT
));
234 pFormat
->AddEntry(pEntry
);
236 m_pDoc
->AddCondFormatData(pFormat
->GetRange(), 0, 1);
237 auto pFormatTmp
= pFormat
.get();
238 pList
->InsertNew(std::move(pFormat
));
240 m_pDoc
->InsertRow(0,0,m_pDoc
->MaxCol(),0,4,2);
241 const ScRangeList
& rRange
= pFormatTmp
->GetRange();
242 CPPUNIT_ASSERT_EQUAL(ScRangeList(ScRange(0,0,0,3,5,0)), rRange
);
244 m_pDoc
->DeleteTab(0);
247 void TestCondformat::testCondFormatInsertDeleteSheets()
249 m_pDoc
->InsertTab(0, "Test");
251 // Add a conditional format to B2:B4.
252 auto pFormat
= std::make_unique
<ScConditionalFormat
>(1, m_pDoc
);
253 pFormat
->SetRange(ScRange(1,1,0,1,3,0));
255 auto pFormatTmp
= pFormat
.get();
256 sal_uLong nKey
= m_pDoc
->AddCondFormat(std::move(pFormat
), 0);
258 // Add condition in which if the value equals 2, set the "Result" style.
259 ScCondFormatEntry
* pEntry
= new ScCondFormatEntry(
260 ScConditionMode::Equal
, "=2", "" , *m_pDoc
, ScAddress(0,0,0), ScResId(STR_STYLENAME_RESULT
));
261 pFormatTmp
->AddEntry(pEntry
);
263 // Apply the format to the range.
264 m_pDoc
->AddCondFormatData(pFormatTmp
->GetRange(), 0, nKey
);
266 // Make sure this conditional format entry is really there.
267 ScConditionalFormatList
* pList
= m_pDoc
->GetCondFormList(0);
268 CPPUNIT_ASSERT(pList
);
269 const ScConditionalFormat
* pCheck
= pList
->GetFormat(nKey
);
270 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong conditional format instance.", pCheck
, const_cast<const ScConditionalFormat
*>(pFormatTmp
));
272 // ... and its range is B2:B4.
273 ScRangeList aCheckRange
= pCheck
->GetRange();
274 CPPUNIT_ASSERT_EQUAL_MESSAGE("This should be a single range.", size_t(1), aCheckRange
.size());
275 const ScRange
* pRange
= &aCheckRange
[0];
276 CPPUNIT_ASSERT(pRange
);
277 CPPUNIT_ASSERT_EQUAL_MESSAGE("Format should be applied to B2:B4.", ScRange(1,1,0,1,3,0), *pRange
);
279 ScDocFunc
& rFunc
= m_xDocShell
->GetDocFunc();
281 // Insert a new sheet at the left.
282 bool bInserted
= rFunc
.InsertTable(0, "Inserted", true, true);
283 CPPUNIT_ASSERT(bInserted
);
285 pList
= m_pDoc
->GetCondFormList(1);
286 CPPUNIT_ASSERT(pList
);
287 pCheck
= pList
->GetFormat(nKey
);
288 CPPUNIT_ASSERT(pCheck
);
290 // Make sure the range also got shifted.
291 aCheckRange
= pCheck
->GetRange();
292 CPPUNIT_ASSERT_EQUAL_MESSAGE("This should be a single range.", size_t(1), aCheckRange
.size());
293 pRange
= &aCheckRange
[0];
294 CPPUNIT_ASSERT(pRange
);
295 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
);
297 // Delete the sheet to the left.
298 bool bDeleted
= rFunc
.DeleteTable(0, true);
299 CPPUNIT_ASSERT(bDeleted
);
301 pList
= m_pDoc
->GetCondFormList(0);
302 CPPUNIT_ASSERT(pList
);
303 pCheck
= pList
->GetFormat(nKey
);
304 CPPUNIT_ASSERT(pCheck
);
306 // Make sure the range got shifted back.
307 aCheckRange
= pCheck
->GetRange();
308 CPPUNIT_ASSERT_EQUAL_MESSAGE("This should be a single range.", size_t(1), aCheckRange
.size());
309 pRange
= &aCheckRange
[0];
310 CPPUNIT_ASSERT(pRange
);
311 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
);
313 SfxUndoManager
* pUndoMgr
= m_pDoc
->GetUndoManager();
314 CPPUNIT_ASSERT(pUndoMgr
);
316 // Undo and re-check.
319 pList
= m_pDoc
->GetCondFormList(1);
320 CPPUNIT_ASSERT(pList
);
321 pCheck
= pList
->GetFormat(nKey
);
322 CPPUNIT_ASSERT(pCheck
);
324 aCheckRange
= pCheck
->GetRange();
325 CPPUNIT_ASSERT_EQUAL_MESSAGE("This should be a single range.", size_t(1), aCheckRange
.size());
326 pRange
= &aCheckRange
[0];
327 CPPUNIT_ASSERT(pRange
);
328 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
);
330 #if 0 // TODO : Undo of sheet insertion currently depends on the presence of
331 // view shell, and crashes when executed during cppunit run.
333 // Undo again and re-check.
336 pList
= m_pDoc
->GetCondFormList(0);
337 CPPUNIT_ASSERT(pList
);
338 pCheck
= pList
->GetFormat(nKey
);
339 CPPUNIT_ASSERT(pCheck
);
341 // Make sure the range got shifted back.
342 aCheckRange
= pCheck
->GetRange();
343 CPPUNIT_ASSERT_MESSAGE("This should be a single range.", aCheckRange
.size() == 1);
344 pRange
= aCheckRange
[0];
345 CPPUNIT_ASSERT(pRange
);
346 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));
348 m_pDoc
->DeleteTab(1);
351 m_pDoc
->DeleteTab(0);
354 void TestCondformat::testCondCopyPaste()
356 m_pDoc
->InsertTab(0, "Test");
358 auto pFormat
= std::make_unique
<ScConditionalFormat
>(1, m_pDoc
);
359 ScRange
aCondFormatRange(0,0,0,3,3,0);
360 ScRangeList
aRangeList(aCondFormatRange
);
361 pFormat
->SetRange(aRangeList
);
363 ScCondFormatEntry
* pEntry
= new ScCondFormatEntry(ScConditionMode::Direct
,"=B2","",*m_pDoc
,ScAddress(0,0,0),ScResId(STR_STYLENAME_RESULT
));
364 pFormat
->AddEntry(pEntry
);
365 sal_uLong nIndex
= m_pDoc
->AddCondFormat(std::move(pFormat
), 0);
367 ScDocument
aClipDoc(SCDOCMODE_CLIP
);
368 copyToClip(m_pDoc
, aCondFormatRange
, &aClipDoc
);
370 ScRange
aTargetRange(4,4,0,7,7,0);
371 pasteFromClip(m_pDoc
, aTargetRange
, &aClipDoc
);
373 ScConditionalFormat
* pPastedFormat
= m_pDoc
->GetCondFormat(7,7,0);
374 CPPUNIT_ASSERT(pPastedFormat
);
376 // Pasting the same conditional format must modify existing format, making its range
377 // combined of previous range and newly pasted range having the conditional format.
378 // No new conditional formats must be created.
379 CPPUNIT_ASSERT_EQUAL(size_t(1), m_pDoc
->GetCondFormList(0)->size());
380 aRangeList
.Join(aTargetRange
);
381 CPPUNIT_ASSERT_EQUAL(aRangeList
, pPastedFormat
->GetRange());
382 CPPUNIT_ASSERT_EQUAL(sal_uInt32(nIndex
), pPastedFormat
->GetKey());
383 const SfxPoolItem
* pItem
= m_pDoc
->GetAttr( 7, 7, 0, ATTR_CONDITIONAL
);
384 const ScCondFormatItem
* pCondFormatItem
= static_cast<const ScCondFormatItem
*>(pItem
);
386 CPPUNIT_ASSERT(pCondFormatItem
);
387 CPPUNIT_ASSERT_EQUAL(size_t(1), pCondFormatItem
->GetCondFormatData().size());
388 CPPUNIT_ASSERT_EQUAL(sal_uInt32(nIndex
), pCondFormatItem
->GetCondFormatData().front());
390 m_pDoc
->DeleteTab(0);
393 void TestCondformat::testCondCopyPasteSingleCell()
395 m_pDoc
->InsertTab(0, "Test");
397 auto pFormat
= std::make_unique
<ScConditionalFormat
>(1, m_pDoc
);
398 ScRange
aCondFormatRange(0,0,0,3,3,0);
399 ScRangeList
aRangeList(aCondFormatRange
);
400 pFormat
->SetRange(aRangeList
);
402 ScCondFormatEntry
* pEntry
= new ScCondFormatEntry(ScConditionMode::Direct
,"=B2","",*m_pDoc
,ScAddress(0,0,0),ScResId(STR_STYLENAME_RESULT
));
403 pFormat
->AddEntry(pEntry
);
404 sal_uLong nIndex
= m_pDoc
->AddCondFormat(std::move(pFormat
), 0);
406 ScDocument
aClipDoc(SCDOCMODE_CLIP
);
407 copyToClip(m_pDoc
, ScRange(0,0,0,0,0,0), &aClipDoc
);
409 ScRange
aTargetRange(4,4,0,4,4,0);
410 pasteOneCellFromClip(m_pDoc
, aTargetRange
, &aClipDoc
);
412 ScConditionalFormat
* pPastedFormat
= m_pDoc
->GetCondFormat(4,4,0);
413 CPPUNIT_ASSERT(pPastedFormat
);
415 // Pasting the same conditional format must modify existing format, making its range
416 // combined of previous range and newly pasted range having the conditional format.
417 // No new conditional formats must be created.
418 CPPUNIT_ASSERT_EQUAL(size_t(1), m_pDoc
->GetCondFormList(0)->size());
419 aRangeList
.Join(aTargetRange
);
420 CPPUNIT_ASSERT_EQUAL(aRangeList
, pPastedFormat
->GetRange());
421 CPPUNIT_ASSERT_EQUAL(sal_uInt32(nIndex
), pPastedFormat
->GetKey());
422 const SfxPoolItem
* pItem
= m_pDoc
->GetAttr( 4, 4, 0, ATTR_CONDITIONAL
);
423 const ScCondFormatItem
* pCondFormatItem
= static_cast<const ScCondFormatItem
*>(pItem
);
425 CPPUNIT_ASSERT(pCondFormatItem
);
426 CPPUNIT_ASSERT_EQUAL(size_t(1), pCondFormatItem
->GetCondFormatData().size());
427 CPPUNIT_ASSERT_EQUAL(sal_uInt32(nIndex
), pCondFormatItem
->GetCondFormatData().front() );
429 m_pDoc
->DeleteTab(0);
432 void TestCondformat::testCondCopyPasteSingleCellToRange()
434 m_pDoc
->InsertTab(0, "Test");
436 auto pFormat
= std::make_unique
<ScConditionalFormat
>(1, m_pDoc
);
437 ScRange
aCondFormatRange(0,0,0,3,3,0);
438 ScRangeList
aRangeList(aCondFormatRange
);
439 pFormat
->SetRange(aRangeList
);
441 ScCondFormatEntry
* pEntry
= new ScCondFormatEntry(ScConditionMode::Direct
,"=B2","",*m_pDoc
,ScAddress(0,0,0),ScResId(STR_STYLENAME_RESULT
));
442 pFormat
->AddEntry(pEntry
);
443 sal_uLong nIndex
= m_pDoc
->AddCondFormat(std::move(pFormat
), 0);
445 ScDocument
aClipDoc(SCDOCMODE_CLIP
);
446 copyToClip(m_pDoc
, ScRange(0,0,0,0,0,0), &aClipDoc
);
447 ScRange
aTargetRange(4,4,0,5,8,0);
448 pasteOneCellFromClip(m_pDoc
, aTargetRange
, &aClipDoc
);
450 // Pasting the same conditional format must modify existing format, making its range
451 // combined of previous range and newly pasted range having the conditional format.
452 // No new conditional formats must be created.
453 CPPUNIT_ASSERT_EQUAL(size_t(1), m_pDoc
->GetCondFormList(0)->size());
454 aRangeList
.Join(aTargetRange
);
455 for(SCROW nRow
= 4; nRow
<= 8; ++nRow
)
457 for (SCCOL nCol
= 4; nCol
<= 5; ++nCol
)
459 ScConditionalFormat
* pPastedFormat
= m_pDoc
->GetCondFormat(nCol
, nRow
, 0);
460 CPPUNIT_ASSERT(pPastedFormat
);
462 CPPUNIT_ASSERT_EQUAL(aRangeList
, pPastedFormat
->GetRange());
463 sal_uLong nPastedKey
= pPastedFormat
->GetKey();
464 CPPUNIT_ASSERT_EQUAL(nIndex
, nPastedKey
);
465 const SfxPoolItem
* pItem
= m_pDoc
->GetAttr( nCol
, nRow
, 0, ATTR_CONDITIONAL
);
466 const ScCondFormatItem
* pCondFormatItem
= static_cast<const ScCondFormatItem
*>(pItem
);
468 CPPUNIT_ASSERT(pCondFormatItem
);
469 CPPUNIT_ASSERT_EQUAL(size_t(1), pCondFormatItem
->GetCondFormatData().size());
470 CPPUNIT_ASSERT_EQUAL(sal_uInt32(nIndex
), pCondFormatItem
->GetCondFormatData().front() );
474 m_pDoc
->DeleteTab(0);
477 void TestCondformat::testCondCopyPasteSingleCellIntoSameFormatRange()
479 m_pDoc
->InsertTab(0, "Test");
481 auto pFormat
= std::make_unique
<ScConditionalFormat
>(1, m_pDoc
);
482 ScRange
aCondFormatRange(0, 0, 0, 3, 3, 0);
483 ScRangeList
aRangeList(aCondFormatRange
);
484 pFormat
->SetRange(aRangeList
);
486 ScCondFormatEntry
* pEntry
= new ScCondFormatEntry(ScConditionMode::Direct
, "=B2", "", *m_pDoc
, ScAddress(0, 0, 0), ScResId(STR_STYLENAME_RESULT
));
487 pFormat
->AddEntry(pEntry
);
488 sal_uLong nIndex
= m_pDoc
->AddCondFormat(std::move(pFormat
), 0);
490 ScDocument
aClipDoc(SCDOCMODE_CLIP
);
491 copyToClip(m_pDoc
, ScRange(1, 1, 0, 1, 1, 0), &aClipDoc
);
493 ScRange
aTargetRange(2, 2, 0, 2, 2, 0);
494 pasteFromClip(m_pDoc
, aTargetRange
, &aClipDoc
);
496 ScConditionalFormat
* pPastedFormat
= m_pDoc
->GetCondFormat(2, 2, 0);
497 CPPUNIT_ASSERT(pPastedFormat
);
499 // Pasting the same conditional format into the same range must not modify existing format,
500 // since it already covers the pasted range. No new conditional formats must be created.
501 CPPUNIT_ASSERT_EQUAL(size_t(1), m_pDoc
->GetCondFormList(0)->size());
502 CPPUNIT_ASSERT_EQUAL(aRangeList
, pPastedFormat
->GetRange());
503 CPPUNIT_ASSERT_EQUAL(sal_uInt32(nIndex
), pPastedFormat
->GetKey());
504 const SfxPoolItem
* pItem
= m_pDoc
->GetAttr(2, 2, 0, ATTR_CONDITIONAL
);
505 const ScCondFormatItem
* pCondFormatItem
= static_cast<const ScCondFormatItem
*>(pItem
);
507 CPPUNIT_ASSERT(pCondFormatItem
);
508 CPPUNIT_ASSERT_EQUAL(size_t(1), pCondFormatItem
->GetCondFormatData().size());
509 CPPUNIT_ASSERT_EQUAL(sal_uInt32(nIndex
), pCondFormatItem
->GetCondFormatData().front());
511 m_pDoc
->DeleteTab(0);
514 void TestCondformat::testCondCopyPasteSingleRowToRange()
516 m_pDoc
->InsertTab(0, "Test");
518 auto pFormat
= std::make_unique
<ScConditionalFormat
>(1, m_pDoc
);
519 ScRange
aCondFormatRange(0,0,0,0,0,0);
520 ScRangeList
aRangeList(aCondFormatRange
);
521 pFormat
->SetRange(aRangeList
);
523 ScCondFormatEntry
* pEntry
= new ScCondFormatEntry(ScConditionMode::Direct
,"=B2","",*m_pDoc
,ScAddress(0,0,0),ScResId(STR_STYLENAME_RESULT
));
524 pFormat
->AddEntry(pEntry
);
525 auto pFormatTmp
= pFormat
.get();
526 m_pDoc
->AddCondFormat(std::move(pFormat
), 0);
528 ScDocument
aClipDoc(SCDOCMODE_CLIP
);
529 copyToClip(m_pDoc
, ScRange(0,0,0,m_pDoc
->MaxCol(),0,0), &aClipDoc
);
530 ScRange
aTargetRange(0,4,0,m_pDoc
->MaxCol(),4,0);
531 pasteOneCellFromClip(m_pDoc
, aTargetRange
, &aClipDoc
);
533 ScConditionalFormat
* pNewFormat
= m_pDoc
->GetCondFormat(0, 4, 0);
534 CPPUNIT_ASSERT(pNewFormat
);
535 CPPUNIT_ASSERT_EQUAL(pNewFormat
->GetKey(), pFormatTmp
->GetKey());
537 for (SCCOL nCol
= 1; nCol
<= m_pDoc
->MaxCol(); ++nCol
)
539 ScConditionalFormat
* pNewFormat2
= m_pDoc
->GetCondFormat(nCol
, 4, 0);
540 CPPUNIT_ASSERT(!pNewFormat2
);
543 m_pDoc
->DeleteTab(0);
546 void TestCondformat::testCondCopyPasteSingleRowToRange2()
548 m_pDoc
->InsertTab(0, "Test");
550 auto pFormat
= std::make_unique
<ScConditionalFormat
>(1, m_pDoc
);
551 ScRange
aCondFormatRange(0,0,0,0,0,0);
552 ScRangeList
aRangeList(aCondFormatRange
);
553 pFormat
->SetRange(aRangeList
);
555 ScCondFormatEntry
* pEntry
= new ScCondFormatEntry(ScConditionMode::Direct
,"=B2","",*m_pDoc
,ScAddress(0,0,0),ScResId(STR_STYLENAME_RESULT
));
556 pFormat
->AddEntry(pEntry
);
557 m_pDoc
->AddCondFormat(std::move(pFormat
), 0);
559 ScDocument
aClipDoc(SCDOCMODE_CLIP
);
560 copyToClip(m_pDoc
, ScRange(0,0,0,3,0,0), &aClipDoc
);
561 ScRange
aTargetRange(0,4,0,m_pDoc
->MaxCol(),4,0);
562 pasteOneCellFromClip(m_pDoc
, aTargetRange
, &aClipDoc
);
564 for (SCCOL nCol
= 0; nCol
<= m_pDoc
->MaxCol(); ++nCol
)
566 ScConditionalFormat
* pNewFormat
= m_pDoc
->GetCondFormat(nCol
, 4, 0);
568 CPPUNIT_ASSERT(pNewFormat
);
570 CPPUNIT_ASSERT(!pNewFormat
);
573 m_pDoc
->DeleteTab(0);
576 void TestCondformat::testCondCopyPasteSheetBetweenDoc()
578 m_pDoc
->InsertTab(0, "Test");
580 auto pFormat
= std::make_unique
<ScConditionalFormat
>(1, m_pDoc
);
581 ScRange
aCondFormatRange(0,0,0,3,3,0);
582 ScRangeList
aRangeList(aCondFormatRange
);
583 pFormat
->SetRange(aRangeList
);
585 ScCondFormatEntry
* pEntry
= new ScCondFormatEntry(ScConditionMode::Direct
,"=B2","",*m_pDoc
,ScAddress(0,0,0),ScResId(STR_STYLENAME_RESULT
));
586 pFormat
->AddEntry(pEntry
);
587 m_pDoc
->AddCondFormat(std::move(pFormat
), 0);
590 aDoc
.TransferTab(*m_pDoc
, 0, 0);
592 ScConditionalFormatList
* pList
= aDoc
.GetCondFormList(0);
593 CPPUNIT_ASSERT_EQUAL(size_t(1), pList
->size());
595 m_pDoc
->DeleteTab(0);
598 void TestCondformat::testCondCopyPasteSheet()
600 m_pDoc
->InsertTab(0, "Test");
602 auto pFormat
= std::make_unique
<ScConditionalFormat
>(1, m_pDoc
);
603 ScRange
aCondFormatRange(0,0,0,3,3,0);
604 ScRangeList
aRangeList(aCondFormatRange
);
605 pFormat
->SetRange(aRangeList
);
607 ScCondFormatEntry
* pEntry
= new ScCondFormatEntry(ScConditionMode::Direct
,"=B2","",*m_pDoc
,ScAddress(0,0,0),ScResId(STR_STYLENAME_RESULT
));
608 pFormat
->AddEntry(pEntry
);
609 m_pDoc
->AddCondFormat(std::move(pFormat
), 0);
611 m_pDoc
->CopyTab(0, SC_TAB_APPEND
);
613 ScConditionalFormatList
* pList
= m_pDoc
->GetCondFormList(1);
614 CPPUNIT_ASSERT_EQUAL(size_t(1), pList
->size());
616 ScConditionalFormat
& rFormat
= **pList
->begin();
617 const ScRangeList
& rRange
= rFormat
.GetRange();
618 CPPUNIT_ASSERT_EQUAL(ScRangeList(ScRange(0,0,1,3,3,1)), rRange
);
619 sal_uInt32 nKey
= rFormat
.GetKey();
620 const SfxPoolItem
* pItem
= m_pDoc
->GetAttr( 2, 2, 1, ATTR_CONDITIONAL
);
621 const ScCondFormatItem
* pCondFormatItem
= static_cast<const ScCondFormatItem
*>(pItem
);
623 CPPUNIT_ASSERT(pCondFormatItem
);
624 CPPUNIT_ASSERT_EQUAL(size_t(1), pCondFormatItem
->GetCondFormatData().size());
625 CPPUNIT_ASSERT_EQUAL( nKey
, pCondFormatItem
->GetCondFormatData().front() );
627 m_pDoc
->DeleteTab(1);
628 m_pDoc
->DeleteTab(0);
631 void TestCondformat::testIconSet()
633 m_pDoc
->InsertTab(0, "Test");
634 ScConditionalFormatList
* pList
= m_pDoc
->GetCondFormList(0);
636 auto pFormat
= std::make_unique
<ScConditionalFormat
>(1, m_pDoc
);
637 ScRangeList
aRangeList(ScRange(0,0,0,0,0,0));
638 pFormat
->SetRange(aRangeList
);
640 ScIconSetFormat
* pEntry
= new ScIconSetFormat(m_pDoc
);
641 ScIconSetFormatData
* pData
= new ScIconSetFormatData
;
642 pData
->m_Entries
.emplace_back(new ScColorScaleEntry(0, COL_BLUE
));
643 pData
->m_Entries
.emplace_back(new ScColorScaleEntry(1, COL_GREEN
));
644 pData
->m_Entries
.emplace_back(new ScColorScaleEntry(2, COL_RED
));
645 pEntry
->SetIconSetData(pData
);
647 m_pDoc
->AddCondFormatData(pFormat
->GetRange(), 0, 1);
648 pList
->InsertNew(std::move(pFormat
));
651 double nVal
; sal_Int32 nIndex
;
659 for(size_t i
= 0; i
< SAL_N_ELEMENTS(aTests
); ++i
)
661 m_pDoc
->SetValue(0,0,0,aTests
[i
].nVal
);
662 std::unique_ptr
<ScIconSetInfo
> pInfo
= pEntry
->GetIconSetInfo(ScAddress(0,0,0));
663 CPPUNIT_ASSERT_EQUAL(aTests
[i
].nIndex
, pInfo
->nIconIndex
);
667 m_pDoc
->DeleteTab(0);
670 void TestCondformat::testDataBarLengthAutomaticAxis()
672 m_pDoc
->InsertTab(0, "Test");
674 static const ScDataBarLengthData aValues
[] = {
686 testDataBarLengthImpl(m_pDoc
, aValues
, ScRange(0,0,0,0,7,0),
687 3, COLORSCALE_VALUE
, 7, COLORSCALE_VALUE
, 0.0, databar::AUTOMATIC
);
689 static const ScDataBarLengthData aValues2
[] = {
708 testDataBarLengthImpl(m_pDoc
, aValues2
, ScRange(1,0,0,1,15,0),
709 -4, COLORSCALE_VALUE
, 8, COLORSCALE_VALUE
, 1.0/3.0 * 100, databar::AUTOMATIC
);
711 static const ScDataBarLengthData aValues3
[] = {
718 testDataBarLengthImpl(m_pDoc
, aValues3
, ScRange(2,0,0,2,3,0),
719 0, COLORSCALE_MIN
, 0, COLORSCALE_MAX
, 0, databar::AUTOMATIC
);
721 static const ScDataBarLengthData aValues4
[] = {
728 testDataBarLengthImpl(m_pDoc
, aValues4
, ScRange(3,0,0,3,3,0),
729 0, COLORSCALE_AUTO
, 0, COLORSCALE_AUTO
, 0, databar::AUTOMATIC
);
731 m_pDoc
->DeleteTab(0);
734 void TestCondformat::testDataBarLengthMiddleAxis()
736 m_pDoc
->InsertTab(0, "Test");
738 static const ScDataBarLengthData aValues
[] = {
751 testDataBarLengthImpl(m_pDoc
, aValues
, ScRange(0,0,0,0,8,0),
752 2, COLORSCALE_VALUE
, 8, COLORSCALE_VALUE
, 50.0, databar::MIDDLE
);
754 static const ScDataBarLengthData aValues2
[] = {
773 testDataBarLengthImpl(m_pDoc
, aValues2
, ScRange(1,0,0,1,15,0),
774 -4, COLORSCALE_VALUE
, 8, COLORSCALE_VALUE
, 50.0, databar::MIDDLE
);
776 m_pDoc
->DeleteTab(0);
779 void TestCondformat::testCondFormatEndsWithStr()
781 m_pDoc
->InsertTab(0, "Test");
783 // case insensitive matching
784 ScConditionEntry
aEntry(ScConditionMode::EndsWith
, "\"teststring\"", "", *m_pDoc
, ScAddress(),
785 "", "", formula::FormulaGrammar::GRAM_DEFAULT
, formula::FormulaGrammar::GRAM_DEFAULT
);
787 svl::SharedStringPool
& rStringPool
= m_pDoc
->GetSharedStringPool();
788 svl::SharedString aStr
= rStringPool
.intern("SimpleTestString");
789 ScRefCellValue
aVal(&aStr
);
790 ScAddress
aPos(0, 0, 0);
792 bool bValid
= aEntry
.IsCellValid(aVal
, aPos
);
793 CPPUNIT_ASSERT(bValid
);
795 m_pDoc
->DeleteTab(0);
798 void TestCondformat::testCondFormatEndsWithVal()
800 m_pDoc
->InsertTab(0, "Test");
802 ScConditionEntry
aEntry(ScConditionMode::EndsWith
, "2", "", *m_pDoc
, ScAddress(),
803 "", "", formula::FormulaGrammar::GRAM_DEFAULT
, formula::FormulaGrammar::GRAM_DEFAULT
);
805 for (sal_Int32 i
= 0; i
< 15; ++i
)
807 ScRefCellValue
aVal(i
);
808 ScAddress
aPos(0, 0, 0);
810 bool bValid
= aEntry
.IsCellValid(aVal
, aPos
);
811 bool bShouldBeValid
= (i
% 10) == 2;
812 CPPUNIT_ASSERT_EQUAL(bShouldBeValid
, bValid
);
815 m_pDoc
->DeleteTab(0);
818 void TestCondformat::testFormulaListenerSingleCellToSingleCell()
820 m_pDoc
->InsertTab(0, "test");
822 ScCompiler
aCompiler(*m_pDoc
, ScAddress(10, 10, 0), formula::FormulaGrammar::GRAM_ENGLISH
);
824 std::unique_ptr
<ScTokenArray
> pTokenArray(aCompiler
.CompileString("A1"));
826 ScFormulaListener
aListener(*m_pDoc
);
828 aListener
.addTokenArray(pTokenArray
.get(), ScAddress(10, 10, 0));
830 m_pDoc
->SetValue(ScAddress(0, 0, 0), 1.0);
831 CPPUNIT_ASSERT(aListener
.NeedsRepaint());
833 m_pDoc
->DeleteTab(0);
836 void TestCondformat::testFormulaListenerSingleCellToMultipleCells()
838 m_pDoc
->InsertTab(0, "test");
840 ScCompiler
aCompiler(*m_pDoc
, ScAddress(10, 10, 0), formula::FormulaGrammar::GRAM_ENGLISH
);
842 std::unique_ptr
<ScTokenArray
> pTokenArray(aCompiler
.CompileString("A1"));
844 ScFormulaListener
aListener(*m_pDoc
);
846 aListener
.addTokenArray(pTokenArray
.get(), ScAddress(10, 10, 0));
848 m_pDoc
->SetValue(ScAddress(0, 0, 0), 1.0);
849 CPPUNIT_ASSERT(aListener
.NeedsRepaint());
851 m_pDoc
->DeleteTab(0);
854 void TestCondformat::testFormulaListenerMultipleCellsToSingleCell()
856 m_pDoc
->InsertTab(0, "test");
858 ScCompiler
aCompiler(*m_pDoc
, ScAddress(10, 10, 0), formula::FormulaGrammar::GRAM_ENGLISH
);
860 std::unique_ptr
<ScTokenArray
> pTokenArray(aCompiler
.CompileString("A1"));
862 ScFormulaListener
aListener(*m_pDoc
);
864 aListener
.addTokenArray(pTokenArray
.get(), ScAddress(10, 10, 0));
866 m_pDoc
->SetValue(ScAddress(0, 0, 0), 1.0);
867 CPPUNIT_ASSERT(aListener
.NeedsRepaint());
869 m_pDoc
->DeleteTab(0);
872 void TestCondformat::testFormulaListenerMultipleCellsToMultipleCells()
874 m_pDoc
->InsertTab(0, "test");
876 ScCompiler
aCompiler(*m_pDoc
, ScAddress(10, 10, 0), formula::FormulaGrammar::GRAM_ENGLISH
);
878 std::unique_ptr
<ScTokenArray
> pTokenArray(aCompiler
.CompileString("A1"));
880 ScFormulaListener
aListener(*m_pDoc
);
882 aListener
.addTokenArray(pTokenArray
.get(), ScAddress(10, 10, 0));
884 m_pDoc
->SetValue(ScAddress(0, 0, 0), 1.0);
885 CPPUNIT_ASSERT(aListener
.NeedsRepaint());
887 m_pDoc
->DeleteTab(0);
890 void TestCondformat::testFormulaListenerUpdateInsertTab()
892 m_pDoc
->InsertTab(0, "test");
894 ScCompiler
aCompiler(*m_pDoc
, ScAddress(10, 10, 0), formula::FormulaGrammar::GRAM_ENGLISH
);
895 std::unique_ptr
<ScTokenArray
> pTokenArray(aCompiler
.CompileString("A1"));
897 ScFormulaListener
aListener(*m_pDoc
);
898 aListener
.addTokenArray(pTokenArray
.get(), ScAddress(10, 10, 0));
899 CPPUNIT_ASSERT(!aListener
.NeedsRepaint());
901 m_pDoc
->InsertTab(0, "new_tab");
903 // check that the listener has moved to the new sheet
904 m_pDoc
->SetValue(ScAddress(0, 0, 1), 1.0);
905 CPPUNIT_ASSERT(aListener
.NeedsRepaint());
907 // check that we are not listening to the old sheet
908 m_pDoc
->SetValue(ScAddress(0, 0, 0), 1.0);
909 CPPUNIT_ASSERT(!aListener
.NeedsRepaint());
911 m_pDoc
->DeleteTab(0);
914 void TestCondformat::testFormulaListenerUpdateDeleteTab()
916 m_pDoc
->InsertTab(0, "test");
917 m_pDoc
->InsertTab(0, "to_delete");
919 ScCompiler
aCompiler(*m_pDoc
, ScAddress(10, 10, 1), formula::FormulaGrammar::GRAM_ENGLISH
);
920 std::unique_ptr
<ScTokenArray
> pTokenArray(aCompiler
.CompileString("A1"));
922 ScFormulaListener
aListener(*m_pDoc
);
923 aListener
.addTokenArray(pTokenArray
.get(), ScAddress(10, 10, 1));
924 CPPUNIT_ASSERT(!aListener
.NeedsRepaint());
926 m_pDoc
->DeleteTab(0);
928 // check that the listener has moved
929 m_pDoc
->SetValue(ScAddress(0, 0, 0), 1.0);
930 CPPUNIT_ASSERT(aListener
.NeedsRepaint());
932 m_pDoc
->DeleteTab(0);
935 void TestCondformat::testCondFormatUpdateMoveTab()
937 m_pDoc
->InsertTab(0, "test");
938 m_pDoc
->InsertTab(1, "Test2");
940 ScConditionEntry
* pEntry
= new ScConditionEntry(ScConditionMode::Equal
, "A1", "", *m_pDoc
, ScAddress(10, 10, 0), "", "", formula::FormulaGrammar::GRAM_DEFAULT
, formula::FormulaGrammar::GRAM_DEFAULT
);
942 auto pFormat
= std::make_unique
<ScConditionalFormat
>(0, m_pDoc
);
943 pFormat
->SetRange(ScRange(10, 10, 0, 10, 12, 0));
944 auto pFormatTmp
= pFormat
.get();
945 m_pDoc
->AddCondFormat(std::move(pFormat
), 0);
947 pFormatTmp
->AddEntry(pEntry
);
949 // the conditional format should listen to A1:A3
950 for (SCROW nRow
= 0; nRow
< 3; ++nRow
)
952 m_pDoc
->SetValue(ScAddress(0, nRow
, 0), 1.0);
953 CPPUNIT_ASSERT(pEntry
->NeedsRepaint());
956 m_pDoc
->MoveTab(0, 1);
958 // the conditional format should listen to A1:A3 on the second sheet
959 for (SCROW nRow
= 0; nRow
< 3; ++nRow
)
961 m_pDoc
->SetValue(ScAddress(0, nRow
, 1), 1.0);
962 CPPUNIT_ASSERT(pEntry
->NeedsRepaint());
964 m_pDoc
->SetValue(ScAddress(0, nRow
, 0), 1.0);
965 CPPUNIT_ASSERT(!pEntry
->NeedsRepaint());
968 m_pDoc
->DeleteTab(1);
969 m_pDoc
->DeleteTab(0);
972 void TestCondformat::testCondFormatUpdateInsertTab()
974 m_pDoc
->InsertTab(0, "test");
976 ScConditionEntry
* pEntry
= new ScConditionEntry(ScConditionMode::Equal
, "A1", "", *m_pDoc
, ScAddress(10, 10, 0), "", "", formula::FormulaGrammar::GRAM_DEFAULT
, formula::FormulaGrammar::GRAM_DEFAULT
);
978 auto pFormat
= std::make_unique
<ScConditionalFormat
>(0, m_pDoc
);
979 pFormat
->SetRange(ScRange(10, 10, 0, 10, 12, 0));
980 auto pFormatTmp
= pFormat
.get();
981 m_pDoc
->AddCondFormat(std::move(pFormat
), 0);
983 pFormatTmp
->AddEntry(pEntry
);
985 // the conditional format should listen to A1:A3
986 for (SCROW nRow
= 0; nRow
< 3; ++nRow
)
988 m_pDoc
->SetValue(ScAddress(0, nRow
, 0), 1.0);
989 CPPUNIT_ASSERT(pEntry
->NeedsRepaint());
991 m_pDoc
->SetValue(ScAddress(0, nRow
, 1), 1.0);
992 CPPUNIT_ASSERT(!pEntry
->NeedsRepaint());
995 m_pDoc
->InsertTab(0, "test2");
997 // the conditional format should listen to A1:A3 on the second sheet
998 for (SCROW nRow
= 0; nRow
< 3; ++nRow
)
1000 m_pDoc
->SetValue(ScAddress(0, nRow
, 1), 1.0);
1001 CPPUNIT_ASSERT(pEntry
->NeedsRepaint());
1003 m_pDoc
->SetValue(ScAddress(0, nRow
, 0), 1.0);
1004 CPPUNIT_ASSERT(!pEntry
->NeedsRepaint());
1007 m_pDoc
->DeleteTab(1);
1008 m_pDoc
->DeleteTab(0);
1011 void TestCondformat::testCondFormatUpdateDeleteTab()
1013 m_pDoc
->InsertTab(0, "test");
1014 m_pDoc
->InsertTab(1, "Test2");
1016 ScConditionEntry
* pEntry
= new ScConditionEntry(ScConditionMode::Equal
, "A1", "", *m_pDoc
, ScAddress(10, 10, 1), "", "", formula::FormulaGrammar::GRAM_DEFAULT
, formula::FormulaGrammar::GRAM_DEFAULT
);
1018 auto pFormat
= std::make_unique
<ScConditionalFormat
>(0, m_pDoc
);
1019 pFormat
->SetRange(ScRange(10, 10, 1, 10, 12, 1));
1020 auto pFormatTmp
= pFormat
.get();
1021 m_pDoc
->AddCondFormat(std::move(pFormat
), 1);
1023 pFormatTmp
->AddEntry(pEntry
);
1025 // the conditional format should listen to A1:A3 on the second sheet
1026 for (SCROW nRow
= 0; nRow
< 3; ++nRow
)
1028 m_pDoc
->SetValue(ScAddress(0, nRow
, 1), 1.0);
1029 CPPUNIT_ASSERT(pEntry
->NeedsRepaint());
1032 m_pDoc
->DeleteTab(0);
1034 // the conditional format should listen to A1:A3 on the second sheet
1035 for (SCROW nRow
= 0; nRow
< 3; ++nRow
)
1037 m_pDoc
->SetValue(ScAddress(0, nRow
, 0), 1.0);
1038 CPPUNIT_ASSERT(pEntry
->NeedsRepaint());
1041 m_pDoc
->DeleteTab(0);
1044 void TestCondformat::testCondFormatUpdateReference()
1046 m_pDoc
->InsertTab(0, "test");
1047 m_pDoc
->InsertTab(1, "Test2");
1049 ScConditionEntry
* pEntry
= new ScConditionEntry(ScConditionMode::Equal
, "A1", "", *m_pDoc
, ScAddress(10, 10, 0), "", "", formula::FormulaGrammar::GRAM_DEFAULT
, formula::FormulaGrammar::GRAM_DEFAULT
);
1051 auto pFormat
= std::make_unique
<ScConditionalFormat
>(0, m_pDoc
);
1052 pFormat
->SetRange(ScRange(10, 10, 0, 10, 12, 0));
1053 auto pFormatTmp
= pFormat
.get();
1054 m_pDoc
->AddCondFormat(std::move(pFormat
), 0);
1056 pFormatTmp
->AddEntry(pEntry
);
1058 // the conditional format should listen to A1:A3
1059 for (SCROW nRow
= 0; nRow
< 3; ++nRow
)
1061 m_pDoc
->SetValue(ScAddress(0, nRow
, 0), 1.0);
1062 CPPUNIT_ASSERT(pEntry
->NeedsRepaint());
1065 m_pDoc
->DeleteTab(1);
1066 m_pDoc
->DeleteTab(0);
1069 void TestCondformat::testCondFormatUpdateReferenceDelRow()
1071 m_pDoc
->InsertTab(0, "test");
1073 ScConditionEntry
* pEntry
= new ScConditionEntry(ScConditionMode::Equal
, "B6", "", *m_pDoc
, ScAddress(0, 5, 0), "", "", formula::FormulaGrammar::GRAM_DEFAULT
, formula::FormulaGrammar::GRAM_DEFAULT
);
1075 auto pFormat
= std::make_unique
<ScConditionalFormat
>(0, m_pDoc
);
1076 pFormat
->SetRange(ScRange(0, 5, 0, 0, 5, 0));
1077 auto pFormatTmp
= pFormat
.get();
1078 m_pDoc
->AddCondFormat(std::move(pFormat
), 0);
1080 pFormatTmp
->AddEntry(pEntry
);
1082 m_pDoc
->DeleteRow(0, 0, m_pDoc
->MaxCol(), 0, 4, 1);
1084 OUString aStr
= pEntry
->GetExpression(ScAddress(0, 4, 0), 0);
1085 CPPUNIT_ASSERT_EQUAL(OUString("B5"), aStr
);
1087 m_pDoc
->DeleteTab(0);
1090 void TestCondformat::testCondFormatUpdateReferenceInsRow()
1092 m_pDoc
->InsertTab(0, "test");
1094 ScConditionEntry
* pEntry
= new ScConditionEntry(ScConditionMode::Equal
, "B6", "", *m_pDoc
, ScAddress(0, 5, 0), "", "", formula::FormulaGrammar::GRAM_DEFAULT
, formula::FormulaGrammar::GRAM_DEFAULT
);
1096 auto pFormat
= std::make_unique
<ScConditionalFormat
>(0, m_pDoc
);
1097 pFormat
->SetRange(ScRange(0, 5, 0, 0, 5, 0));
1098 auto pFormatTmp
= pFormat
.get();
1099 m_pDoc
->AddCondFormat(std::move(pFormat
), 0);
1101 pFormatTmp
->AddEntry(pEntry
);
1103 m_pDoc
->InsertRow(0, 0, m_pDoc
->MaxCol(), 0, 4, 1);
1105 OUString aStr
= pEntry
->GetExpression(ScAddress(0, 6, 0), 0);
1106 CPPUNIT_ASSERT_EQUAL(OUString("B7"), aStr
);
1108 m_pDoc
->DeleteTab(0);
1111 void TestCondformat::testCondFormatUndoList()
1113 m_pDoc
->InsertTab(0, "test");
1115 ScConditionEntry
* pEntry
= new ScConditionEntry(ScConditionMode::Equal
, "B6", "", *m_pDoc
, ScAddress(0, 5, 0), "", "", formula::FormulaGrammar::GRAM_DEFAULT
, formula::FormulaGrammar::GRAM_DEFAULT
);
1117 auto pFormat
= std::make_unique
<ScConditionalFormat
>(0, m_pDoc
);
1118 pFormat
->AddEntry(pEntry
);
1119 pFormat
->SetRange(ScRange(0, 0, 0, 0, 5, 0));
1120 auto pFormatTmp
= pFormat
.get();
1121 m_pDoc
->AddCondFormat(std::move(pFormat
), 0);
1122 m_pDoc
->AddCondFormatData(pFormatTmp
->GetRange(), 0, pFormatTmp
->GetKey());
1124 ScDocFunc
& rFunc
= m_xDocShell
->GetDocFunc();
1126 CPPUNIT_ASSERT_EQUAL(size_t(1), m_pDoc
->GetCondFormList(0)->size());
1127 for (SCROW nRow
= 0; nRow
<= 5; ++nRow
)
1128 CPPUNIT_ASSERT(m_pDoc
->GetCondFormat(0, nRow
, 0));
1130 ScConditionalFormatList
* pNewList
= new ScConditionalFormatList();
1132 rFunc
.SetConditionalFormatList(pNewList
, 0);
1134 CPPUNIT_ASSERT_EQUAL(size_t(0), m_pDoc
->GetCondFormList(0)->size());
1135 for (SCROW nRow
= 0; nRow
<= 5; ++nRow
)
1136 CPPUNIT_ASSERT(!m_pDoc
->GetCondFormat(0, nRow
, 0));
1138 m_pDoc
->GetUndoManager()->Undo();
1140 CPPUNIT_ASSERT_EQUAL(size_t(1), m_pDoc
->GetCondFormList(0)->size());
1141 for (SCROW nRow
= 0; nRow
<= 5; ++nRow
)
1142 CPPUNIT_ASSERT(m_pDoc
->GetCondFormat(0, nRow
, 0));
1144 m_pDoc
->GetUndoManager()->Redo();
1146 CPPUNIT_ASSERT_EQUAL(size_t(0), m_pDoc
->GetCondFormList(0)->size());
1147 for (SCROW nRow
= 0; nRow
<= 5; ++nRow
)
1148 CPPUNIT_ASSERT(!m_pDoc
->GetCondFormat(0, nRow
, 0));
1150 m_pDoc
->DeleteTab(0);
1153 void TestCondformat::testMultipleSingleCellCondFormatCopyPaste()
1155 m_pDoc
->InsertTab(0, "Test");
1157 sal_uInt32 nFirstCondFormatKey
= addSingleCellCondFormat(m_pDoc
, ScAddress(0, 0, 0), 1, "=A2");
1158 sal_uInt32 nSecondCondFormatKey
= addSingleCellCondFormat(m_pDoc
, ScAddress(1, 0, 0), 2, "=B3");
1160 ScDocument
aClipDoc(SCDOCMODE_CLIP
);
1161 copyToClip(m_pDoc
, ScRange(0,0,0,2,0,0), &aClipDoc
);
1162 ScRange
aTargetRange(2,4,0,7,4,0);
1163 pasteOneCellFromClip(m_pDoc
, aTargetRange
, &aClipDoc
);
1165 for (SCCOL nCol
= 2; nCol
<= 7; ++nCol
)
1167 ScConditionalFormat
* pFormat
= m_pDoc
->GetCondFormat(nCol
, 4, 0);
1168 if (((nCol
- 2) % 3) == 0)
1170 CPPUNIT_ASSERT_EQUAL(pFormat
->GetKey(), nFirstCondFormatKey
);
1172 else if (((nCol
- 2) % 3) == 1)
1174 CPPUNIT_ASSERT_EQUAL(pFormat
->GetKey(), nSecondCondFormatKey
);
1178 CPPUNIT_ASSERT(!pFormat
);
1182 m_pDoc
->DeleteTab(0);
1185 void TestCondformat::testDeduplicateMultipleCondFormats()
1187 m_pDoc
->InsertTab(0, "Test");
1189 sal_uInt32 nFirstCondFormatKey
= addSingleCellCondFormat(m_pDoc
, ScAddress(0, 0, 0), 1, "=B2");
1190 sal_uInt32 nSecondCondFormatKey
= addSingleCellCondFormat(m_pDoc
, ScAddress(1, 0, 0), 2, "=B2");
1192 ScDocument
aClipDoc(SCDOCMODE_CLIP
);
1193 copyToClip(m_pDoc
, ScRange(0,0,0,2,0,0), &aClipDoc
);
1194 ScRange
aTargetRange(2,4,0,7,4,0);
1195 pasteOneCellFromClip(m_pDoc
, aTargetRange
, &aClipDoc
);
1197 for (SCCOL nCol
= 2; nCol
<= 7; ++nCol
)
1199 ScConditionalFormat
* pFormat
= m_pDoc
->GetCondFormat(nCol
, 4, 0);
1200 if (((nCol
- 2) % 3) == 0)
1202 CPPUNIT_ASSERT_EQUAL(pFormat
->GetKey(), nFirstCondFormatKey
);
1204 else if (((nCol
- 2) % 3) == 1)
1206 CPPUNIT_ASSERT_EQUAL(pFormat
->GetKey(), nSecondCondFormatKey
);
1210 CPPUNIT_ASSERT(!pFormat
);
1214 m_pDoc
->DeleteTab(0);
1217 void TestCondformat::testCondFormatListenToOwnRange()
1219 m_pDoc
->InsertTab(0, "Test");
1221 ScConditionalFormatList
* pList
= m_pDoc
->GetCondFormList(0);
1223 auto pFormat
= std::make_unique
<ScConditionalFormat
>(1, m_pDoc
);
1224 ScRangeList
aRangeList(ScRange(0,0,0,10,0,0));
1225 pFormat
->SetRange(aRangeList
);
1227 ScIconSetFormat
* pEntry
= new ScIconSetFormat(m_pDoc
);
1228 ScIconSetFormatData
* pData
= new ScIconSetFormatData
;
1229 pData
->m_Entries
.emplace_back(new ScColorScaleEntry(0, COL_BLUE
));
1230 pData
->m_Entries
.emplace_back(new ScColorScaleEntry(1, COL_GREEN
));
1231 pData
->m_Entries
.emplace_back(new ScColorScaleEntry(2, COL_RED
));
1232 pEntry
->SetIconSetData(pData
);
1233 pEntry
->SetParent(pFormat
.get());
1235 m_pDoc
->AddCondFormatData(pFormat
->GetRange(), 0, 1);
1236 pFormat
->AddEntry(pEntry
);
1237 pList
->InsertNew(std::move(pFormat
));
1239 bool bFirstCallbackCalled
= false;
1240 std::function
<void()> aFirstCallback
= [&]() {bFirstCallbackCalled
= true;};
1241 pData
->m_Entries
[0]->SetType(COLORSCALE_PERCENT
);
1242 pData
->m_Entries
[0]->SetRepaintCallback(aFirstCallback
);
1244 m_pDoc
->SetValue(0, 0, 0, -1.0);
1246 CPPUNIT_ASSERT(bFirstCallbackCalled
);
1248 m_pDoc
->DeleteTab(0);
1251 void TestCondformat::testCondFormatVolatileFunctionRecalc()
1253 m_pDoc
->InsertTab(0, "Test");
1255 m_pDoc
->SetValue(0, 0, 0, 0.5);
1257 ScConditionalFormatList
* pList
= m_pDoc
->GetCondFormList(0);
1259 auto pFormat
= std::make_unique
<ScConditionalFormat
>(1, m_pDoc
);
1260 ScRangeList
aRangeList(ScRange(0,0,0,10,0,0));
1261 pFormat
->SetRange(aRangeList
);
1263 ScCondFormatEntry
* pEntry
= new ScCondFormatEntry(ScConditionMode::Greater
,"RAND()","",*m_pDoc
,ScAddress(0,0,0),ScResId(STR_STYLENAME_RESULT
));
1264 pEntry
->SetParent(pFormat
.get());
1266 m_pDoc
->AddCondFormatData(pFormat
->GetRange(), 0, 1);
1267 pFormat
->AddEntry(pEntry
);
1268 auto pFormatTmp
= pFormat
.get();
1269 pList
->InsertNew(std::move(pFormat
));
1271 ScRefCellValue
aCell(*m_pDoc
, ScAddress(0, 0, 0));
1272 bool bValid
= pEntry
->IsCellValid(aCell
, ScAddress(0, 0, 0));
1274 bool bNewValid
= bValid
;
1275 // chance of a random failure is 0.5^100, anyone hitting that will get a beer from me
1276 for (size_t i
= 0; i
< 100; ++i
)
1278 pFormatTmp
->CalcAll();
1279 bNewValid
= pEntry
->IsCellValid(aCell
, ScAddress(0, 0, 0));
1281 if (bValid
!= bNewValid
)
1285 CPPUNIT_ASSERT(bValid
!= bNewValid
);
1287 m_pDoc
->DeleteTab(0);
1290 CPPUNIT_TEST_SUITE_REGISTRATION(TestCondformat
);
1292 CPPUNIT_PLUGIN_IMPLEMENT();
1294 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */