sw/qa/extras/ooxmlexport/data/fdo38244.docx |binary sw/qa/extras/ooxmlexport/ooxmlexport.cxx | 68 +++++++++++++++++++++++++ sw/qa/extras/rtfexport/data/fdo38244.rtf | 15 +++++ sw/qa/extras/rtfexport/rtfexport.cxx | 28 ++++++++++ sw/source/filter/ww8/rtfattributeoutput.cxx | 20 ++++++- sw/source/filter/ww8/rtfattributeoutput.hxx | 7 ++ writerfilter/source/rtftok/rtfdocumentimpl.cxx | 48 ++++++++++++++++- writerfilter/source/rtftok/rtfdocumentimpl.hxx | 6 +- 8 files changed, 187 insertions(+), 5 deletions(-)
New commits: commit 5da91ea59329e3993a10c72fa02bc1f1dbf398d8 Author: Miklos Vajna <vmik...@suse.cz> Date: Wed Jul 18 11:43:02 2012 +0200 implement export of RTF_ATNREF, RTF_ATRFSTART and RTF_ATRFEND Change-Id: I829ec1fbca990f3d42121270f0bf3647dbd08a30 diff --git a/sw/qa/extras/rtfexport/data/fdo38244.rtf b/sw/qa/extras/rtfexport/data/fdo38244.rtf new file mode 100644 index 0000000..1db8ee1 --- /dev/null +++ b/sw/qa/extras/rtfexport/data/fdo38244.rtf @@ -0,0 +1,15 @@ +{\rtf1\pard\plain +aaa +{\*\atrfstart 0} +bbb +{\*\atrfend 0} +{\*\atnid M} +{\*\atnauthor Miklos} +\chatn +{\*\annotation +{\*\atnref 0} +{\*\atndate 0} +Content} + ccc +\par +} diff --git a/sw/qa/extras/rtfexport/rtfexport.cxx b/sw/qa/extras/rtfexport/rtfexport.cxx index 599b5b6..ff23b6a 100644 --- a/sw/qa/extras/rtfexport/rtfexport.cxx +++ b/sw/qa/extras/rtfexport/rtfexport.cxx @@ -50,6 +50,7 @@ public: void testFdo50087(); void testFdo50831(); void testFdo48335(); + void testFdo38244(); CPPUNIT_TEST_SUITE(Test); #if !defined(MACOSX) && !defined(WNT) @@ -60,6 +61,7 @@ public: CPPUNIT_TEST(testFdo50087); CPPUNIT_TEST(testFdo50831); CPPUNIT_TEST(testFdo48335); + CPPUNIT_TEST(testFdo38244); #endif CPPUNIT_TEST_SUITE_END(); @@ -174,6 +176,32 @@ void Test::testFdo48335() CPPUNIT_ASSERT_EQUAL(OUString("SoftPageBreak"), aValue); } +void Test::testFdo38244() +{ + // See ooxmlexport's testFdo38244(). + roundtrip("fdo38244.rtf"); + + // Test comment range feature. + uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY); + uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xTextDocument->getText(), uno::UNO_QUERY); + uno::Reference<container::XEnumeration> xParaEnum = xParaEnumAccess->createEnumeration(); + uno::Reference<container::XEnumerationAccess> xRunEnumAccess(xParaEnum->nextElement(), uno::UNO_QUERY); + uno::Reference<container::XEnumeration> xRunEnum = xRunEnumAccess->createEnumeration(); + xRunEnum->nextElement(); + uno::Reference<beans::XPropertySet> xPropertySet(xRunEnum->nextElement(), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(OUString("TextFieldStart"), getProperty<OUString>(xPropertySet, "TextPortionType")); + xRunEnum->nextElement(); + xPropertySet.set(xRunEnum->nextElement(), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(OUString("TextFieldEnd"), getProperty<OUString>(xPropertySet, "TextPortionType")); + + // Test initials. + uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference<container::XEnumerationAccess> xFieldsAccess(xTextFieldsSupplier->getTextFields()); + uno::Reference<container::XEnumeration> xFields(xFieldsAccess->createEnumeration()); + xPropertySet.set(xFields->nextElement(), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(OUString("M"), getProperty<OUString>(xPropertySet, "Initials")); +} + CPPUNIT_TEST_SUITE_REGISTRATION(Test); CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/sw/source/filter/ww8/rtfattributeoutput.cxx b/sw/source/filter/ww8/rtfattributeoutput.cxx index 5957606..5019f18 100644 --- a/sw/source/filter/ww8/rtfattributeoutput.cxx +++ b/sw/source/filter/ww8/rtfattributeoutput.cxx @@ -3002,7 +3002,7 @@ void RtfAttributeOutput::PostitField( const SwField* pFld ) const SwPostItField& rPFld = *(SwPostItField*)pFld; m_aRunText->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_ATNID " "); - m_aRunText->append(OUStringToOString(OUString(rPFld.GetPar1()), m_rExport.eCurrentEncoding)); + m_aRunText->append(OUStringToOString(OUString(rPFld.GetInitials()), m_rExport.eCurrentEncoding)); m_aRunText->append("}"); m_aRunText->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_ATNAUTHOR " "); m_aRunText->append(OUStringToOString(OUString(rPFld.GetPar1()), m_rExport.eCurrentEncoding)); @@ -3010,6 +3010,9 @@ void RtfAttributeOutput::PostitField( const SwField* pFld ) m_aRunText->append(OOO_STRING_SVTOOLS_RTF_CHATN); m_aRunText->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_ANNOTATION); + m_aRunText->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_ATNREF " "); + m_aRunText->append(sal_Int32(m_nPostitFieldsMaxId++)); + m_aRunText->append('}'); m_aRunText->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_ATNDATE " "); m_aRunText->append((sal_Int32)sw::ms::DateTime2DTTM(rPFld.GetDateTime())); m_aRunText->append('}'); @@ -3017,6 +3020,20 @@ void RtfAttributeOutput::PostitField( const SwField* pFld ) m_aRunText->append('}'); } +void RtfAttributeOutput::WritePostitFieldStart() +{ + m_aRunText->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_ATRFSTART " "); + m_aRunText->append(sal_Int32(m_nPostitFieldsMaxId)); + m_aRunText->append("}"); +} + +void RtfAttributeOutput::WritePostitFieldEnd() +{ + m_aRunText->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_ATRFEND " "); + m_aRunText->append(sal_Int32(m_nPostitFieldsMaxId)); + m_aRunText->append("}"); +} + bool RtfAttributeOutput::DropdownField( const SwField* /*pFld*/ ) { // this is handled in OutputFlyFrame_Impl() @@ -3040,6 +3057,7 @@ RtfAttributeOutput::RtfAttributeOutput( RtfExport &rExport ) m_aCells(), m_bSingleEmptyRun(false), m_bInRun(false), + m_nPostitFieldsMaxId(0), m_pPrevPageDesc(0) { SAL_INFO("sw.rtf", OSL_THIS_FUNC); diff --git a/sw/source/filter/ww8/rtfattributeoutput.hxx b/sw/source/filter/ww8/rtfattributeoutput.hxx index cf05b97..c9b34bc 100644 --- a/sw/source/filter/ww8/rtfattributeoutput.hxx +++ b/sw/source/filter/ww8/rtfattributeoutput.hxx @@ -75,6 +75,10 @@ public: /// Called after we end outputting the attributes. virtual void EndRunProperties( const SwRedlineData* pRedlineData ); + virtual void WritePostitFieldStart(); + + virtual void WritePostitFieldEnd(); + /// Output text (inside a run). virtual void RunText( const String& rText, rtl_TextEncoding eCharSet = RTL_TEXTENCODING_UTF8 ); @@ -545,6 +549,9 @@ private: bool m_bSingleEmptyRun; bool m_bInRun; + + unsigned int m_nPostitFieldsMaxId; + public: RtfAttributeOutput( RtfExport &rExport ); commit 75bcb45ae2afc04be48871e4978b7d9f15cfbddb Author: Miklos Vajna <vmik...@suse.cz> Date: Tue Jul 17 17:59:09 2012 +0200 implement import of RTF_ATRFSTART, RTF_ATRFEND and RTF_ATNID Change-Id: I1dc3d3a33dcad2707468b1bfc1baa5239fddee05 diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.cxx b/writerfilter/source/rtftok/rtfdocumentimpl.cxx index b3655c5..c7b719e 100644 --- a/writerfilter/source/rtftok/rtfdocumentimpl.cxx +++ b/writerfilter/source/rtftok/rtfdocumentimpl.cxx @@ -280,6 +280,11 @@ void RTFDocumentImpl::setAuthor(rtl::OUString& rAuthor) m_aAuthor = rAuthor; } +void RTFDocumentImpl::setAuthorInitials(rtl::OUString& rAuthorInitials) +{ + m_aAuthorInitials = rAuthorInitials; +} + bool RTFDocumentImpl::isSubstream() const { return m_pSuperstream != 0; @@ -320,6 +325,11 @@ void RTFDocumentImpl::resolveSubstream(sal_uInt32 nPos, Id nId, OUString& rIgnor pImpl->setAuthor(m_aAuthor); m_aAuthor = OUString(); } + if (!m_aAuthorInitials.isEmpty()) + { + pImpl->setAuthorInitials(m_aAuthorInitials); + m_aAuthorInitials = OUString(); + } pImpl->seek(nPos); SAL_INFO("writerfilter", "substream start"); Mapper().substream(nId, pImpl); @@ -932,6 +942,7 @@ void RTFDocumentImpl::text(OUString& rString) case DESTINATION_TITLE: case DESTINATION_SUBJECT: case DESTINATION_DOCCOMM: + case DESTINATION_ATNID: m_aStates.top().aDestinationText.append(rString); break; case DESTINATION_EQINSTRUCTION: @@ -1240,11 +1251,19 @@ int RTFDocumentImpl::dispatchDestination(RTFKeyword nKeyword) else { // If there is an author set, emit it now. - if (!m_aAuthor.isEmpty()) + if (!m_aAuthor.isEmpty() || !m_aAuthorInitials.isEmpty()) { - RTFValue::Pointer_t pValue(new RTFValue(m_aAuthor)); RTFSprms aAttributes; - aAttributes.set(NS_ooxml::LN_CT_TrackChange_author, pValue); + if (!m_aAuthor.isEmpty()) + { + RTFValue::Pointer_t pValue(new RTFValue(m_aAuthor)); + aAttributes.set(NS_ooxml::LN_CT_TrackChange_author, pValue); + } + if (!m_aAuthorInitials.isEmpty()) + { + RTFValue::Pointer_t pValue(new RTFValue(m_aAuthorInitials)); + aAttributes.set(NS_ooxml::LN_CT_Comment_initials, pValue); + } writerfilter::Reference<Properties>::Pointer_t const pProperties(new RTFReferenceProperties(aAttributes)); Mapper().props(pProperties); } @@ -1350,6 +1369,27 @@ int RTFDocumentImpl::dispatchDestination(RTFKeyword nKeyword) case RTF_DOCCOMM: m_aStates.top().nDestinationState = DESTINATION_DOCCOMM; break; + case RTF_ATRFSTART: + case RTF_ATRFEND: + { + // We could send the real value here, but that would make the + // tokenizer more complicated, and dmapper doesn't read the + // result anyway. + RTFValue::Pointer_t pValue(new RTFValue(0)); + m_aStates.top().nDestinationState = DESTINATION_SKIP; + + RTFSprms aAttributes; + if (nKeyword == RTF_ATRFSTART) + aAttributes.set(NS_ooxml::LN_EG_RangeMarkupElements_commentRangeStart, pValue); + else + aAttributes.set(NS_ooxml::LN_EG_RangeMarkupElements_commentRangeEnd, pValue); + writerfilter::Reference<Properties>::Pointer_t const pProperties(new RTFReferenceProperties(aAttributes)); + Mapper().props(pProperties); + } + break; + case RTF_ATNID: + m_aStates.top().nDestinationState = DESTINATION_ATNID; + break; default: SAL_INFO("writerfilter", OSL_THIS_FUNC << ": TODO handle destination '" << lcl_RtfToString(nKeyword) << "'"); // Make sure we skip destinations (even without \*) till we don't handle them @@ -3365,6 +3405,8 @@ int RTFDocumentImpl::popState() } else if (m_aStates.top().nDestinationState == DESTINATION_ANNOTATIONAUTHOR) m_aAuthor = m_aStates.top().aDestinationText.makeStringAndClear(); + else if (m_aStates.top().nDestinationState == DESTINATION_ATNID) + m_aAuthorInitials = m_aStates.top().aDestinationText.makeStringAndClear(); else if (m_aStates.top().nDestinationState == DESTINATION_FALT) { OUString aStr(m_aStates.top().aDestinationText.makeStringAndClear()); diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.hxx b/writerfilter/source/rtftok/rtfdocumentimpl.hxx index 5756b5a..34dddd2 100644 --- a/writerfilter/source/rtftok/rtfdocumentimpl.hxx +++ b/writerfilter/source/rtftok/rtfdocumentimpl.hxx @@ -117,7 +117,8 @@ namespace writerfilter { DESTINATION_PARAGRAPHNUMBERING_TEXTAFTER, DESTINATION_TITLE, DESTINATION_SUBJECT, - DESTINATION_DOCCOMM + DESTINATION_DOCCOMM, + DESTINATION_ATNID }; enum RTFBorderState @@ -355,6 +356,7 @@ namespace writerfilter { void setSubstream(bool bIsSubtream); void setSuperstream(RTFDocumentImpl *pSuperstream); void setAuthor(rtl::OUString& rAuthor); + void setAuthorInitials(rtl::OUString& rAuthorInitials); bool isSubstream() const; void finishSubstream(); void setIgnoreFirst(rtl::OUString& rIgnoreFirst); @@ -481,6 +483,8 @@ namespace writerfilter { std::map<int, rtl::OUString> m_aAuthors; /// Annotation author of the next annotation. rtl::OUString m_aAuthor; + /// Initials of author of the next annotation. + rtl::OUString m_aAuthorInitials; RTFSprms m_aFormfieldSprms; RTFSprms m_aFormfieldAttributes; commit b8146f5126e8290b5b287f0a6176ff6619f34f67 Author: Miklos Vajna <vmik...@suse.cz> Date: Tue Jul 17 13:09:14 2012 +0200 fdo#38244 testcase Change-Id: I6df325a20994f789e4c6acdf5a2912a57a034276 diff --git a/sw/qa/extras/ooxmlexport/data/fdo38244.docx b/sw/qa/extras/ooxmlexport/data/fdo38244.docx new file mode 100644 index 0000000..2551f0c Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/fdo38244.docx differ diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx index 859cc89..c426c37 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx @@ -40,11 +40,13 @@ class Test : public SwModelTestBase public: void testZoom(); void defaultTabStopNotInStyles(); + void testFdo38244(); CPPUNIT_TEST_SUITE(Test); #if !defined(MACOSX) && !defined(WNT) CPPUNIT_TEST(testZoom); CPPUNIT_TEST(defaultTabStopNotInStyles); + CPPUNIT_TEST(testFdo38244); #endif CPPUNIT_TEST_SUITE_END(); @@ -91,6 +93,72 @@ void Test::defaultTabStopNotInStyles() CPPUNIT_ASSERT_EQUAL( static_cast<sal_Int32>(0), stops.getLength()); } +void Test::testFdo38244() +{ + roundtrip("fdo38244.docx"); + + /* + * Comments attached to a range was imported without the range, check for the fieldmark start/end positions. + * + * oParas = ThisComponent.Text.createEnumeration + * oPara = oParas.nextElement + * oRuns = oPara.createEnumeration + * oRun = oRuns.nextElement + * oRun = oRuns.nextElement 'TextFieldStart + * oRun = oRuns.nextElement + * oRun = oRuns.nextElement 'TextFieldEnd + * xray oRun.TextPortionType + */ + uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY); + uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xTextDocument->getText(), uno::UNO_QUERY); + uno::Reference<container::XEnumeration> xParaEnum = xParaEnumAccess->createEnumeration(); + uno::Reference<container::XEnumerationAccess> xRunEnumAccess(xParaEnum->nextElement(), uno::UNO_QUERY); + uno::Reference<container::XEnumeration> xRunEnum = xRunEnumAccess->createEnumeration(); + xRunEnum->nextElement(); + uno::Reference<beans::XPropertySet> xPropertySet(xRunEnum->nextElement(), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(OUString("TextFieldStart"), getProperty<OUString>(xPropertySet, "TextPortionType")); + xRunEnum->nextElement(); + xPropertySet.set(xRunEnum->nextElement(), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(OUString("TextFieldEnd"), getProperty<OUString>(xPropertySet, "TextPortionType")); + + /* + * Initials were not imported. + * + * oFields = ThisComponent.TextFields.createEnumeration + * oField = oFields.nextElement + * xray oField.Initials + */ + uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference<container::XEnumerationAccess> xFieldsAccess(xTextFieldsSupplier->getTextFields()); + uno::Reference<container::XEnumeration> xFields(xFieldsAccess->createEnumeration()); + xPropertySet.set(xFields->nextElement(), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(OUString("M"), getProperty<OUString>(xPropertySet, "Initials")); + + /* + * There was a fake empty paragraph at the end of the comment text. + * + * oFields = ThisComponent.TextFields.createEnumeration + * oField = oFields.nextElement + * oParas = oField.TextRange.createEnumeration + * oPara = oParas.nextElement + * oPara = oParas.nextElement + */ + + xParaEnumAccess.set(getProperty< uno::Reference<container::XEnumerationAccess> >(xPropertySet, "TextRange"), uno::UNO_QUERY); + xParaEnum = xParaEnumAccess->createEnumeration(); + xParaEnum->nextElement(); + bool bCaught = false; + try + { + xParaEnum->nextElement(); + } + catch (container::NoSuchElementException&) + { + bCaught = true; + } + CPPUNIT_ASSERT_EQUAL(true, bCaught); +} + CPPUNIT_TEST_SUITE_REGISTRATION(Test); CPPUNIT_PLUGIN_IMPLEMENT(); _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits