/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
// Insert a new record to make sure the user and date-time are correct.
rDoc.SetString(ScAddress(1, 8, 0), u"New String"_ustr);
ScCellValue aEmpty;
pCT->AppendContent(ScAddress(1, 8, 0), aEmpty);
pAction = pCT->GetLast(); if (!pAction)
{
cerr << "Failed to retrieve last revision." << endl; returnfalse;
}
if (rOwnerName != pAction->GetUser())
{
cerr << "Wrong user name." << endl; returnfalse;
}
DateTime aDTNew = pAction->GetDateTime(); if (aDTNew <= aDT)
{
cerr << "Time stamp of the new revision should be more recent than that of the " "last revision."
<< endl; returnfalse;
}
staticconst Color aXclColors[] = {
0x0000B050, // green
0x00FF0000, // red
0x000070C0, // blue
0x00FFFF00, // yellow
};
for (size_t i = 0; i < SAL_N_ELEMENTS(aXclColors); ++i)
{ if (aXclColors[i] != rDoc.GetTabBgColor(i))
{
cerr << "wrong sheet color for sheet " << i << endl; returnfalse;
}
}
returntrue;
}
} aTest;
createScDoc("xlsx/sheet-tab-color.xlsx");
{
ScDocument* pDoc = getScDoc(); bool bRes = aTest.checkContent(*pDoc);
CPPUNIT_ASSERT_MESSAGE("Failed on the initial content check.", bRes);
}
saveAndReload(u"Calc Office Open XML"_ustr);
ScDocument* pDoc = getScDoc(); bool bRes = aTest.checkContent(*pDoc);
CPPUNIT_ASSERT_MESSAGE("Failed on the content check after reload.", bRes);
}
// shape in background has lowest index
assertXPath(pXmlDoc, "/office:document-content/office:body/office:spreadsheet/table:table[1]/" "table:table-row[1]/table:table-cell[1]/draw:custom-shape", "z-index", u"0");
assertXPath(pXmlDoc, "/office:document-content/office:body/office:spreadsheet/table:table[1]/" "table:table-row[1]/table:table-cell[1]/draw:custom-shape" "/attribute::table:table-background",
1);
assertXPath(pXmlDoc, "/office:document-content/office:body/office:spreadsheet/table:table[1]/" "table:table-row[1]/table:table-cell[1]/draw:custom-shape", "table-background", u"true"); // shape in foreground, previously index 1
assertXPath(pXmlDoc, "/office:document-content/office:body/office:spreadsheet/table:table[1]/" "table:table-row[1]/table:table-cell[2]/draw:custom-shape", "z-index", u"2"); // attribute is only written for value "true"
assertXPath(pXmlDoc, "/office:document-content/office:body/office:spreadsheet/table:table[1]/" "table:table-row[1]/table:table-cell[2]/draw:custom-shape" "/attribute::table:table-background",
0); // shape in foreground, previously index 0
assertXPath(pXmlDoc, "/office:document-content/office:body/office:spreadsheet/table:table[1]/" "table:table-row[3]/table:table-cell[1]/draw:custom-shape", "z-index", u"1"); // attribute is only written for value "true"
assertXPath(pXmlDoc, "/office:document-content/office:body/office:spreadsheet/table:table[1]/" "table:table-row[3]/table:table-cell[1]/draw:custom-shape" "/attribute::table:table-background",
0); // shape in foreground, previously index 4
assertXPath(pXmlDoc, "/office:document-content/office:body/office:spreadsheet/table:table[1]/" "table:shapes/draw:custom-shape", "z-index", u"3"); // attribute is only written for value "true"
assertXPath(pXmlDoc, "/office:document-content/office:body/office:spreadsheet/table:table[1]/" "table:shapes/draw:custom-shape" "/attribute::table:table-background",
0); // form control, previously index 3
assertXPath(pXmlDoc, "/office:document-content/office:body/office:spreadsheet/table:table[1]/" "table:shapes/draw:control", "z-index", u"4"); // attribute is only written for value "true"
assertXPath(pXmlDoc, "/office:document-content/office:body/office:spreadsheet/table:table[1]/" "table:shapes/draw:control" "/attribute::table:table-background",
0);
}
// A3:A12 and B3:B12 are numbers from 1 to 10. for (SCROW i = 0; i <= 9; ++i)
{ double fExpected = i + 1.0;
ScAddress aPos(0, i + 2, 0); double fActual = rDoc.GetValue(aPos); if (fExpected != fActual)
{
cerr << "Wrong value in A" << (i + 2) << ": expected=" << fExpected
<< ", actual=" << fActual << endl; returnfalse;
}
aPos.IncCol();
ScFormulaCell* pFC = rDoc.GetFormulaCell(aPos); if (!pFC)
{
cerr << "B" << (i + 2) << " should be a formula cell." << endl; returnfalse;
}
OUString aFormula = pFC->GetCode()->CreateString(aCxt, aPos);
aExpected = "Coefficients!RC[-1]"; if (aFormula != aExpected)
{
cerr << "Wrong formula in B" << (i + 2) << ": expected='" << aExpected
<< "', actual='" << aFormula << "'" << endl; returnfalse;
}
fActual = rDoc.GetValue(aPos); if (fExpected != fActual)
{
cerr << "Wrong value in B" << (i + 2) << ": expected=" << fExpected
<< ", actual=" << fActual << endl; returnfalse;
}
}
returntrue;
}
} aTest;
createScDoc("ods/shared-formula/3d-reference.ods");
{ // Check the content of the original.
ScDocument* pDoc = getScDoc(); bool bRes = aTest.checkContent(*pDoc);
CPPUNIT_ASSERT_MESSAGE("Content check on the original document failed.", bRes);
}
saveAndReload(u"MS Excel 97"_ustr);
// Check the content of the reloaded. This should be identical.
ScDocument* pDoc = getScDoc(); bool bRes = aTest.checkContent(*pDoc);
CPPUNIT_ASSERT_MESSAGE("Content check on the reloaded document failed.", bRes);
}
// Make sure the sheet tab colors are not set. for (SCROW i = 0; i <= 1; ++i)
{
Color aTabBgColor = rDoc.GetTabBgColor(i); if (aTabBgColor != COL_AUTO)
{
cerr << "The tab color of Sheet " << (i + 1) << " should not be explicitly set."
<< endl; returnfalse;
}
}
// B2:B7 should show 1,2,3,4,5,6. double fExpected = 1.0; for (SCROW i = 1; i <= 6; ++i, ++fExpected)
{
ScAddress aPos(1, i, 0); double fVal = rDoc.GetValue(aPos); if (fVal != fExpected)
{
cerr << "Wrong value in B" << (i + 1) << ": expected=" << fExpected
<< ", actual=" << fVal << endl; returnfalse;
}
}
// C2:C7 should show 10,20,...,60.
fExpected = 10.0; for (SCROW i = 1; i <= 6; ++i, fExpected += 10.0)
{
ScAddress aPos(2, i, 0); double fVal = rDoc.GetValue(aPos); if (fVal != fExpected)
{
cerr << "Wrong value in C" << (i + 1) << ": expected=" << fExpected
<< ", actual=" << fVal << endl; returnfalse;
}
}
// D2:D7 should show 1,2,...,6.
fExpected = 1.0; for (SCROW i = 1; i <= 6; ++i, ++fExpected)
{
ScAddress aPos(3, i, 0); double fVal = rDoc.GetValue(aPos); if (fVal != fExpected)
{
cerr << "Wrong value in D" << (i + 1) << ": expected=" << fExpected
<< ", actual=" << fVal << endl; returnfalse;
}
}
returntrue;
}
} aTest;
createScDoc("xlsx/shared-formula/3d-reference.xlsx");
{
ScDocument* pDoc = getScDoc(); bool bRes = aTest.checkContent(*pDoc);
CPPUNIT_ASSERT_MESSAGE("Content check on the initial document failed.", bRes);
pDoc->CalcAll(); // Recalculate to flush all cached results.
bRes = aTest.checkContent(*pDoc);
CPPUNIT_ASSERT_MESSAGE("Content check on the initial recalculated document failed.", bRes);
}
// Save and reload, and check the content again.
saveAndReload(u"Calc Office Open XML"_ustr);
ScDocument* pDoc = getScDoc();
pDoc->CalcAll(); // Recalculate to flush all cached results.
bool bRes = aTest.checkContent(*pDoc);
CPPUNIT_ASSERT_MESSAGE("Content check on the reloaded document failed.", bRes);
}
CPPUNIT_TEST_FIXTURE(ScExportTest3, testSharedFormulaStringResultExportXLSX)
{ struct
{ bool checkContent(ScDocument& rDoc)
{
{ // B2:B7 should show A,B,...,F. constchar* const expected[] = { "A", "B", "C", "D", "E", "F" }; for (SCROW i = 0; i <= 5; ++i)
{
ScAddress aPos(1, i + 1, 0);
OUString aStr = rDoc.GetString(aPos);
OUString aExpected = OUString::createFromAscii(expected[i]); if (aStr != aExpected)
{
cerr << "Wrong value in B" << (i + 2) << ": expected='" << aExpected
<< "', actual='" << aStr << "'" << endl; returnfalse;
}
}
}
{ // C2:C7 should show AA,BB,...,FF. constchar* const expected[] = { "AA", "BB", "CC", "DD", "EE", "FF" }; for (SCROW i = 0; i <= 5; ++i)
{
ScAddress aPos(2, i + 1, 0);
OUString aStr = rDoc.GetString(aPos);
OUString aExpected = OUString::createFromAscii(expected[i]); if (aStr != aExpected)
{
cerr << "Wrong value in C" << (i + 2) << ": expected='" << aExpected
<< "', actual='" << aStr << "'" << endl; returnfalse;
}
}
}
// Check content without re-calculation, to test cached formula results. bool bRes = aTest.checkContent(*pDoc);
CPPUNIT_ASSERT_MESSAGE("Content check on the initial document failed.", bRes);
// Now, re-calculate and check the results.
pDoc->CalcAll();
bRes = aTest.checkContent(*pDoc);
CPPUNIT_ASSERT_MESSAGE("Content check on the initial recalculated document failed.", bRes);
} // Reload and check again.
saveAndReload(u"Calc Office Open XML"_ustr);
ScDocument* pDoc = getScDoc();
bool bRes = aTest.checkContent(*pDoc);
CPPUNIT_ASSERT_MESSAGE("Content check on the reloaded document failed.", bRes);
}
saveAndReload(sFormatType);
ScDocument* pDoc = getScDoc();
pDoc->CalcAll(); // perform hard re-calculation.
testCeilingFloor_Impl(*pDoc);
}
CPPUNIT_TEST_FIXTURE(ScExportTest3, testCeilingFloorXLSX)
{
testCeilingFloor(u"Calc Office Open XML"_ustr);
}
CPPUNIT_TEST_FIXTURE(ScExportTest3, testCeilingFloorODSToXLSX)
{ // tdf#100011 - Cannot open sheet containing FLOOR/CEILING functions by MS Excel, after export to .xlsx
createScDoc("ods/ceiling-floor.ods");
save(u"Calc Office Open XML"_ustr);
xmlDocUniquePtr pSheet = parseExport(u"xl/workbook.xml"_ustr);
CPPUNIT_ASSERT(pSheet);
// there shouldn't be any defined names during export of FLOOR and CEILING functions to .xlsx
assertXPath(pSheet, "/x:workbook/x:definedNames", 0);
}
// Check there is a relation to itemProps1.xml.
assertXPath(pRelsDoc, "/rels:Relationships/rels:Relationship", 1);
assertXPath(pRelsDoc, "/rels:Relationships/rels:Relationship[@Id='rId1']", "Target",
u"itemProps1.xml");
save(u"calc8"_ustr);
xmlDocUniquePtr pDoc = parseExport(u"content.xml"_ustr);
CPPUNIT_ASSERT(pDoc);
OUString aURL = getXPath(pDoc, "/office:document-content/office:body/office:spreadsheet/table:table/" "table:table-row[2]/table:table-cell[2]/text:p/text:a", "href"); #ifdef _WIN32 // if the exported document is not on the same drive then the linked document, // there is no way to get a relative URL for the link, because ../X:/ is undefined. if (!aURL.startsWith(".."))
{
sal_Unicode aDocDrive = lcl_getWindowsDrive(maTempFile.GetURL());
sal_Unicode aLinkDrive = lcl_getWindowsDrive(aURL);
CPPUNIT_ASSERT_MESSAGE("document on the same drive but no relative link!", aDocDrive != 0);
CPPUNIT_ASSERT_MESSAGE("document on the same drive but no relative link!", aLinkDrive != 0);
CPPUNIT_ASSERT_MESSAGE("document on the same drive but no relative link!",
aDocDrive != aLinkDrive); return;
} #endif // make sure that the URL is relative
CPPUNIT_ASSERT(aURL.startsWith(".."));
}
for (size_t i = 0; i < aFilterNames.size(); ++i)
{ // Check whether the export code swaps in the image which was swapped out before.
createScDoc("ods/document_with_two_images.ods");
const OString sFailedMessage
= OString::Concat("Failed on filter: ") + aFilterNames[i].toUtf8();
// Export the document and import again for a check
saveAndReload(aFilterNames[i]);
// Check whether graphic exported well after it was swapped out
uno::Reference<sheet::XSpreadsheetDocument> xDoc(mxComponent, UNO_QUERY_THROW);
uno::Reference<container::XIndexAccess> xIA(xDoc->getSheets(), UNO_QUERY_THROW);
uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(xIA->getByIndex(0),
UNO_QUERY_THROW);
uno::Reference<container::XIndexAccess> xDraws(xDrawPageSupplier->getDrawPage(),
UNO_QUERY_THROW);
CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), static_cast<sal_Int32>(2),
xDraws->getCount());
CPPUNIT_TEST_FIXTURE(ScExportTest3, testLinkedGraphicRT)
{ // Problem was with linked images
std::vector<OUString> aFilterNames{ u"calc8"_ustr, u"MS Excel 97"_ustr,
u"Calc Office Open XML"_ustr };
for (size_t i = 0; i < aFilterNames.size(); ++i)
{ // Load the original file with one image
createScDoc("ods/document_with_linked_graphic.ods"); const OString sFailedMessage
= OString::Concat("Failed on filter: ") + aFilterNames[i].toUtf8();
// Export the document and import again for a check
saveAndReload(aFilterNames[i]);
ScDocument* pDoc = getScDoc();
ScRangeData* pRangeData = pDoc->GetRangeName()->findByUpperName(u"HTML_1"_ustr);
ScSingleRefData* pRef = pRangeData->GetCode()->FirstToken()->GetSingleRef(); // see tdf#119141 for the reason why this isn't Sheet1.HTML_1
CPPUNIT_ASSERT_MESSAGE("HTML_1 is an absolute reference", !pRef->IsTabRel());
}
// Without the fix in place, this test would have failed with // - Expected: Character 0x16 is here ->><<-- // - Actual :
CPPUNIT_ASSERT_EQUAL(u"Character 0x16 is here ->><<--"_ustr, pDoc->GetString(1, 0, 0));
CPPUNIT_ASSERT_EQUAL(u"File opens in libre office, but can't be saved as xlsx"_ustr,
pDoc->GetString(2, 0, 0));
CPPUNIT_ASSERT_EQUAL(u"row 2"_ustr, pDoc->GetString(0, 1, 0));
CPPUNIT_ASSERT_EQUAL(u"Subsequent rows get truncated"_ustr, pDoc->GetString(1, 1, 0));
CPPUNIT_ASSERT_EQUAL(u"This cell goes missing"_ustr, pDoc->GetString(2, 1, 0));
CPPUNIT_ASSERT_EQUAL(u"row 3"_ustr, pDoc->GetString(0, 2, 0));
CPPUNIT_ASSERT_EQUAL(u"Subsequent rows get truncated"_ustr, pDoc->GetString(1, 2, 0));
CPPUNIT_ASSERT_EQUAL(u"This cell goes missing"_ustr, pDoc->GetString(2, 2, 0));
}
save(u"Calc Office Open XML"_ustr);
xmlDocUniquePtr pDoc = parseExport(u"xl/drawings/drawing1.xml"_ustr);
CPPUNIT_ASSERT(pDoc);
OUString fontSize = getXPath(
pDoc, "/xdr:wsDr/xdr:twoCellAnchor/xdr:sp[1]/xdr:txBody/a:p[1]/a:r[1]/a:rPr", "sz"); // make sure that the font size is 18
CPPUNIT_ASSERT_EQUAL(u"1800"_ustr, fontSize);
}
save(u"Calc Office Open XML"_ustr);
xmlDocUniquePtr pDoc = parseExport(u"xl/drawings/drawing1.xml"_ustr);
CPPUNIT_ASSERT(pDoc); // Make sure the underline type is double line
assertXPath(pDoc, "/xdr:wsDr/xdr:twoCellAnchor[1]/xdr:sp[1]/xdr:txBody/a:p[1]/a:r[1]/a:rPr", "u", u"dbl");
assertXPath(pDoc, "/xdr:wsDr/xdr:twoCellAnchor[1]/xdr:sp[1]/xdr:txBody/a:p[1]/a:r[1]/a:rPr", "b", u"1"); // Make sure that the underline color is RED
assertXPath(pDoc, "/xdr:wsDr/xdr:twoCellAnchor[1]/xdr:sp[1]/xdr:txBody/a:p[1]/a:r[1]/a:rPr/a:uFill/" "a:solidFill/a:srgbClr", "val", u"ff0000");
// Make sure the underline type is drawn with heavy line
assertXPath(pDoc, "/xdr:wsDr/xdr:twoCellAnchor[2]/xdr:sp[1]/xdr:txBody/a:p[1]/a:r[1]/a:rPr", "u", u"heavy"); // tdf#104219 Make sure that uFill is not existing and uFillTx is set. // It mean that color is automatic, should be the same color as the text.
assertXPath(
pDoc, "/xdr:wsDr/xdr:twoCellAnchor[2]/xdr:sp[1]/xdr:txBody/a:p[1]/a:r[1]/a:rPr/a:uFill", 0);
assertXPath(pDoc, "/xdr:wsDr/xdr:twoCellAnchor[2]/xdr:sp[1]/xdr:txBody/a:p[1]/a:r[1]/a:rPr/a:uFillTx",
1);
}
// tdf#158460: ensure B1 is NOT set to wrap text, so Excel keeps displaying as single line
SCTAB nTab = 0;
SCROW nRow = 0;
CPPUNIT_ASSERT(!getScDoc()->GetAttr(1, nRow, nTab, ATTR_LINEBREAK)->GetValue()); // Without the fix, this wrapped to two lines high (841). It should be 1 line high (529). int nHeight = convertTwipToMm100(getScDoc()->GetRowHeight(nRow, nTab, false));
CPPUNIT_ASSERT_LESS(600, nHeight);
}
// There are two cell-anchored objects on the first sheet.
ScDocument* pDoc = getScDoc();
CPPUNIT_ASSERT_MESSAGE("There should be at least one sheet.", pDoc->GetTableCount() > 0);
ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer();
SdrPage* pPage = pDrawLayer->GetPage(0);
CPPUNIT_ASSERT_MESSAGE("draw page for sheet 1 should exist.", pPage);
SdrObject* pObj = pPage->GetObj(0);
CPPUNIT_ASSERT_MESSAGE("Failed to get drawing object.", pObj);
// Check cell anchor state
ScAnchorType oldType = ScDrawLayer::GetAnchorType(*pObj);
CPPUNIT_ASSERT_EQUAL_MESSAGE("Failed to get anchor type", SCA_CELL_RESIZE, oldType);
// Get anchor data
ScDrawObjData* pData = ScDrawLayer::GetObjData(pObj);
CPPUNIT_ASSERT_MESSAGE("Failed to retrieve user data for this object.", pData);
CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.",
!pData->getShapeRect().IsEmpty());
// Get non rotated anchor data
ScDrawObjData* pNData = ScDrawLayer::GetNonRotatedObjData(pObj);
CPPUNIT_ASSERT_MESSAGE("Failed to retrieve non rotated user data for this object.", pNData);
CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.",
!pNData->getShapeRect().IsEmpty());
// Get anchor data
pData = ScDrawLayer::GetObjData(pObj);
CPPUNIT_ASSERT_MESSAGE("Failed to retrieve user data for this object.", pData);
CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.",
!pData->getShapeRect().IsEmpty());
// Get non rotated anchor data
pNData = ScDrawLayer::GetNonRotatedObjData(pObj);
CPPUNIT_ASSERT_MESSAGE("Failed to retrieve non rotated user data for this object.", pNData);
CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.",
!pNData->getShapeRect().IsEmpty());
// Check if data has moved to new rows
CPPUNIT_ASSERT_EQUAL(pData->maStart.Row(), aDataStart.Row() + 2);
CPPUNIT_ASSERT_EQUAL(pData->maEnd.Row(), aDataEnd.Row() + 2);
// Save the anchor data
aDataStart = pData->maStart;
aDataEnd = pData->maEnd;
aNDataStart = pNData->maStart;
aNDataEnd = pNData->maEnd;
// Save the document and load again to check anchor persist
saveAndReload(u"calc8"_ustr);
// There are two cell-anchored objects on the first sheet.
pDoc = getScDoc();
CPPUNIT_ASSERT_MESSAGE("There should be at least one sheet.", pDoc->GetTableCount() > 0);
pDrawLayer = pDoc->GetDrawLayer();
pPage = pDrawLayer->GetPage(0);
CPPUNIT_ASSERT_MESSAGE("draw page for sheet 1 should exist.", pPage);
pObj = pPage->GetObj(0);
CPPUNIT_ASSERT_MESSAGE("Failed to get drawing object.", pObj);
// Check cell anchor state
oldType = ScDrawLayer::GetAnchorType(*pObj);
CPPUNIT_ASSERT_EQUAL_MESSAGE("Failed to get anchor type", SCA_CELL_RESIZE, oldType);
// Get anchor data
pData = ScDrawLayer::GetObjData(pObj);
CPPUNIT_ASSERT_MESSAGE("Failed to retrieve user data for this object.", pData);
CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.",
!pData->getShapeRect().IsEmpty());
// Get non rotated anchor data
pNData = ScDrawLayer::GetNonRotatedObjData(pObj);
CPPUNIT_ASSERT_MESSAGE("Failed to retrieve non rotated user data for this object.", pNData);
CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.",
!pNData->getShapeRect().IsEmpty());
// Check if data after save it
CPPUNIT_ASSERT_EQUAL(pData->maStart, aDataStart);
CPPUNIT_ASSERT_EQUAL(pData->maEnd, aDataEnd);
// Insert a column.
pDoc->InsertCol(ScRange(aDataStart.Col(), 0, 0, aDataStart.Col(), pDoc->MaxRow(), 0));
// Get anchor data
pData = ScDrawLayer::GetObjData(pObj);
CPPUNIT_ASSERT_MESSAGE("Failed to retrieve user data for this object.", pData);
CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.",
!pData->getShapeRect().IsEmpty());
// Get non rotated anchor data
pNData = ScDrawLayer::GetNonRotatedObjData(pObj);
CPPUNIT_ASSERT_MESSAGE("Failed to retrieve non rotated user data for this object.", pNData);
CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.",
!pNData->getShapeRect().IsEmpty());
// Check if data has moved to new rows
CPPUNIT_ASSERT_EQUAL(pData->maStart.Col(), SCCOL(aDataStart.Col() + 1));
CPPUNIT_ASSERT_EQUAL(pData->maEnd.Col(), SCCOL(aDataEnd.Col() + 1));
// Save the anchor data
aDataStart = pData->maStart;
aDataEnd = pData->maEnd;
aNDataStart = pNData->maStart;
aNDataEnd = pNData->maEnd;
// Save the document and load again to check anchor persist
saveAndReload(u"calc8"_ustr);
// There are two cell-anchored objects on the first sheet.
pDoc = getScDoc();
CPPUNIT_ASSERT_MESSAGE("There should be at least one sheet.", pDoc->GetTableCount() > 0);
pDrawLayer = pDoc->GetDrawLayer();
pPage = pDrawLayer->GetPage(0);
CPPUNIT_ASSERT_MESSAGE("draw page for sheet 1 should exist.", pPage);
pObj = pPage->GetObj(0);
CPPUNIT_ASSERT_MESSAGE("Failed to get drawing object.", pObj);
// Check cell anchor state
oldType = ScDrawLayer::GetAnchorType(*pObj);
CPPUNIT_ASSERT_EQUAL_MESSAGE("Failed to get anchor type", SCA_CELL_RESIZE, oldType);
// Get anchor data
pData = ScDrawLayer::GetObjData(pObj);
CPPUNIT_ASSERT_MESSAGE("Failed to retrieve user data for this object.", pData);
CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.",
!pData->getShapeRect().IsEmpty());
// Get non rotated anchor data
pNData = ScDrawLayer::GetNonRotatedObjData(pObj);
CPPUNIT_ASSERT_MESSAGE("Failed to retrieve non rotated user data for this object.", pNData);
CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.",
!pNData->getShapeRect().IsEmpty());
// Check if data after save it
CPPUNIT_ASSERT_EQUAL(pData->maStart, aDataStart);
CPPUNIT_ASSERT_EQUAL(pData->maEnd, aDataEnd);
CPPUNIT_TEST_FIXTURE(ScExportTest3, testConditionalFormatPriorityCheckXLSX)
{
createScDoc("xlsx/conditional_fmt_checkpriority.xlsx");
save(u"Calc Office Open XML"_ustr);
xmlDocUniquePtr pDoc = parseExport(u"xl/worksheets/sheet1.xml"_ustr);
CPPUNIT_ASSERT(pDoc);
constexpr bool bHighPriorityExtensionA1
= true; // Should A1's extension cfRule has higher priority than normal cfRule ?
constexpr bool bHighPriorityExtensionA3
= false; // Should A3's extension cfRule has higher priority than normal cfRule ?
size_t nA1NormalPriority = 0;
size_t nA1ExtPriority = 0;
size_t nA3NormalPriority = 0;
size_t nA3ExtPriority = 0; for (size_t nIdx = 1; nIdx <= 2; ++nIdx)
{
OString aIdx = OString::number(nIdx);
OUString aCellAddr = getXPath(pDoc, "//x:conditionalFormatting[" + aIdx + "]", "sqref");
OUString aPriority
= getXPath(pDoc, "//x:conditionalFormatting[" + aIdx + "]/x:cfRule", "priority");
CPPUNIT_ASSERT_MESSAGE("conditionalFormatting sqref must be either A1 or A3",
aCellAddr == "A1" || aCellAddr == "A3"); if (aCellAddr == "A1")
nA1NormalPriority = aPriority.toUInt32(); else
nA3NormalPriority = aPriority.toUInt32();
aCellAddr = getXPathContent(
pDoc, "//x:extLst/x:ext[1]/x14:conditionalFormattings/x14:conditionalFormatting[" + aIdx
+ "]/xm:sqref");
aPriority
= getXPath(pDoc, "//x:extLst/x:ext[1]/x14:conditionalFormattings/x14:conditionalFormatting["
+ aIdx + "]/x14:cfRule", "priority");
CPPUNIT_ASSERT_MESSAGE("x14:conditionalFormatting sqref must be either A1 or A3",
aCellAddr == "A1" || aCellAddr == "A3"); if (aCellAddr == "A1")
nA1ExtPriority = aPriority.toUInt32(); else
nA3ExtPriority = aPriority.toUInt32();
}
CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong priorities for A1", bHighPriorityExtensionA1,
nA1ExtPriority < nA1NormalPriority);
CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong priorities for A3", bHighPriorityExtensionA3,
nA3ExtPriority < nA3NormalPriority);
}
CPPUNIT_TEST_FIXTURE(ScExportTest3, testConditionalFormatOriginXLSX)
{
createScDoc("xlsx/conditional_fmt_origin.xlsx");
save(u"Calc Office Open XML"_ustr);
xmlDocUniquePtr pDoc = parseExport(u"xl/worksheets/sheet1.xml"_ustr);
CPPUNIT_ASSERT(pDoc); // tdf#124953 : The range-list is B3:C6 F1:G2, origin address in the formula should be B1, not B3.
OUString aFormula = getXPathContent(pDoc, "//x:conditionalFormatting/x:cfRule/x:formula");
CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong origin address in formula",
u"NOT(ISERROR(SEARCH(\"BAC\",B1)))"_ustr, aFormula);
}
// FILESAVE: XLSX export with long sheet names (length > 31 characters)
CPPUNIT_TEST_FIXTURE(ScExportTest3, testTdf79998)
{ // check: original document has tab name > 31 characters
createScDoc("ods/tdf79998.ods");
ScDocument* pDoc = getScDoc(); const std::vector<OUString> aTabNames1 = pDoc->GetAllTableNames();
CPPUNIT_ASSERT_EQUAL(u"Utilities (FX Kurse, Kreditkarten etc)"_ustr, aTabNames1[1]);
// check: saved XLSX document has truncated tab name
saveAndReload(u"Calc Office Open XML"_ustr);
pDoc = getScDoc(); const std::vector<OUString> aTabNames2 = pDoc->GetAllTableNames();
CPPUNIT_ASSERT_EQUAL(u"Utilities (FX Kurse, Kreditkart"_ustr, aTabNames2[1]);
}
CPPUNIT_TEST_FIXTURE(ScExportTest3, testLegacyCellAnchoredRotatedShape)
{
{ // This example doc contains cell anchored shape that is rotated, the // rotated shape is in fact clipped by the sheet boundaries (and thus // is a good edge case test to see if we import it still correctly)
createScDoc("ods/legacycellanchoredrotatedclippedshape.ods");
ScDocument* pDoc = getScDoc(); // ensure the imported legacy rotated shape is in the expected position
tools::Rectangle aRect(6000, -2000, 8000, 4000); // ensure the imported ( and converted ) anchor ( note we internally now store the anchor in // terms of the rotated shape ) is more or less contains the correct info
ScDrawObjData aAnchor;
aAnchor.maStart.SetRow(0);
aAnchor.maStart.SetCol(5);
aAnchor.maEnd.SetRow(3);
aAnchor.maEnd.SetCol(7);
impl_testLegacyCellAnchoredRotatedShape(*pDoc, aRect, aAnchor); // test save and reload // for some reason having this test in subsequent_export-test.cxx causes // a core dump in editeng ( so moved to here )
saveAndReload(u"calc8"_ustr);
pDoc = getScDoc();
impl_testLegacyCellAnchoredRotatedShape(*pDoc, aRect, aAnchor);
}
{ // This example doc contains cell anchored shape that is rotated, the // rotated shape is in fact clipped by the sheet boundaries, additionally // the shape is completely hidden because the rows the shape occupies // are hidden
createScDoc("ods/legacycellanchoredrotatedhiddenshape.ods");
ScDocument* pDoc = getScDoc(); // ensure the imported legacy rotated shape is in the expected position
tools::Rectangle aRect(6000, -2000, 8000, 4000);
// ensure the imported (and converted) anchor (note we internally now store the anchor in // terms of the rotated shape) is more or less contains the correct info
ScDrawObjData aAnchor;
aAnchor.maStart.SetRow(0);
aAnchor.maStart.SetCol(5);
aAnchor.maEnd.SetRow(3);
aAnchor.maEnd.SetCol(7);
pDoc->ShowRows(0, 9, 0, true); // show relevant rows
pDoc->SetDrawPageSize(0); // trigger recalcpos
impl_testLegacyCellAnchoredRotatedShape(*pDoc, aRect, aAnchor); // test save and reload
saveAndReload(u"calc8"_ustr);
pDoc = getScDoc();
impl_testLegacyCellAnchoredRotatedShape(*pDoc, aRect, aAnchor);
}
{ // This example doc contains cell anchored shape that is rotated
createScDoc("ods/legacycellanchoredrotatedshape.ods");
ScDocument* pDoc = getScDoc(); // ensure the imported legacy rotated shape is in the expected position
tools::Rectangle aRect(6000, 3000, 8000, 9000); // ensure the imported (and converted) anchor (note we internally now store the anchor in // terms of the rotated shape) more or less contains the correct info
ScDrawObjData aAnchor;
aAnchor.maStart.SetRow(3);
aAnchor.maStart.SetCol(6);
aAnchor.maEnd.SetRow(9);
aAnchor.maEnd.SetCol(8); // test import
impl_testLegacyCellAnchoredRotatedShape(*pDoc, aRect, aAnchor); // test save and reload
saveAndReload(u"calc8"_ustr);
pDoc = getScDoc();
impl_testLegacyCellAnchoredRotatedShape(*pDoc, aRect, aAnchor);
}
}
CPPUNIT_TEST_FIXTURE(ScExportTest3, testTdf137576_Measureline)
{ // The document contains a vertical measure line, anchored "To Cell (resize with cell)" with // length 37mm. Save and reload had resulted in a line of 0mm length.
// Get document
createScDoc("ods/tdf137576_Measureline.ods");
ScDocument* pDoc = getScDoc();
// Get shape
ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer();
CPPUNIT_ASSERT_MESSAGE("Load: No ScDrawLayer", pDrawLayer);
SdrPage* pPage = pDrawLayer->GetPage(0);
CPPUNIT_ASSERT_MESSAGE("Load: No draw page", pPage);
SdrMeasureObj* pObj = static_cast<SdrMeasureObj*>(pPage->GetObj(0));
CPPUNIT_ASSERT_MESSAGE("Load: No measure object", pObj);
// Check start and end point of measureline const Point aStart = pObj->GetPoint(0);
CPPUNIT_ASSERT_POINT_EQUAL_WITH_TOLERANCE(Point(4800, 1500), aStart, 1); const Point aEnd = pObj->GetPoint(1);
CPPUNIT_ASSERT_POINT_EQUAL_WITH_TOLERANCE(Point(4800, 5200), aEnd, 1);
// Save and reload
saveAndReload(u"calc8"_ustr);
pDoc = getScDoc();
// Get shape
pDrawLayer = pDoc->GetDrawLayer();
CPPUNIT_ASSERT_MESSAGE("Reload: No ScDrawLayer", pDrawLayer);
pPage = pDrawLayer->GetPage(0);
CPPUNIT_ASSERT_MESSAGE("Reload: No draw page", pPage);
pObj = static_cast<SdrMeasureObj*>(pPage->GetObj(0));
CPPUNIT_ASSERT_MESSAGE("Reload: No measure object", pObj);
// Check start and end point of measureline, should be unchanged const Point aStart2 = pObj->GetPoint(0);
CPPUNIT_ASSERT_POINT_EQUAL_WITH_TOLERANCE(Point(4800, 1500), aStart2, 1); const Point aEnd2 = pObj->GetPoint(1);
CPPUNIT_ASSERT_POINT_EQUAL_WITH_TOLERANCE(Point(4800, 5200), aEnd2, 1);
}
CPPUNIT_TEST_FIXTURE(ScExportTest3, testTdf137044_CoverHiddenRows)
{ // The document contains a shape anchored "To Cell (resize with cell)" with start in cell A4 and // end in cell A7. Row height is 30mm. Hiding rows 5 and 6, then saving and reload had resulted // in a wrong end cell offset and thus a wrong height of the shape.
// Get document
createScDoc("ods/tdf137044_CoverHiddenRows.ods");
ScDocument* pDoc = getScDoc();
// Get shape
ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer();
CPPUNIT_ASSERT_MESSAGE("Load: No ScDrawLayer", pDrawLayer);
SdrPage* pPage = pDrawLayer->GetPage(0);
CPPUNIT_ASSERT_MESSAGE("Load: No draw page", pPage);
SdrObject* pObj = pPage->GetObj(0);
CPPUNIT_ASSERT_MESSAGE("Load: No object", pObj);
// Get original object values
tools::Rectangle aSnapRectOrig = pObj->GetSnapRect();
Point aOriginalEndOffset = ScDrawLayer::GetObjData(pObj)->maEndOffset;
CPPUNIT_ASSERT_RECTANGLE_EQUAL_WITH_TOLERANCE(
tools::Rectangle(Point(500, 3500), Size(1501, 11001)), aSnapRectOrig, 1);
CPPUNIT_ASSERT_POINT_EQUAL_WITH_TOLERANCE(Point(2000, 2499), aOriginalEndOffset, 1);
// Hide rows 5 and 6 in UI = row index 4 to 5.
pDoc->SetRowHidden(4, 5, 0, true);
// Save and reload
saveAndReload(u"calc8"_ustr);
pDoc = getScDoc();
// Get shape
pDrawLayer = pDoc->GetDrawLayer();
CPPUNIT_ASSERT_MESSAGE("Reload: No ScDrawLayer", pDrawLayer);
pPage = pDrawLayer->GetPage(0);
CPPUNIT_ASSERT_MESSAGE("Reload: No draw page", pPage);
pObj = pPage->GetObj(0);
CPPUNIT_ASSERT_MESSAGE("Reload: No object", pObj);
// Get new values and compare. End offset should be the same, height should be 6000 smaller.
tools::Rectangle aSnapRectReload = pObj->GetSnapRect();
Point aReloadEndOffset = ScDrawLayer::GetObjData(pObj)->maEndOffset;
CPPUNIT_ASSERT_RECTANGLE_EQUAL_WITH_TOLERANCE(
tools::Rectangle(Point(500, 3500), Size(1501, 5001)), aSnapRectReload, 1);
CPPUNIT_ASSERT_POINT_EQUAL_WITH_TOLERANCE(Point(2000, 2499), aReloadEndOffset, 1);
}
// Vertical mirror on center should not change the snap rect.
pObj->Mirror(aSnapRectOrig.LeftCenter(), aSnapRectOrig.RightCenter()); const tools::Rectangle aSnapRectFlip = pObj->GetSnapRect();
CPPUNIT_ASSERT_RECTANGLE_EQUAL_WITH_TOLERANCE(aSnapRectOrig, aSnapRectFlip, 1);
// Save and reload
saveAndReload(u"calc8"_ustr);
pDoc = getScDoc();
// Get shape
pDrawLayer = pDoc->GetDrawLayer();
CPPUNIT_ASSERT_MESSAGE("Reload: No ScDrawLayer", pDrawLayer);
pPage = pDrawLayer->GetPage(0);
CPPUNIT_ASSERT_MESSAGE("Reload: No draw page", pPage);
pObj = pPage->GetObj(0);
CPPUNIT_ASSERT_MESSAGE("Reload: No object", pObj);
// Check pos and size of shape again, should be unchanged const tools::Rectangle aSnapRectReload = pObj->GetSnapRect();
CPPUNIT_ASSERT_RECTANGLE_EQUAL_WITH_TOLERANCE(aSnapRectOrig, aSnapRectReload, 1);
}
pStream->Seek(0);
CPPUNIT_ASSERT_EQUAL(sal_uInt64(0), pStream->Tell());
pStream->StartReadingUnicodeText(RTL_TEXTENCODING_UTF8); // Without the fix in place, this test would have failed with // - Expected: 3 // - Actual : 0 (no byte order mark was read)
CPPUNIT_ASSERT_EQUAL(sal_uInt64(3), pStream->Tell());
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.