1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "hyperlinkcontext.hxx"
22 #include <com/sun/star/xml/sax/XFastContextHandler.hpp>
24 #include <oox/helper/attributelist.hxx>
25 #include <oox/helper/propertymap.hxx>
26 #include <oox/core/relations.hxx>
27 #include <oox/core/xmlfilterbase.hxx>
28 #include <oox/token/namespaces.hxx>
29 #include <oox/token/properties.hxx>
30 #include <oox/token/tokens.hxx>
31 #include <o3tl/string_view.hxx>
32 #include <ooxresid.hxx>
33 #include <strings.hrc>
35 using namespace ::oox::core
;
37 namespace oox::drawingml
{
39 HyperLinkContext::HyperLinkContext( ContextHandler2Helper
const & rParent
,
40 const AttributeList
& rAttribs
, PropertyMap
& aProperties
)
41 : ContextHandler2( rParent
)
42 , maProperties(aProperties
)
45 OUString aRelId
= rAttribs
.getStringDefaulted( R_TOKEN( id
) );
46 if ( !aRelId
.isEmpty() )
48 sHref
= getRelations().getExternalTargetFromRelId( aRelId
);
49 if( !sHref
.isEmpty() )
51 sURL
= getFilter().getAbsoluteUrl( sHref
);
55 // not sure if we also need to set sHref to the internal target
56 sURL
= getRelations().getInternalTargetFromRelId( aRelId
);
59 OUString sTooltip
= rAttribs
.getStringDefaulted( XML_tooltip
);
60 if ( !sTooltip
.isEmpty() )
61 maProperties
.setProperty(PROP_Representation
, sTooltip
);
63 OUString sFrame
= rAttribs
.getStringDefaulted( XML_tgtFrame
);
64 if( !sFrame
.isEmpty() )
65 maProperties
.setProperty(PROP_TargetFrame
, sFrame
);
67 OUString aAction
= rAttribs
.getStringDefaulted( XML_action
);
68 if ( !aAction
.isEmpty() )
70 // reserved values of the unrestricted string aAction:
71 // ppaction://customshow?id=SHOW_ID // custom presentation
72 // ppaction://hlinkfile // external file via r:id
73 // ppaction://hlinkpres?slideindex=SLIDE_NUM // external presentation via r:id
74 // ppaction://hlinkshowjump?jump=endshow
75 // ppaction://hlinkshowjump?jump=firstslide
76 // ppaction://hlinkshowjump?jump=lastslide
77 // ppaction://hlinkshowjump?jump=lastslideviewed
78 // ppaction://hlinkshowjump?jump=nextslide
79 // ppaction://hlinkshowjump?jump=previousslide
80 // ppaction://hlinksldjump
81 // ppaction://macro?name=MACRO_NAME
84 static constexpr OUString
sPPAction( u
"ppaction://"_ustr
);
85 if ( aAction
.matchIgnoreAsciiCase( sPPAction
) )
87 OUString
aPPAct( aAction
.copy( sPPAction
.getLength() ) );
88 sal_Int32 nIndex
= aPPAct
.indexOf( '?' );
89 OUString
aPPAction( nIndex
> 0 ? aPPAct
.copy( 0, nIndex
) : aPPAct
);
91 if ( aPPAction
.match( "hlinkshowjump" ) )
93 static constexpr OUString
sJump( u
"jump="_ustr
);
94 if ( aPPAct
.match( sJump
, nIndex
+ 1 ) )
96 std::u16string_view
aDestination( aPPAct
.subView( nIndex
+ 1 + sJump
.getLength() ) );
97 sURL
+= OUString::Concat("#action?jump=") + aDestination
;
100 else if ( aPPAction
.match( "hlinksldjump" ) )
104 sal_Int32 nIndex2
= 0;
105 while ( nIndex2
< sHref
.getLength() )
107 sal_Unicode nChar
= sHref
[ nIndex2
];
108 if ( ( nChar
>= '0' ) && ( nChar
<= '9' ) )
112 if ( nIndex2
&& ( nIndex2
!= sHref
.getLength() ) )
114 sal_Int32 nLength
= 1;
115 while( ( nIndex2
+ nLength
) < sHref
.getLength() )
117 sal_Unicode nChar
= sHref
[ nIndex2
+ nLength
];
118 if ( ( nChar
< '0' ) || ( nChar
> '9' ) )
122 sal_Int32 nPageNumber
= o3tl::toInt32(sHref
.subView( nIndex2
, nLength
));
125 const OUString
aSlideType( sHref
.copy( 0, nIndex2
) );
126 if ( aSlideType
.match( "slide" ) )
127 sURL
= "#" + URLResId(STR_SLIDE_NAME
) + " " + OUString::number( nPageNumber
);
128 else if ( aSlideType
.match( "notesSlide" ) )
129 sURL
= "#Notes " + OUString::number( nPageNumber
);
130 // else: todo for other types such as notesMaster or slideMaster as they can't be referenced easily
135 maProperties
.setProperty(PROP_Action
, aAction
);
138 if ( !sURL
.isEmpty() )
139 maProperties
.setProperty(PROP_URL
, sURL
);
141 OUString sInvalidUrl
= rAttribs
.getStringDefaulted(XML_invalidUrl
);
142 if (!sInvalidUrl
.isEmpty())
143 maProperties
.setProperty(PROP_InvalidUrl
, sInvalidUrl
);
145 bool bHistory
= rAttribs
.getBool(XML_history
, true); // default="true"
146 if (!bHistory
) // set only if it is false
147 maProperties
.setProperty(PROP_History
, bHistory
);
149 bool bHighlightClick
= rAttribs
.getBool(XML_highlightClick
, false);
151 maProperties
.setProperty(PROP_HighlightClick
, bHighlightClick
);
153 bool bEndSnd
= rAttribs
.getBool(XML_endSnd
, false);
155 maProperties
.setProperty(PROP_EndSnd
, bEndSnd
);
158 HyperLinkContext::~HyperLinkContext()
162 ContextHandlerRef
HyperLinkContext::onCreateContext(
163 ::sal_Int32 aElement
, const AttributeList
& )
167 case A_TOKEN( extLst
):
168 maProperties
.setProperty(PROP_CharColor
, XML_fillcolor
);
171 // TODO use getEmbeddedWAVAudioFile() here
178 } // namespace oox::drawingml
180 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */