nss: upgrade to release 3.73
[LibreOffice.git] / sc / qa / unit / ucalc_condformat.cxx
blob212723a26d616465673eae80be617e4e5bb486e7
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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/.
8 */
10 #include <memory>
11 #include "ucalc.hxx"
12 #include "helper/qahelper.hxx"
14 #include <conditio.hxx>
15 #include <colorscale.hxx>
17 #include <clipparam.hxx>
18 #include <globstr.hrc>
19 #include <scresid.hxx>
20 #include <docfunc.hxx>
21 #include <scitems.hxx>
22 #include <attrib.hxx>
23 #include <fillinfo.hxx>
24 #include <compiler.hxx>
25 #include <tokenarray.hxx>
27 #include <svl/sharedstringpool.hxx>
29 void Test::testCopyPasteSkipEmptyConditionalFormatting()
31 m_pDoc->InsertTab(0, "Test");
33 ScRange aDestRange(0,0,0,1,2,0);
34 ScRange aSrcRange(3,3,0,5,4,0);
36 ScMarkData aMark(m_pDoc->GetSheetLimits());
37 aMark.SetMarkArea(aDestRange);
39 m_pDoc->SetValue(0,0,0,1);
40 m_pDoc->SetValue(1,0,0,1);
41 m_pDoc->SetValue(0,1,0,1);
42 m_pDoc->SetValue(0,2,0,1);
43 m_pDoc->SetValue(1,2,0,1);
45 //create conditional formatting for A1:B3
46 ScConditionalFormatList* pCondFormatList = new ScConditionalFormatList();
47 m_pDoc->SetCondFormList(pCondFormatList, 0);
49 auto pFormat = std::make_unique<ScConditionalFormat>(1, m_pDoc);
50 pFormat->SetRange(aDestRange);
51 sal_uLong nCondFormatKey = m_pDoc->AddCondFormat(std::move(pFormat), 0);
53 // Prepare a clipboard content interleaved with empty cells.
54 ScDocument aClipDoc(SCDOCMODE_CLIP);
55 aClipDoc.ResetClip(m_pDoc, &aMark);
56 ScClipParam aParam(aSrcRange, false);
57 aClipDoc.SetClipParam(aParam);
58 aClipDoc.SetValue(3,3,0,2);
59 aClipDoc.SetValue(4,3,0,2);
60 aClipDoc.SetValue(4,4,0,2);
61 aClipDoc.SetValue(3,5,0,2);
62 aClipDoc.SetValue(4,5,0,2);
64 auto pClipFormat = std::make_unique<ScConditionalFormat>(2, &aClipDoc);
65 pClipFormat->SetRange(aSrcRange);
66 aClipDoc.AddCondFormat(std::move(pClipFormat), 0);
68 // Create undo document.
69 ScDocument* pUndoDoc = new ScDocument(SCDOCMODE_UNDO);
70 pUndoDoc->InitUndo(*m_pDoc, 0, 0);
71 m_pDoc->CopyToDocument(aDestRange, InsertDeleteFlags::CONTENTS, false, *pUndoDoc, &aMark);
73 // Paste clipboard content onto A1:A5 but skip empty cells.
74 m_pDoc->CopyFromClip(aDestRange, aMark, InsertDeleteFlags::CONTENTS, pUndoDoc, &aClipDoc, true, false, false, true/*bSkipEmpty*/);
76 ScConditionalFormatList* pList = m_pDoc->GetCondFormList(0);
77 CPPUNIT_ASSERT_EQUAL(size_t(2), pList->size());
78 CPPUNIT_ASSERT(m_pDoc->GetCondFormat(1,1,0));
79 // empty cell in copy area does not overwrite conditional formatting
80 CPPUNIT_ASSERT_EQUAL(sal_uInt32(nCondFormatKey), m_pDoc->GetCondFormat(1,1,0)->GetKey());
81 for(SCCOL nCol = 0; nCol <= 1; ++nCol)
83 for(SCROW nRow = 0; nRow <= 2; ++nRow)
85 if(nRow == 1 && nCol == 1)
86 continue;
88 CPPUNIT_ASSERT(m_pDoc->GetCondFormat(nCol, nRow, 0));
89 CPPUNIT_ASSERT(nCondFormatKey != m_pDoc->GetCondFormat(nCol, nRow, 0)->GetKey());
92 m_pDoc->DeleteTab(0);
95 void Test::testCondFormatINSDEL()
97 // fdo#62206
98 m_pDoc->InsertTab(0, "Test");
99 ScConditionalFormatList* pList = m_pDoc->GetCondFormList(0);
101 auto pFormat = std::make_unique<ScConditionalFormat>(1, m_pDoc);
102 ScRangeList aRangeList(ScRange(0,0,0,0,3,0));
103 pFormat->SetRange(aRangeList);
104 ScCondFormatEntry* pEntry = new ScCondFormatEntry(ScConditionMode::Direct,"=B2","",*m_pDoc,ScAddress(0,0,0),ScResId(STR_STYLENAME_RESULT));
105 pFormat->AddEntry(pEntry);
107 m_pDoc->AddCondFormatData(pFormat->GetRange(), 0, 1);
108 auto pFormatTmp = pFormat.get();
109 pList->InsertNew(std::move(pFormat));
111 m_pDoc->InsertCol(0,0,MAXROW,0,0,2);
112 const ScRangeList& rRange = pFormatTmp->GetRange();
113 CPPUNIT_ASSERT_EQUAL(static_cast<const ScRangeList&>(ScRange(2,0,0,2,3,0)), rRange);
115 OUString aExpr = pEntry->GetExpression(ScAddress(2,0,0), 0);
116 CPPUNIT_ASSERT_EQUAL(OUString("D2"), aExpr);
118 m_pDoc->DeleteTab(0);
121 void Test::testCondFormatInsertCol()
123 m_pDoc->InsertTab(0, "Test");
124 ScConditionalFormatList* pList = m_pDoc->GetCondFormList(0);
126 auto pFormat = std::make_unique<ScConditionalFormat>(1, m_pDoc);
127 ScRangeList aRangeList(ScRange(0,0,0,3,3,0));
128 pFormat->SetRange(aRangeList);
130 ScCondFormatEntry* pEntry = new ScCondFormatEntry(ScConditionMode::Direct,"=B2","",*m_pDoc,ScAddress(0,0,0),ScResId(STR_STYLENAME_RESULT));
131 pFormat->AddEntry(pEntry);
133 m_pDoc->AddCondFormatData(pFormat->GetRange(), 0, 1);
134 auto pFormatTmp = pFormat.get();
135 pList->InsertNew(std::move(pFormat));
137 m_pDoc->InsertCol(0,0,MAXROW,0,4,2);
138 const ScRangeList& rRange = pFormatTmp->GetRange();
139 CPPUNIT_ASSERT_EQUAL(ScRangeList(ScRange(0,0,0,5,3,0)), rRange);
141 m_pDoc->DeleteTab(0);
144 void Test::testCondFormatInsertRow()
146 m_pDoc->InsertTab(0, "Test");
147 ScConditionalFormatList* pList = m_pDoc->GetCondFormList(0);
149 auto pFormat = std::make_unique<ScConditionalFormat>(1, m_pDoc);
150 ScRangeList aRangeList(ScRange(0,0,0,3,3,0));
151 pFormat->SetRange(aRangeList);
153 ScCondFormatEntry* pEntry = new ScCondFormatEntry(ScConditionMode::Direct,"=B2","",*m_pDoc,ScAddress(0,0,0),ScResId(STR_STYLENAME_RESULT));
154 pFormat->AddEntry(pEntry);
156 m_pDoc->AddCondFormatData(pFormat->GetRange(), 0, 1);
157 auto pFormatTmp = pFormat.get();
158 pList->InsertNew(std::move(pFormat));
160 m_pDoc->InsertRow(0,0,MAXCOL,0,4,2);
161 const ScRangeList& rRange = pFormatTmp->GetRange();
162 CPPUNIT_ASSERT_EQUAL(ScRangeList(ScRange(0,0,0,3,5,0)), rRange);
164 m_pDoc->DeleteTab(0);
167 void Test::testCondFormatInsertDeleteSheets()
169 m_pDoc->InsertTab(0, "Test");
171 // Add a conditional format to B2:B4.
172 auto pFormat = std::make_unique<ScConditionalFormat>(1, m_pDoc);
173 pFormat->SetRange(ScRange(1,1,0,1,3,0));
175 auto pFormatTmp = pFormat.get();
176 sal_uLong nKey = m_pDoc->AddCondFormat(std::move(pFormat), 0);
178 // Add condition in which if the value equals 2, set the "Result" style.
179 ScCondFormatEntry* pEntry = new ScCondFormatEntry(
180 ScConditionMode::Equal, "=2", "" , *m_pDoc, ScAddress(0,0,0), ScResId(STR_STYLENAME_RESULT));
181 pFormatTmp->AddEntry(pEntry);
183 // Apply the format to the range.
184 m_pDoc->AddCondFormatData(pFormatTmp->GetRange(), 0, nKey);
186 // Make sure this conditional format entry is really there.
187 ScConditionalFormatList* pList = m_pDoc->GetCondFormList(0);
188 CPPUNIT_ASSERT(pList);
189 const ScConditionalFormat* pCheck = pList->GetFormat(nKey);
190 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong conditional format instance.", pCheck, const_cast<const ScConditionalFormat*>(pFormatTmp));
192 // ... and its range is B2:B4.
193 ScRangeList aCheckRange = pCheck->GetRange();
194 CPPUNIT_ASSERT_EQUAL_MESSAGE("This should be a single range.", size_t(1), aCheckRange.size());
195 const ScRange* pRange = &aCheckRange[0];
196 CPPUNIT_ASSERT(pRange);
197 CPPUNIT_ASSERT_EQUAL_MESSAGE("Format should be applied to B2:B4.", ScRange(1,1,0,1,3,0), *pRange);
199 ScDocFunc& rFunc = getDocShell().GetDocFunc();
201 // Insert a new sheet at the left.
202 bool bInserted = rFunc.InsertTable(0, "Inserted", true, true);
203 CPPUNIT_ASSERT(bInserted);
205 pList = m_pDoc->GetCondFormList(1);
206 CPPUNIT_ASSERT(pList);
207 pCheck = pList->GetFormat(nKey);
208 CPPUNIT_ASSERT(pCheck);
210 // Make sure the range also got shifted.
211 aCheckRange = pCheck->GetRange();
212 CPPUNIT_ASSERT_EQUAL_MESSAGE("This should be a single range.", size_t(1), aCheckRange.size());
213 pRange = &aCheckRange[0];
214 CPPUNIT_ASSERT(pRange);
215 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);
217 // Delete the sheet to the left.
218 bool bDeleted = rFunc.DeleteTable(0, true);
219 CPPUNIT_ASSERT(bDeleted);
221 pList = m_pDoc->GetCondFormList(0);
222 CPPUNIT_ASSERT(pList);
223 pCheck = pList->GetFormat(nKey);
224 CPPUNIT_ASSERT(pCheck);
226 // Make sure the range got shifted back.
227 aCheckRange = pCheck->GetRange();
228 CPPUNIT_ASSERT_EQUAL_MESSAGE("This should be a single range.", size_t(1), aCheckRange.size());
229 pRange = &aCheckRange[0];
230 CPPUNIT_ASSERT(pRange);
231 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);
233 SfxUndoManager* pUndoMgr = m_pDoc->GetUndoManager();
234 CPPUNIT_ASSERT(pUndoMgr);
236 // Undo and re-check.
237 pUndoMgr->Undo();
239 pList = m_pDoc->GetCondFormList(1);
240 CPPUNIT_ASSERT(pList);
241 pCheck = pList->GetFormat(nKey);
242 CPPUNIT_ASSERT(pCheck);
244 aCheckRange = pCheck->GetRange();
245 CPPUNIT_ASSERT_EQUAL_MESSAGE("This should be a single range.", size_t(1), aCheckRange.size());
246 pRange = &aCheckRange[0];
247 CPPUNIT_ASSERT(pRange);
248 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);
250 #if 0 // TODO : Undo of sheet insertion currently depends on the presence of
251 // view shell, and crashes when executed during cppunit run.
253 // Undo again and re-check.
254 pUndoMgr->Undo();
256 pList = m_pDoc->GetCondFormList(0);
257 CPPUNIT_ASSERT(pList);
258 pCheck = pList->GetFormat(nKey);
259 CPPUNIT_ASSERT(pCheck);
261 // Make sure the range got shifted back.
262 aCheckRange = pCheck->GetRange();
263 CPPUNIT_ASSERT_MESSAGE("This should be a single range.", aCheckRange.size() == 1);
264 pRange = aCheckRange[0];
265 CPPUNIT_ASSERT(pRange);
266 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));
267 #else
268 m_pDoc->DeleteTab(1);
269 #endif
271 m_pDoc->DeleteTab(0);
274 void Test::testCondCopyPaste()
276 m_pDoc->InsertTab(0, "Test");
278 auto pFormat = std::make_unique<ScConditionalFormat>(1, m_pDoc);
279 ScRange aCondFormatRange(0,0,0,3,3,0);
280 ScRangeList aRangeList(aCondFormatRange);
281 pFormat->SetRange(aRangeList);
283 ScCondFormatEntry* pEntry = new ScCondFormatEntry(ScConditionMode::Direct,"=B2","",*m_pDoc,ScAddress(0,0,0),ScResId(STR_STYLENAME_RESULT));
284 pFormat->AddEntry(pEntry);
285 sal_uLong nIndex = m_pDoc->AddCondFormat(std::move(pFormat), 0);
287 ScDocument aClipDoc(SCDOCMODE_CLIP);
288 copyToClip(m_pDoc, aCondFormatRange, &aClipDoc);
290 ScRange aTargetRange(4,4,0,7,7,0);
291 pasteFromClip(m_pDoc, aTargetRange, &aClipDoc);
293 ScConditionalFormat* pPastedFormat = m_pDoc->GetCondFormat(7,7,0);
294 CPPUNIT_ASSERT(pPastedFormat);
296 // Pasting the same conditional format must modify existing format, making its range
297 // combined of previous range and newly pasted range having the conditional format.
298 // No new conditional formats must be created.
299 CPPUNIT_ASSERT_EQUAL(size_t(1), m_pDoc->GetCondFormList(0)->size());
300 aRangeList.Join(aTargetRange);
301 CPPUNIT_ASSERT_EQUAL(aRangeList, pPastedFormat->GetRange());
302 CPPUNIT_ASSERT_EQUAL(sal_uInt32(nIndex), pPastedFormat->GetKey());
303 const SfxPoolItem* pItem = m_pDoc->GetAttr( 7, 7, 0, ATTR_CONDITIONAL );
304 const ScCondFormatItem* pCondFormatItem = static_cast<const ScCondFormatItem*>(pItem);
306 CPPUNIT_ASSERT(pCondFormatItem);
307 CPPUNIT_ASSERT_EQUAL(size_t(1), pCondFormatItem->GetCondFormatData().size());
308 CPPUNIT_ASSERT_EQUAL(sal_uInt32(nIndex), pCondFormatItem->GetCondFormatData().front());
310 m_pDoc->DeleteTab(0);
313 void Test::testCondCopyPasteSingleCell()
315 m_pDoc->InsertTab(0, "Test");
317 auto pFormat = std::make_unique<ScConditionalFormat>(1, m_pDoc);
318 ScRange aCondFormatRange(0,0,0,3,3,0);
319 ScRangeList aRangeList(aCondFormatRange);
320 pFormat->SetRange(aRangeList);
322 ScCondFormatEntry* pEntry = new ScCondFormatEntry(ScConditionMode::Direct,"=B2","",*m_pDoc,ScAddress(0,0,0),ScResId(STR_STYLENAME_RESULT));
323 pFormat->AddEntry(pEntry);
324 sal_uLong nIndex = m_pDoc->AddCondFormat(std::move(pFormat), 0);
326 ScDocument aClipDoc(SCDOCMODE_CLIP);
327 copyToClip(m_pDoc, ScRange(0,0,0,0,0,0), &aClipDoc);
329 ScRange aTargetRange(4,4,0,4,4,0);
330 pasteOneCellFromClip(m_pDoc, aTargetRange, &aClipDoc);
332 ScConditionalFormat* pPastedFormat = m_pDoc->GetCondFormat(4,4,0);
333 CPPUNIT_ASSERT(pPastedFormat);
335 // Pasting the same conditional format must modify existing format, making its range
336 // combined of previous range and newly pasted range having the conditional format.
337 // No new conditional formats must be created.
338 CPPUNIT_ASSERT_EQUAL(size_t(1), m_pDoc->GetCondFormList(0)->size());
339 aRangeList.Join(aTargetRange);
340 CPPUNIT_ASSERT_EQUAL(aRangeList, pPastedFormat->GetRange());
341 CPPUNIT_ASSERT_EQUAL(sal_uInt32(nIndex), pPastedFormat->GetKey());
342 const SfxPoolItem* pItem = m_pDoc->GetAttr( 4, 4, 0, ATTR_CONDITIONAL );
343 const ScCondFormatItem* pCondFormatItem = static_cast<const ScCondFormatItem*>(pItem);
345 CPPUNIT_ASSERT(pCondFormatItem);
346 CPPUNIT_ASSERT_EQUAL(size_t(1), pCondFormatItem->GetCondFormatData().size());
347 CPPUNIT_ASSERT_EQUAL(sal_uInt32(nIndex), pCondFormatItem->GetCondFormatData().front() );
349 m_pDoc->DeleteTab(0);
352 void Test::testCondCopyPasteSingleCellToRange()
354 m_pDoc->InsertTab(0, "Test");
356 auto pFormat = std::make_unique<ScConditionalFormat>(1, m_pDoc);
357 ScRange aCondFormatRange(0,0,0,3,3,0);
358 ScRangeList aRangeList(aCondFormatRange);
359 pFormat->SetRange(aRangeList);
361 ScCondFormatEntry* pEntry = new ScCondFormatEntry(ScConditionMode::Direct,"=B2","",*m_pDoc,ScAddress(0,0,0),ScResId(STR_STYLENAME_RESULT));
362 pFormat->AddEntry(pEntry);
363 sal_uLong nIndex = m_pDoc->AddCondFormat(std::move(pFormat), 0);
365 ScDocument aClipDoc(SCDOCMODE_CLIP);
366 copyToClip(m_pDoc, ScRange(0,0,0,0,0,0), &aClipDoc);
367 ScRange aTargetRange(4,4,0,5,8,0);
368 pasteOneCellFromClip(m_pDoc, aTargetRange, &aClipDoc);
370 // Pasting the same conditional format must modify existing format, making its range
371 // combined of previous range and newly pasted range having the conditional format.
372 // No new conditional formats must be created.
373 CPPUNIT_ASSERT_EQUAL(size_t(1), m_pDoc->GetCondFormList(0)->size());
374 aRangeList.Join(aTargetRange);
375 for(SCROW nRow = 4; nRow <= 8; ++nRow)
377 for (SCCOL nCol = 4; nCol <= 5; ++nCol)
379 ScConditionalFormat* pPastedFormat = m_pDoc->GetCondFormat(nCol, nRow, 0);
380 CPPUNIT_ASSERT(pPastedFormat);
382 CPPUNIT_ASSERT_EQUAL(aRangeList, pPastedFormat->GetRange());
383 sal_uLong nPastedKey = pPastedFormat->GetKey();
384 CPPUNIT_ASSERT_EQUAL(nIndex, nPastedKey);
385 const SfxPoolItem* pItem = m_pDoc->GetAttr( nCol, nRow, 0, ATTR_CONDITIONAL );
386 const ScCondFormatItem* pCondFormatItem = static_cast<const ScCondFormatItem*>(pItem);
388 CPPUNIT_ASSERT(pCondFormatItem);
389 CPPUNIT_ASSERT_EQUAL(size_t(1), pCondFormatItem->GetCondFormatData().size());
390 CPPUNIT_ASSERT_EQUAL(sal_uInt32(nIndex), pCondFormatItem->GetCondFormatData().front() );
394 m_pDoc->DeleteTab(0);
397 void Test::testCondCopyPasteSingleCellIntoSameFormatRange()
399 m_pDoc->InsertTab(0, "Test");
401 auto pFormat = std::make_unique<ScConditionalFormat>(1, m_pDoc);
402 ScRange aCondFormatRange(0, 0, 0, 3, 3, 0);
403 ScRangeList aRangeList(aCondFormatRange);
404 pFormat->SetRange(aRangeList);
406 ScCondFormatEntry* pEntry = new ScCondFormatEntry(ScConditionMode::Direct, "=B2", "", *m_pDoc, ScAddress(0, 0, 0), ScResId(STR_STYLENAME_RESULT));
407 pFormat->AddEntry(pEntry);
408 sal_uLong nIndex = m_pDoc->AddCondFormat(std::move(pFormat), 0);
410 ScDocument aClipDoc(SCDOCMODE_CLIP);
411 copyToClip(m_pDoc, ScRange(1, 1, 0, 1, 1, 0), &aClipDoc);
413 ScRange aTargetRange(2, 2, 0, 2, 2, 0);
414 pasteFromClip(m_pDoc, aTargetRange, &aClipDoc);
416 ScConditionalFormat* pPastedFormat = m_pDoc->GetCondFormat(2, 2, 0);
417 CPPUNIT_ASSERT(pPastedFormat);
419 // Pasting the same conditional format into the same range must not modify existing format,
420 // since it already covers the pasted range. No new conditional formats must be created.
421 CPPUNIT_ASSERT_EQUAL(size_t(1), m_pDoc->GetCondFormList(0)->size());
422 CPPUNIT_ASSERT_EQUAL(aRangeList, pPastedFormat->GetRange());
423 CPPUNIT_ASSERT_EQUAL(sal_uInt32(nIndex), pPastedFormat->GetKey());
424 const SfxPoolItem* pItem = m_pDoc->GetAttr(2, 2, 0, ATTR_CONDITIONAL);
425 const ScCondFormatItem* pCondFormatItem = static_cast<const ScCondFormatItem*>(pItem);
427 CPPUNIT_ASSERT(pCondFormatItem);
428 CPPUNIT_ASSERT_EQUAL(size_t(1), pCondFormatItem->GetCondFormatData().size());
429 CPPUNIT_ASSERT_EQUAL(sal_uInt32(nIndex), pCondFormatItem->GetCondFormatData().front());
431 m_pDoc->DeleteTab(0);
434 void Test::testCondCopyPasteSingleRowToRange()
436 m_pDoc->InsertTab(0, "Test");
438 auto pFormat = std::make_unique<ScConditionalFormat>(1, m_pDoc);
439 ScRange aCondFormatRange(0,0,0,0,0,0);
440 ScRangeList aRangeList(aCondFormatRange);
441 pFormat->SetRange(aRangeList);
443 ScCondFormatEntry* pEntry = new ScCondFormatEntry(ScConditionMode::Direct,"=B2","",*m_pDoc,ScAddress(0,0,0),ScResId(STR_STYLENAME_RESULT));
444 pFormat->AddEntry(pEntry);
445 auto pFormatTmp = pFormat.get();
446 m_pDoc->AddCondFormat(std::move(pFormat), 0);
448 ScDocument aClipDoc(SCDOCMODE_CLIP);
449 copyToClip(m_pDoc, ScRange(0,0,0,MAXCOL,0,0), &aClipDoc);
450 ScRange aTargetRange(0,4,0,MAXCOL,4,0);
451 pasteOneCellFromClip(m_pDoc, aTargetRange, &aClipDoc);
453 ScConditionalFormat* pNewFormat = m_pDoc->GetCondFormat(0, 4, 0);
454 CPPUNIT_ASSERT(pNewFormat);
455 CPPUNIT_ASSERT_EQUAL(pNewFormat->GetKey(), pFormatTmp->GetKey());
457 for (SCCOL nCol = 1; nCol <= MAXCOL; ++nCol)
459 ScConditionalFormat* pNewFormat2 = m_pDoc->GetCondFormat(nCol, 4, 0);
460 CPPUNIT_ASSERT(!pNewFormat2);
463 m_pDoc->DeleteTab(0);
466 void Test::testCondCopyPasteSingleRowToRange2()
468 m_pDoc->InsertTab(0, "Test");
470 auto pFormat = std::make_unique<ScConditionalFormat>(1, m_pDoc);
471 ScRange aCondFormatRange(0,0,0,0,0,0);
472 ScRangeList aRangeList(aCondFormatRange);
473 pFormat->SetRange(aRangeList);
475 ScCondFormatEntry* pEntry = new ScCondFormatEntry(ScConditionMode::Direct,"=B2","",*m_pDoc,ScAddress(0,0,0),ScResId(STR_STYLENAME_RESULT));
476 pFormat->AddEntry(pEntry);
477 m_pDoc->AddCondFormat(std::move(pFormat), 0);
479 ScDocument aClipDoc(SCDOCMODE_CLIP);
480 copyToClip(m_pDoc, ScRange(0,0,0,3,0,0), &aClipDoc);
481 ScRange aTargetRange(0,4,0,MAXCOL,4,0);
482 pasteOneCellFromClip(m_pDoc, aTargetRange, &aClipDoc);
484 for (SCCOL nCol = 0; nCol <= MAXCOL; ++nCol)
486 ScConditionalFormat* pNewFormat = m_pDoc->GetCondFormat(nCol, 4, 0);
487 if (nCol % 4 == 0)
488 CPPUNIT_ASSERT(pNewFormat);
489 else
490 CPPUNIT_ASSERT(!pNewFormat);
493 m_pDoc->DeleteTab(0);
496 void Test::testCondCopyPasteSheetBetweenDoc()
498 m_pDoc->InsertTab(0, "Test");
500 auto pFormat = std::make_unique<ScConditionalFormat>(1, m_pDoc);
501 ScRange aCondFormatRange(0,0,0,3,3,0);
502 ScRangeList aRangeList(aCondFormatRange);
503 pFormat->SetRange(aRangeList);
505 ScCondFormatEntry* pEntry = new ScCondFormatEntry(ScConditionMode::Direct,"=B2","",*m_pDoc,ScAddress(0,0,0),ScResId(STR_STYLENAME_RESULT));
506 pFormat->AddEntry(pEntry);
507 m_pDoc->AddCondFormat(std::move(pFormat), 0);
509 ScDocument aDoc;
510 aDoc.TransferTab(*m_pDoc, 0, 0);
512 ScConditionalFormatList* pList = aDoc.GetCondFormList(0);
513 CPPUNIT_ASSERT_EQUAL(size_t(1), pList->size());
515 m_pDoc->DeleteTab(0);
518 void Test::testCondCopyPasteSheet()
520 m_pDoc->InsertTab(0, "Test");
522 auto pFormat = std::make_unique<ScConditionalFormat>(1, m_pDoc);
523 ScRange aCondFormatRange(0,0,0,3,3,0);
524 ScRangeList aRangeList(aCondFormatRange);
525 pFormat->SetRange(aRangeList);
527 ScCondFormatEntry* pEntry = new ScCondFormatEntry(ScConditionMode::Direct,"=B2","",*m_pDoc,ScAddress(0,0,0),ScResId(STR_STYLENAME_RESULT));
528 pFormat->AddEntry(pEntry);
529 m_pDoc->AddCondFormat(std::move(pFormat), 0);
531 m_pDoc->CopyTab(0, SC_TAB_APPEND);
533 ScConditionalFormatList* pList = m_pDoc->GetCondFormList(1);
534 CPPUNIT_ASSERT_EQUAL(size_t(1), pList->size());
536 ScConditionalFormat& rFormat = **pList->begin();
537 const ScRangeList& rRange = rFormat.GetRange();
538 CPPUNIT_ASSERT_EQUAL(ScRangeList(ScRange(0,0,1,3,3,1)), rRange);
539 sal_uInt32 nKey = rFormat.GetKey();
540 const SfxPoolItem* pItem = m_pDoc->GetAttr( 2, 2, 1, ATTR_CONDITIONAL );
541 const ScCondFormatItem* pCondFormatItem = static_cast<const ScCondFormatItem*>(pItem);
543 CPPUNIT_ASSERT(pCondFormatItem);
544 CPPUNIT_ASSERT_EQUAL(size_t(1), pCondFormatItem->GetCondFormatData().size());
545 CPPUNIT_ASSERT_EQUAL( nKey, pCondFormatItem->GetCondFormatData().front() );
547 m_pDoc->DeleteTab(1);
548 m_pDoc->DeleteTab(0);
551 void Test::testIconSet()
553 m_pDoc->InsertTab(0, "Test");
554 ScConditionalFormatList* pList = m_pDoc->GetCondFormList(0);
556 auto pFormat = std::make_unique<ScConditionalFormat>(1, m_pDoc);
557 ScRangeList aRangeList(ScRange(0,0,0,0,0,0));
558 pFormat->SetRange(aRangeList);
560 ScIconSetFormat* pEntry = new ScIconSetFormat(m_pDoc);
561 ScIconSetFormatData* pData = new ScIconSetFormatData;
562 pData->m_Entries.emplace_back(new ScColorScaleEntry(0, COL_BLUE));
563 pData->m_Entries.emplace_back(new ScColorScaleEntry(1, COL_GREEN));
564 pData->m_Entries.emplace_back(new ScColorScaleEntry(2, COL_RED));
565 pEntry->SetIconSetData(pData);
567 m_pDoc->AddCondFormatData(pFormat->GetRange(), 0, 1);
568 pList->InsertNew(std::move(pFormat));
570 static struct {
571 double nVal; sal_Int32 nIndex;
572 } const aTests[] = {
573 { -1.0, 0 },
574 { 0.0, 0 },
575 { 1.0, 1 },
576 { 2.0, 2 },
577 { 3.0, 2 }
579 for(size_t i = 0; i < SAL_N_ELEMENTS(aTests); ++i)
581 m_pDoc->SetValue(0,0,0,aTests[i].nVal);
582 std::unique_ptr<ScIconSetInfo> pInfo = pEntry->GetIconSetInfo(ScAddress(0,0,0));
583 CPPUNIT_ASSERT_EQUAL(aTests[i].nIndex, pInfo->nIconIndex);
586 delete pEntry;
587 m_pDoc->DeleteTab(0);
590 namespace {
592 struct ScDataBarLengthData
594 double nVal;
595 double nLength;
598 void testDataBarLengthImpl(ScDocument* pDoc, const ScDataBarLengthData* pData, const ScRange& rRange,
599 double nMinVal, ScColorScaleEntryType eMinType,
600 double nMaxVal, ScColorScaleEntryType eMaxType,
601 double nZeroPos, databar::ScAxisPosition eAxisPos)
603 std::unique_ptr<ScConditionalFormat> pFormat(new ScConditionalFormat(1, pDoc));
604 ScRangeList aRangeList(rRange);
605 pFormat->SetRange(aRangeList);
607 SCCOL nCol = rRange.aStart.Col();
609 ScDataBarFormat* pDatabar = new ScDataBarFormat(pDoc);
610 pFormat->AddEntry(pDatabar);
612 ScDataBarFormatData* pFormatData = new ScDataBarFormatData();
613 pFormatData->meAxisPosition = eAxisPos;
615 pFormatData->mpLowerLimit.reset(new ScColorScaleEntry());
616 pFormatData->mpLowerLimit->SetValue(nMinVal);
617 pFormatData->mpLowerLimit->SetType(eMinType);
618 pFormatData->mpUpperLimit.reset(new ScColorScaleEntry());
619 pFormatData->mpUpperLimit->SetValue(nMaxVal);
620 pFormatData->mpUpperLimit->SetType(eMaxType);
621 pDatabar->SetDataBarData(pFormatData);
623 for (size_t i = 0; pData[i].nLength != -200; ++i)
625 pDoc->SetValue(nCol, i, 0, pData[i].nVal);
628 for (size_t i = 0; pData[i].nLength != -200; ++i)
630 std::unique_ptr<ScDataBarInfo> xInfo(pDatabar->GetDataBarInfo(ScAddress(nCol, i, 0)));
631 CPPUNIT_ASSERT(xInfo);
632 ASSERT_DOUBLES_EQUAL(pData[i].nLength, xInfo->mnLength);
633 ASSERT_DOUBLES_EQUAL(nZeroPos, xInfo->mnZero);
639 void Test::testDataBarLengthAutomaticAxis()
641 m_pDoc->InsertTab(0, "Test");
643 static const ScDataBarLengthData aValues[] = {
644 { 2, 0 },
645 { 3, 0 },
646 { 4, 25.0 },
647 { 5, 50.0 },
648 { 6, 75.0 },
649 { 7, 100.0 },
650 { 8, 100.0 },
651 { 9, 100.0 },
652 { 0, -200 }
655 testDataBarLengthImpl(m_pDoc, aValues, ScRange(0,0,0,0,7,0),
656 3, COLORSCALE_VALUE, 7, COLORSCALE_VALUE, 0.0, databar::AUTOMATIC);
658 static const ScDataBarLengthData aValues2[] = {
659 { -6, -100 },
660 { -5, -100 },
661 { -4, -100 },
662 { -3, -75.0 },
663 { -2, -50.0 },
664 { -1, -25.0 },
665 { 0, 0.0 },
666 { 1, 12.5 },
667 { 2, 25.0 },
668 { 3, 37.5 },
669 { 4, 50.0 },
670 { 5, 62.5 },
671 { 6, 75.0 },
672 { 7, 87.5 },
673 { 8, 100.0 },
674 { 9, 100.0 },
675 { 0, -200 }
677 testDataBarLengthImpl(m_pDoc, aValues2, ScRange(1,0,0,1,15,0),
678 -4, COLORSCALE_VALUE, 8, COLORSCALE_VALUE, 1.0/3.0 * 100, databar::AUTOMATIC);
680 static const ScDataBarLengthData aValues3[] = {
681 { 2, 0.0 },
682 { 3, 25.0 },
683 { 4, 50.0 },
684 { 6, 100.0 },
685 { 0, -200 }
687 testDataBarLengthImpl(m_pDoc, aValues3, ScRange(2,0,0,2,3,0),
688 0, COLORSCALE_MIN, 0, COLORSCALE_MAX, 0, databar::AUTOMATIC);
690 static const ScDataBarLengthData aValues4[] = {
691 { 2, 40.0 },
692 { 3, 60.0 },
693 { 4, 80.0 },
694 { 5, 100.0 },
695 { 0, -200 }
697 testDataBarLengthImpl(m_pDoc, aValues4, ScRange(3,0,0,3,3,0),
698 0, COLORSCALE_AUTO, 0, COLORSCALE_AUTO, 0, databar::AUTOMATIC);
700 m_pDoc->DeleteTab(0);
703 void Test::testDataBarLengthMiddleAxis()
705 m_pDoc->InsertTab(0, "Test");
707 static const ScDataBarLengthData aValues[] = {
708 { 1, 25.0 },
709 { 2, 25.0 },
710 { 3, 37.5 },
711 { 4, 50.0 },
712 { 5, 62.5 },
713 { 6, 75.0 },
714 { 7, 87.5 },
715 { 8, 100.0 },
716 { 9, 100.0 },
717 { 0, -200 }
720 testDataBarLengthImpl(m_pDoc, aValues, ScRange(0,0,0,0,8,0),
721 2, COLORSCALE_VALUE, 8, COLORSCALE_VALUE, 50.0, databar::MIDDLE);
723 static const ScDataBarLengthData aValues2[] = {
724 { -6, -50 },
725 { -5, -50 },
726 { -4, -50 },
727 { -3, -37.5 },
728 { -2, -25.0 },
729 { -1, -12.5 },
730 { 0, 0.0 },
731 { 1, 12.5 },
732 { 2, 25.0 },
733 { 3, 37.5 },
734 { 4, 50.0 },
735 { 5, 62.5 },
736 { 6, 75.0 },
737 { 7, 87.5 },
738 { 8, 100.0 },
739 { 9, 100.0 },
740 { 0, -200 }
742 testDataBarLengthImpl(m_pDoc, aValues2, ScRange(1,0,0,1,15,0),
743 -4, COLORSCALE_VALUE, 8, COLORSCALE_VALUE, 50.0, databar::MIDDLE);
745 m_pDoc->DeleteTab(0);
748 void Test::testCondFormatEndsWithStr()
750 m_pDoc->InsertTab(0, "Test");
752 ScConditionEntry aEntry(ScConditionMode::EndsWith, "\"TestString\"", "", *m_pDoc, ScAddress(),
753 "", "", formula::FormulaGrammar::GRAM_DEFAULT, formula::FormulaGrammar::GRAM_DEFAULT);
755 svl::SharedStringPool& rStringPool = m_pDoc->GetSharedStringPool();
756 svl::SharedString aStr = rStringPool.intern("SimpleTestString");
757 ScRefCellValue aVal(&aStr);
758 ScAddress aPos(0, 0, 0);
760 bool bValid = aEntry.IsCellValid(aVal, aPos);
761 CPPUNIT_ASSERT(bValid);
763 m_pDoc->DeleteTab(0);
766 void Test::testCondFormatEndsWithVal()
768 m_pDoc->InsertTab(0, "Test");
770 ScConditionEntry aEntry(ScConditionMode::EndsWith, "2", "", *m_pDoc, ScAddress(),
771 "", "", formula::FormulaGrammar::GRAM_DEFAULT, formula::FormulaGrammar::GRAM_DEFAULT);
773 for (sal_Int32 i = 0; i < 15; ++i)
775 ScRefCellValue aVal(i);
776 ScAddress aPos(0, 0, 0);
778 bool bValid = aEntry.IsCellValid(aVal, aPos);
779 bool bShouldBeValid = (i % 10) == 2;
780 CPPUNIT_ASSERT_EQUAL(bShouldBeValid, bValid);
783 m_pDoc->DeleteTab(0);
786 void Test::testFormulaListenerSingleCellToSingleCell()
788 m_pDoc->InsertTab(0, "test");
790 ScCompiler aCompiler(*m_pDoc, ScAddress(10, 10, 0), formula::FormulaGrammar::GRAM_ENGLISH);
792 std::unique_ptr<ScTokenArray> pTokenArray(aCompiler.CompileString("A1"));
794 ScFormulaListener aListener(*m_pDoc);
796 aListener.addTokenArray(pTokenArray.get(), ScAddress(10, 10, 0));
798 m_pDoc->SetValue(ScAddress(0, 0, 0), 1.0);
799 CPPUNIT_ASSERT(aListener.NeedsRepaint());
801 m_pDoc->DeleteTab(0);
804 void Test::testFormulaListenerSingleCellToMultipleCells()
806 m_pDoc->InsertTab(0, "test");
808 ScCompiler aCompiler(*m_pDoc, ScAddress(10, 10, 0), formula::FormulaGrammar::GRAM_ENGLISH);
810 std::unique_ptr<ScTokenArray> pTokenArray(aCompiler.CompileString("A1"));
812 ScFormulaListener aListener(*m_pDoc);
814 aListener.addTokenArray(pTokenArray.get(), ScAddress(10, 10, 0));
816 m_pDoc->SetValue(ScAddress(0, 0, 0), 1.0);
817 CPPUNIT_ASSERT(aListener.NeedsRepaint());
819 m_pDoc->DeleteTab(0);
822 void Test::testFormulaListenerMultipleCellsToSingleCell()
824 m_pDoc->InsertTab(0, "test");
826 ScCompiler aCompiler(*m_pDoc, ScAddress(10, 10, 0), formula::FormulaGrammar::GRAM_ENGLISH);
828 std::unique_ptr<ScTokenArray> pTokenArray(aCompiler.CompileString("A1"));
830 ScFormulaListener aListener(*m_pDoc);
832 aListener.addTokenArray(pTokenArray.get(), ScAddress(10, 10, 0));
834 m_pDoc->SetValue(ScAddress(0, 0, 0), 1.0);
835 CPPUNIT_ASSERT(aListener.NeedsRepaint());
837 m_pDoc->DeleteTab(0);
840 void Test::testFormulaListenerMultipleCellsToMultipleCells()
842 m_pDoc->InsertTab(0, "test");
844 ScCompiler aCompiler(*m_pDoc, ScAddress(10, 10, 0), formula::FormulaGrammar::GRAM_ENGLISH);
846 std::unique_ptr<ScTokenArray> pTokenArray(aCompiler.CompileString("A1"));
848 ScFormulaListener aListener(*m_pDoc);
850 aListener.addTokenArray(pTokenArray.get(), ScAddress(10, 10, 0));
852 m_pDoc->SetValue(ScAddress(0, 0, 0), 1.0);
853 CPPUNIT_ASSERT(aListener.NeedsRepaint());
855 m_pDoc->DeleteTab(0);
858 void Test::testFormulaListenerUpdateInsertTab()
860 m_pDoc->InsertTab(0, "test");
862 ScCompiler aCompiler(*m_pDoc, ScAddress(10, 10, 0), formula::FormulaGrammar::GRAM_ENGLISH);
863 std::unique_ptr<ScTokenArray> pTokenArray(aCompiler.CompileString("A1"));
865 ScFormulaListener aListener(*m_pDoc);
866 aListener.addTokenArray(pTokenArray.get(), ScAddress(10, 10, 0));
867 CPPUNIT_ASSERT(!aListener.NeedsRepaint());
869 m_pDoc->InsertTab(0, "new_tab");
871 // check that the listener has moved to the new sheet
872 m_pDoc->SetValue(ScAddress(0, 0, 1), 1.0);
873 CPPUNIT_ASSERT(aListener.NeedsRepaint());
875 // check that we are not listening to the old sheet
876 m_pDoc->SetValue(ScAddress(0, 0, 0), 1.0);
877 CPPUNIT_ASSERT(!aListener.NeedsRepaint());
879 m_pDoc->DeleteTab(0);
882 void Test::testFormulaListenerUpdateDeleteTab()
884 m_pDoc->InsertTab(0, "test");
885 m_pDoc->InsertTab(0, "to_delete");
887 ScCompiler aCompiler(*m_pDoc, ScAddress(10, 10, 1), formula::FormulaGrammar::GRAM_ENGLISH);
888 std::unique_ptr<ScTokenArray> pTokenArray(aCompiler.CompileString("A1"));
890 ScFormulaListener aListener(*m_pDoc);
891 aListener.addTokenArray(pTokenArray.get(), ScAddress(10, 10, 1));
892 CPPUNIT_ASSERT(!aListener.NeedsRepaint());
894 m_pDoc->DeleteTab(0);
896 // check that the listener has moved
897 m_pDoc->SetValue(ScAddress(0, 0, 0), 1.0);
898 CPPUNIT_ASSERT(aListener.NeedsRepaint());
900 m_pDoc->DeleteTab(0);
903 void Test::testCondFormatUpdateMoveTab()
905 m_pDoc->InsertTab(0, "test");
906 m_pDoc->InsertTab(1, "Test2");
908 ScConditionEntry* pEntry = new ScConditionEntry(ScConditionMode::Equal, "A1", "", *m_pDoc, ScAddress(10, 10, 0), "", "", formula::FormulaGrammar::GRAM_DEFAULT, formula::FormulaGrammar::GRAM_DEFAULT);
910 auto pFormat = std::make_unique<ScConditionalFormat>(0, m_pDoc);
911 pFormat->SetRange(ScRange(10, 10, 0, 10, 12, 0));
912 auto pFormatTmp = pFormat.get();
913 m_pDoc->AddCondFormat(std::move(pFormat), 0);
915 pFormatTmp->AddEntry(pEntry);
917 // the conditional format should listen to A1:A3
918 for (SCROW nRow = 0; nRow < 3; ++nRow)
920 m_pDoc->SetValue(ScAddress(0, nRow, 0), 1.0);
921 CPPUNIT_ASSERT(pEntry->NeedsRepaint());
924 m_pDoc->MoveTab(0, 1);
926 // the conditional format should listen to A1:A3 on the second sheet
927 for (SCROW nRow = 0; nRow < 3; ++nRow)
929 m_pDoc->SetValue(ScAddress(0, nRow, 1), 1.0);
930 CPPUNIT_ASSERT(pEntry->NeedsRepaint());
932 m_pDoc->SetValue(ScAddress(0, nRow, 0), 1.0);
933 CPPUNIT_ASSERT(!pEntry->NeedsRepaint());
936 m_pDoc->DeleteTab(1);
937 m_pDoc->DeleteTab(0);
940 void Test::testCondFormatUpdateInsertTab()
942 m_pDoc->InsertTab(0, "test");
944 ScConditionEntry* pEntry = new ScConditionEntry(ScConditionMode::Equal, "A1", "", *m_pDoc, ScAddress(10, 10, 0), "", "", formula::FormulaGrammar::GRAM_DEFAULT, formula::FormulaGrammar::GRAM_DEFAULT);
946 auto pFormat = std::make_unique<ScConditionalFormat>(0, m_pDoc);
947 pFormat->SetRange(ScRange(10, 10, 0, 10, 12, 0));
948 auto pFormatTmp = pFormat.get();
949 m_pDoc->AddCondFormat(std::move(pFormat), 0);
951 pFormatTmp->AddEntry(pEntry);
953 // the conditional format should listen to A1:A3
954 for (SCROW nRow = 0; nRow < 3; ++nRow)
956 m_pDoc->SetValue(ScAddress(0, nRow, 0), 1.0);
957 CPPUNIT_ASSERT(pEntry->NeedsRepaint());
959 m_pDoc->SetValue(ScAddress(0, nRow, 1), 1.0);
960 CPPUNIT_ASSERT(!pEntry->NeedsRepaint());
963 m_pDoc->InsertTab(0, "test2");
965 // the conditional format should listen to A1:A3 on the second sheet
966 for (SCROW nRow = 0; nRow < 3; ++nRow)
968 m_pDoc->SetValue(ScAddress(0, nRow, 1), 1.0);
969 CPPUNIT_ASSERT(pEntry->NeedsRepaint());
971 m_pDoc->SetValue(ScAddress(0, nRow, 0), 1.0);
972 CPPUNIT_ASSERT(!pEntry->NeedsRepaint());
975 m_pDoc->DeleteTab(1);
976 m_pDoc->DeleteTab(0);
979 void Test::testCondFormatUpdateDeleteTab()
981 m_pDoc->InsertTab(0, "test");
982 m_pDoc->InsertTab(1, "Test2");
984 ScConditionEntry* pEntry = new ScConditionEntry(ScConditionMode::Equal, "A1", "", *m_pDoc, ScAddress(10, 10, 1), "", "", formula::FormulaGrammar::GRAM_DEFAULT, formula::FormulaGrammar::GRAM_DEFAULT);
986 auto pFormat = std::make_unique<ScConditionalFormat>(0, m_pDoc);
987 pFormat->SetRange(ScRange(10, 10, 1, 10, 12, 1));
988 auto pFormatTmp = pFormat.get();
989 m_pDoc->AddCondFormat(std::move(pFormat), 1);
991 pFormatTmp->AddEntry(pEntry);
993 // the conditional format should listen to A1:A3 on the second sheet
994 for (SCROW nRow = 0; nRow < 3; ++nRow)
996 m_pDoc->SetValue(ScAddress(0, nRow, 1), 1.0);
997 CPPUNIT_ASSERT(pEntry->NeedsRepaint());
1000 m_pDoc->DeleteTab(0);
1002 // the conditional format should listen to A1:A3 on the second sheet
1003 for (SCROW nRow = 0; nRow < 3; ++nRow)
1005 m_pDoc->SetValue(ScAddress(0, nRow, 0), 1.0);
1006 CPPUNIT_ASSERT(pEntry->NeedsRepaint());
1009 m_pDoc->DeleteTab(0);
1012 void Test::testCondFormatUpdateReference()
1014 m_pDoc->InsertTab(0, "test");
1015 m_pDoc->InsertTab(1, "Test2");
1017 ScConditionEntry* pEntry = new ScConditionEntry(ScConditionMode::Equal, "A1", "", *m_pDoc, ScAddress(10, 10, 0), "", "", formula::FormulaGrammar::GRAM_DEFAULT, formula::FormulaGrammar::GRAM_DEFAULT);
1019 auto pFormat = std::make_unique<ScConditionalFormat>(0, m_pDoc);
1020 pFormat->SetRange(ScRange(10, 10, 0, 10, 12, 0));
1021 auto pFormatTmp = pFormat.get();
1022 m_pDoc->AddCondFormat(std::move(pFormat), 0);
1024 pFormatTmp->AddEntry(pEntry);
1026 // the conditional format should listen to A1:A3
1027 for (SCROW nRow = 0; nRow < 3; ++nRow)
1029 m_pDoc->SetValue(ScAddress(0, nRow, 0), 1.0);
1030 CPPUNIT_ASSERT(pEntry->NeedsRepaint());
1033 m_pDoc->DeleteTab(1);
1034 m_pDoc->DeleteTab(0);
1037 void Test::testCondFormatUpdateReferenceDelRow()
1039 m_pDoc->InsertTab(0, "test");
1041 ScConditionEntry* pEntry = new ScConditionEntry(ScConditionMode::Equal, "B6", "", *m_pDoc, ScAddress(0, 5, 0), "", "", formula::FormulaGrammar::GRAM_DEFAULT, formula::FormulaGrammar::GRAM_DEFAULT);
1043 auto pFormat = std::make_unique<ScConditionalFormat>(0, m_pDoc);
1044 pFormat->SetRange(ScRange(0, 5, 0, 0, 5, 0));
1045 auto pFormatTmp = pFormat.get();
1046 m_pDoc->AddCondFormat(std::move(pFormat), 0);
1048 pFormatTmp->AddEntry(pEntry);
1050 m_pDoc->DeleteRow(0, 0, MAXCOL, 0, 4, 1);
1052 OUString aStr = pEntry->GetExpression(ScAddress(0, 4, 0), 0);
1053 CPPUNIT_ASSERT_EQUAL(OUString("B5"), aStr);
1055 m_pDoc->DeleteTab(0);
1058 void Test::testCondFormatUpdateReferenceInsRow()
1060 m_pDoc->InsertTab(0, "test");
1062 ScConditionEntry* pEntry = new ScConditionEntry(ScConditionMode::Equal, "B6", "", *m_pDoc, ScAddress(0, 5, 0), "", "", formula::FormulaGrammar::GRAM_DEFAULT, formula::FormulaGrammar::GRAM_DEFAULT);
1064 auto pFormat = std::make_unique<ScConditionalFormat>(0, m_pDoc);
1065 pFormat->SetRange(ScRange(0, 5, 0, 0, 5, 0));
1066 auto pFormatTmp = pFormat.get();
1067 m_pDoc->AddCondFormat(std::move(pFormat), 0);
1069 pFormatTmp->AddEntry(pEntry);
1071 m_pDoc->InsertRow(0, 0, MAXCOL, 0, 4, 1);
1073 OUString aStr = pEntry->GetExpression(ScAddress(0, 6, 0), 0);
1074 CPPUNIT_ASSERT_EQUAL(OUString("B7"), aStr);
1076 m_pDoc->DeleteTab(0);
1079 void Test::testCondFormatUndoList()
1081 m_pDoc->InsertTab(0, "test");
1083 ScConditionEntry* pEntry = new ScConditionEntry(ScConditionMode::Equal, "B6", "", *m_pDoc, ScAddress(0, 5, 0), "", "", formula::FormulaGrammar::GRAM_DEFAULT, formula::FormulaGrammar::GRAM_DEFAULT);
1085 auto pFormat = std::make_unique<ScConditionalFormat>(0, m_pDoc);
1086 pFormat->AddEntry(pEntry);
1087 pFormat->SetRange(ScRange(0, 0, 0, 0, 5, 0));
1088 auto pFormatTmp = pFormat.get();
1089 m_pDoc->AddCondFormat(std::move(pFormat), 0);
1090 m_pDoc->AddCondFormatData(pFormatTmp->GetRange(), 0, pFormatTmp->GetKey());
1092 ScDocFunc& rFunc = getDocShell().GetDocFunc();
1094 CPPUNIT_ASSERT_EQUAL(size_t(1), m_pDoc->GetCondFormList(0)->size());
1095 for (SCROW nRow = 0; nRow <= 5; ++nRow)
1096 CPPUNIT_ASSERT(m_pDoc->GetCondFormat(0, nRow, 0));
1098 ScConditionalFormatList* pNewList = new ScConditionalFormatList();
1100 rFunc.SetConditionalFormatList(pNewList, 0);
1102 CPPUNIT_ASSERT_EQUAL(size_t(0), m_pDoc->GetCondFormList(0)->size());
1103 for (SCROW nRow = 0; nRow <= 5; ++nRow)
1104 CPPUNIT_ASSERT(!m_pDoc->GetCondFormat(0, nRow, 0));
1106 m_pDoc->GetUndoManager()->Undo();
1108 CPPUNIT_ASSERT_EQUAL(size_t(1), m_pDoc->GetCondFormList(0)->size());
1109 for (SCROW nRow = 0; nRow <= 5; ++nRow)
1110 CPPUNIT_ASSERT(m_pDoc->GetCondFormat(0, nRow, 0));
1112 m_pDoc->GetUndoManager()->Redo();
1114 CPPUNIT_ASSERT_EQUAL(size_t(0), m_pDoc->GetCondFormList(0)->size());
1115 for (SCROW nRow = 0; nRow <= 5; ++nRow)
1116 CPPUNIT_ASSERT(!m_pDoc->GetCondFormat(0, nRow, 0));
1118 m_pDoc->DeleteTab(0);
1121 namespace {
1123 sal_uInt32 addSingleCellCondFormat(ScDocument* pDoc, const ScAddress& rAddr, sal_uInt32 nKey, const OUString& rCondition)
1125 auto pFormat = std::make_unique<ScConditionalFormat>(nKey, pDoc);
1126 ScRange aCondFormatRange(rAddr);
1127 ScRangeList aRangeList(aCondFormatRange);
1128 pFormat->SetRange(aRangeList);
1130 ScCondFormatEntry* pEntry = new ScCondFormatEntry(ScConditionMode::Direct, rCondition, "",
1131 *pDoc, ScAddress(0,0,0), ScResId(STR_STYLENAME_RESULT));
1132 pFormat->AddEntry(pEntry);
1133 return pDoc->AddCondFormat(std::move(pFormat), 0);
1138 void Test::testMultipleSingleCellCondFormatCopyPaste()
1140 m_pDoc->InsertTab(0, "Test");
1142 sal_uInt32 nFirstCondFormatKey = addSingleCellCondFormat(m_pDoc, ScAddress(0, 0, 0), 1, "=A2");
1143 sal_uInt32 nSecondCondFormatKey = addSingleCellCondFormat(m_pDoc, ScAddress(1, 0, 0), 2, "=B3");
1145 ScDocument aClipDoc(SCDOCMODE_CLIP);
1146 copyToClip(m_pDoc, ScRange(0,0,0,2,0,0), &aClipDoc);
1147 ScRange aTargetRange(2,4,0,7,4,0);
1148 pasteOneCellFromClip(m_pDoc, aTargetRange, &aClipDoc);
1150 for (SCCOL nCol = 2; nCol <= 7; ++nCol)
1152 ScConditionalFormat* pFormat = m_pDoc->GetCondFormat(nCol, 4, 0);
1153 if (((nCol - 2) % 3) == 0)
1155 CPPUNIT_ASSERT_EQUAL(pFormat->GetKey(), nFirstCondFormatKey);
1157 else if (((nCol - 2) % 3) == 1)
1159 CPPUNIT_ASSERT_EQUAL(pFormat->GetKey(), nSecondCondFormatKey);
1161 else
1163 CPPUNIT_ASSERT(!pFormat);
1167 m_pDoc->DeleteTab(0);
1170 void Test::testDeduplicateMultipleCondFormats()
1172 m_pDoc->InsertTab(0, "Test");
1174 sal_uInt32 nFirstCondFormatKey = addSingleCellCondFormat(m_pDoc, ScAddress(0, 0, 0), 1, "=B2");
1175 sal_uInt32 nSecondCondFormatKey = addSingleCellCondFormat(m_pDoc, ScAddress(1, 0, 0), 2, "=B2");
1177 ScDocument aClipDoc(SCDOCMODE_CLIP);
1178 copyToClip(m_pDoc, ScRange(0,0,0,2,0,0), &aClipDoc);
1179 ScRange aTargetRange(2,4,0,7,4,0);
1180 pasteOneCellFromClip(m_pDoc, aTargetRange, &aClipDoc);
1182 for (SCCOL nCol = 2; nCol <= 7; ++nCol)
1184 ScConditionalFormat* pFormat = m_pDoc->GetCondFormat(nCol, 4, 0);
1185 if (((nCol - 2) % 3) == 0)
1187 CPPUNIT_ASSERT_EQUAL(pFormat->GetKey(), nFirstCondFormatKey);
1189 else if (((nCol - 2) % 3) == 1)
1191 CPPUNIT_ASSERT_EQUAL(pFormat->GetKey(), nSecondCondFormatKey);
1193 else
1195 CPPUNIT_ASSERT(!pFormat);
1199 m_pDoc->DeleteTab(0);
1202 void Test::testCondFormatListenToOwnRange()
1204 m_pDoc->InsertTab(0, "Test");
1206 ScConditionalFormatList* pList = m_pDoc->GetCondFormList(0);
1208 auto pFormat = std::make_unique<ScConditionalFormat>(1, m_pDoc);
1209 ScRangeList aRangeList(ScRange(0,0,0,10,0,0));
1210 pFormat->SetRange(aRangeList);
1212 ScIconSetFormat* pEntry = new ScIconSetFormat(m_pDoc);
1213 ScIconSetFormatData* pData = new ScIconSetFormatData;
1214 pData->m_Entries.emplace_back(new ScColorScaleEntry(0, COL_BLUE));
1215 pData->m_Entries.emplace_back(new ScColorScaleEntry(1, COL_GREEN));
1216 pData->m_Entries.emplace_back(new ScColorScaleEntry(2, COL_RED));
1217 pEntry->SetIconSetData(pData);
1218 pEntry->SetParent(pFormat.get());
1220 m_pDoc->AddCondFormatData(pFormat->GetRange(), 0, 1);
1221 pFormat->AddEntry(pEntry);
1222 pList->InsertNew(std::move(pFormat));
1224 bool bFirstCallbackCalled = false;
1225 std::function<void()> aFirstCallback = [&]() {bFirstCallbackCalled = true;};
1226 pData->m_Entries[0]->SetType(COLORSCALE_PERCENT);
1227 pData->m_Entries[0]->SetRepaintCallback(aFirstCallback);
1229 m_pDoc->SetValue(0, 0, 0, -1.0);
1231 CPPUNIT_ASSERT(bFirstCallbackCalled);
1233 m_pDoc->DeleteTab(0);
1236 void Test::testCondFormatVolatileFunctionRecalc()
1238 m_pDoc->InsertTab(0, "Test");
1240 m_pDoc->SetValue(0, 0, 0, 0.5);
1242 ScConditionalFormatList* pList = m_pDoc->GetCondFormList(0);
1244 auto pFormat = std::make_unique<ScConditionalFormat>(1, m_pDoc);
1245 ScRangeList aRangeList(ScRange(0,0,0,10,0,0));
1246 pFormat->SetRange(aRangeList);
1248 ScCondFormatEntry* pEntry = new ScCondFormatEntry(ScConditionMode::Greater,"RAND()","",*m_pDoc,ScAddress(0,0,0),ScResId(STR_STYLENAME_RESULT));
1249 pEntry->SetParent(pFormat.get());
1251 m_pDoc->AddCondFormatData(pFormat->GetRange(), 0, 1);
1252 pFormat->AddEntry(pEntry);
1253 auto pFormatTmp = pFormat.get();
1254 pList->InsertNew(std::move(pFormat));
1256 ScRefCellValue aCell(*m_pDoc, ScAddress(0, 0, 0));
1257 bool bValid = pEntry->IsCellValid(aCell, ScAddress(0, 0, 0));
1259 bool bNewValid = bValid;
1260 // chance of a random failure is 0.5^100, anyone hitting that will get a beer from me
1261 for (size_t i = 0; i < 100; ++i)
1263 pFormatTmp->CalcAll();
1264 bNewValid = pEntry->IsCellValid(aCell, ScAddress(0, 0, 0));
1266 if (bValid != bNewValid)
1267 break;
1270 CPPUNIT_ASSERT(bValid != bNewValid);
1272 m_pDoc->DeleteTab(0);
1275 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */