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 {
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 {
private:
......@@ -69,6 +79,7 @@ private:
sal_Int32 mnXmlNamespace;
Fraction maFraction;
MapMode maMapModeSrc, maMapModeDest;
std::shared_ptr<URLTransformer> mpURLTransformer;
::com::sun::star::awt::Size MapSize( const ::com::sun::star::awt::Size& ) const;
......@@ -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 );
virtual ~ShapeExport() {}
void SetURLTranslator(std::shared_ptr<URLTransformer> pTransformer);
static bool NonEmptyText( ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > xIface );
ShapeExport&
......
......@@ -107,6 +107,20 @@ using ::sax_fastparser::FSHelperPtr;
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) \
GetProperty( rXPropSet, OUString(#propName))
......@@ -130,6 +144,12 @@ ShapeExport::ShapeExport( sal_Int32 nXmlNamespace, FSHelperPtr pFS, ShapeHashMap
, maMapModeDest( MAP_INCH, Point(), maFraction, maFraction )
, 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
......@@ -445,7 +465,8 @@ ShapeExport& ShapeExport::WriteCustomShape( Reference< XShape > xShape )
{
OUString sRelId = mpFB->addRelation( mpFS->getOutputStream(),
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink",
sURL, true );
mpURLTransformer->getTransformedString(sURL),
mpURLTransformer->isExternalURL(sURL));
mpFS->singleElementNS( XML_a, XML_hlinkClick,
FSNS( XML_r,XML_id ), USS( sRelId ),
......
......@@ -1332,8 +1332,8 @@ XclMacroHelper::SetMacroLink( const OUString& rMacroName )
return false;
}
XclExpShapeObj::XclExpShapeObj( XclExpObjectManager& rRoot, ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > xShape ) :
XclObjAny( rRoot, xShape ),
XclExpShapeObj::XclExpShapeObj( XclExpObjectManager& rRoot, ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > xShape, ScDocument* pDoc ) :
XclObjAny( rRoot, xShape, pDoc ),
XclMacroHelper( rRoot )
{
if( SdrObject* pSdrObj = ::GetSdrObjectFromXShape( xShape ) )
......
......@@ -58,7 +58,7 @@ class ShapeInteractionHelper
{
public:
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 );
};
......
......@@ -250,7 +250,8 @@ protected:
public:
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();
com::sun::star::uno::Reference< com::sun::star::drawing::XShape >
......@@ -264,6 +265,7 @@ public:
private:
com::sun::star::uno::Reference< com::sun::star::drawing::XShape >
mxShape;
ScDocument* mpDoc;
};
// --- class ExcBof8_Base --------------------------------------------
......
......@@ -211,7 +211,7 @@ public:
class XclExpShapeObj : public XclObjAny, public XclMacroHelper
{
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();
private:
virtual void WriteSubRecs( XclExpStream& rStrm ) SAL_OVERRIDE;
......
......@@ -206,7 +206,7 @@ EscherExHostAppData* XclEscherEx::StartShape( const Reference< XShape >& rxShape
//added for exporting OCX control
sal_Int16 nMsCtlType = 0;
if ( !pObj )
pCurrXclObj = new XclObjAny( mrObjMgr, rxShape ); // just what is it?!?
pCurrXclObj = new XclObjAny( mrObjMgr, rxShape, GetDocPtr() ); // just what is it?!?
else
{
pCurrXclObj = NULL;
......@@ -231,10 +231,10 @@ EscherExHostAppData* XclEscherEx::StartShape( const Reference< XShape >& rxShape
pCurrXclObj = new XclObjOle( mrObjMgr, *pObj );
}
else // just a metafile
pCurrXclObj = new XclObjAny( mrObjMgr, rxShape );
pCurrXclObj = new XclObjAny( mrObjMgr, rxShape, GetDocPtr() );
}
else
pCurrXclObj = new XclObjAny( mrObjMgr, rxShape );
pCurrXclObj = new XclObjAny( mrObjMgr, rxShape, GetDocPtr() );
}
else if( nObjType == OBJ_UNO )
{
......@@ -255,13 +255,13 @@ EscherExHostAppData* XclEscherEx::StartShape( const Reference< XShape >& rxShape
else //TBX Form Control
pCurrXclObj = CreateTBXCtrlObj( rxShape, pChildAnchor );
if( !pCurrXclObj )
pCurrXclObj = new XclObjAny( mrObjMgr, rxShape ); // just a metafile
pCurrXclObj = new XclObjAny( mrObjMgr, rxShape, GetDocPtr() ); // just a metafile
}
else if( !ScDrawLayer::IsNoteCaption( pObj ) )
{
// ignore permanent note shapes
// #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 );
}
}
......@@ -542,9 +542,9 @@ void XclEscherClientTextbox::WriteData( EscherEx& /*rEx*/ ) const
}
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
......
......@@ -30,6 +30,7 @@
#include <editeng/writingmodeitem.hxx>
#include <vcl/svapp.hxx>
#include <vcl/settings.hxx>
#include <tools/urlobj.hxx>
#include <rtl/math.hxx>
#include <svl/zformat.hxx>
......@@ -956,9 +957,10 @@ void XclObjOle::Save( XclExpStream& rStrm )
// --- 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 )
, mxShape( rShape )
, mpDoc(pDoc)
{
}
......@@ -1047,6 +1049,104 @@ GetEditAs( XclObjAny& rObj )
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 )
{
// ignore group shapes at the moment, we don't process them correctly
......@@ -1057,6 +1157,8 @@ void XclObjAny::SaveXml( XclExpXmlStream& rStrm )
sax_fastparser::FSHelperPtr pDrawing = rStrm.GetCurrentStream();
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
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