summaryrefslogtreecommitdiff
path: root/writerfilter
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.co.uk>2016-02-23 09:13:40 +0100
committerAndras Timar <andras.timar@collabora.com>2016-04-04 23:55:30 +0200
commitcbed174f94dd2b262e97d09f40cd5e9fd6f34852 (patch)
tree1fa8892c23a7a8854f1b847c2c82a9a4e82e7c06 /writerfilter
parent0d1e9f68b962ed3e86fc7b6e06abb29cca83196a (diff)
tdf#59699 RTF import: handle INCLUDEPICTURE field
On one hand, don't handle a fieldmark for it in dmapper. On the other hand, handle the field in the RTF tokenizer as it would be {\pict ...hexdump... }, that will result in an inline picture, as wanted. (cherry picked from commit 6f94cab9c43f88624b58a47ad03ad5f87032595d) Conflicts: writerfilter/source/dmapper/DomainMapper_Impl.cxx writerfilter/source/rtftok/rtfdocumentimpl.hxx Change-Id: I554fdf017920350144300fd86617bf74eed8995b Reviewed-on: https://gerrit.libreoffice.org/23298 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Michael Stahl <mstahl@redhat.com> (cherry picked from commit b5464c15078b57e852100a76f03fadef3186c93d)
Diffstat (limited to 'writerfilter')
-rw-r--r--writerfilter/Library_writerfilter.mk1
-rw-r--r--writerfilter/inc/rtftok/RTFDocument.hxx3
-rw-r--r--writerfilter/source/dmapper/DomainMapper_Impl.cxx3
-rw-r--r--writerfilter/source/dmapper/FieldTypes.hxx1
-rw-r--r--writerfilter/source/filter/RtfFilter.cxx2
-rw-r--r--writerfilter/source/rtftok/rtfdocumentfactory.cxx4
-rw-r--r--writerfilter/source/rtftok/rtfdocumentimpl.cxx67
-rw-r--r--writerfilter/source/rtftok/rtfdocumentimpl.hxx6
8 files changed, 77 insertions, 10 deletions
diff --git a/writerfilter/Library_writerfilter.mk b/writerfilter/Library_writerfilter.mk
index 6149401d284c..c81ff5651e05 100644
--- a/writerfilter/Library_writerfilter.mk
+++ b/writerfilter/Library_writerfilter.mk
@@ -21,6 +21,7 @@ $(eval $(call gb_Library_set_include,writerfilter,\
$$(INCLUDE) \
-I$(SRCDIR)/writerfilter/inc \
-I$(SRCDIR)/writerfilter/source \
+ -I$(SRCDIR)/writerfilter/source/dmapper \
))
$(eval $(call gb_Library_use_sdk_api,writerfilter))
diff --git a/writerfilter/inc/rtftok/RTFDocument.hxx b/writerfilter/inc/rtftok/RTFDocument.hxx
index 01a988029505..1d96bec145de 100644
--- a/writerfilter/inc/rtftok/RTFDocument.hxx
+++ b/writerfilter/inc/rtftok/RTFDocument.hxx
@@ -15,6 +15,7 @@
#include <com/sun/star/lang/XComponent.hpp>
#include <com/sun/star/frame/XFrame.hpp>
#include <com/sun/star/task/XStatusIndicator.hpp>
+#include <unotools/mediadescriptor.hxx>
namespace writerfilter
{
@@ -44,7 +45,7 @@ public:
css::uno::Reference<css::lang::XComponent> const& xDstDoc,
css::uno::Reference<css::frame::XFrame> const& xFrame,
css::uno::Reference<css::task::XStatusIndicator> const& xStatusIndicator,
- bool bIsNewDoc);
+ const utl::MediaDescriptor& rMediaDescriptor);
};
} // namespace rtftok
} // namespace writerfilter
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index 02a965a682d1..2906e24f4840 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -2816,7 +2816,7 @@ if(!bFilled)
{OUString("HYPERLINK"), "", "", FIELD_HYPERLINK },
{OUString("IF"), "ConditionalText", "", FIELD_IF },
// {OUString("INFO"), "","", FIELD_INFO },
-// {OUString("INCLUDEPICTURE"), "", "", FIELD_INCLUDEPICTURE},
+ {OUString("INCLUDEPICTURE"), "", "", FIELD_INCLUDEPICTURE},
{OUString("KEYWORDS"), "DocInfo.KeyWords", "", FIELD_KEYWORDS },
{OUString("LASTSAVEDBY"), "DocInfo.ChangeAuthor", "", FIELD_LASTSAVEDBY },
{OUString("MACROBUTTON"), "Macro", "", FIELD_MACROBUTTON },
@@ -3516,6 +3516,7 @@ void DomainMapper_Impl::CloseFieldCommand()
case FIELD_CITATION:
case FIELD_TC:
case FIELD_EQ:
+ case FIELD_INCLUDEPICTURE:
bCreateField = false;
break;
case FIELD_FORMCHECKBOX :
diff --git a/writerfilter/source/dmapper/FieldTypes.hxx b/writerfilter/source/dmapper/FieldTypes.hxx
index 0ce6e1f5ad90..a9b8a2eca50f 100644
--- a/writerfilter/source/dmapper/FieldTypes.hxx
+++ b/writerfilter/source/dmapper/FieldTypes.hxx
@@ -120,7 +120,6 @@ enum FieldId
,FIELD_INFO
/* INCLUDEPICTURE path \* MERGEFORMAT->
old filter imports an embedded picture
- todo: not yet supported
*/
,FIELD_INCLUDEPICTURE
/* KEYWORDS keyword \* defaultswitch \* Numberingswitch \* MERGEFORMAT ->
diff --git a/writerfilter/source/filter/RtfFilter.cxx b/writerfilter/source/filter/RtfFilter.cxx
index 7bf88b2d218f..96f8d1522e75 100644
--- a/writerfilter/source/filter/RtfFilter.cxx
+++ b/writerfilter/source/filter/RtfFilter.cxx
@@ -148,7 +148,7 @@ sal_Bool RtfFilter::filter(const uno::Sequence< beans::PropertyValue >& aDescrip
writerfilter::Stream::Pointer_t pStream(
writerfilter::dmapper::DomainMapperFactory::createMapper(m_xContext, xInputStream, m_xDstDoc, bRepairStorage, eType, xInsertTextRange, aMediaDesc));
writerfilter::rtftok::RTFDocument::Pointer_t pDocument(
- writerfilter::rtftok::RTFDocumentFactory::createDocument(m_xContext, xInputStream, m_xDstDoc, xFrame, xStatusIndicator, bIsNewDoc));
+ writerfilter::rtftok::RTFDocumentFactory::createDocument(m_xContext, xInputStream, m_xDstDoc, xFrame, xStatusIndicator, aMediaDesc));
pDocument->resolve(*pStream);
bResult = true;
sal_uInt32 nEndTime = osl_getGlobalTimer();
diff --git a/writerfilter/source/rtftok/rtfdocumentfactory.cxx b/writerfilter/source/rtftok/rtfdocumentfactory.cxx
index 0722bff44ee3..aadfc38e71ce 100644
--- a/writerfilter/source/rtftok/rtfdocumentfactory.cxx
+++ b/writerfilter/source/rtftok/rtfdocumentfactory.cxx
@@ -19,9 +19,9 @@ RTFDocument::Pointer_t RTFDocumentFactory::createDocument(css::uno::Reference< c
css::uno::Reference< css::lang::XComponent > const& xDstDoc,
css::uno::Reference< css::frame::XFrame > const& xFrame,
css::uno::Reference< css::task::XStatusIndicator > const& xStatusIndicator,
- bool bIsNewDoc)
+ const utl::MediaDescriptor& rMediaDescriptor)
{
- return std::make_shared<RTFDocumentImpl>(xContext, xInputStream, xDstDoc, xFrame, xStatusIndicator, bIsNewDoc);
+ return std::make_shared<RTFDocumentImpl>(xContext, xInputStream, xDstDoc, xFrame, xStatusIndicator, rMediaDescriptor);
}
} // namespace rtftok
diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.cxx b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
index c6f3d323a170..f9cf14618b63 100644
--- a/writerfilter/source/rtftok/rtfdocumentimpl.cxx
+++ b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
@@ -35,6 +35,8 @@
#include <ooxml/resourceids.hxx>
#include <oox/token/namespaces.hxx>
#include <oox/drawingml/drawingmltypes.hxx>
+#include <rtl/uri.hxx>
+#include <dmapper/DomainMapper_Impl.hxx>
#include <rtfsdrimport.hxx>
#include <rtflookahead.hxx>
#include <rtfcharsets.hxx>
@@ -212,7 +214,7 @@ RTFDocumentImpl::RTFDocumentImpl(uno::Reference<uno::XComponentContext> const& x
uno::Reference<lang::XComponent> const& xDstDoc,
uno::Reference<frame::XFrame> const& xFrame,
uno::Reference<task::XStatusIndicator> const& xStatusIndicator,
- bool bIsNewDoc)
+ const utl::MediaDescriptor& rMediaDescriptor)
: m_xContext(xContext),
m_xInputStream(xInputStream),
m_xDstDoc(xDstDoc),
@@ -272,7 +274,8 @@ RTFDocumentImpl::RTFDocumentImpl(uno::Reference<uno::XComponentContext> const& x
m_bHadSect(false),
m_nCellxMax(0),
m_nListPictureId(0),
- m_bIsNewDoc(bIsNewDoc)
+ m_bIsNewDoc(!rMediaDescriptor.getUnpackedValueOrDefault("InsertMode", false)),
+ m_rMediaDescriptor(rMediaDescriptor)
{
OSL_ASSERT(xInputStream.is());
m_pInStream.reset(utl::UcbStreamHelper::CreateStream(xInputStream, true));
@@ -343,7 +346,7 @@ void RTFDocumentImpl::resolveSubstream(sal_Size nPos, Id nId, OUString& rIgnoreF
{
sal_Size nCurrent = Strm().Tell();
// Seek to header position, parse, then seek back.
- auto pImpl = std::make_shared<RTFDocumentImpl>(m_xContext, m_xInputStream, m_xDstDoc, m_xFrame, m_xStatusIndicator, m_bIsNewDoc);
+ auto pImpl = std::make_shared<RTFDocumentImpl>(m_xContext, m_xInputStream, m_xDstDoc, m_xFrame, m_xStatusIndicator, m_rMediaDescriptor);
pImpl->setSuperstream(this);
pImpl->setStreamType(nId);
pImpl->setIgnoreFirst(rIgnoreFirst);
@@ -1544,6 +1547,24 @@ RTFError RTFDocumentImpl::dispatchDestination(RTFKeyword nKeyword)
if (!aBuf.isEmpty() && !isalnum(ch))
bFoundCode = true;
}
+
+ if (aBuf.toString() == "INCLUDEPICTURE")
+ {
+ // Extract the field argument of INCLUDEPICTURE: we handle that
+ // at a tokenizer level, as DOCX has no such field.
+ aBuf.append(ch);
+ while (true)
+ {
+ Strm().ReadChar(ch);
+ if (ch == '}')
+ break;
+ aBuf.append(ch);
+ }
+ OUString aFieldCommand = OStringToOUString(aBuf.toString(), RTL_TEXTENCODING_UTF8);
+ boost::tuple<OUString, std::vector<OUString>, std::vector<OUString> > aResult = writerfilter::dmapper::lcl_SplitFieldCommand(aFieldCommand);
+ m_aPicturePath = boost::get<1>(aResult).empty() ? OUString() : boost::get<1>(aResult).front();
+ }
+
Strm().Seek(nPos);
// Form data should be handled only for form fields if any
@@ -5124,6 +5145,46 @@ RTFError RTFDocumentImpl::popState()
break;
case Destination::FIELDRESULT:
singleChar(cFieldEnd);
+
+ if (!m_aPicturePath.isEmpty())
+ {
+ // Read the picture into m_aStates.top().aDestinationText.
+ pushState();
+ dispatchDestination(RTF_PICT);
+ if (m_aPicturePath.endsWith(".png"))
+ dispatchFlag(RTF_PNGBLIP);
+ OUString aFileURL = m_rMediaDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_URL(), OUString());
+ OUString aPictureURL;
+ try
+ {
+ aPictureURL = rtl::Uri::convertRelToAbs(aFileURL, m_aPicturePath);
+ }
+ catch(const rtl::MalformedUriException& rException)
+ {
+ SAL_WARN("writerfilter", "rtl::Uri::convertRelToAbs() failed: " << rException.getMessage());
+ }
+
+ if (!aPictureURL.isEmpty())
+ {
+ SvFileStream aStream(aPictureURL, StreamMode::READ);
+ if (aStream.IsOpen())
+ {
+ OUStringBuffer aBuf;
+ while (aStream.good())
+ {
+ unsigned char ch = 0;
+ aStream.ReadUChar(ch);
+ if (ch < 16)
+ aBuf.append("0");
+ aBuf.append(OUString::number(ch, 16));
+ }
+ m_aStates.top().aDestinationText = aBuf;
+ }
+ }
+ popState();
+ m_aPicturePath.clear();
+ }
+
break;
case Destination::LEVELTEXT:
{
diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.hxx b/writerfilter/source/rtftok/rtfdocumentimpl.hxx
index 863b95215ed7..823ccc212bf9 100644
--- a/writerfilter/source/rtftok/rtfdocumentimpl.hxx
+++ b/writerfilter/source/rtftok/rtfdocumentimpl.hxx
@@ -332,7 +332,7 @@ public:
css::uno::Reference<css::lang::XComponent> const& xDstDoc,
css::uno::Reference<css::frame::XFrame> const& xFrame,
css::uno::Reference<css::task::XStatusIndicator> const& xStatusIndicator,
- bool bIsNewDoc);
+ const utl::MediaDescriptor& rMediaDescriptor);
virtual ~RTFDocumentImpl();
// RTFDocument
@@ -565,6 +565,8 @@ private:
bool m_bFormField;
/// If a frame start token is already sent to dmapper (nesting them is not OK).
bool m_bIsInFrame;
+ /// For the INCLUDEPICTURE field's argument.
+ OUString m_aPicturePath;
// Unicode characters are collected here so we don't have to send them one by one.
OUStringBuffer m_aUnicodeBuffer;
/// Same for hex characters.
@@ -593,6 +595,8 @@ private:
/// New document means not pasting into an existing one.
bool m_bIsNewDoc;
+ /// The media descriptor contains e.g. the base URL of the document.
+ const utl::MediaDescriptor& m_rMediaDescriptor;
};
} // namespace rtftok
} // namespace writerfilter