sc/qa/unit/subsequent_export-test.cxx | 183 ++++++++++++++++++++++++++++++++-- sc/source/filter/xml/xmlcelli.cxx | 16 +- sc/source/filter/xml/xmlcelli.hxx | 2 3 files changed, 183 insertions(+), 18 deletions(-)
New commits: commit 969d5a3b97903fe32b3a7da0c3de8bf86f323c17 Author: Kohei Yoshida <kohei.yosh...@gmail.com> Date: Mon Aug 26 15:28:46 2013 -0400 fdo#68581: The first paragraph text can be legitimately empty. Change-Id: I2309a0c6aebc8a111e67e2e3d591cbabfbbadfb4 diff --git a/sc/source/filter/xml/xmlcelli.cxx b/sc/source/filter/xml/xmlcelli.cxx index 69f5a73..1f17009 100644 --- a/sc/source/filter/xml/xmlcelli.cxx +++ b/sc/source/filter/xml/xmlcelli.cxx @@ -600,10 +600,10 @@ void ScXMLTableRowCellContext::PushFormat(sal_Int32 nBegin, sal_Int32 nEnd, cons OUString ScXMLTableRowCellContext::GetFirstParagraph() const { - if (maFirstParagraph.isEmpty()) + if (!maFirstParagraph) return mpEditEngine->GetText(0); - return maFirstParagraph; + return *maFirstParagraph; } void ScXMLTableRowCellContext::PushParagraphFieldDate(const OUString& rStyleName) @@ -635,12 +635,12 @@ void ScXMLTableRowCellContext::PushParagraphEnd() if (mbEditEngineHasText) { - if (!maFirstParagraph.isEmpty()) + if (maFirstParagraph) { // Flush the cached first paragraph first. mpEditEngine->Clear(); - mpEditEngine->SetText(maFirstParagraph); - maFirstParagraph = OUString(); + mpEditEngine->SetText(*maFirstParagraph); + maFirstParagraph.reset(); } mpEditEngine->InsertParagraph(mpEditEngine->GetParagraphCount(), maParagraph.makeStringAndClear()); } @@ -652,7 +652,7 @@ void ScXMLTableRowCellContext::PushParagraphEnd() } else if (mnCurParagraph == 0) { - maFirstParagraph = maParagraph.makeStringAndClear(); + maFirstParagraph.reset(maParagraph.makeStringAndClear()); mbEditEngineHasText = true; } @@ -1089,10 +1089,10 @@ void ScXMLTableRowCellContext::PutTextCell( const ScAddress& rCurrentPos, } else if (mbEditEngineHasText) { - if (!maFirstParagraph.isEmpty()) + if (maFirstParagraph) { // This is a normal text without format runs. - rDoc.setStringCell(rCurrentPos, maFirstParagraph); + rDoc.setStringCell(rCurrentPos, *maFirstParagraph); } else { diff --git a/sc/source/filter/xml/xmlcelli.hxx b/sc/source/filter/xml/xmlcelli.hxx index e49e3a3..15c95fb 100644 --- a/sc/source/filter/xml/xmlcelli.hxx +++ b/sc/source/filter/xml/xmlcelli.hxx @@ -63,9 +63,9 @@ class ScXMLTableRowCellContext : public ScXMLImportContext boost::optional<FormulaWithNamespace> maFormula; /// table:formula attribute boost::optional<OUString> maStringValue; /// office:string-value attribute boost::optional<OUString> maContentValidationName; + boost::optional<OUString> maFirstParagraph; /// unformatted first paragraph, for better performance. ScEditEngineDefaulter* mpEditEngine; - OUString maFirstParagraph; /// unformatted first paragraph, for better performance. OUStringBuffer maParagraph; sal_Int32 mnCurParagraph; commit 70e582c8cd3f5f0eedfead6c9da8c771db34e49b Author: Kohei Yoshida <kohei.yosh...@gmail.com> Date: Mon Aug 26 15:11:33 2013 -0400 Add more test cases for rich text cell export to ODS. This currently fails due to a real bug. Change-Id: Ia8a91f0794837cae2b6c3beab656f3377f3d0f6a diff --git a/sc/qa/unit/subsequent_export-test.cxx b/sc/qa/unit/subsequent_export-test.cxx index 6ec6550..b805e4f 100644 --- a/sc/qa/unit/subsequent_export-test.cxx +++ b/sc/qa/unit/subsequent_export-test.cxx @@ -36,6 +36,8 @@ #include "editeng/postitem.hxx" #include "editeng/editdata.hxx" #include "editeng/eeitem.hxx" +#include "editeng/editobj.hxx" +#include "editeng/sectionattribute.hxx" using namespace ::com::sun::star; using namespace ::com::sun::star::uno; @@ -343,10 +345,140 @@ void ScExportTest::testNamedRangeBugfdo62729() void ScExportTest::testRichTextExportODS() { + struct + { + static bool isBold(const editeng::SectionAttribute& rAttr) + { + if (rAttr.maAttributes.empty()) + return false; + + std::vector<const SfxPoolItem*>::const_iterator it = rAttr.maAttributes.begin(), itEnd = rAttr.maAttributes.end(); + for (; it != itEnd; ++it) + { + const SfxPoolItem* p = *it; + if (p->Which() != EE_CHAR_WEIGHT) + continue; + + return static_cast<const SvxWeightItem*>(p)->GetWeight() == WEIGHT_BOLD; + } + return false; + } + + static bool isItalic(const editeng::SectionAttribute& rAttr) + { + if (rAttr.maAttributes.empty()) + return false; + + std::vector<const SfxPoolItem*>::const_iterator it = rAttr.maAttributes.begin(), itEnd = rAttr.maAttributes.end(); + for (; it != itEnd; ++it) + { + const SfxPoolItem* p = *it; + if (p->Which() != EE_CHAR_ITALIC) + continue; + + return static_cast<const SvxPostureItem*>(p)->GetPosture() == ITALIC_NORMAL; + } + return false; + } + + bool checkB2(const EditTextObject* pText) const + { + if (!pText) + return false; + + if (pText->GetParagraphCount() != 1) + return false; + + if (pText->GetText(0) != "Bold and Italic") + return false; + + std::vector<editeng::SectionAttribute> aSecAttrs; + pText->GetAllSectionAttributes(aSecAttrs); + if (aSecAttrs.size() != 3) + return false; + + // Check the first bold section. + const editeng::SectionAttribute* pAttr = &aSecAttrs[0]; + if (pAttr->mnParagraph != 0 ||pAttr->mnStart != 0 || pAttr->mnEnd != 4) + return false; + + if (pAttr->maAttributes.size() != 1 || !isBold(*pAttr)) + return false; + + // The middle section should be unformatted. + pAttr = &aSecAttrs[1]; + if (pAttr->mnParagraph != 0 ||pAttr->mnStart != 4 || pAttr->mnEnd != 9) + return false; + + if (!pAttr->maAttributes.empty()) + return false; + + // The last section should be italic. + pAttr = &aSecAttrs[2]; + if (pAttr->mnParagraph != 0 ||pAttr->mnStart != 9 || pAttr->mnEnd != 15) + return false; + + if (pAttr->maAttributes.size() != 1 || !isItalic(*pAttr)) + return false; + + return true; + } + + bool checkB4(const EditTextObject* pText) const + { + if (!pText) + return false; + + if (pText->GetParagraphCount() != 3) + return false; + + if (pText->GetText(0) != "One") + return false; + + if (pText->GetText(1) != "Two") + return false; + + if (pText->GetText(2) != "Three") + return false; + + return true; + } + + bool checkB5(const EditTextObject* pText) const + { + if (!pText) + return false; + + if (pText->GetParagraphCount() != 6) + return false; + + if (pText->GetText(0) != "") + return false; + + if (pText->GetText(1) != "Two") + return false; + + if (pText->GetText(2) != "Three") + return false; + + if (pText->GetText(3) != "") + return false; + + if (pText->GetText(4) != "Five") + return false; + + if (pText->GetText(5) != "") + return false; + + return true; + } + + } aCheckFunc; + // Start with an empty document, put one edit text cell, and make sure it // survives the save and reload. - ScDocShellRef xNewDocSh = loadDoc("empty.", ODS); - ScDocument* pDoc = xNewDocSh->GetDocument(); + ScDocShellRef xOrigDocSh = loadDoc("empty.", ODS); + ScDocument* pDoc = xOrigDocSh->GetDocument(); CPPUNIT_ASSERT(pDoc); CPPUNIT_ASSERT_MESSAGE("This document should at least have one sheet.", pDoc->GetTableCount() > 0); @@ -380,23 +512,56 @@ void ScExportTest::testRichTextExportODS() // Set this edit text to cell B2. pDoc->SetEditText(ScAddress(1,1,0), rEE.CreateTextObject()); const EditTextObject* pEditText = pDoc->GetEditText(ScAddress(1,1,0)); - CPPUNIT_ASSERT_MESSAGE("B2 should be an edit text.", pEditText); + CPPUNIT_ASSERT_MESSAGE("Incorret B2 value.", aCheckFunc.checkB2(pEditText)); // Now, save and reload this document. - ScDocShellRef xDocSh = saveAndReload(xNewDocSh, ODS); - xNewDocSh->DoClose(); - CPPUNIT_ASSERT(xDocSh.Is()); - pDoc = xDocSh->GetDocument(); + ScDocShellRef xNewDocSh = saveAndReload(xOrigDocSh, ODS); + xOrigDocSh->DoClose(); + CPPUNIT_ASSERT(xNewDocSh.Is()); + pDoc = xNewDocSh->GetDocument(); CPPUNIT_ASSERT(pDoc); CPPUNIT_ASSERT_MESSAGE("Reloaded document should at least have one sheet.", pDoc->GetTableCount() > 0); // Make sure the content of B2 is still intact. - CPPUNIT_ASSERT_EQUAL(aCellText, pDoc->GetString(ScAddress(1,1,0))); + CPPUNIT_ASSERT_MESSAGE("Incorret B2 value.", aCheckFunc.checkB2(pEditText)); + + // Insert a multi-line content to B4. + rEE.Clear(); + rEE.SetText("One\nTwo\nThree"); + pDoc->SetEditText(ScAddress(3,1,0), rEE.CreateTextObject()); + pEditText = pDoc->GetEditText(ScAddress(3,1,0)); + CPPUNIT_ASSERT_MESSAGE("Incorret B4 value.", aCheckFunc.checkB4(pEditText)); + + // Reload the doc again, and check the content of B2 and B4. + ScDocShellRef xNewDocSh2 = saveAndReload(xNewDocSh, ODS); + pDoc = xNewDocSh2->GetDocument(); + xNewDocSh->DoClose(); pEditText = pDoc->GetEditText(ScAddress(1,1,0)); CPPUNIT_ASSERT_MESSAGE("B2 should be an edit text.", pEditText); + pEditText = pDoc->GetEditText(ScAddress(3,1,0)); + CPPUNIT_ASSERT_MESSAGE("Incorret B4 value.", aCheckFunc.checkB4(pEditText)); - xDocSh->DoClose(); + // Insert a multi-line content to B5, but this time, set some empty paragraphs. + rEE.Clear(); + rEE.SetText("\nTwo\nThree\n\nFive\n"); + pDoc->SetEditText(ScAddress(4,1,0), rEE.CreateTextObject()); + pEditText = pDoc->GetEditText(ScAddress(4,1,0)); + CPPUNIT_ASSERT_MESSAGE("Incorret B5 value.", aCheckFunc.checkB5(pEditText)); + + // Reload the doc again, and check the content of B2, B4 and B6. + ScDocShellRef xNewDocSh3 = saveAndReload(xNewDocSh2, ODS); + pDoc = xNewDocSh3->GetDocument(); + xNewDocSh2->DoClose(); + + pEditText = pDoc->GetEditText(ScAddress(1,1,0)); + CPPUNIT_ASSERT_MESSAGE("Incorret B2 value.", aCheckFunc.checkB2(pEditText)); + pEditText = pDoc->GetEditText(ScAddress(3,1,0)); + CPPUNIT_ASSERT_MESSAGE("Incorret B4 value.", aCheckFunc.checkB4(pEditText)); + pEditText = pDoc->GetEditText(ScAddress(4,1,0)); + CPPUNIT_ASSERT_MESSAGE("Incorret B5 value.", aCheckFunc.checkB5(pEditText)); + + xNewDocSh3->DoClose(); } namespace { _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits