summaryrefslogtreecommitdiff
path: root/oox
diff options
context:
space:
mode:
authorGülşah Köse <gulsah.kose@collabora.com>2021-07-07 00:27:58 +0300
committerGülşah Köse <gulsah.kose@collabora.com>2021-07-12 15:46:03 +0200
commit876b0ae4b50ed85ab0975215efda805248a46993 (patch)
tree37417e5b08eef4c69fca1febabf86565f2e58138 /oox
parentfb5b05f92e13c064c0af1009d5597d77c949937f (diff)
tdf143222 Handle alternate content of graphicData element.
Handle alternate content and make true choice. According to ooxml spec ole object requires exactly one pic element. (ECMA-376 Part 1, Annex A, CT_OleObject). In the current case first choice has not pic element and we should allow fallback processing. Change-Id: I30b7de703b8c2f00d6bf286e05eea505ac3627f2 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/118539 Tested-by: Jenkins Reviewed-by: Gülşah Köse <gulsah.kose@collabora.com> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/118676 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice@gmail.com> Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
Diffstat (limited to 'oox')
-rw-r--r--oox/source/core/contexthandler2.cxx85
-rw-r--r--oox/source/core/fragmenthandler2.cxx70
-rw-r--r--oox/source/drawingml/graphicshapecontext.cxx11
3 files changed, 95 insertions, 71 deletions
diff --git a/oox/source/core/contexthandler2.cxx b/oox/source/core/contexthandler2.cxx
index a63a9b6ba1a5..be4c9806c5fc 100644
--- a/oox/source/core/contexthandler2.cxx
+++ b/oox/source/core/contexthandler2.cxx
@@ -18,16 +18,20 @@
*/
#include <oox/core/contexthandler2.hxx>
+#include <oox/core/xmlfilterbase.hxx>
#include <oox/helper/attributelist.hxx>
#include <oox/token/namespaces.hxx>
#include <oox/token/tokens.hxx>
#include <rtl/ustrbuf.hxx>
#include <o3tl/safeint.hxx>
#include <osl/diagnose.h>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
namespace oox::core {
using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::xml::sax;
/** Information about a processed element. */
@@ -40,10 +44,11 @@ struct ElementInfo
explicit ElementInfo() : maChars( 0), mnElement( XML_TOKEN_INVALID ), mbTrimSpaces( false ) {}
};
-ContextHandler2Helper::ContextHandler2Helper( bool bEnableTrimSpace ) :
+ContextHandler2Helper::ContextHandler2Helper( bool bEnableTrimSpace, XmlFilterBase& rFilter ) :
mxContextStack( std::make_shared<ContextStack>() ),
mnRootStackSize( 0 ),
- mbEnableTrimSpace( bEnableTrimSpace )
+ mbEnableTrimSpace( bEnableTrimSpace ),
+ mrFilter( rFilter )
{
pushElementInfo( XML_ROOT_CONTEXT );
}
@@ -51,7 +56,8 @@ ContextHandler2Helper::ContextHandler2Helper( bool bEnableTrimSpace ) :
ContextHandler2Helper::ContextHandler2Helper( const ContextHandler2Helper& rParent ) :
mxContextStack( rParent.mxContextStack ),
mnRootStackSize( rParent.mxContextStack->size() ),
- mbEnableTrimSpace( rParent.mbEnableTrimSpace )
+ mbEnableTrimSpace( rParent.mbEnableTrimSpace ),
+ mrFilter(rParent.mrFilter)
{
}
@@ -188,6 +194,13 @@ ContextHandler2::~ContextHandler2()
Reference< XFastContextHandler > SAL_CALL ContextHandler2::createFastChildContext(
sal_Int32 nElement, const Reference< XFastAttributeList >& rxAttribs )
{
+ if( getNamespace( nElement ) == NMSP_mce ) // TODO for checking 'Ignorable'
+ {
+ if( prepareMceContext( nElement, AttributeList( rxAttribs ) ) )
+ return this;
+ return nullptr;
+ }
+
return implCreateChildContext( nElement, rxAttribs );
}
@@ -207,6 +220,72 @@ void SAL_CALL ContextHandler2::endFastElement( sal_Int32 nElement )
implEndElement( nElement );
}
+bool ContextHandler2Helper::prepareMceContext( sal_Int32 nElement, const AttributeList& rAttribs )
+{
+ switch( nElement )
+ {
+ case MCE_TOKEN( AlternateContent ):
+ addMCEState( MCE_STATE::Started );
+ break;
+
+ case MCE_TOKEN( Choice ):
+ {
+ if (isMCEStateEmpty() || getMCEState() != MCE_STATE::Started)
+ return false;
+
+ OUString aRequires = rAttribs.getString( XML_Requires, "none" );
+
+ // At this point we can't access namespaces as the correct xml filter
+ // is long gone. For now let's decide depending on a list of supported
+ // namespaces like we do in writerfilter
+
+ std::vector<OUString> aSupportedNS =
+ {
+ "a14", // Impress needs this to import math formulas.
+ "p14",
+ "p15",
+ "x12ac",
+ "v"
+ };
+
+ Reference<XServiceInfo> xModel(getDocFilter().getModel(), UNO_QUERY);
+ if (xModel.is() && xModel->supportsService("com.sun.star.sheet.SpreadsheetDocument"))
+ {
+ // No a14 for Calc documents, it would cause duplicated shapes as-is.
+ auto it = std::find(aSupportedNS.begin(), aSupportedNS.end(), "a14");
+ if (it != aSupportedNS.end())
+ {
+ aSupportedNS.erase(it);
+ }
+ }
+
+ if (std::find(aSupportedNS.begin(), aSupportedNS.end(), aRequires) != aSupportedNS.end())
+ setMCEState( MCE_STATE::FoundChoice ) ;
+ else
+ return false;
+ }
+ break;
+
+ case MCE_TOKEN( Fallback ):
+ if( !isMCEStateEmpty() && getMCEState() == MCE_STATE::Started )
+ break;
+ return false;
+ default:
+ {
+ OUString str = rAttribs.getString( MCE_TOKEN( Ignorable ), OUString() );
+ if( !str.isEmpty() )
+ {
+ // Sequence< css::xml::FastAttribute > attrs = rAttribs.getFastAttributeList()->getFastAttributes();
+ // printf("MCE: %s\n", OUStringToOString( str, RTL_TEXTENCODING_UTF8 ).getStr() );
+ // TODO: Check & Get the namespaces in "Ignorable"
+ // printf("NS: %d : %s\n", attrs.getLength(), OUStringToOString( str, RTL_TEXTENCODING_UTF8 ).getStr() );
+ }
+ }
+ return false;
+ }
+ return true;
+}
+
// oox.core.RecordContext interface -------------------------------------------
ContextHandlerRef ContextHandler2::createRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm )
diff --git a/oox/source/core/fragmenthandler2.cxx b/oox/source/core/fragmenthandler2.cxx
index 121f3443731f..3ee410fad854 100644
--- a/oox/source/core/fragmenthandler2.cxx
+++ b/oox/source/core/fragmenthandler2.cxx
@@ -34,7 +34,7 @@ using namespace ::com::sun::star::xml::sax;
FragmentHandler2::FragmentHandler2( XmlFilterBase& rFilter, const OUString& rFragmentPath, bool bEnableTrimSpace ) :
FragmentHandler( rFilter, rFragmentPath ),
- ContextHandler2Helper( bEnableTrimSpace )
+ ContextHandler2Helper( bEnableTrimSpace, rFilter )
{
}
@@ -54,72 +54,6 @@ void SAL_CALL FragmentHandler2::endDocument()
finalizeImport();
}
-bool FragmentHandler2::prepareMceContext( sal_Int32 nElement, const AttributeList& rAttribs )
-{
- switch( nElement )
- {
- case MCE_TOKEN( AlternateContent ):
- aMceState.push_back( MCE_STATE::Started );
- break;
-
- case MCE_TOKEN( Choice ):
- {
- if (aMceState.empty() || aMceState.back() != MCE_STATE::Started)
- return false;
-
- OUString aRequires = rAttribs.getString( XML_Requires, "none" );
-
- // At this point we can't access namespaces as the correct xml filter
- // is long gone. For now let's decide depending on a list of supported
- // namespaces like we do in writerfilter
-
- std::vector<OUString> aSupportedNS =
- {
- "a14", // Impress needs this to import math formulas.
- "p14",
- "p15",
- "x12ac",
- "v",
- };
-
- uno::Reference<lang::XServiceInfo> xModel(getFilter().getModel(), uno::UNO_QUERY);
- if (xModel.is() && xModel->supportsService("com.sun.star.sheet.SpreadsheetDocument"))
- {
- // No a14 for Calc documents, it would cause duplicated shapes as-is.
- auto it = std::find(aSupportedNS.begin(), aSupportedNS.end(), "a14");
- if (it != aSupportedNS.end())
- {
- aSupportedNS.erase(it);
- }
- }
-
- if (std::find(aSupportedNS.begin(), aSupportedNS.end(), aRequires) != aSupportedNS.end())
- aMceState.back() = MCE_STATE::FoundChoice;
- else
- return false;
- }
- break;
-
- case MCE_TOKEN( Fallback ):
- if( !aMceState.empty() && aMceState.back() == MCE_STATE::Started )
- break;
- return false;
- default:
- {
- OUString str = rAttribs.getString( MCE_TOKEN( Ignorable ), OUString() );
- if( !str.isEmpty() )
- {
- // Sequence< css::xml::FastAttribute > attrs = rAttribs.getFastAttributeList()->getFastAttributes();
- // printf("MCE: %s\n", OUStringToOString( str, RTL_TEXTENCODING_UTF8 ).getStr() );
- // TODO: Check & Get the namespaces in "Ignorable"
- // printf("NS: %d : %s\n", attrs.getLength(), OUStringToOString( str, RTL_TEXTENCODING_UTF8 ).getStr() );
- }
- }
- return false;
- }
- return true;
-}
-
// com.sun.star.xml.sax.XFastContextHandler interface -------------------------
Reference< XFastContextHandler > SAL_CALL FragmentHandler2::createFastChildContext(
@@ -151,7 +85,7 @@ void SAL_CALL FragmentHandler2::endFastElement( sal_Int32 nElement )
switch( nElement )
{
case MCE_TOKEN( AlternateContent ):
- aMceState.pop_back();
+ removeMCEState();
break;
}
diff --git a/oox/source/drawingml/graphicshapecontext.cxx b/oox/source/drawingml/graphicshapecontext.cxx
index 61d96b583c67..6d6e2d3dcbca 100644
--- a/oox/source/drawingml/graphicshapecontext.cxx
+++ b/oox/source/drawingml/graphicshapecontext.cxx
@@ -210,6 +210,7 @@ ContextHandlerRef OleObjectGraphicDataContext::onCreateContext( sal_Int32 nEleme
mrOleObjectInfo.maName = rAttribs.getXString( XML_name, OUString() );
mrOleObjectInfo.maProgId = rAttribs.getXString( XML_progId, OUString() );
mrOleObjectInfo.mbShowAsIcon = rAttribs.getBool( XML_showAsIcon, false );
+ mrOleObjectInfo.mbHasPicture = false; // Initialize as false
return this;
}
break;
@@ -223,6 +224,7 @@ ContextHandlerRef OleObjectGraphicDataContext::onCreateContext( sal_Int32 nEleme
mrOleObjectInfo.mbAutoUpdate = rAttribs.getBool( XML_updateAutomatic, false );
break;
case PPT_TOKEN( pic ):
+ mrOleObjectInfo.mbHasPicture = true; // Set true if ole object has picture element.
return new GraphicShapeContext( *this, mpMasterShapePtr, mpShapePtr );
break;
}
@@ -231,6 +233,15 @@ ContextHandlerRef OleObjectGraphicDataContext::onCreateContext( sal_Int32 nEleme
return nullptr;
}
+void OleObjectGraphicDataContext::onEndElement()
+{
+ if( getCurrentElement() == PPT_TOKEN( oleObj ) && !isMCEStateEmpty() )
+ {
+ if( getMCEState() == MCE_STATE::FoundChoice && !mrOleObjectInfo.mbHasPicture )
+ setMCEState( MCE_STATE::Started );
+ }
+}
+
DiagramGraphicDataContext::DiagramGraphicDataContext( ContextHandler2Helper const & rParent, const ShapePtr& pShapePtr )
: ShapeContext( rParent, ShapePtr(), pShapePtr )
{