diff --git a/editeng/inc/editeng/editobj.hxx b/editeng/inc/editeng/editobj.hxx index 93a590c0a784..16bc0be626e5 100644 --- a/editeng/inc/editeng/editobj.hxx +++ b/editeng/inc/editeng/editobj.hxx @@ -39,6 +39,7 @@ DBG_NAMEEX( EE_EditTextObject ) class SfxItemPool; class SfxStyleSheetPool; class SvxFieldItem; +class SvxFieldData; namespace editeng { @@ -99,6 +100,7 @@ public: bool IsFieldObject() const; const SvxFieldItem* GetField() const; + const SvxFieldData* GetFieldData(size_t nPara, size_t nPos, sal_Int32 nType) const; bool HasField( sal_Int32 nType = com::sun::star::text::textfield::Type::UNSPECIFIED ) const; const SfxItemSet& GetParaAttribs(size_t nPara) const; diff --git a/editeng/source/editeng/editobj.cxx b/editeng/source/editeng/editobj.cxx index 0433ea5aa195..823139622d44 100644 --- a/editeng/source/editeng/editobj.cxx +++ b/editeng/source/editeng/editobj.cxx @@ -256,6 +256,11 @@ const SvxFieldItem* EditTextObject::GetField() const return mpImpl->GetField(); } +const SvxFieldData* EditTextObject::GetFieldData(size_t nPara, size_t nPos, sal_Int32 nType) const +{ + return mpImpl->GetFieldData(nPara, nPos, nType); +} + bool EditTextObject::HasField( sal_Int32 nType ) const { return mpImpl->HasField(nType); @@ -703,6 +708,41 @@ const SvxFieldItem* EditTextObjectImpl::GetField() const return 0; } +const SvxFieldData* EditTextObjectImpl::GetFieldData(size_t nPara, size_t nPos, sal_Int32 nType) const +{ + if (nPara >= aContents.size()) + return NULL; + + const ContentInfo& rC = aContents[nPara]; + if (nPos >= rC.aAttribs.size()) + // URL position is out-of-bound. + return NULL; + + ContentInfo::XEditAttributesType::const_iterator it = rC.aAttribs.begin(), itEnd = rC.aAttribs.end(); + size_t nCurPos = 0; + for (; it != itEnd; ++it) + { + const XEditAttribute& rAttr = *it; + if (rAttr.GetItem()->Which() != EE_FEATURE_FIELD) + // Skip attributes that are not fields. + continue; + + const SvxFieldItem* pField = static_cast(rAttr.GetItem()); + const SvxFieldData* pFldData = pField->GetField(); + if (nType != text::textfield::Type::UNSPECIFIED && nType != pFldData->GetClassId()) + // Field type doesn't match. Skip it. UNSPECIFIED matches all field types. + continue; + + if (nCurPos == nPos) + // Found it! + return pFldData; + + ++nCurPos; + } + + return NULL; // field not found. +} + bool EditTextObjectImpl::HasField( sal_Int32 nType ) const { size_t nParagraphs = aContents.size(); diff --git a/editeng/source/editeng/editobj2.hxx b/editeng/source/editeng/editobj2.hxx index 5c5905023887..c1aa77ffc58d 100644 --- a/editeng/source/editeng/editobj2.hxx +++ b/editeng/source/editeng/editobj2.hxx @@ -221,6 +221,8 @@ public: bool IsFieldObject() const; const SvxFieldItem* GetField() const; + const SvxFieldData* GetFieldData(size_t nPara, size_t nPos, sal_Int32 nType) const; + bool HasField( sal_Int32 nType = com::sun::star::text::textfield::Type::UNSPECIFIED ) const; const SfxItemSet& GetParaAttribs(size_t nPara) const; diff --git a/sc/qa/unit/data/ods/rich-text-cells.ods b/sc/qa/unit/data/ods/rich-text-cells.ods index a869b0be873a..da3a1edcada3 100644 Binary files a/sc/qa/unit/data/ods/rich-text-cells.ods and b/sc/qa/unit/data/ods/rich-text-cells.ods differ diff --git a/sc/qa/unit/subsequent_filters-test.cxx b/sc/qa/unit/subsequent_filters-test.cxx index ff09d2759fe1..d89d95d9de64 100644 --- a/sc/qa/unit/subsequent_filters-test.cxx +++ b/sc/qa/unit/subsequent_filters-test.cxx @@ -48,6 +48,7 @@ #include #include #include +#include "editeng/flditem.hxx" #include #include "validat.hxx" #include "formulacell.hxx" @@ -1757,6 +1758,15 @@ void ScFiltersTest::testRichTextContentODS() CPPUNIT_ASSERT_MESSAGE("Failed to retrieve edit text object.", pEditText); CPPUNIT_ASSERT_MESSAGE("Date field item not found.", pEditText->HasField(text::textfield::Type::DOCINFO_TITLE)); + // URL for a file in the same directory. It should be converted into an absolute URL on import. + aPos.IncRow(); + pEditText = pDoc->GetEditText(aPos); + CPPUNIT_ASSERT_MESSAGE("Failed to retrieve edit text object.", pEditText); + const SvxFieldData* pData = pEditText->GetFieldData(0, 0, text::textfield::Type::URL); + CPPUNIT_ASSERT_MESSAGE("Failed to get the URL data.", pData && pData->GetClassId() == text::textfield::Type::URL); + const SvxURLField* pURLData = static_cast(pData); + CPPUNIT_ASSERT_MESSAGE("URL is not absolute with respect to the file system.", pURLData->GetURL().startsWith("file:///")); + xDocSh->DoClose(); } diff --git a/sc/source/filter/xml/xmlcelli.cxx b/sc/source/filter/xml/xmlcelli.cxx index 5f4acb9bc8fb..b97a2458cc6c 100644 --- a/sc/source/filter/xml/xmlcelli.cxx +++ b/sc/source/filter/xml/xmlcelli.cxx @@ -598,7 +598,8 @@ void ScXMLTableRowCellContext::PushParagraphFieldDocTitle(const OUString& rStyle void ScXMLTableRowCellContext::PushParagraphFieldURL( const OUString& rURL, const OUString& rRep, const OUString& rStyleName) { - PushParagraphField(new SvxURLField(rURL, rRep, SVXURLFORMAT_REPR), rStyleName); + OUString aAbsURL = GetScImport().GetAbsoluteReference(rURL); + PushParagraphField(new SvxURLField(aAbsURL, rRep, SVXURLFORMAT_REPR), rStyleName); } void ScXMLTableRowCellContext::PushParagraphEnd()