Kaydet (Commit) 5d33f663 authored tarafından Markus Mohrhard's avatar Markus Mohrhard

transform calc URLs to OOXML format, related tdf#91334

Change-Id: I497a6600e155200e913ed386a539f284a5c86320
üst 27dde674
...@@ -40,6 +40,16 @@ namespace drawing { ...@@ -40,6 +40,16 @@ namespace drawing {
namespace oox { namespace drawingml { namespace oox { namespace drawingml {
class OOX_DLLPUBLIC URLTransformer
{
public:
virtual ~URLTransformer();
virtual OUString getTransformedString(const OUString& rURL) const;
virtual bool isExternalURL(const OUString& rURL) const;
};
class OOX_DLLPUBLIC ShapeExport : public DrawingML { class OOX_DLLPUBLIC ShapeExport : public DrawingML {
private: private:
...@@ -69,6 +79,7 @@ private: ...@@ -69,6 +79,7 @@ private:
sal_Int32 mnXmlNamespace; sal_Int32 mnXmlNamespace;
Fraction maFraction; Fraction maFraction;
MapMode maMapModeSrc, maMapModeDest; MapMode maMapModeSrc, maMapModeDest;
std::shared_ptr<URLTransformer> mpURLTransformer;
::com::sun::star::awt::Size MapSize( const ::com::sun::star::awt::Size& ) const; ::com::sun::star::awt::Size MapSize( const ::com::sun::star::awt::Size& ) const;
...@@ -81,6 +92,8 @@ public: ...@@ -81,6 +92,8 @@ public:
ShapeExport( sal_Int32 nXmlNamespace, ::sax_fastparser::FSHelperPtr pFS, ShapeHashMap* pShapeMap = NULL, ::oox::core::XmlFilterBase* pFB = NULL, DocumentType eDocumentType = DOCUMENT_PPTX, DMLTextExport* pTextExport = 0 ); ShapeExport( sal_Int32 nXmlNamespace, ::sax_fastparser::FSHelperPtr pFS, ShapeHashMap* pShapeMap = NULL, ::oox::core::XmlFilterBase* pFB = NULL, DocumentType eDocumentType = DOCUMENT_PPTX, DMLTextExport* pTextExport = 0 );
virtual ~ShapeExport() {} virtual ~ShapeExport() {}
void SetURLTranslator(std::shared_ptr<URLTransformer> pTransformer);
static bool NonEmptyText( ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > xIface ); static bool NonEmptyText( ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > xIface );
ShapeExport& ShapeExport&
......
...@@ -107,6 +107,20 @@ using ::sax_fastparser::FSHelperPtr; ...@@ -107,6 +107,20 @@ using ::sax_fastparser::FSHelperPtr;
namespace oox { namespace drawingml { namespace oox { namespace drawingml {
URLTransformer::~URLTransformer()
{
}
OUString URLTransformer::getTransformedString(const OUString& rString) const
{
return rString;
}
bool URLTransformer::isExternalURL(const OUString& /*rURL*/) const
{
return true;
}
#define GETA(propName) \ #define GETA(propName) \
GetProperty( rXPropSet, OUString(#propName)) GetProperty( rXPropSet, OUString(#propName))
...@@ -130,6 +144,12 @@ ShapeExport::ShapeExport( sal_Int32 nXmlNamespace, FSHelperPtr pFS, ShapeHashMap ...@@ -130,6 +144,12 @@ ShapeExport::ShapeExport( sal_Int32 nXmlNamespace, FSHelperPtr pFS, ShapeHashMap
, maMapModeDest( MAP_INCH, Point(), maFraction, maFraction ) , maMapModeDest( MAP_INCH, Point(), maFraction, maFraction )
, mpShapeMap( pShapeMap ? pShapeMap : &maShapeMap ) , mpShapeMap( pShapeMap ? pShapeMap : &maShapeMap )
{ {
mpURLTransformer.reset(new URLTransformer);
}
void ShapeExport::SetURLTranslator(std::shared_ptr<URLTransformer> pTransformer)
{
mpURLTransformer = pTransformer;
} }
awt::Size ShapeExport::MapSize( const awt::Size& rSize ) const awt::Size ShapeExport::MapSize( const awt::Size& rSize ) const
...@@ -445,7 +465,8 @@ ShapeExport& ShapeExport::WriteCustomShape( Reference< XShape > xShape ) ...@@ -445,7 +465,8 @@ ShapeExport& ShapeExport::WriteCustomShape( Reference< XShape > xShape )
{ {
OUString sRelId = mpFB->addRelation( mpFS->getOutputStream(), OUString sRelId = mpFB->addRelation( mpFS->getOutputStream(),
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink", "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink",
sURL, true ); mpURLTransformer->getTransformedString(sURL),
mpURLTransformer->isExternalURL(sURL));
mpFS->singleElementNS( XML_a, XML_hlinkClick, mpFS->singleElementNS( XML_a, XML_hlinkClick,
FSNS( XML_r,XML_id ), USS( sRelId ), FSNS( XML_r,XML_id ), USS( sRelId ),
......
...@@ -1332,8 +1332,8 @@ XclMacroHelper::SetMacroLink( const OUString& rMacroName ) ...@@ -1332,8 +1332,8 @@ XclMacroHelper::SetMacroLink( const OUString& rMacroName )
return false; return false;
} }
XclExpShapeObj::XclExpShapeObj( XclExpObjectManager& rRoot, ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > xShape ) : XclExpShapeObj::XclExpShapeObj( XclExpObjectManager& rRoot, ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > xShape, ScDocument* pDoc ) :
XclObjAny( rRoot, xShape ), XclObjAny( rRoot, xShape, pDoc ),
XclMacroHelper( rRoot ) XclMacroHelper( rRoot )
{ {
if( SdrObject* pSdrObj = ::GetSdrObjectFromXShape( xShape ) ) if( SdrObject* pSdrObj = ::GetSdrObjectFromXShape( xShape ) )
......
...@@ -58,7 +58,7 @@ class ShapeInteractionHelper ...@@ -58,7 +58,7 @@ class ShapeInteractionHelper
{ {
public: public:
static XclExpShapeObj* CreateShapeObj( XclExpObjectManager& rObjMgr, const ::com::sun::star::uno::Reference< static XclExpShapeObj* CreateShapeObj( XclExpObjectManager& rObjMgr, const ::com::sun::star::uno::Reference<
::com::sun::star::drawing::XShape >& xShape ); ::com::sun::star::drawing::XShape >& xShape, ScDocument* pDoc );
static void PopulateShapeInteractionInfo( XclExpObjectManager& rObjMgr, const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& xShape, EscherExHostAppData& rHostAppData ); static void PopulateShapeInteractionInfo( XclExpObjectManager& rObjMgr, const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& xShape, EscherExHostAppData& rHostAppData );
}; };
......
...@@ -250,7 +250,8 @@ protected: ...@@ -250,7 +250,8 @@ protected:
public: public:
XclObjAny( XclExpObjectManager& rObjMgr, XclObjAny( XclExpObjectManager& rObjMgr,
const com::sun::star::uno::Reference< com::sun::star::drawing::XShape >& rShape ); const com::sun::star::uno::Reference< com::sun::star::drawing::XShape >& rShape,
ScDocument* pDoc);
virtual ~XclObjAny(); virtual ~XclObjAny();
com::sun::star::uno::Reference< com::sun::star::drawing::XShape > com::sun::star::uno::Reference< com::sun::star::drawing::XShape >
...@@ -264,6 +265,7 @@ public: ...@@ -264,6 +265,7 @@ public:
private: private:
com::sun::star::uno::Reference< com::sun::star::drawing::XShape > com::sun::star::uno::Reference< com::sun::star::drawing::XShape >
mxShape; mxShape;
ScDocument* mpDoc;
}; };
// --- class ExcBof8_Base -------------------------------------------- // --- class ExcBof8_Base --------------------------------------------
......
...@@ -211,7 +211,7 @@ public: ...@@ -211,7 +211,7 @@ public:
class XclExpShapeObj : public XclObjAny, public XclMacroHelper class XclExpShapeObj : public XclObjAny, public XclMacroHelper
{ {
public: public:
explicit XclExpShapeObj( XclExpObjectManager& rRoot, ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > xShape ); explicit XclExpShapeObj( XclExpObjectManager& rRoot, ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > xShape, ScDocument* pDoc );
virtual ~XclExpShapeObj(); virtual ~XclExpShapeObj();
private: private:
virtual void WriteSubRecs( XclExpStream& rStrm ) SAL_OVERRIDE; virtual void WriteSubRecs( XclExpStream& rStrm ) SAL_OVERRIDE;
......
...@@ -206,7 +206,7 @@ EscherExHostAppData* XclEscherEx::StartShape( const Reference< XShape >& rxShape ...@@ -206,7 +206,7 @@ EscherExHostAppData* XclEscherEx::StartShape( const Reference< XShape >& rxShape
//added for exporting OCX control //added for exporting OCX control
sal_Int16 nMsCtlType = 0; sal_Int16 nMsCtlType = 0;
if ( !pObj ) if ( !pObj )
pCurrXclObj = new XclObjAny( mrObjMgr, rxShape ); // just what is it?!? pCurrXclObj = new XclObjAny( mrObjMgr, rxShape, GetDocPtr() ); // just what is it?!?
else else
{ {
pCurrXclObj = NULL; pCurrXclObj = NULL;
...@@ -231,10 +231,10 @@ EscherExHostAppData* XclEscherEx::StartShape( const Reference< XShape >& rxShape ...@@ -231,10 +231,10 @@ EscherExHostAppData* XclEscherEx::StartShape( const Reference< XShape >& rxShape
pCurrXclObj = new XclObjOle( mrObjMgr, *pObj ); pCurrXclObj = new XclObjOle( mrObjMgr, *pObj );
} }
else // just a metafile else // just a metafile
pCurrXclObj = new XclObjAny( mrObjMgr, rxShape ); pCurrXclObj = new XclObjAny( mrObjMgr, rxShape, GetDocPtr() );
} }
else else
pCurrXclObj = new XclObjAny( mrObjMgr, rxShape ); pCurrXclObj = new XclObjAny( mrObjMgr, rxShape, GetDocPtr() );
} }
else if( nObjType == OBJ_UNO ) else if( nObjType == OBJ_UNO )
{ {
...@@ -255,13 +255,13 @@ EscherExHostAppData* XclEscherEx::StartShape( const Reference< XShape >& rxShape ...@@ -255,13 +255,13 @@ EscherExHostAppData* XclEscherEx::StartShape( const Reference< XShape >& rxShape
else //TBX Form Control else //TBX Form Control
pCurrXclObj = CreateTBXCtrlObj( rxShape, pChildAnchor ); pCurrXclObj = CreateTBXCtrlObj( rxShape, pChildAnchor );
if( !pCurrXclObj ) if( !pCurrXclObj )
pCurrXclObj = new XclObjAny( mrObjMgr, rxShape ); // just a metafile pCurrXclObj = new XclObjAny( mrObjMgr, rxShape, GetDocPtr() ); // just a metafile
} }
else if( !ScDrawLayer::IsNoteCaption( pObj ) ) else if( !ScDrawLayer::IsNoteCaption( pObj ) )
{ {
// ignore permanent note shapes // ignore permanent note shapes
// #i12190# do not ignore callouts (do not filter by object type ID) // #i12190# do not ignore callouts (do not filter by object type ID)
pCurrXclObj = ShapeInteractionHelper::CreateShapeObj( mrObjMgr, rxShape ); pCurrXclObj = ShapeInteractionHelper::CreateShapeObj( mrObjMgr, rxShape, GetDocPtr() );
ShapeInteractionHelper::PopulateShapeInteractionInfo( mrObjMgr, rxShape, *pCurrAppData ); ShapeInteractionHelper::PopulateShapeInteractionInfo( mrObjMgr, rxShape, *pCurrAppData );
} }
} }
...@@ -542,9 +542,9 @@ void XclEscherClientTextbox::WriteData( EscherEx& /*rEx*/ ) const ...@@ -542,9 +542,9 @@ void XclEscherClientTextbox::WriteData( EscherEx& /*rEx*/ ) const
} }
XclExpShapeObj* XclExpShapeObj*
ShapeInteractionHelper::CreateShapeObj( XclExpObjectManager& rObjMgr, const Reference< XShape >& xShape ) ShapeInteractionHelper::CreateShapeObj( XclExpObjectManager& rObjMgr, const Reference< XShape >& xShape, ScDocument* pDoc )
{ {
return new XclExpShapeObj( rObjMgr, xShape ); return new XclExpShapeObj( rObjMgr, xShape, pDoc );
} }
void void
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#include <editeng/writingmodeitem.hxx> #include <editeng/writingmodeitem.hxx>
#include <vcl/svapp.hxx> #include <vcl/svapp.hxx>
#include <vcl/settings.hxx> #include <vcl/settings.hxx>
#include <tools/urlobj.hxx>
#include <rtl/math.hxx> #include <rtl/math.hxx>
#include <svl/zformat.hxx> #include <svl/zformat.hxx>
...@@ -956,9 +957,10 @@ void XclObjOle::Save( XclExpStream& rStrm ) ...@@ -956,9 +957,10 @@ void XclObjOle::Save( XclExpStream& rStrm )
// --- class XclObjAny ------------------------------------------- // --- class XclObjAny -------------------------------------------
XclObjAny::XclObjAny( XclExpObjectManager& rObjMgr, const Reference< XShape >& rShape ) XclObjAny::XclObjAny( XclExpObjectManager& rObjMgr, const Reference< XShape >& rShape, ScDocument* pDoc )
: XclObj( rObjMgr, EXC_OBJTYPE_UNKNOWN ) : XclObj( rObjMgr, EXC_OBJTYPE_UNKNOWN )
, mxShape( rShape ) , mxShape( rShape )
, mpDoc(pDoc)
{ {
} }
...@@ -1047,6 +1049,104 @@ GetEditAs( XclObjAny& rObj ) ...@@ -1047,6 +1049,104 @@ GetEditAs( XclObjAny& rObj )
return "absolute"; return "absolute";
} }
namespace {
sal_uInt16 parseRange(const OUString& rString, ScRange& rRange, ScDocument* pDoc)
{
// start with the address convention set in the document
formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
sal_uInt16 nResult = rRange.Parse(rString, pDoc, eConv);
if ( (nResult & SCA_VALID) )
return nResult;
// try the default calc address convention
nResult = rRange.Parse(rString, pDoc);
if ( (nResult & SCA_VALID) )
return nResult;
// try excel a1
return rRange.Parse(rString, pDoc, formula::FormulaGrammar::CONV_XL_A1);
}
sal_uInt16 parseAddress(const OUString& rString, ScAddress& rAddress, ScDocument* pDoc)
{
// start with the address convention set in the document
formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
sal_uInt16 nResult = rAddress.Parse(rString, pDoc, eConv);
if ( (nResult & SCA_VALID) )
return nResult;
// try the default calc address convention
nResult = rAddress.Parse(rString, pDoc);
if ( (nResult & SCA_VALID) )
return nResult;
// try excel a1
return rAddress.Parse(rString, pDoc, formula::FormulaGrammar::CONV_XL_A1);
}
bool transformURL(const OUString& rOldURL, OUString& rNewURL, ScDocument* pDoc)
{
if (rOldURL.startsWith("#"))
{
// URL has to be decoded for escaped characters (%20)
OUString aURL = INetURLObject::decode( rOldURL,
INetURLObject::DECODE_WITH_CHARSET,
RTL_TEXTENCODING_UTF8 );
OUString aAddressString = aURL.copy(1);
ScRange aRange;
ScAddress aAddress;
sal_uInt16 nResult = parseRange(aAddressString, aRange, pDoc);
if (nResult & SCA_VALID)
{
OUString aString = aRange.Format(nResult, pDoc, formula::FormulaGrammar::CONV_XL_OOX);
rNewURL = OUString("#") + aString;
return true;
}
else
{
nResult = parseAddress(aAddressString, aAddress, pDoc);
if(nResult & SCA_VALID)
{
OUString aString = aAddress.Format(nResult, pDoc, formula::FormulaGrammar::CONV_XL_OOX);
rNewURL = OUString("#") + aString;
return true;
}
}
}
rNewURL = rOldURL;
return false;
}
class ScURLTransformer : public oox::drawingml::URLTransformer
{
public:
ScURLTransformer(ScDocument& rDoc):
mrDoc(rDoc)
{
}
virtual OUString getTransformedString(const OUString& rURL) const SAL_OVERRIDE
{
OUString aNewURL;
transformURL(rURL, aNewURL, &mrDoc);
return aNewURL;
}
virtual bool isExternalURL(const OUString& rURL) const SAL_OVERRIDE
{
OUString aNewURL;
return transformURL(rURL, aNewURL, &mrDoc);
}
private:
ScDocument& mrDoc;
};
}
void XclObjAny::SaveXml( XclExpXmlStream& rStrm ) void XclObjAny::SaveXml( XclExpXmlStream& rStrm )
{ {
// ignore group shapes at the moment, we don't process them correctly // ignore group shapes at the moment, we don't process them correctly
...@@ -1057,6 +1157,8 @@ void XclObjAny::SaveXml( XclExpXmlStream& rStrm ) ...@@ -1057,6 +1157,8 @@ void XclObjAny::SaveXml( XclExpXmlStream& rStrm )
sax_fastparser::FSHelperPtr pDrawing = rStrm.GetCurrentStream(); sax_fastparser::FSHelperPtr pDrawing = rStrm.GetCurrentStream();
ShapeExport aDML( XML_xdr, pDrawing, NULL, &rStrm, DrawingML::DOCUMENT_XLSX ); ShapeExport aDML( XML_xdr, pDrawing, NULL, &rStrm, DrawingML::DOCUMENT_XLSX );
std::shared_ptr<oox::drawingml::URLTransformer> pURLTransformer(new ScURLTransformer(*mpDoc));
aDML.SetURLTranslator(pURLTransformer);
pDrawing->startElement( FSNS( XML_xdr, XML_twoCellAnchor ), // OOXTODO: oneCellAnchor, absoluteAnchor pDrawing->startElement( FSNS( XML_xdr, XML_twoCellAnchor ), // OOXTODO: oneCellAnchor, absoluteAnchor
XML_editAs, GetEditAs( *this ), XML_editAs, GetEditAs( *this ),
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment