EPUB export: support image popup for images and text
Handle relative links on image / text as data for a popup. Pick the images up from <base directory>/<base name>/<relative url> as a start. Change-Id: I9b6183d554e3792aa71dfffc19a671a0e4c302cc Reviewed-on: https://gerrit.libreoffice.org/45601 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Miklos Vajna <vmiklos@collabora.co.uk>
This commit is contained in:
parent
553a35bed7
commit
7dcb4fef3b
8 changed files with 401 additions and 2 deletions
301
external/libepubgen/libepubgen-epub3.patch.1
vendored
301
external/libepubgen/libepubgen-epub3.patch.1
vendored
|
@ -5053,3 +5053,304 @@ index 96e7623..6b4c7c2 100644
|
|||
--
|
||||
2.13.6
|
||||
|
||||
From bc80bf98172e8e0f8c803dec0b8e74e233ac482e Mon Sep 17 00:00:00 2001
|
||||
From: Miklos Vajna <vmiklos@collabora.co.uk>
|
||||
Date: Fri, 24 Nov 2017 16:28:58 +0100
|
||||
Subject: [PATCH 1/2] EPUBHTMLGenerator: support image popup for images
|
||||
|
||||
If the user of the lib uses the librevenge:mime-type and
|
||||
office:binary-data keys (instead of xlink:href) for a link around an
|
||||
image, then open that image in a popup (using the footnote markup).
|
||||
|
||||
The usual assumption is that the footnote anchor is trivial (just a
|
||||
string) and the content is complex, but here the situation is the
|
||||
opposite: the anchor can be something complex, OTOH the footnote content
|
||||
is always a single inline image -- this requires the new
|
||||
closeAnchor mode when adding the footnote label.
|
||||
---
|
||||
src/lib/EPUBHTMLGenerator.cpp | 79 ++++++++++++++++++++++++++++++--------
|
||||
src/test/EPUBTextGeneratorTest.cpp | 34 ++++++++++++++++
|
||||
2 files changed, 96 insertions(+), 17 deletions(-)
|
||||
|
||||
diff --git a/src/lib/EPUBHTMLGenerator.cpp b/src/lib/EPUBHTMLGenerator.cpp
|
||||
index 6b4c7c2..75b0866 100644
|
||||
--- a/src/lib/EPUBHTMLGenerator.cpp
|
||||
+++ b/src/lib/EPUBHTMLGenerator.cpp
|
||||
@@ -222,7 +222,8 @@ struct TextZoneSink
|
||||
//! destructor
|
||||
~TextZoneSink() { }
|
||||
//! add a label called on main and a label in this ( delayed to allow openParagraph to be called )
|
||||
- void addLabel(EPUBXMLSink &output, const librevenge::RVNGString &number)
|
||||
+ //! @param closeAnchor determintes if the anchor on the main sink should be closed or not.
|
||||
+ void addLabel(EPUBXMLSink &output, const librevenge::RVNGString &number, bool closeAnchor)
|
||||
{
|
||||
// Unique label, e.g. 'F1' for the first footnote.
|
||||
std::string lbl=label();
|
||||
@@ -244,9 +245,12 @@ struct TextZoneSink
|
||||
aAttrs.insert("epub:type", "noteref");
|
||||
aAttrs.insert("href", ("#data" + lbl).c_str());
|
||||
output.openElement("a", aAttrs);
|
||||
- output.insertCharacters(uiLabel.c_str());
|
||||
- output.closeElement("a");
|
||||
- output.closeElement("sup");
|
||||
+ if (closeAnchor)
|
||||
+ {
|
||||
+ output.insertCharacters(uiLabel.c_str());
|
||||
+ output.closeElement("a");
|
||||
+ output.closeElement("sup");
|
||||
+ }
|
||||
}
|
||||
flush();
|
||||
if (version == 30)
|
||||
@@ -259,13 +263,16 @@ struct TextZoneSink
|
||||
RVNGPropertyList supAttrs;
|
||||
if (version < 30)
|
||||
supAttrs.insert("id", ("data" + lbl).c_str());
|
||||
- m_delayedLabel.openElement("sup", supAttrs);
|
||||
- RVNGPropertyList aAttrs;
|
||||
- aAttrs.insert("href", ("#called" + lbl).c_str());
|
||||
- m_delayedLabel.openElement("a", aAttrs);
|
||||
- m_delayedLabel.insertCharacters(uiLabel.c_str());
|
||||
- m_delayedLabel.closeElement("a");
|
||||
- m_delayedLabel.closeElement("sup");
|
||||
+ if (closeAnchor)
|
||||
+ {
|
||||
+ m_delayedLabel.openElement("sup", supAttrs);
|
||||
+ RVNGPropertyList aAttrs;
|
||||
+ aAttrs.insert("href", ("#called" + lbl).c_str());
|
||||
+ m_delayedLabel.openElement("a", aAttrs);
|
||||
+ m_delayedLabel.insertCharacters(uiLabel.c_str());
|
||||
+ m_delayedLabel.closeElement("a");
|
||||
+ m_delayedLabel.closeElement("sup");
|
||||
+ }
|
||||
}
|
||||
//! flush delayed label, ...
|
||||
void flush()
|
||||
@@ -379,6 +386,7 @@ struct EPUBHTMLGeneratorImpl
|
||||
, m_version(version)
|
||||
, m_frameAnchorTypes()
|
||||
, m_framePropertiesStack()
|
||||
+ , m_linkPropertiesStack()
|
||||
, m_stylesMethod(stylesMethod)
|
||||
, m_actualSink()
|
||||
, m_sinkStack()
|
||||
@@ -475,6 +483,8 @@ struct EPUBHTMLGeneratorImpl
|
||||
|
||||
std::stack<std::string> m_frameAnchorTypes;
|
||||
std::stack<RVNGPropertyList> m_framePropertiesStack;
|
||||
+ /// This is used for links which don't have a href.
|
||||
+ std::stack<RVNGPropertyList> m_linkPropertiesStack;
|
||||
|
||||
EPUBStylesMethod m_stylesMethod;
|
||||
|
||||
@@ -702,14 +712,29 @@ void EPUBHTMLGenerator::openLink(const RVNGPropertyList &propList)
|
||||
|
||||
attrs.insert("href", href.c_str());
|
||||
}
|
||||
- m_impl->output(false).openElement("a", attrs);
|
||||
+ const librevenge::RVNGProperty *binaryDataProp = propList["office:binary-data"];
|
||||
+ const librevenge::RVNGProperty *mimeTypeProp = propList["librevenge:mime-type"];
|
||||
+ if (binaryDataProp && mimeTypeProp)
|
||||
+ {
|
||||
+ // This is not a real link, but more an additional image on top of an
|
||||
+ // existing one, map it to footnotes instead.
|
||||
+ RVNGPropertyList linkProperties;
|
||||
+ linkProperties.insert("office:binary-data", binaryDataProp->clone());
|
||||
+ linkProperties.insert("librevenge:mime-type", mimeTypeProp->clone());
|
||||
+ m_impl->m_linkPropertiesStack.push(linkProperties);
|
||||
+ }
|
||||
+ else
|
||||
+ m_impl->output(false).openElement("a", attrs);
|
||||
}
|
||||
|
||||
void EPUBHTMLGenerator::closeLink()
|
||||
{
|
||||
if (m_impl->m_ignore)
|
||||
return;
|
||||
- m_impl->output().closeElement("a");
|
||||
+ if (!m_impl->m_linkPropertiesStack.empty())
|
||||
+ m_impl->m_linkPropertiesStack.pop();
|
||||
+ else
|
||||
+ m_impl->output().closeElement("a");
|
||||
}
|
||||
|
||||
void EPUBHTMLGenerator::insertTab()
|
||||
@@ -820,7 +845,8 @@ void EPUBHTMLGenerator::openFootnote(const RVNGPropertyList &propList)
|
||||
librevenge::RVNGString number;
|
||||
if (const librevenge::RVNGProperty *numProp = propList["librevenge:number"])
|
||||
number = numProp->getStr();
|
||||
- m_impl->getSink().addLabel(output, number);
|
||||
+ bool closeAnchor = m_impl->m_linkPropertiesStack.empty();
|
||||
+ m_impl->getSink().addLabel(output, number, closeAnchor);
|
||||
}
|
||||
|
||||
void EPUBHTMLGenerator::closeFootnote()
|
||||
@@ -838,7 +864,7 @@ void EPUBHTMLGenerator::openEndnote(const RVNGPropertyList &)
|
||||
return;
|
||||
EPUBXMLSink &output = m_impl->output();
|
||||
m_impl->push(EPUBHTMLTextZone::Z_EndNote);
|
||||
- m_impl->getSink().addLabel(output, librevenge::RVNGString());
|
||||
+ m_impl->getSink().addLabel(output, librevenge::RVNGString(), true);
|
||||
}
|
||||
|
||||
void EPUBHTMLGenerator::closeEndnote()
|
||||
@@ -854,7 +880,7 @@ void EPUBHTMLGenerator::openComment(const RVNGPropertyList & /*propList*/)
|
||||
return;
|
||||
EPUBXMLSink &output = m_impl->output();
|
||||
m_impl->push(EPUBHTMLTextZone::Z_Comment);
|
||||
- m_impl->getSink().addLabel(output, librevenge::RVNGString());
|
||||
+ m_impl->getSink().addLabel(output, librevenge::RVNGString(), true);
|
||||
}
|
||||
|
||||
void EPUBHTMLGenerator::closeComment()
|
||||
@@ -1067,7 +1093,26 @@ void EPUBHTMLGenerator::insertBinaryObject(const RVNGPropertyList &propList)
|
||||
attrs.insert("src", path.relativeTo(m_impl->m_path).str().c_str());
|
||||
// FIXME: use alternative repr. if available
|
||||
attrs.insert("alt", path.str().c_str());
|
||||
- m_impl->output().insertEmptyElement("img", attrs);
|
||||
+ if (!m_impl->m_linkPropertiesStack.empty())
|
||||
+ {
|
||||
+ RVNGPropertyList &linkProperties = m_impl->m_linkPropertiesStack.top();
|
||||
+ // Save the main sink, as m_impl->output() will point to the footnote sink.
|
||||
+ libepubgen::EPUBXMLSink &main = m_impl->output();
|
||||
+ openFootnote(RVNGPropertyList());
|
||||
+ main.insertEmptyElement("img", attrs);
|
||||
+ main.closeElement("a");
|
||||
+ main.closeElement("sup");
|
||||
+ const EPUBPath &linkPath = m_impl->m_imageManager.insert(
|
||||
+ RVNGBinaryData(linkProperties["office:binary-data"]->getStr()),
|
||||
+ linkProperties["librevenge:mime-type"]->getStr());
|
||||
+ RVNGPropertyList linkAttrs;
|
||||
+ linkAttrs.insert("src", linkPath.relativeTo(m_impl->m_path).str().c_str());
|
||||
+ linkAttrs.insert("alt", linkPath.str().c_str());
|
||||
+ m_impl->output().insertEmptyElement("img", linkAttrs);
|
||||
+ closeFootnote();
|
||||
+ }
|
||||
+ else
|
||||
+ m_impl->output().insertEmptyElement("img", attrs);
|
||||
|
||||
if (!wrapStyle.empty())
|
||||
{
|
||||
--
|
||||
2.13.6
|
||||
|
||||
|
||||
From 6e094bbe9fd8c1784ef3c348d04e2add8b48fc67 Mon Sep 17 00:00:00 2001
|
||||
From: Miklos Vajna <vmiklos@collabora.co.uk>
|
||||
Date: Fri, 24 Nov 2017 17:18:53 +0100
|
||||
Subject: [PATCH 2/2] EPUBHTMLGenerator: support image popup for text
|
||||
|
||||
And also make sure that the popup anchor is not superscript.
|
||||
---
|
||||
src/lib/EPUBHTMLGenerator.cpp | 44 ++++++++++++++++++++++++++------------
|
||||
src/lib/EPUBHTMLGenerator.h | 4 ++++
|
||||
src/test/EPUBTextGeneratorTest.cpp | 31 ++++++++++++++++++++++++++-
|
||||
3 files changed, 64 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/src/lib/EPUBHTMLGenerator.cpp b/src/lib/EPUBHTMLGenerator.cpp
|
||||
index 75b0866..5c6421c 100644
|
||||
--- a/src/lib/EPUBHTMLGenerator.cpp
|
||||
+++ b/src/lib/EPUBHTMLGenerator.cpp
|
||||
@@ -239,7 +239,8 @@ struct TextZoneSink
|
||||
{
|
||||
RVNGPropertyList supAttrs;
|
||||
supAttrs.insert("id", ("called" + lbl).c_str());
|
||||
- output.openElement("sup", supAttrs);
|
||||
+ if (closeAnchor)
|
||||
+ output.openElement("sup", supAttrs);
|
||||
RVNGPropertyList aAttrs;
|
||||
if (version == 30)
|
||||
aAttrs.insert("epub:type", "noteref");
|
||||
@@ -769,7 +770,9 @@ void EPUBHTMLGenerator::insertText(const RVNGString &text)
|
||||
{
|
||||
if (m_impl->m_ignore)
|
||||
return;
|
||||
- m_impl->output().insertCharacters(text);
|
||||
+ EPUBXMLSink &sink = openPopup();
|
||||
+ sink.insertCharacters(text);
|
||||
+ closePopup(sink);
|
||||
m_impl->m_hasText = true;
|
||||
}
|
||||
|
||||
@@ -1093,15 +1096,37 @@ void EPUBHTMLGenerator::insertBinaryObject(const RVNGPropertyList &propList)
|
||||
attrs.insert("src", path.relativeTo(m_impl->m_path).str().c_str());
|
||||
// FIXME: use alternative repr. if available
|
||||
attrs.insert("alt", path.str().c_str());
|
||||
+ EPUBXMLSink &sink = openPopup();
|
||||
+ sink.insertEmptyElement("img", attrs);
|
||||
+ closePopup(sink);
|
||||
+
|
||||
+ if (!wrapStyle.empty())
|
||||
+ {
|
||||
+ attrs.clear();
|
||||
+ attrs.insert("style", wrapStyle);
|
||||
+ m_impl->output().insertEmptyElement("br", attrs);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+EPUBXMLSink &EPUBHTMLGenerator::openPopup()
|
||||
+{
|
||||
if (!m_impl->m_linkPropertiesStack.empty())
|
||||
{
|
||||
- RVNGPropertyList &linkProperties = m_impl->m_linkPropertiesStack.top();
|
||||
// Save the main sink, as m_impl->output() will point to the footnote sink.
|
||||
libepubgen::EPUBXMLSink &main = m_impl->output();
|
||||
openFootnote(RVNGPropertyList());
|
||||
- main.insertEmptyElement("img", attrs);
|
||||
+ return main;
|
||||
+ }
|
||||
+ else
|
||||
+ return m_impl->output();
|
||||
+}
|
||||
+
|
||||
+void EPUBHTMLGenerator::closePopup(EPUBXMLSink &main)
|
||||
+{
|
||||
+ if (!m_impl->m_linkPropertiesStack.empty())
|
||||
+ {
|
||||
+ RVNGPropertyList &linkProperties = m_impl->m_linkPropertiesStack.top();
|
||||
main.closeElement("a");
|
||||
- main.closeElement("sup");
|
||||
const EPUBPath &linkPath = m_impl->m_imageManager.insert(
|
||||
RVNGBinaryData(linkProperties["office:binary-data"]->getStr()),
|
||||
linkProperties["librevenge:mime-type"]->getStr());
|
||||
@@ -1111,15 +1136,6 @@ void EPUBHTMLGenerator::insertBinaryObject(const RVNGPropertyList &propList)
|
||||
m_impl->output().insertEmptyElement("img", linkAttrs);
|
||||
closeFootnote();
|
||||
}
|
||||
- else
|
||||
- m_impl->output().insertEmptyElement("img", attrs);
|
||||
-
|
||||
- if (!wrapStyle.empty())
|
||||
- {
|
||||
- attrs.clear();
|
||||
- attrs.insert("style", wrapStyle);
|
||||
- m_impl->output().insertEmptyElement("br", attrs);
|
||||
- }
|
||||
}
|
||||
|
||||
void EPUBHTMLGenerator::insertEquation(const RVNGPropertyList & /* propList */) {}
|
||||
diff --git a/src/lib/EPUBHTMLGenerator.h b/src/lib/EPUBHTMLGenerator.h
|
||||
index 11f20cb..3699179 100644
|
||||
--- a/src/lib/EPUBHTMLGenerator.h
|
||||
+++ b/src/lib/EPUBHTMLGenerator.h
|
||||
@@ -27,6 +27,7 @@ class EPUBSpanStyleManager;
|
||||
class EPUBParagraphStyleManager;
|
||||
class EPUBTableStyleManager;
|
||||
class EPUBPath;
|
||||
+class EPUBXMLSink;
|
||||
|
||||
class EPUBHTMLGenerator : public librevenge::RVNGTextInterface
|
||||
{
|
||||
@@ -112,6 +113,9 @@ public:
|
||||
void insertEquation(const librevenge::RVNGPropertyList &propList) override;
|
||||
|
||||
private:
|
||||
+ EPUBXMLSink &openPopup();
|
||||
+ void closePopup(EPUBXMLSink &main);
|
||||
+
|
||||
std::unique_ptr<EPUBHTMLGeneratorImpl> m_impl;
|
||||
|
||||
// Unimplemented to prevent compiler from creating crasher ones
|
||||
--
|
||||
2.13.6
|
||||
|
||||
|
|
|
@ -89,6 +89,7 @@ public:
|
|||
void testFontEmbedding();
|
||||
void testImageLink();
|
||||
void testFootnote();
|
||||
void testPopup();
|
||||
|
||||
CPPUNIT_TEST_SUITE(EPUBExportTest);
|
||||
CPPUNIT_TEST(testOutlineLevel);
|
||||
|
@ -126,6 +127,7 @@ public:
|
|||
CPPUNIT_TEST(testFontEmbedding);
|
||||
CPPUNIT_TEST(testImageLink);
|
||||
CPPUNIT_TEST(testFootnote);
|
||||
CPPUNIT_TEST(testPopup);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
};
|
||||
|
||||
|
@ -702,6 +704,26 @@ void EPUBExportTest::testFootnote()
|
|||
assertXPath(mpXmlDoc, "//xhtml:body/xhtml:aside", "type", "footnote");
|
||||
}
|
||||
|
||||
void EPUBExportTest::testPopup()
|
||||
{
|
||||
createDoc("popup.odt", {});
|
||||
|
||||
mpXmlDoc = parseExport("OEBPS/sections/section0001.xhtml");
|
||||
// Test image popup anchor.
|
||||
assertXPath(mpXmlDoc, "//xhtml:body/xhtml:p[1]/xhtml:a", "type", "noteref");
|
||||
assertXPath(mpXmlDoc, "//xhtml:body/xhtml:p[1]/xhtml:a/xhtml:img", 1);
|
||||
// Test image popup content.
|
||||
assertXPath(mpXmlDoc, "//xhtml:body/xhtml:aside[1]", "type", "footnote");
|
||||
assertXPath(mpXmlDoc, "//xhtml:body/xhtml:aside[1]/xhtml:img", 1);
|
||||
|
||||
// Test text popup anchor.
|
||||
assertXPath(mpXmlDoc, "//xhtml:body/xhtml:p[2]/xhtml:span/xhtml:a", "type", "noteref");
|
||||
assertXPathContent(mpXmlDoc, "//xhtml:body/xhtml:p[2]/xhtml:span/xhtml:a", "link");
|
||||
// Test text popup content.
|
||||
assertXPath(mpXmlDoc, "//xhtml:body/xhtml:aside[2]", "type", "footnote");
|
||||
assertXPath(mpXmlDoc, "//xhtml:body/xhtml:aside[2]/xhtml:img", 1);
|
||||
}
|
||||
|
||||
CPPUNIT_TEST_SUITE_REGISTRATION(EPUBExportTest);
|
||||
|
||||
}
|
||||
|
|
BIN
writerperfect/qa/unit/data/writer/epubexport/popup.odt
Normal file
BIN
writerperfect/qa/unit/data/writer/epubexport/popup.odt
Normal file
Binary file not shown.
Binary file not shown.
After Width: | Height: | Size: 766 B |
|
@ -14,11 +14,15 @@
|
|||
#include <libepubgen/EPUBTextGenerator.h>
|
||||
#include <libepubgen/libepubgen-decls.h>
|
||||
|
||||
#include <com/sun/star/beans/PropertyAttribute.hpp>
|
||||
#include <com/sun/star/beans/XPropertySet.hpp>
|
||||
#include <com/sun/star/frame/XModel.hpp>
|
||||
#include <com/sun/star/lang/XInitialization.hpp>
|
||||
#include <com/sun/star/uno/XComponentContext.hpp>
|
||||
#include <com/sun/star/xml/sax/XDocumentHandler.hpp>
|
||||
|
||||
#include <comphelper/genericpropertyset.hxx>
|
||||
#include <comphelper/propertysetinfo.hxx>
|
||||
#include <cppuhelper/supportsservice.hxx>
|
||||
|
||||
#include "exp/xmlimp.hxx"
|
||||
|
@ -82,7 +86,17 @@ sal_Bool EPUBExportFilter::filter(const uno::Sequence<beans::PropertyValue> &rDe
|
|||
uno::Reference<xml::sax::XDocumentHandler> xExportHandler(new exp::XMLImport(mxContext, aGenerator, aSourceURL, rDescriptor));
|
||||
|
||||
uno::Reference<lang::XInitialization> xInitialization(mxContext->getServiceManager()->createInstanceWithContext("com.sun.star.comp.Writer.XMLOasisExporter", mxContext), uno::UNO_QUERY);
|
||||
xInitialization->initialize({uno::makeAny(xExportHandler)});
|
||||
|
||||
// A subset of parameters are passed in as a property set.
|
||||
comphelper::PropertyMapEntry const aInfoMap[] =
|
||||
{
|
||||
{OUString("BaseURI"), 0, cppu::UnoType<OUString>::get(), beans::PropertyAttribute::MAYBEVOID, 0},
|
||||
{OUString(), 0, css::uno::Type(), 0, 0}
|
||||
};
|
||||
uno::Reference<beans::XPropertySet> xInfoSet(comphelper::GenericPropertySet_CreateInstance(new comphelper::PropertySetInfo(aInfoMap)));
|
||||
xInfoSet->setPropertyValue("BaseURI", uno::makeAny(aSourceURL));
|
||||
|
||||
xInitialization->initialize({uno::makeAny(xExportHandler), uno::makeAny(xInfoSet)});
|
||||
uno::Reference<document::XExporter> xExporter(xInitialization, uno::UNO_QUERY);
|
||||
xExporter->setSourceDocument(mxSourceDocument);
|
||||
uno::Reference<document::XFilter> xFilter(xInitialization, uno::UNO_QUERY);
|
||||
|
|
|
@ -265,6 +265,9 @@ void XMLTextFrameHyperlinkContext::startElement(const OUString &/*rName*/, const
|
|||
FillStyles(rAttributeValue, mrImport.GetAutomaticTextStyles(), mrImport.GetTextStyles(), m_aPropertyList);
|
||||
else
|
||||
{
|
||||
if (rAttributeName == "xlink:href" && mrImport.FillPopupData(rAttributeValue, aPropertyList))
|
||||
continue;
|
||||
|
||||
// This affects the link's properties.
|
||||
OString sName = OUStringToOString(rAttributeName, RTL_TEXTENCODING_UTF8);
|
||||
OString sValue = OUStringToOString(rAttributeValue, RTL_TEXTENCODING_UTF8);
|
||||
|
@ -331,6 +334,9 @@ void XMLHyperlinkContext::startElement(const OUString &/*rName*/, const css::uno
|
|||
FillStyles(rAttributeValue, mrImport.GetAutomaticTextStyles(), mrImport.GetTextStyles(), m_aPropertyList);
|
||||
else
|
||||
{
|
||||
if (rAttributeName == "xlink:href" && mrImport.FillPopupData(rAttributeValue, aPropertyList))
|
||||
continue;
|
||||
|
||||
// This affects the link's properties.
|
||||
OString sName = OUStringToOString(rAttributeName, RTL_TEXTENCODING_UTF8);
|
||||
OString sValue = OUStringToOString(rAttributeValue, RTL_TEXTENCODING_UTF8);
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include <initializer_list>
|
||||
#include <unordered_map>
|
||||
|
||||
#include <com/sun/star/uri/UriReferenceFactory.hpp>
|
||||
#include <com/sun/star/xml/sax/InputSource.hpp>
|
||||
#include <com/sun/star/xml/sax/Parser.hpp>
|
||||
#include <rtl/uri.hxx>
|
||||
|
@ -242,7 +243,8 @@ rtl::Reference<XMLImportContext> XMLOfficeDocContext::CreateChildContext(const O
|
|||
|
||||
XMLImport::XMLImport(const uno::Reference<uno::XComponentContext> &xContext, librevenge::RVNGTextInterface &rGenerator, const OUString &rURL, const uno::Sequence<beans::PropertyValue> &rDescriptor)
|
||||
: mrGenerator(rGenerator),
|
||||
mxContext(xContext)
|
||||
mxContext(xContext),
|
||||
maDocumentBaseURL(rURL)
|
||||
{
|
||||
uno::Sequence<beans::PropertyValue> aFilterData;
|
||||
for (sal_Int32 i = 0; i < rDescriptor.getLength(); ++i)
|
||||
|
@ -270,6 +272,8 @@ XMLImport::XMLImport(const uno::Reference<uno::XComponentContext> &xContext, lib
|
|||
}
|
||||
|
||||
FindXMPMetadata(mxContext, rURL, aFilterData, maMetaData);
|
||||
|
||||
mxUriReferenceFactory = uri::UriReferenceFactory::create(mxContext);
|
||||
}
|
||||
|
||||
const librevenge::RVNGPropertyListVector &XMLImport::GetCoverImages()
|
||||
|
@ -282,6 +286,54 @@ const librevenge::RVNGPropertyList &XMLImport::GetMetaData()
|
|||
return maMetaData;
|
||||
}
|
||||
|
||||
bool XMLImport::FillPopupData(const OUString &rURL, librevenge::RVNGPropertyList &rPropList)
|
||||
{
|
||||
uno::Reference<uri::XUriReference> xUriRef;
|
||||
try
|
||||
{
|
||||
xUriRef = mxUriReferenceFactory->parse(rURL);
|
||||
}
|
||||
catch (const uno::Exception &rException)
|
||||
{
|
||||
SAL_WARN("writerperfect", "XMLImport::FillPopupData: XUriReference::parse() failed:" << rException.Message);
|
||||
}
|
||||
bool bRelative = false;
|
||||
if (xUriRef.is())
|
||||
bRelative = !xUriRef->isAbsolute();
|
||||
if (!bRelative)
|
||||
return false;
|
||||
|
||||
OUString aAbs;
|
||||
INetURLObject aBaseURL(maDocumentBaseURL);
|
||||
try
|
||||
{
|
||||
aAbs = rtl::Uri::convertRelToAbs(maDocumentBaseURL, aBaseURL.GetBase() + "/" + rURL);
|
||||
}
|
||||
catch (const rtl::MalformedUriException &rException)
|
||||
{
|
||||
SAL_WARN("writerperfect", "XMLImport::FillPopupData: convertRelToAbs() failed:" << rException.getMessage());
|
||||
}
|
||||
if (aAbs.isEmpty())
|
||||
return false;
|
||||
|
||||
SvFileStream aStream(aAbs, StreamMode::READ);
|
||||
if (aStream.IsOpen())
|
||||
{
|
||||
librevenge::RVNGBinaryData aBinaryData;
|
||||
SvMemoryStream aMemoryStream;
|
||||
aMemoryStream.WriteStream(aStream);
|
||||
aBinaryData.append(static_cast<const unsigned char *>(aMemoryStream.GetBuffer()), aMemoryStream.GetSize());
|
||||
rPropList.insert("office:binary-data", aBinaryData);
|
||||
|
||||
INetURLObject aAbsURL(aAbs);
|
||||
OUString aMimeType = GetMimeType(aAbsURL.GetExtension());
|
||||
rPropList.insert("librevenge:mime-type", aMimeType.toUtf8().getStr());
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
rtl::Reference<XMLImportContext> XMLImport::CreateContext(const OUString &rName, const css::uno::Reference<css::xml::sax::XAttributeList> &/*xAttribs*/)
|
||||
{
|
||||
if (rName == "office:document")
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
#include <com/sun/star/beans/PropertyValue.hpp>
|
||||
#include <com/sun/star/uno/XComponentContext.hpp>
|
||||
#include <com/sun/star/uri/XUriReferenceFactory.hpp>
|
||||
#include <com/sun/star/xml/sax/XDocumentHandler.hpp>
|
||||
|
||||
#include <cppuhelper/implbase.hxx>
|
||||
|
@ -55,6 +56,8 @@ class XMLImport : public cppu::WeakImplHelper
|
|||
/// Author, date, etc -- overwrites what would be from the document out of the box.
|
||||
librevenge::RVNGPropertyList maMetaData;
|
||||
const css::uno::Reference<css::uno::XComponentContext> &mxContext;
|
||||
css::uno::Reference<css::uri::XUriReferenceFactory> mxUriReferenceFactory;
|
||||
OUString maDocumentBaseURL;
|
||||
|
||||
public:
|
||||
XMLImport(const css::uno::Reference<css::uno::XComponentContext> &xContext, librevenge::RVNGTextInterface &rGenerator, const OUString &rURL, const css::uno::Sequence<css::beans::PropertyValue> &rDescriptor);
|
||||
|
@ -78,6 +81,7 @@ public:
|
|||
std::map<OUString, librevenge::RVNGPropertyList> &GetGraphicStyles();
|
||||
const librevenge::RVNGPropertyListVector &GetCoverImages();
|
||||
const librevenge::RVNGPropertyList &GetMetaData();
|
||||
bool FillPopupData(const OUString &rURL, librevenge::RVNGPropertyList &rPropList);
|
||||
|
||||
// XDocumentHandler
|
||||
void SAL_CALL startDocument() override;
|
||||
|
|
Loading…
Reference in a new issue