fix fdo#58237 import hyperlinks for shapes in xlsx documents

Change-Id: Ib0c661dbb3ce9a2f8c8d29707a1cf0c65aadc81f
diff --git a/oox/inc/oox/core/relations.hxx b/oox/inc/oox/core/relations.hxx
index f840448..94b9908 100644
--- a/oox/inc/oox/core/relations.hxx
+++ b/oox/inc/oox/core/relations.hxx
@@ -79,6 +79,8 @@ public:

    /** Returns the external target of the relation with the passed relation identifier. */
    ::rtl::OUString     getExternalTargetFromRelId( const ::rtl::OUString& rRelId ) const;
    /** Returns the internal target of the relation with the passed relation identifier. */
    ::rtl::OUString     getInternalTargetFromRelId( const ::rtl::OUString& rRelId ) const;

    /** Returns the full fragment path for the target of the passed relation. */
    ::rtl::OUString     getFragmentPathFromRelation( const Relation& rRelation ) const;
diff --git a/oox/source/core/relations.cxx b/oox/source/core/relations.cxx
index 501f515..c49fe63 100644
--- a/oox/source/core/relations.cxx
+++ b/oox/source/core/relations.cxx
@@ -83,6 +83,12 @@ OUString Relations::getExternalTargetFromRelId( const OUString& rRelId ) const
    return (pRelation && pRelation->mbExternal) ? pRelation->maTarget : OUString();
}

OUString Relations::getInternalTargetFromRelId( const OUString& rRelId ) const
{
    const Relation* pRelation = getRelationFromRelId( rRelId );
    return (pRelation && !pRelation->mbExternal) ? pRelation->maTarget : OUString();
}

