tdf#130857 qt weld: Implement QtInstanceWidget::strip_mnemonic
[LibreOffice.git] / sc / qa / unit / copy_paste_test.cxx
blobb1691fc23d5d1fe520fc766d4bc26af13b148758
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 <sal/config.h>
12 #include "helper/qahelper.hxx"
13 #include <comphelper/servicehelper.hxx>
15 #include <docsh.hxx>
16 #include <docfunc.hxx>
17 #include <cellmergeoption.hxx>
18 #include <tabvwsh.hxx>
19 #include <impex.hxx>
20 #include <scitems.hxx>
21 #include <attrib.hxx>
22 #include <userlist.hxx>
23 #include <undomanager.hxx>
25 using namespace ::com::sun::star;
26 using namespace ::com::sun::star::uno;
28 class ScCopyPasteTest : public ScModelTestBase
30 public:
31 ScCopyPasteTest();
33 void testCopyPasteXLS();
34 void testTdf84411();
35 void testTdf124565();
36 void testTdf126421();
37 void testTdf107394();
38 void testTdf53431_fillOnAutofilter();
39 void testTdf40993_fillMergedCells();
40 void testTdf43958_clickSelectOnMergedCells();
41 void testTdf88782_autofillLinearNumbersInMergedCells();
42 void tdf137621_autofillMergedBool();
43 void tdf137205_autofillDatesInMergedCells();
44 void tdf137653_137654_autofillUserlist();
45 void tdf113500_autofillMixed();
46 void tdf137625_autofillMergedUserlist();
47 void tdf137624_autofillMergedMixed();
48 void tdf122716_rtf_portion_encoding();
50 CPPUNIT_TEST_SUITE(ScCopyPasteTest);
51 CPPUNIT_TEST(testCopyPasteXLS);
52 CPPUNIT_TEST(testTdf84411);
53 CPPUNIT_TEST(testTdf124565);
54 CPPUNIT_TEST(testTdf126421);
55 CPPUNIT_TEST(testTdf107394);
56 CPPUNIT_TEST(testTdf53431_fillOnAutofilter);
57 CPPUNIT_TEST(testTdf40993_fillMergedCells);
58 CPPUNIT_TEST(testTdf43958_clickSelectOnMergedCells);
59 CPPUNIT_TEST(testTdf88782_autofillLinearNumbersInMergedCells);
60 CPPUNIT_TEST(tdf137621_autofillMergedBool);
61 CPPUNIT_TEST(tdf137205_autofillDatesInMergedCells);
62 CPPUNIT_TEST(tdf137653_137654_autofillUserlist);
63 CPPUNIT_TEST(tdf113500_autofillMixed);
64 CPPUNIT_TEST(tdf137625_autofillMergedUserlist);
65 CPPUNIT_TEST(tdf137624_autofillMergedMixed);
66 CPPUNIT_TEST(tdf122716_rtf_portion_encoding);
67 CPPUNIT_TEST_SUITE_END();
69 private:
70 void addToUserList(const OUString& rStr);
73 // tdf#83366
74 void ScCopyPasteTest::testCopyPasteXLS()
76 createScDoc("xls/chartx2.xls");
77 ScDocument* pDoc = getScDoc();
78 ScTabViewShell* pViewShell = getViewShell();
80 // 2. Highlight B2:C5
81 ScRange aSrcRange;
82 ScRefFlags nRes = aSrcRange.Parse(u"B2:C5"_ustr, *pDoc, pDoc->GetAddressConvention());
83 CPPUNIT_ASSERT_MESSAGE("Failed to parse.", (nRes & ScRefFlags::VALID));
85 ScMarkData aMark(pDoc->GetSheetLimits());
86 aMark.SetMarkArea(aSrcRange);
88 pViewShell->GetViewData().GetMarkData().SetMarkArea(aSrcRange);
90 // 3. Copy
91 ScDocument aClipDoc(SCDOCMODE_CLIP);
92 pViewShell->GetViewData().GetView()->CopyToClip(&aClipDoc, false, false, false, false);
94 // Open a new document
95 createScDoc();
97 pViewShell = getViewShell();
99 // 6. Paste
100 pViewShell->GetViewData().GetView()->PasteFromClip(InsertDeleteFlags::ALL, &aClipDoc);
103 namespace {
105 ScMarkData::MarkedTabsType TabsInRange(const ScRange& r)
107 ScMarkData::MarkedTabsType aResult;
108 for (SCTAB i = r.aStart.Tab(); i <= r.aEnd.Tab(); ++i)
109 aResult.insert(i);
110 return aResult;
113 void lcl_copy( const OUString& rSrcRange, const OUString& rDstRange, ScDocument& rDoc, ScTabViewShell* pViewShell)
115 ScDocument aClipDoc(SCDOCMODE_CLIP);
117 // 1. Copy
118 ScRange aSrcRange;
119 ScRefFlags nRes = aSrcRange.Parse(rSrcRange, rDoc, rDoc.GetAddressConvention());
120 CPPUNIT_ASSERT_MESSAGE("Failed to parse.", (nRes & ScRefFlags::VALID));
121 pViewShell->GetViewData().GetMarkData().SetMarkArea(aSrcRange);
122 pViewShell->GetViewData().GetMarkData().SetSelectedTabs(TabsInRange(aSrcRange));
123 pViewShell->GetViewData().GetView()->CopyToClip(&aClipDoc, false, false, false, false);
125 // 2. Paste
126 ScRange aDstRange;
127 nRes = aDstRange.Parse(rDstRange, rDoc, rDoc.GetAddressConvention());
128 CPPUNIT_ASSERT_MESSAGE("Failed to parse.", (nRes & ScRefFlags::VALID));
129 pViewShell->GetViewData().GetMarkData().SetMarkArea(aDstRange);
130 pViewShell->GetViewData().GetMarkData().SetSelectedTabs(TabsInRange(aDstRange));
131 pViewShell->GetViewData().GetView()->PasteFromClip(InsertDeleteFlags::ALL, &aClipDoc);
134 } // anonymous namespace
136 void ScCopyPasteTest::testTdf84411()
138 createScDoc();
139 ScDocument* pDoc = getScDoc();
140 ScTabViewShell* pViewShell = getViewShell();
142 // 2. Setup data and formulas
143 for (unsigned int r = 0; r <= 4991; ++r)
144 for (unsigned int c = 0; c <= 14; ++c)
145 pDoc->SetValue( ScAddress(c,r,0), (r+1)*(c+1) );
147 pDoc->SetString(ScAddress(15,10000,0), u"=AVERAGE(A10001:O10001)"_ustr);
148 pDoc->SetString(ScAddress(16,10000,0), u"=MIN(A10001:O10001)"_ustr);
149 pDoc->SetString(ScAddress(17,10000,0), u"=MAX(A10001:O10001)"_ustr);
151 lcl_copy(u"P10001:R10001"_ustr, u"P10002:R12500"_ustr, *pDoc, pViewShell);
154 // 3. Disable OpenCL
155 ScModelObj* pModelObj = comphelper::getFromUnoTunnel<ScModelObj>(mxComponent);
156 CPPUNIT_ASSERT(pModelObj);
157 bool bOpenCLState = ScCalcConfig::isOpenCLEnabled();
158 pModelObj->enableOpenCL(false);
159 CPPUNIT_ASSERT(!ScCalcConfig::isOpenCLEnabled() || ScCalcConfig::getForceCalculationType() == ForceCalculationOpenCL);
160 pModelObj->enableAutomaticCalculation(true);
163 // 4. Copy and Paste
164 lcl_copy(u"A1:O2500"_ustr, u"A10001:O12500"_ustr, *pDoc, pViewShell);
166 lcl_copy(u"A2501:O5000"_ustr, u"A12501:O15000"_ustr, *pDoc, pViewShell);
168 lcl_copy(u"P10001:R10001"_ustr, u"P12501:R15000"_ustr, *pDoc, pViewShell);
171 // 5. Close the document (Ctrl-W)
172 pModelObj->enableOpenCL(bOpenCLState);
175 void ScCopyPasteTest::testTdf124565()
177 createScDoc();
178 ScDocument* pDoc = getScDoc();
179 ScTabViewShell* pViewShell = getViewShell();
181 // Set content and height of first row
182 pDoc->SetString(ScAddress(0, 0, 0), u"Test"_ustr);
183 pDoc->SetRowHeight(0, 0, 500);
184 pDoc->SetManualHeight(0, 0, 0, true);
186 // Copy first row
187 ScDocument aClipDoc(SCDOCMODE_CLIP);
188 ScRange aCopyRange(0, 0, 0, aClipDoc.MaxCol(), 0, 0);
189 pViewShell->GetViewData().GetMarkData().SetMarkArea(aCopyRange);
190 pViewShell->GetViewData().GetView()->CopyToClip(&aClipDoc, false, false, false, false);
192 // Paste to second row
193 SCTAB nTab = 0;
194 SCCOL nCol = 0;
195 SCROW nRow = 1;
197 ScRange aPasteRange(nCol, nRow, nTab, aClipDoc.MaxCol(), nRow, nTab);
198 pViewShell->GetViewData().GetMarkData().SetMarkArea(aPasteRange);
199 pViewShell->GetViewData().GetView()->PasteFromClip(InsertDeleteFlags::ALL, &aClipDoc);
201 // Copy-pasted?
202 CPPUNIT_ASSERT_EQUAL_MESSAGE("String was not pasted!", u"Test"_ustr, pDoc->GetString(nCol, nRow, nTab));
204 // And height same as in source?
205 CPPUNIT_ASSERT_EQUAL_MESSAGE("Row#2 height is invalid!", sal_uInt16(500), pDoc->GetRowHeight(nRow, nTab));
207 CPPUNIT_ASSERT_MESSAGE("Row#2 must be manual height!", pDoc->IsManualRowHeight(nRow, nTab));
210 void ScCopyPasteTest::testTdf126421()
212 createScDoc();
213 ScDocument* pDoc = getScDoc();
214 ScTabViewShell* pViewShell = getViewShell();
216 // 2. Setup data
217 for (int r = 0; r < 2; ++r)
218 for (int c = 0; c < 1024; ++c)
219 pDoc->SetValue(c, r, 0, (c + 1) * 100 + (r + 1));
221 const SCTAB n2ndTab = pDoc->GetMaxTableNumber() + 1;
222 pDoc->MakeTable(n2ndTab);
223 const auto aTabNames = pDoc->GetAllTableNames();
225 lcl_copy(aTabNames[0] + ".A1:AMJ2", aTabNames[n2ndTab] + ".A1:AMJ2", *pDoc, pViewShell);
227 // 3. Check all cells in destination table
228 for (int r = 0; r < 2; ++r)
229 for (int c = 0; c < 1024; ++c)
230 CPPUNIT_ASSERT_EQUAL(double((c + 1) * 100 + (r + 1)), pDoc->GetValue(c, r, n2ndTab));
233 void ScCopyPasteTest::testTdf107394()
235 createScDoc();
236 ScDocument* pDoc = getScDoc();
238 sal_uInt16 nFirstRowHeight = pDoc->GetRowHeight(0, 0);
239 sal_uInt16 nSecondRowHeight = pDoc->GetRowHeight(1, 0);
240 CPPUNIT_ASSERT_EQUAL(nFirstRowHeight, nSecondRowHeight);
242 // Import values to A1:A2.
243 ScImportExport aObj(*pDoc, ScAddress(0,0,0));
244 aObj.SetImportBroadcast(true);
246 SvMemoryStream aStream;
247 aStream.WriteOString("<pre>First\nVery long sentence.</pre>");
248 aStream.Seek(0);
249 CPPUNIT_ASSERT(aObj.ImportStream(aStream, OUString(), SotClipboardFormatId::HTML));
251 CPPUNIT_ASSERT_EQUAL(u"First"_ustr, pDoc->GetString(ScAddress(0,0,0)));
252 CPPUNIT_ASSERT_EQUAL(u"Very long sentence."_ustr, pDoc->GetString(ScAddress(0,1,0)));
254 nFirstRowHeight = pDoc->GetRowHeight(0, 0);
255 nSecondRowHeight = pDoc->GetRowHeight(1, 0);
256 CPPUNIT_ASSERT_GREATER(nFirstRowHeight, nSecondRowHeight);
258 // Undo, and check the result.
259 SfxUndoManager* pUndoMgr = pDoc->GetUndoManager();
260 CPPUNIT_ASSERT_MESSAGE("Failed to get the undo manager.", pUndoMgr);
261 pUndoMgr->Undo();
263 CPPUNIT_ASSERT(pDoc->GetString(ScAddress(0,0,0)).isEmpty());
264 CPPUNIT_ASSERT(pDoc->GetString(ScAddress(0,1,0)).isEmpty());
266 nFirstRowHeight = pDoc->GetRowHeight(0, 0);
267 nSecondRowHeight = pDoc->GetRowHeight(1, 0);
268 // Without the accompanying fix in place, this test would have failed:
269 // - Expected: 256
270 // - Actual : 477
271 // i.e. the increased height of the second row remained after undo.
272 CPPUNIT_ASSERT_EQUAL(nFirstRowHeight, nSecondRowHeight);
275 static ScMF lcl_getMergeFlagOfCell(const ScDocument& rDoc, SCCOL nCol, SCROW nRow, SCTAB nTab)
277 const SfxPoolItem& rPoolItem = rDoc.GetPattern(nCol, nRow, nTab)->GetItem(ATTR_MERGE_FLAG);
278 const ScMergeFlagAttr& rMergeFlag = static_cast<const ScMergeFlagAttr&>(rPoolItem);
279 return rMergeFlag.GetValue();
282 static ScAddress lcl_getMergeSizeOfCell(const ScDocument& rDoc, SCCOL nCol, SCROW nRow, SCTAB nTab)
284 const SfxPoolItem& rPoolItem = rDoc.GetPattern(nCol, nRow, nTab)->GetItem(ATTR_MERGE);
285 const ScMergeAttr& rMerge = static_cast<const ScMergeAttr&>(rPoolItem);
286 return ScAddress(rMerge.GetColMerge(), rMerge.GetRowMerge(), nTab);
289 void ScCopyPasteTest::testTdf53431_fillOnAutofilter()
291 createScDoc("ods/tdf53431_autofilterFilldown.ods");
292 ScDocument* pDoc = getScDoc();
293 ScTabViewShell* pViewShell = getViewShell();
295 //Fill should not clone Autofilter button
296 pViewShell->GetViewData().GetMarkData().SetMarkArea(ScRange(1, 1, 0, 2, 4, 0));
297 pViewShell->FillSimple(FILL_TO_BOTTOM);
298 CPPUNIT_ASSERT((lcl_getMergeFlagOfCell(*pDoc, 1, 1, 0) & ScMF::Auto));
299 CPPUNIT_ASSERT((lcl_getMergeFlagOfCell(*pDoc, 2, 1, 0) & ScMF::Auto));
300 CPPUNIT_ASSERT(!(lcl_getMergeFlagOfCell(*pDoc, 1, 4, 0) & ScMF::Auto));
302 pViewShell->GetViewData().GetMarkData().SetMarkArea(ScRange(1, 1, 0, 4, 4, 0));
303 pViewShell->FillSimple(FILL_TO_RIGHT);
304 CPPUNIT_ASSERT((lcl_getMergeFlagOfCell(*pDoc, 1, 1, 0) & ScMF::Auto));
305 CPPUNIT_ASSERT((lcl_getMergeFlagOfCell(*pDoc, 2, 1, 0) & ScMF::Auto));
306 CPPUNIT_ASSERT(!(lcl_getMergeFlagOfCell(*pDoc, 4, 1, 0) & ScMF::Auto));
307 CPPUNIT_ASSERT(!(lcl_getMergeFlagOfCell(*pDoc, 1, 4, 0) & ScMF::Auto));
308 CPPUNIT_ASSERT(!(lcl_getMergeFlagOfCell(*pDoc, 4, 4, 0) & ScMF::Auto));
310 //Fill should not delete Autofilter buttons
311 pViewShell->GetViewData().GetMarkData().SetMarkArea(ScRange(0, 0, 0, 2, 4, 0));
312 pViewShell->FillSimple(FILL_TO_TOP);
313 CPPUNIT_ASSERT((lcl_getMergeFlagOfCell(*pDoc, 1, 1, 0) & ScMF::Auto));
314 CPPUNIT_ASSERT((lcl_getMergeFlagOfCell(*pDoc, 2, 1, 0) & ScMF::Auto));
315 CPPUNIT_ASSERT(!(lcl_getMergeFlagOfCell(*pDoc, 1, 0, 0) & ScMF::Auto));
317 //Fill should not clone Autofilter button
318 pViewShell->GetViewData().GetMarkData().SetMarkArea(ScRange(1, 1, 0, 2, 4, 0));
319 pViewShell->FillSimple(FILL_TO_BOTTOM);
320 CPPUNIT_ASSERT((lcl_getMergeFlagOfCell(*pDoc, 1, 1, 0) & ScMF::Auto));
321 CPPUNIT_ASSERT((lcl_getMergeFlagOfCell(*pDoc, 2, 1, 0) & ScMF::Auto));
322 CPPUNIT_ASSERT(!(lcl_getMergeFlagOfCell(*pDoc, 1, 4, 0) & ScMF::Auto));
324 pViewShell->GetViewData().GetMarkData().SetMarkArea(ScRange(1, 1, 0, 4, 4, 0));
325 pViewShell->FillSimple(FILL_TO_RIGHT);
326 CPPUNIT_ASSERT((lcl_getMergeFlagOfCell(*pDoc, 1, 1, 0) & ScMF::Auto));
327 CPPUNIT_ASSERT((lcl_getMergeFlagOfCell(*pDoc, 2, 1, 0) & ScMF::Auto));
328 CPPUNIT_ASSERT(!(lcl_getMergeFlagOfCell(*pDoc, 4, 1, 0) & ScMF::Auto));
329 CPPUNIT_ASSERT(!(lcl_getMergeFlagOfCell(*pDoc, 1, 4, 0) & ScMF::Auto));
330 CPPUNIT_ASSERT(!(lcl_getMergeFlagOfCell(*pDoc, 4, 4, 0) & ScMF::Auto));
332 //Fill should not delete Autofilter buttons
333 pViewShell->GetViewData().GetMarkData().SetMarkArea(ScRange(0, 0, 0, 2, 4, 0));
334 pViewShell->FillSimple(FILL_TO_TOP);
335 CPPUNIT_ASSERT((lcl_getMergeFlagOfCell(*pDoc, 1, 1, 0) & ScMF::Auto));
336 CPPUNIT_ASSERT((lcl_getMergeFlagOfCell(*pDoc, 2, 1, 0) & ScMF::Auto));
337 CPPUNIT_ASSERT(!(lcl_getMergeFlagOfCell(*pDoc, 1, 0, 0) & ScMF::Auto));
339 pViewShell->GetViewData().GetMarkData().SetMarkArea(ScRange(0, 0, 0, 4, 4, 0));
340 pViewShell->FillSimple(FILL_TO_LEFT);
341 CPPUNIT_ASSERT((lcl_getMergeFlagOfCell(*pDoc, 1, 1, 0) & ScMF::Auto));
342 CPPUNIT_ASSERT((lcl_getMergeFlagOfCell(*pDoc, 2, 1, 0) & ScMF::Auto));
343 CPPUNIT_ASSERT(!(lcl_getMergeFlagOfCell(*pDoc, 0, 1, 0) & ScMF::Auto));
346 void ScCopyPasteTest::testTdf40993_fillMergedCells()
348 createScDoc("ods/tdf40993_fillMergedCells.ods");
349 ScDocument* pDoc = getScDoc();
350 ScTabViewShell* pViewShell = getViewShell();
352 // check content of the merged cell H11:I11
353 CPPUNIT_ASSERT_EQUAL(u"1.5"_ustr, pDoc->GetString(ScAddress(7, 10, 0)));
355 // fill operation on the merged cell should clone ATTR_MERGE and ATTR_MERGE_FLAG
356 // (as long as ATTR_MERGE_FLAG has only ScMF::Hor or ScMF::Ver)
358 // select merged cell
359 pViewShell->GetViewData().GetMarkData().SetMarkArea(ScRange(7, 10, 0, 8, 10, 0));
360 // copy its content in the next ten rows
361 pViewShell->FillAuto(FILL_TO_BOTTOM, 7, 10, 8, 10, 10);
362 for (int i = 7; i < 9; i++)
364 ScMF nOriginFlag = lcl_getMergeFlagOfCell(*pDoc, i, 10, 0);
365 ScAddress aOriginMerge = lcl_getMergeSizeOfCell(*pDoc, i, 10, 0);
367 // ATTR_MERGE_FLAG: top left cell is NONE, the other cell shows horizontal overlapping
368 CPPUNIT_ASSERT_EQUAL(i == 7 ? ScMF::NONE : ScMF::Hor, nOriginFlag);
370 // ATTR_MERGE: top left cell contains the size of the
371 // merged area (2:1), the other cell doesn't
372 CPPUNIT_ASSERT_EQUAL(i == 7 ? ScAddress(2, 1, 0): ScAddress(0, 0, 0), aOriginMerge);
374 for (int j = 11; j < 21; j++)
376 // check copying of ATTR_MERGE and ATTR_MERGE_FLAG
377 CPPUNIT_ASSERT_EQUAL(lcl_getMergeFlagOfCell(*pDoc, i, j, 0), nOriginFlag);
378 CPPUNIT_ASSERT_EQUAL(lcl_getMergeSizeOfCell(*pDoc, i, j, 0), aOriginMerge);
382 CPPUNIT_ASSERT_EQUAL(lcl_getMergeFlagOfCell(*pDoc, 7, 21, 0),
383 lcl_getMergeFlagOfCell(*pDoc, 7, 10, 0));
384 CPPUNIT_ASSERT(lcl_getMergeSizeOfCell(*pDoc, 7, 21, 0) !=
385 lcl_getMergeSizeOfCell(*pDoc, 7, 10, 0));
386 CPPUNIT_ASSERT(lcl_getMergeFlagOfCell(*pDoc, 8, 21, 0) !=
387 lcl_getMergeFlagOfCell(*pDoc, 8, 10, 0));
388 CPPUNIT_ASSERT_EQUAL(lcl_getMergeSizeOfCell(*pDoc, 8, 21, 0),
389 lcl_getMergeSizeOfCell(*pDoc, 8, 10, 0));
391 // area A6:E9 with various merged cells copied vertically and horizontally
392 pViewShell->GetViewData().GetMarkData().SetMarkArea(ScRange(0, 5, 0, 4, 8, 0));
393 pViewShell->FillAuto(FILL_TO_BOTTOM, 0, 5, 4, 8, 12);
394 pViewShell->GetViewData().GetMarkData().SetMarkArea(ScRange(0, 5, 0, 4, 8, 0));
395 pViewShell->FillAuto(FILL_TO_RIGHT, 0, 5, 4, 8, 10);
396 for (int i = 0; i < 5; i++)
398 for (int j = 5; j < 9; j++)
400 ScMF nOriginFlag = lcl_getMergeFlagOfCell(*pDoc, i, j, 0);
401 ScAddress aOriginMerge = lcl_getMergeSizeOfCell(*pDoc, i, j, 0);
402 // copies contain the same ATTR_MERGE and ATTR_MERGE_FLAG
403 for (int k = 0; k < 12; k += 4)
405 CPPUNIT_ASSERT_EQUAL(lcl_getMergeFlagOfCell(*pDoc, i, j + k, 0), nOriginFlag);
406 CPPUNIT_ASSERT_EQUAL(lcl_getMergeSizeOfCell(*pDoc, i, j + k, 0), aOriginMerge);
408 for (int k = 0; k < 10; k += 5)
410 CPPUNIT_ASSERT_EQUAL(lcl_getMergeFlagOfCell(*pDoc, i + k, j, 0), nOriginFlag);
411 CPPUNIT_ASSERT_EQUAL(lcl_getMergeSizeOfCell(*pDoc, i + k, j, 0), aOriginMerge);
415 CPPUNIT_ASSERT_EQUAL(lcl_getMergeSizeOfCell(*pDoc, 1, 5, 0), ScAddress(2, 4, 0));
416 CPPUNIT_ASSERT_EQUAL(lcl_getMergeSizeOfCell(*pDoc, 0, 5, 0), ScAddress(1, 2, 0));
417 CPPUNIT_ASSERT_EQUAL(lcl_getMergeSizeOfCell(*pDoc, 4, 6, 0), ScAddress(1, 2, 0));
418 CPPUNIT_ASSERT_EQUAL(lcl_getMergeSizeOfCell(*pDoc, 3, 5, 0), ScAddress(2, 1, 0));
421 static void lcl_clickAndCheckCurrentArea(SCCOL nCol, SCROW nRow, SCCOL nCol2, SCROW nRow2, ScTabViewShell* pViewShell)
423 ScRange aRange;
424 pViewShell->GetViewData().SetCurX(nCol);
425 pViewShell->GetViewData().SetCurY(nRow);
426 pViewShell->GetViewData().GetSimpleArea(aRange);
427 CPPUNIT_ASSERT_EQUAL(aRange, ScRange(nCol, nRow, 0, nCol2, nRow2, 0));
430 void ScCopyPasteTest::testTdf43958_clickSelectOnMergedCells()
432 createScDoc("ods/tdf40993_fillMergedCells.ods");
433 ScTabViewShell* pViewShell = getViewShell();
435 // select cell (e.g. by clicking on it) and check what is selected [but not marked]:
436 // if it is the top left cell of a merged area, the selection is enlarged to the area
437 lcl_clickAndCheckCurrentArea(1, 5, 2, 8, pViewShell); // B6 -> B6:C9
438 lcl_clickAndCheckCurrentArea(0, 5, 0, 6, pViewShell); // A6 -> A6:A7
439 lcl_clickAndCheckCurrentArea(3, 5, 4, 5, pViewShell); // D6 -> D6:E6
440 lcl_clickAndCheckCurrentArea(4, 6, 4, 7, pViewShell); // D7 -> D6:D7
441 lcl_clickAndCheckCurrentArea(7, 10, 8, 10, pViewShell); // H11 -> H11:I11
442 lcl_clickAndCheckCurrentArea(7, 13, 8, 13, pViewShell); // H14 -> H14:I14
444 // otherwise it remains the same
445 lcl_clickAndCheckCurrentArea(0, 7, 0, 7, pViewShell); // A8
446 lcl_clickAndCheckCurrentArea(0, 8, 0, 8, pViewShell); // A9
447 lcl_clickAndCheckCurrentArea(2, 6, 2, 6, pViewShell); // C7
448 lcl_clickAndCheckCurrentArea(2, 7, 2, 7, pViewShell); // C8
449 lcl_clickAndCheckCurrentArea(2, 8, 2, 8, pViewShell); // C9
452 void ScCopyPasteTest::testTdf88782_autofillLinearNumbersInMergedCells()
454 createScDoc("ods/tdf88782_AutofillLinearNumbersInMergedCells.ods");
455 ScDocument* pDoc = getScDoc();
456 ScTabViewShell* pViewShell = getViewShell();
458 // merge the yellow cells
459 ScCellMergeOption aMergeOptions(9, 11, 10, 13); //J12:K14
460 aMergeOptions.maTabs.insert(0);
461 ScDocShell* pDocSh = pViewShell->GetViewData().GetDocShell();
462 pDocSh->GetDocFunc().MergeCells(aMergeOptions, false, true, true, false);
464 // fillauto numbers, these areas contain mostly merged cells
465 pViewShell->FillAuto(FILL_TO_BOTTOM, 1, 8, 3, 14, 7); // B9:D15 -> B9:D22
466 pViewShell->FillAuto(FILL_TO_BOTTOM, 5, 8, 7, 17, 10); // F9:H18 -> F9:H28
467 pViewShell->FillAuto(FILL_TO_BOTTOM, 9, 8, 10, 13, 6); // J9:K14 -> J9:K20
468 pViewShell->FillAuto(FILL_TO_RIGHT, 9, 30, 16, 35, 8); //J31:Q36 -> J31:Y36
469 pViewShell->FillAuto(FILL_TO_LEFT, 9, 30, 16, 35, 8); //J31:Q36 -> B31:Q36
471 // compare the results of fill-down with the reference stored in the test file
472 // this compares the whole area blindly, for specific test cases, check the test file
473 // the test file have instructions / explanations, so that is easy to understand
474 for (int nCol = 1; nCol <= 10; nCol++)
476 for (int nRow = 8; nRow <= 27; nRow++)
478 CellType nType1 = pDoc->GetCellType(ScAddress(nCol, nRow, 0));
479 CellType nType2 = pDoc->GetCellType(ScAddress(nCol + 22, nRow, 0));
480 double* pValue1 = pDoc->GetValueCell(ScAddress(nCol, nRow, 0));
481 double* pValue2 = pDoc->GetValueCell(ScAddress(nCol + 22, nRow, 0));
483 CPPUNIT_ASSERT_EQUAL(nType1, nType2);
484 if (pValue2 != nullptr)
485 CPPUNIT_ASSERT_EQUAL(*pValue1, *pValue2); //cells with number value
486 else
487 CPPUNIT_ASSERT_EQUAL(pValue1, pValue2); //empty cells
491 // compare the results of fill-right and left with the reference stored in the test file
492 for (int nCol = 1; nCol <= 24; nCol++)
494 for (int nRow = 30; nRow <= 35; nRow++)
496 CellType nType1 = pDoc->GetCellType(ScAddress(nCol, nRow, 0));
497 CellType nType2 = pDoc->GetCellType(ScAddress(nCol, nRow + 16, 0));
498 double* pValue1 = pDoc->GetValueCell(ScAddress(nCol, nRow, 0));
499 double* pValue2 = pDoc->GetValueCell(ScAddress(nCol, nRow + 16, 0));
501 CPPUNIT_ASSERT_EQUAL(nType1, nType2);
502 if (pValue2 != nullptr)
503 CPPUNIT_ASSERT_EQUAL(*pValue1, *pValue2);
504 else
505 CPPUNIT_ASSERT_EQUAL(pValue1, pValue2);
510 void ScCopyPasteTest::tdf137621_autofillMergedBool()
512 createScDoc("ods/tdf137621_autofillMergedBool.ods");
513 ScDocument* pDoc = getScDoc();
514 ScTabViewShell* pViewShell = getViewShell();
516 // fillauto booleans, these areas contain only merged cells
517 pViewShell->FillAuto(FILL_TO_RIGHT, 0, 4, 3, 5, 8); //A5:D6
519 // compare the results of fill-right with the reference stored in the test file
520 // this compares the whole area blindly, for specific test cases, check the test file
521 for (int nCol = 4; nCol <= 11; nCol++)
523 for (int nRow = 4; nRow <= 5; nRow++)
525 CellType nType1 = pDoc->GetCellType(ScAddress(nCol, nRow, 0));
526 CellType nType2 = pDoc->GetCellType(ScAddress(nCol, nRow + 3, 0));
527 double* pValue1 = pDoc->GetValueCell(ScAddress(nCol, nRow, 0));
528 double* pValue2 = pDoc->GetValueCell(ScAddress(nCol, nRow + 3, 0));
530 CPPUNIT_ASSERT_EQUAL(nType1, nType2);
531 if (pValue2 != nullptr)
532 CPPUNIT_ASSERT_EQUAL(*pValue1, *pValue2); //cells with boolean value
533 else
534 CPPUNIT_ASSERT_EQUAL(pValue1, pValue2); //empty cells
539 void ScCopyPasteTest::tdf137205_autofillDatesInMergedCells()
541 createScDoc("ods/tdf137205_AutofillDatesInMergedCells.ods");
542 ScDocument* pDoc = getScDoc();
543 ScTabViewShell* pViewShell = getViewShell();
545 // fillauto dates, this areas contain only merged cells
546 pViewShell->FillAuto(FILL_TO_RIGHT, 1, 5, 4, 7, 8); //B6:E8
548 // compare the results of fill-right with the reference stored in the test file
549 // this compares the whole area blindly, for specific test cases, check the test file
550 for (int nCol = 5; nCol <= 12; nCol++)
552 for (int nRow = 5; nRow <= 7; nRow++)
554 CellType nType1 = pDoc->GetCellType(ScAddress(nCol, nRow, 0));
555 CellType nType2 = pDoc->GetCellType(ScAddress(nCol, nRow + 5, 0));
556 double* pValue1 = pDoc->GetValueCell(ScAddress(nCol, nRow, 0));
557 double* pValue2 = pDoc->GetValueCell(ScAddress(nCol, nRow + 5, 0));
559 CPPUNIT_ASSERT_EQUAL(nType1, nType2);
560 if (pValue2 != nullptr)
561 CPPUNIT_ASSERT_EQUAL(*pValue1, *pValue2); //cells with number value
562 else
563 CPPUNIT_ASSERT_EQUAL(pValue1, pValue2); //empty cells
568 void ScCopyPasteTest::addToUserList(const OUString& rStr)
570 ScGlobal::GetUserList().emplace_back(rStr);
573 void ScCopyPasteTest::tdf137653_137654_autofillUserlist()
575 createScDoc("ods/tdf137653_137654_autofillUserlist.ods");
576 ScDocument* pDoc = getScDoc();
577 ScTabViewShell* pViewShell = getViewShell();
579 // delete every userlist to make sure there won't be any string that is in 2 different userlist
580 ScGlobal::GetUserList().clear();
581 addToUserList({ u"January,February,March,April,May,June,July,August,September,October,November,December"_ustr });
582 const ScUserListData* pListData = ScGlobal::GetUserList().GetData(u"January"_ustr);
583 sal_uInt16 nIdx1 = 0, nIdx2 = 0;
584 bool bHasIdx1, bHasIdx2;
585 bool bMatchCase = false;
587 // fillauto userlist, these areas contain only merged cells
588 pViewShell->FillAuto(FILL_TO_RIGHT, 4, 5, 6, 7, 3); //E6:G8
589 pViewShell->FillAuto(FILL_TO_LEFT, 4, 5, 6, 7, 3); //E6:G8
590 pViewShell->FillAuto(FILL_TO_BOTTOM, 1, 18, 3, 19, 2); //B19:D20
591 pViewShell->FillAuto(FILL_TO_TOP, 1, 18, 3, 19, 2); //B19:D20
593 // compare the results of fill-right / -left with the reference stored in the test file
594 // this compares the whole area blindly, for specific test cases, check the test file
595 for (int nCol = 1; nCol <= 9; nCol++)
597 for (int nRow = 5; nRow <= 7; nRow++)
599 CellType nType1 = pDoc->GetCellType(ScAddress(nCol, nRow, 0));
600 CellType nType2 = pDoc->GetCellType(ScAddress(nCol, nRow + 4, 0));
601 bHasIdx1 = pListData->GetSubIndex(pDoc->GetString(nCol, nRow, 0), nIdx1, bMatchCase);
602 bHasIdx2 = pListData->GetSubIndex(pDoc->GetString(nCol, nRow + 4, 0), nIdx2, bMatchCase);
604 CPPUNIT_ASSERT_EQUAL(nType1, nType2);
605 CPPUNIT_ASSERT(bHasIdx1);
606 CPPUNIT_ASSERT(bHasIdx2);
607 CPPUNIT_ASSERT_EQUAL(nIdx1, nIdx2); // userlist index value of cells
611 // compare the results of fill-up / -down
612 for (int nCol = 1; nCol <= 3; nCol++)
614 for (int nRow = 16; nRow <= 21; nRow++)
616 CellType nType1 = pDoc->GetCellType(ScAddress(nCol, nRow, 0));
617 CellType nType2 = pDoc->GetCellType(ScAddress(nCol + 4, nRow, 0));
618 bHasIdx1 = pListData->GetSubIndex(pDoc->GetString(nCol, nRow, 0), nIdx1, bMatchCase);
619 bHasIdx2 = pListData->GetSubIndex(pDoc->GetString(nCol + 4, nRow, 0), nIdx2, bMatchCase);
621 CPPUNIT_ASSERT_EQUAL(nType1, nType2);
622 CPPUNIT_ASSERT(bHasIdx1);
623 CPPUNIT_ASSERT(bHasIdx2);
624 CPPUNIT_ASSERT_EQUAL(nIdx1, nIdx2); // userlist index value of cells
629 void ScCopyPasteTest::tdf113500_autofillMixed()
631 createScDoc("ods/tdf113500_autofillMixed.ods");
632 ScDocument* pDoc = getScDoc();
633 ScTabViewShell* pViewShell = getViewShell();
635 // fillauto userlist, these areas contain only merged cells
636 pViewShell->FillAuto(FILL_TO_RIGHT, 4, 5, 6, 7, 3); //E6:G8
637 pViewShell->FillAuto(FILL_TO_LEFT, 4, 5, 6, 7, 3); //E6:G8
638 pViewShell->FillAuto(FILL_TO_BOTTOM, 1, 18, 3, 19, 2); //B19:D20
639 pViewShell->FillAuto(FILL_TO_TOP, 1, 18, 3, 19, 2); //B19:D20
641 // compare the results of fill-right / -left with the reference stored in the test file
642 // this compares the whole area blindly, for specific test cases, check the test file
643 // do not check the 3. row: a1,b2,a3. It is another bug to fix
644 for (int nCol = 1; nCol <= 9; nCol++)
646 for (int nRow = 5; nRow <= 6; nRow++)
648 CellType nType1 = pDoc->GetCellType(ScAddress(nCol, nRow, 0));
649 CellType nType2 = pDoc->GetCellType(ScAddress(nCol, nRow + 4, 0));
650 OUString aStr1 = pDoc->GetString(nCol, nRow, 0);
651 OUString aStr2 = pDoc->GetString(nCol, nRow + 4, 0);
653 CPPUNIT_ASSERT_EQUAL(nType1, nType2);
654 CPPUNIT_ASSERT_EQUAL(aStr1, aStr2);
658 // compare the results of fill-up / -down
659 // do not check the 2. column: 1st,3rd. It is another bug to fix
660 for (int nCol = 1; nCol <= 3; nCol+=2)
662 for (int nRow = 16; nRow <= 21; nRow++)
664 CellType nType1 = pDoc->GetCellType(ScAddress(nCol, nRow, 0));
665 CellType nType2 = pDoc->GetCellType(ScAddress(nCol + 4, nRow, 0));
666 OUString aStr1 = pDoc->GetString(nCol, nRow, 0);
667 OUString aStr2 = pDoc->GetString(nCol + 4, nRow, 0);
669 CPPUNIT_ASSERT_EQUAL(nType1, nType2);
670 CPPUNIT_ASSERT_EQUAL(aStr1, aStr2);
675 void ScCopyPasteTest::tdf137625_autofillMergedUserlist()
677 createScDoc("ods/tdf137625_autofillMergedUserlist.ods");
678 ScDocument* pDoc = getScDoc();
679 ScTabViewShell* pViewShell = getViewShell();
681 // delete every userlist to make sure there won't be any string that is in 2 different userlist
682 ScGlobal::GetUserList().clear();
683 addToUserList({ u"January,February,March,April,May,June,July,August,September,October,November,December"_ustr });
684 const ScUserListData* pListData = ScGlobal::GetUserList().GetData(u"January"_ustr);
685 sal_uInt16 nIdx1 = 0, nIdx2 = 0;
686 bool bHasIdx1, bHasIdx2;
687 bool bMatchCase = false;
689 // fillauto userlist, these areas contain only merged cells
690 pViewShell->FillAuto(FILL_TO_RIGHT, 7, 5, 12, 7, 6); //H6:M8
691 pViewShell->FillAuto(FILL_TO_LEFT, 7, 5, 12, 7, 6); //H6:M8
692 pViewShell->FillAuto(FILL_TO_BOTTOM, 1, 20, 3, 23, 4); //B21:D24
693 pViewShell->FillAuto(FILL_TO_TOP, 1, 20, 3, 23, 4); //B21:D24
695 // compare the results of fill-right / -left with the reference stored in the test file
696 // this compares the whole area blindly, for specific test cases, check the test file
697 for (int nCol = 1; nCol <= 18; nCol++)
699 for (int nRow = 5; nRow <= 7; nRow++)
701 CellType nType1 = pDoc->GetCellType(ScAddress(nCol, nRow, 0));
702 CellType nType2 = pDoc->GetCellType(ScAddress(nCol, nRow + 4, 0));
703 bHasIdx1 = pListData->GetSubIndex(pDoc->GetString(nCol, nRow, 0), nIdx1, bMatchCase);
704 bHasIdx2 = pListData->GetSubIndex(pDoc->GetString(nCol, nRow + 4, 0), nIdx2, bMatchCase);
706 CPPUNIT_ASSERT_EQUAL(nType1, nType2);
707 CPPUNIT_ASSERT_EQUAL(bHasIdx1, bHasIdx2);
708 if (bHasIdx1)
709 CPPUNIT_ASSERT_EQUAL(nIdx1, nIdx2); //cells with userlist value
713 // compare the results of fill-up / -down
714 for (int nCol = 1; nCol <= 3; nCol++)
716 for (int nRow = 16; nRow <= 27; nRow++)
718 CellType nType1 = pDoc->GetCellType(ScAddress(nCol, nRow, 0));
719 CellType nType2 = pDoc->GetCellType(ScAddress(nCol + 4, nRow, 0));
720 bHasIdx1 = pListData->GetSubIndex(pDoc->GetString(nCol, nRow, 0), nIdx1, bMatchCase);
721 bHasIdx2 = pListData->GetSubIndex(pDoc->GetString(nCol + 4, nRow, 0), nIdx2, bMatchCase);
723 CPPUNIT_ASSERT_EQUAL(nType1, nType2);
724 CPPUNIT_ASSERT_EQUAL(bHasIdx1, bHasIdx2);
725 if (bHasIdx1)
726 CPPUNIT_ASSERT_EQUAL(nIdx1, nIdx2); //cells with userlist value
731 void ScCopyPasteTest::tdf137624_autofillMergedMixed()
733 createScDoc("ods/tdf137624_autofillMergedMixed.ods");
734 ScDocument* pDoc = getScDoc();
735 ScTabViewShell* pViewShell = getViewShell();
737 // add 1aa,2bb,3cc,4dd,5ee,6ff to userlist, to test that autofill won't confuse it with 1aa,3aa
738 // delete every userlist to make sure there won't be any string that is in 2 different userlist
739 ScGlobal::GetUserList().clear();
740 addToUserList({ u"1aa,2bb,3cc,4dd,5ee,6ff"_ustr });
742 // fillauto mixed (string + number), these areas contain only merged cells
743 pViewShell->FillAuto(FILL_TO_RIGHT, 7, 5, 12, 7, 6); //H6:M8
744 pViewShell->FillAuto(FILL_TO_LEFT, 7, 5, 12, 7, 6); //H6:M8
745 pViewShell->FillAuto(FILL_TO_BOTTOM, 1, 20, 3, 23, 4); //B21:D24
746 pViewShell->FillAuto(FILL_TO_TOP, 1, 20, 3, 23, 4); //B21:D24
748 // compare the results of fill-right / -left with the reference stored in the test file
749 // this compares the whole area blindly, for specific test cases, check the test file
750 for (int nCol = 1; nCol <= 18; nCol++)
752 for (int nRow = 5; nRow <= 7; nRow++)
754 CellType nType1 = pDoc->GetCellType(ScAddress(nCol, nRow, 0));
755 CellType nType2 = pDoc->GetCellType(ScAddress(nCol, nRow + 4, 0));
756 OUString aStr1 = pDoc->GetString(nCol, nRow, 0);
757 OUString aStr2 = pDoc->GetString(nCol, nRow + 4, 0);
759 CPPUNIT_ASSERT_EQUAL(nType1, nType2);
760 CPPUNIT_ASSERT_EQUAL(aStr1, aStr2);
764 // compare the results of fill-up / -down
765 for (int nCol = 1; nCol <= 3; nCol++)
767 for (int nRow = 16; nRow <= 27; nRow++)
769 CellType nType1 = pDoc->GetCellType(ScAddress(nCol, nRow, 0));
770 CellType nType2 = pDoc->GetCellType(ScAddress(nCol + 4, nRow, 0));
771 OUString aStr1 = pDoc->GetString(nCol, nRow, 0);
772 OUString aStr2 = pDoc->GetString(nCol + 4, nRow, 0);
774 CPPUNIT_ASSERT_EQUAL(nType1, nType2);
775 CPPUNIT_ASSERT_EQUAL(aStr1, aStr2);
780 void ScCopyPasteTest::tdf122716_rtf_portion_encoding()
782 // Given a document with an explicitly defined "204" (Russian) charset for a font,
783 // and a cell having contents of "Šampūnas", which has character "Š" representable
784 // in Windows-1252 (RTF default), but not in Windows-1251 (i.e. charset 204):
785 createScDoc("xlsx/tdf122716_font_with_charset.xlsx");
786 ScModelObj* pModelObj = comphelper::getFromUnoTunnel<ScModelObj>(mxComponent);
787 // Obtain a transferable, similar to what happens on copy to clipboard:
788 auto xTransferable = pModelObj->getSelection();
789 // Get the RTF data:
790 auto rtf_any = xTransferable->getTransferData({ u"text/rtf"_ustr, {}, {} });
791 css::uno::Sequence<sal_Int8> rtf_bytes;
792 CPPUNIT_ASSERT(rtf_any >>= rtf_bytes);
793 OString rtf_string(reinterpret_cast<const char*>(rtf_bytes.getConstArray()),
794 rtf_bytes.getLength());
795 // Check that the font with charset was actually emitted
796 CPPUNIT_ASSERT(rtf_string.indexOf("\\fcharset204 Liberation Sans;") >= 0);
797 // Make sure that Unicode markup is emitted for the non-Ascii characters.
798 // Without the fix, "\u352" wasn't there, because the export was using Windows-1252
799 // encoding unconditionally, even though the exported font defined a different one;
800 // so the exported characters only had Unicode markup, when not representable in the
801 // Windows-1252 encoding, and "Š" got exported as "\'8a". On import to Writer, font
802 // encoding was used, and "\'8a" was interpreted as a Cyrillic alphabet character.
803 CPPUNIT_ASSERT(rtf_string.indexOf("\\u352\\'3famp\\u363\\'3fnas") >= 0);
806 ScCopyPasteTest::ScCopyPasteTest()
807 : ScModelTestBase(u"/sc/qa/unit/data/"_ustr)
811 CPPUNIT_TEST_SUITE_REGISTRATION(ScCopyPasteTest);
813 CPPUNIT_PLUGIN_IMPLEMENT();
815 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */