001: /* ====================================================================
002: Licensed to the Apache Software Foundation (ASF) under one or more
003: contributor license agreements. See the NOTICE file distributed with
004: this work for additional information regarding copyright ownership.
005: The ASF licenses this file to You under the Apache License, Version 2.0
006: (the "License"); you may not use this file except in compliance with
007: the License. You may obtain a copy of the License at
008:
009: http://www.apache.org/licenses/LICENSE-2.0
010:
011: Unless required by applicable law or agreed to in writing, software
012: distributed under the License is distributed on an "AS IS" BASIS,
013: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: See the License for the specific language governing permissions and
015: limitations under the License.
016: ==================================================================== */
017:
018: package org.apache.poi.hslf.model;
019:
020: import org.apache.poi.hslf.record.*;
021: import org.apache.poi.hslf.usermodel.SlideShow;
022: import org.apache.poi.ddf.EscherContainerRecord;
023: import org.apache.poi.ddf.EscherRecord;
024: import org.apache.poi.ddf.EscherClientDataRecord;
025:
026: import java.util.ArrayList;
027: import java.util.List;
028: import java.util.Iterator;
029:
030: /**
031: * Represents a hyperlink in a PowerPoint document
032: *
033: * @author Yegor Kozlov
034: */
035: public class Hyperlink {
036:
037: private int type;
038: private String address;
039: private String title;
040: private int startIndex, endIndex;
041:
042: /**
043: * Gets the type of the hyperlink action.
044: * Must be a <code>ACTION_*</code> constant defined in <code>InteractiveInfoAtom</code>
045: *
046: * @return the hyperlink URL
047: * @see InteractiveInfoAtom
048: */
049: public int getType() {
050: return type;
051: }
052:
053: /**
054: * Gets the hyperlink URL
055: *
056: * @return the hyperlink URL
057: */
058: public String getAddress() {
059: return address;
060: }
061:
062: /**
063: * Gets the hyperlink user-friendly title (if different from URL)
064: *
065: * @return the hyperlink user-friendly title
066: */
067: public String getTitle() {
068: return title;
069: }
070:
071: /**
072: * Gets the beginning character position
073: *
074: * @return the beginning character position
075: */
076: public int getStartIndex() {
077: return startIndex;
078: }
079:
080: /**
081: * Gets the ending character position
082: *
083: * @return the ending character position
084: */
085: public int getEndIndex() {
086: return endIndex;
087: }
088:
089: /**
090: * Find hyperlinks in a text run
091: *
092: * @param run <code>TextRun</code> to lookup hyperlinks in
093: * @return found hyperlinks or <code>null</code> if not found
094: */
095: protected static Hyperlink[] find(TextRun run) {
096: ArrayList lst = new ArrayList();
097: SlideShow ppt = run.getSheet().getSlideShow();
098: //document-level container which stores info about all links in a presentation
099: ExObjList exobj = ppt.getDocumentRecord().getExObjList();
100: if (exobj == null) {
101: return null;
102: }
103: Record[] records = run._records;
104: if (records != null)
105: find(records, exobj, lst);
106:
107: Hyperlink[] links = null;
108: if (lst.size() > 0) {
109: links = new Hyperlink[lst.size()];
110: lst.toArray(links);
111: }
112: return links;
113: }
114:
115: /**
116: * Find hyperlink assigned to the supplied shape
117: *
118: * @param shape <code>Shape</code> to lookup hyperlink in
119: * @return found hyperlink or <code>null</code>
120: */
121: protected static Hyperlink find(Shape shape) {
122: ArrayList lst = new ArrayList();
123: SlideShow ppt = shape.getSheet().getSlideShow();
124: //document-level container which stores info about all links in a presentation
125: ExObjList exobj = ppt.getDocumentRecord().getExObjList();
126: if (exobj == null) {
127: return null;
128: }
129:
130: EscherContainerRecord spContainer = shape.getSpContainer();
131: List spchild = spContainer.getChildRecords();
132: for (Iterator it = spchild.iterator(); it.hasNext();) {
133: EscherRecord obj = (EscherRecord) it.next();
134: if (obj.getRecordId() == EscherClientDataRecord.RECORD_ID) {
135: byte[] data = ((EscherContainerRecord) obj).serialize();
136: Record[] records = Record.findChildRecords(data, 8,
137: data.length - 8);
138: if (records != null)
139: find(records, exobj, lst);
140: }
141: }
142:
143: return lst.size() == 1 ? (Hyperlink) lst.get(0) : null;
144: }
145:
146: private static void find(Record[] records, ExObjList exobj, List out) {
147: for (int i = 0; i < records.length; i++) {
148: //see if we have InteractiveInfo in the textrun's records
149: if (records[i] instanceof InteractiveInfo) {
150: InteractiveInfo hldr = (InteractiveInfo) records[i];
151: InteractiveInfoAtom info = hldr
152: .getInteractiveInfoAtom();
153: int id = info.getHyperlinkID();
154: ExHyperlink linkRecord = exobj.get(id);
155: if (linkRecord != null) {
156: Hyperlink link = new Hyperlink();
157: link.title = linkRecord.getLinkTitle();
158: link.address = linkRecord.getLinkURL();
159: link.type = info.getAction();
160:
161: if (++i < records.length
162: && records[i] instanceof TxInteractiveInfoAtom) {
163: TxInteractiveInfoAtom txinfo = (TxInteractiveInfoAtom) records[i];
164: link.startIndex = txinfo.getStartIndex();
165: link.endIndex = txinfo.getEndIndex();
166: }
167: out.add(link);
168: }
169: }
170: }
171: }
172: }
|