diff options
author | Markus Mohrhard <markus.mohrhard@googlemail.com> | 2015-05-27 19:15:12 +0200 |
---|---|---|
committer | Markus Mohrhard <markus.mohrhard@googlemail.com> | 2015-05-27 20:41:44 +0200 |
commit | 5d33f6634c5fb84cb2a801d7819c8affb031cc02 (patch) | |
tree | eb924308ceed95a859f92bd6e007258e8441a7aa /sc | |
parent | 27dde67419e8418a79bab3eab4082c5e341dfd04 (diff) |
transform calc URLs to OOXML format, related tdf#91334
Change-Id: I497a6600e155200e913ed386a539f284a5c86320
Diffstat (limited to 'sc')
-rw-r--r-- | sc/source/filter/excel/xeescher.cxx | 4 | ||||
-rw-r--r-- | sc/source/filter/inc/xcl97esc.hxx | 2 | ||||
-rw-r--r-- | sc/source/filter/inc/xcl97rec.hxx | 4 | ||||
-rw-r--r-- | sc/source/filter/inc/xeescher.hxx | 2 | ||||
-rw-r--r-- | sc/source/filter/xcl97/xcl97esc.cxx | 14 | ||||
-rw-r--r-- | sc/source/filter/xcl97/xcl97rec.cxx | 104 |
6 files changed, 117 insertions, 13 deletions
diff --git a/sc/source/filter/excel/xeescher.cxx b/sc/source/filter/excel/xeescher.cxx index 9caee24d6d43..c0d1cf0583ed 100644 --- a/sc/source/filter/excel/xeescher.cxx +++ b/sc/source/filter/excel/xeescher.cxx @@ -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 ) ) diff --git a/sc/source/filter/inc/xcl97esc.hxx b/sc/source/filter/inc/xcl97esc.hxx index e5d1bd1d52ec..a101befb5a7b 100644 --- a/sc/source/filter/inc/xcl97esc.hxx +++ b/sc/source/filter/inc/xcl97esc.hxx @@ -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 ); }; diff --git a/sc/source/filter/inc/xcl97rec.hxx b/sc/source/filter/inc/xcl97rec.hxx index 222c5cba3a27..5b1c744292da 100644 --- a/sc/source/filter/inc/xcl97rec.hxx +++ b/sc/source/filter/inc/xcl97rec.hxx @@ -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 -------------------------------------------- diff --git a/sc/source/filter/inc/xeescher.hxx b/sc/source/filter/inc/xeescher.hxx index 56b183a39e82..98e08d58c2d9 100644 --- a/sc/source/filter/inc/xeescher.hxx +++ b/sc/source/filter/inc/xeescher.hxx @@ -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; diff --git a/sc/source/filter/xcl97/xcl97esc.cxx b/sc/source/filter/xcl97/xcl97esc.cxx index 6bd7448a780e..a17ac85c290b 100644 --- a/sc/source/filter/xcl97/xcl97esc.cxx +++ b/sc/source/filter/xcl97/xcl97esc.cxx @@ -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 diff --git a/sc/source/filter/xcl97/xcl97rec.cxx b/sc/source/filter/xcl97/xcl97rec.cxx index ae8b93b67cc2..46deb7e9c2b6 100644 --- a/sc/source/filter/xcl97/xcl97rec.cxx +++ b/sc/source/filter/xcl97/xcl97rec.cxx @@ -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 ), |