OUString Relations::getFragmentPathFromRelation( const Relation& rRelation ) const
{
    // no target, no fragment path
diff --git a/oox/source/drawingml/hyperlinkcontext.cxx b/oox/source/drawingml/hyperlinkcontext.cxx
index f2d715c..231b7f9 100644
--- a/oox/source/drawingml/hyperlinkcontext.cxx
+++ b/oox/source/drawingml/hyperlinkcontext.cxx
@@ -44,10 +44,12 @@ HyperLinkContext::HyperLinkContext( ContextHandler& rParent,
    {
        OSL_TRACE("OOX: URI rId %s", OUStringToOString (aRelId, RTL_TEXTENCODING_UTF8).pData->buffer);
        sHref = getRelations().getExternalTargetFromRelId( aRelId );
        OUString sExtHref = getRelations().getExternalTargetFromRelId( aRelId );
        sURL = getRelations().getInternalTargetFromRelId( aRelId );
        if( !sHref.isEmpty() )
        {
            OSL_TRACE("OOX: URI href %s", OUStringToOString (sHref, RTL_TEXTENCODING_UTF8).pData->buffer);
            sURL = getFilter().getAbsoluteUrl( sHref );
            sURL = getFilter().getAbsoluteUrl( sExtHref );
        }
    }
    OUString sTooltip = xAttributes->getOptionalValue( R_TOKEN( tooltip ) );
diff --git a/sc/source/filter/inc/worksheetbuffer.hxx b/sc/source/filter/inc/worksheetbuffer.hxx
index bceca55..d58a490 100644
--- a/sc/source/filter/inc/worksheetbuffer.hxx
+++ b/sc/source/filter/inc/worksheetbuffer.hxx
@@ -81,6 +81,10 @@ public:
    sal_Int16           getCalcSheetIndex( const ::rtl::OUString& rWorksheetName ) const;
    /** Returns the finalized name of the sheet with the passed worksheet name. */
    ::rtl::OUString     getCalcSheetName( const ::rtl::OUString& rWorksheetName ) const;
    /** Converts sSheetNameRef (e.g. '#SheetName!A1' to '#SheetName.A1' )
        if sSheetNameRef doesn't start with '#' it is ignored and not modified
    */
    void                convertSheetNameRef( ::rtl::OUString& sSheetNameRef ) const;

private:
    struct SheetInfo : public SheetInfoModel
diff --git a/sc/source/filter/oox/drawingfragment.cxx b/sc/source/filter/oox/drawingfragment.cxx
index bb8fe08..a301326 100644
--- a/sc/source/filter/oox/drawingfragment.cxx
+++ b/sc/source/filter/oox/drawingfragment.cxx
@@ -26,6 +26,9 @@
#include <com/sun/star/script/ScriptEventDescriptor.hpp>
#include <com/sun/star/script/XEventAttacherManager.hpp>
#include <rtl/strbuf.hxx>
#include <svx/svdobj.hxx>
#include "drwlayer.hxx"
#include "userdat.hxx"
#include "oox/drawingml/connectorshapecontext.hxx"
#include "oox/drawingml/graphicshapecontext.hxx"
#include "oox/helper/attributelist.hxx"
@@ -36,11 +39,10 @@
#include "stylesbuffer.hxx"
#include "themebuffer.hxx"
#include "unitconverter.hxx"

#include "worksheetbuffer.hxx"
namespace oox {
namespace xls {

using namespace ::com::sun::star::awt;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::document;
@@ -53,6 +55,10 @@ using namespace ::oox::core;
using namespace ::oox::drawingml;
using namespace ::oox::ole;

using ::com::sun::star::awt::Size;
using ::com::sun::star::awt::Point;
using ::com::sun::star::awt::Rectangle;
using ::com::sun::star::awt::XControlModel;
using ::rtl::OStringBuffer;
using ::rtl::OUString;
using ::rtl::OUStringToOString;
@@ -97,12 +103,24 @@ Shape::Shape( const WorksheetHelper& rHelper, const AttributeList& rAttribs, con

void Shape::finalizeXShape( XmlFilterBase& rFilter, const Reference< XShapes >& rxShapes )
{
    rtl::OUString sURL;
    getShapeProperties()[ PROP_URL ] >>= sURL;
    getWorksheets().convertSheetNameRef( sURL );
    if( !maMacroName.isEmpty() && mxShape.is() )
    {
        VbaMacroAttacherRef xAttacher( new ShapeMacroAttacher( maMacroName, mxShape ) );
        getBaseFilter().getVbaProject().registerMacroAttacher( xAttacher );
    }
    ::oox::drawingml::Shape::finalizeXShape( rFilter, rxShapes );
    if ( !sURL.isEmpty() )
    {
        SdrObject* pObj = SdrObject::getSdrObjectFromXShape( mxShape );
        if ( pObj )
        {
            if ( ScMacroInfo* pInfo = ScDrawLayer::GetMacroInfo( pObj, sal_True ) )
                pInfo->SetHlink( sURL );
        }
    }
}

// ============================================================================
diff --git a/sc/source/filter/oox/worksheetbuffer.cxx b/sc/source/filter/oox/worksheetbuffer.cxx
index 7703ea4..7483900 100644
--- a/sc/source/filter/oox/worksheetbuffer.cxx
+++ b/sc/source/filter/oox/worksheetbuffer.cxx
@@ -110,6 +110,25 @@ OUString WorksheetBuffer::getCalcSheetName( sal_Int32 nWorksheet ) const
    return pSheetInfo ? pSheetInfo->maCalcName : OUString();
}

void WorksheetBuffer::convertSheetNameRef( ::rtl::OUString& sSheetNameRef ) const
{
    // convert '#SheetName!A1' to '#SheetName.A1'
    if( !sSheetNameRef.isEmpty() && (sSheetNameRef[ 0 ] == '#') )
    {
        sal_Int32 nSepPos = sSheetNameRef.lastIndexOf( '!' );
        if( nSepPos > 0 )
        {
            // replace the exclamation mark with a period
            sSheetNameRef = sSheetNameRef.replaceAt( nSepPos, 1, OUString( sal_Unicode( '.' ) ) );
            // #i66592# convert sheet names that have been renamed on import
            OUString aSheetName = sSheetNameRef.copy( 1, nSepPos - 1 );
            OUString aCalcName = getCalcSheetName( aSheetName );
            if( !aCalcName.isEmpty() )
                sSheetNameRef = sSheetNameRef.replaceAt( 1, nSepPos - 1, aCalcName );
        }
    }
}

sal_Int16 WorksheetBuffer::getCalcSheetIndex( const OUString& rWorksheetName ) const
{
    const SheetInfo* pSheetInfo = maSheetInfosByName.get( rWorksheetName ).get();