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/.
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>
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)
88 CPPUNIT_ASSERT(m_pDoc
->GetCondFormat(nCol
, nRow
, 0));
89 CPPUNIT_ASSERT(nCondFormatKey
!= m_pDoc
->GetCondFormat(nCol
, nRow
, 0)->GetKey());
95 void Test::testCondFormatINSDEL()
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.
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.
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));
268 m_pDoc
->DeleteTab(1);
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);
488 CPPUNIT_ASSERT(pNewFormat
);
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);
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
));
571 double nVal
; sal_Int32 nIndex
;
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
);
587 m_pDoc
->DeleteTab(0);
592 struct ScDataBarLengthData
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
[] = {
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
[] = {
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
[] = {
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
[] = {
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
[] = {
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
[] = {
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);
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
);
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
);
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
)
1270 CPPUNIT_ASSERT(bValid
!= bNewValid
);
1272 m_pDoc
->DeleteTab(0);
1275 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */