You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@poi.apache.org by ye...@apache.org on 2007/05/30 13:56:48 UTC

svn commit: r542804 - in /jakarta/poi/trunk/src: documentation/content/xdocs/hslf/ scratchpad/examples/src/org/apache/poi/hslf/examples/ scratchpad/src/org/apache/poi/hslf/model/ scratchpad/src/org/apache/poi/hslf/record/ scratchpad/testcases/org/apach...

Author: yegor
Date: Wed May 30 04:56:46 2007
New Revision: 542804

URL: http://svn.apache.org/viewvc?view=rev&rev=542804
Log:
HSLF: readonly support for hyperlinks

Added:
    jakarta/poi/trunk/src/scratchpad/examples/src/org/apache/poi/hslf/examples/Hyperlinks.java
    jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Hyperlink.java
    jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/TxInteractiveInfoAtom.java
    jakarta/poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/model/TestHyperlink.java
    jakarta/poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/record/TestTxInteractiveInfoAtom.java
Modified:
    jakarta/poi/trunk/src/documentation/content/xdocs/hslf/how-to-shapes.xml
    jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Shape.java
    jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/ShapeGroup.java
    jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Sheet.java
    jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/TextBox.java
    jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/TextRun.java
    jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/EscherTextboxWrapper.java
    jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/ExHyperlink.java
    jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/ExObjList.java
    jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/InteractiveInfoAtom.java
    jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/PPDrawing.java
    jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/RecordTypes.java
    jakarta/poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/model/TestShapes.java
    jakarta/poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/record/TestInteractiveInfo.java
    jakarta/poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/record/TestInteractiveInfoAtom.java

Modified: jakarta/poi/trunk/src/documentation/content/xdocs/hslf/how-to-shapes.xml
URL: http://svn.apache.org/viewvc/jakarta/poi/trunk/src/documentation/content/xdocs/hslf/how-to-shapes.xml?view=diff&rev=542804&r1=542803&r2=542804
==============================================================================
--- jakarta/poi/trunk/src/documentation/content/xdocs/hslf/how-to-shapes.xml (original)
+++ jakarta/poi/trunk/src/documentation/content/xdocs/hslf/how-to-shapes.xml Wed May 30 04:56:46 2007
@@ -38,6 +38,7 @@
                     <li><link href="#SlideTitle">How to set slide title</link></li>
                     <li><link href="#Fill">How to work with slide/shape background</link></li>
                     <li><link href="#Bullets">How to create bulleted lists</link></li>
+                    <li><link href="#Hyperlinks">Hyperlinks</link></li>
                 </ul>
             </section>
             <section><title>Features</title>
@@ -323,31 +324,68 @@
                 <anchor id="Bullets"/>
                 <section><title>How to create bulleted lists</title>
                     <source>
-        SlideShow ppt = new SlideShow();
+  SlideShow ppt = new SlideShow();
 
-        Slide slide = ppt.createSlide();
+  Slide slide = ppt.createSlide();
 
-        TextBox shape = new TextBox();
-        RichTextRun rt = shape.getTextRun().getRichTextRuns()[0];
-        shape.setText(
-                "January\r" +
-                "February\r" +
-                "March\r" +
-                "April");
-        rt.setFontSize(42);
-        rt.setBullet(true);
-        rt.setBulletOffset(0);  //bullet offset
-        rt.setTextOffset(50);   //text offset (should be greater than bullet offset)
-        rt.setBulletChar('\u263A'); //bullet character
-        slide.addShape(shape);
+  TextBox shape = new TextBox();
+  RichTextRun rt = shape.getTextRun().getRichTextRuns()[0];
+  shape.setText(
+          "January\r" +
+          "February\r" +
+          "March\r" +
+          "April");
+  rt.setFontSize(42);
+  rt.setBullet(true);
+  rt.setBulletOffset(0);  //bullet offset
+  rt.setTextOffset(50);   //text offset (should be greater than bullet offset)
+  rt.setBulletChar('\u263A'); //bullet character
+  slide.addShape(shape);
 
-        shape.setAnchor(new java.awt.Rectangle(50, 50, 500, 300));  //position of the text box in the slide
-        slide.addShape(shape);
+  shape.setAnchor(new java.awt.Rectangle(50, 50, 500, 300));  //position of the text box in the slide
+  slide.addShape(shape);
 
-        FileOutputStream out = new FileOutputStream("bullets.ppt");
-        ppt.write(out);
-        out.close();
-                  </source>
+  FileOutputStream out = new FileOutputStream("bullets.ppt");
+  ppt.write(out);
+  out.close();
+                </source>
+                </section>
+                <anchor id="Hyperlinks"/>
+                <section><title>How to read hyperlinks from a slide show</title>
+                    <source>
+    FileInputStream is = new FileInputStream("slideshow.ppt");
+    SlideShow ppt = new SlideShow(is);
+    is.close();
+
+    Slide[] slide = ppt.getSlides();
+    for (int j = 0; j &lt; slide.length; j++) {
+
+        //read hyperlinks from the text runs
+        TextRun[] txt = slide[j].getTextRuns();
+        for (int k = 0; k &lt; txt.length; k++) {
+            String text = txt[k].getText();
+            Hyperlink[] links = txt[k].getHyperlinks();
+            if(links != null) for (int l = 0; l &lt; links.length; l++) {
+                Hyperlink link = links[l];
+                String title = link.getTitle();
+                String address = link.getAddress();
+                String substring = text.substring(link.getStartIndex(), link.getEndIndex()-1); //in ppt end index is inclusive
+            }
+        }
+
+        //in PowerPoint you can assign a hyperlink to a shape without text,
+        //for example to a Line object. The code below demonstrates how to
+        //read such hyperlinks
+        Shape[] sh = slide[j].getShapes();
+        for (int k = 0; k &lt; sh.length; k++) {
+            Hyperlink link = sh[k].getHyperlink();
+            if(link != null)  {
+                String title = link.getTitle();
+                String address = link.getAddress();
+            }
+        }
+    }
+                </source>
                 </section>
                   
             </section>

Added: jakarta/poi/trunk/src/scratchpad/examples/src/org/apache/poi/hslf/examples/Hyperlinks.java
URL: http://svn.apache.org/viewvc/jakarta/poi/trunk/src/scratchpad/examples/src/org/apache/poi/hslf/examples/Hyperlinks.java?view=auto&rev=542804
==============================================================================
--- jakarta/poi/trunk/src/scratchpad/examples/src/org/apache/poi/hslf/examples/Hyperlinks.java (added)
+++ jakarta/poi/trunk/src/scratchpad/examples/src/org/apache/poi/hslf/examples/Hyperlinks.java Wed May 30 04:56:46 2007
@@ -0,0 +1,80 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+package org.apache.poi.hslf.examples;
+
+import org.apache.poi.hslf.usermodel.SlideShow;
+import org.apache.poi.hslf.model.Slide;
+import org.apache.poi.hslf.model.TextRun;
+import org.apache.poi.hslf.model.Hyperlink;
+import org.apache.poi.hslf.model.Shape;
+
+import java.io.FileInputStream;
+
+/**
+ * Demonstrates how to read hyperlinks from  a presentation
+ *
+ * @author Yegor Kozlov
+ */
+public class Hyperlinks {
+
+    public static void main(String[] args) throws Exception {
+        for (int i = 0; i < args.length; i++) {
+            FileInputStream is = new FileInputStream(args[i]);
+            SlideShow ppt = new SlideShow(is);
+            is.close();
+
+            Slide[] slide = ppt.getSlides();
+            for (int j = 0; j < slide.length; j++) {
+                System.out.println("slide " + slide[j].getSlideNumber());
+
+                //read hyperlinks from the slide's text runs
+                System.out.println("reading hyperlinks from the text runs");
+                TextRun[] txt = slide[j].getTextRuns();
+                for (int k = 0; k < txt.length; k++) {
+                    String text = txt[k].getText();
+                    Hyperlink[] links = txt[k].getHyperlinks();
+                    if(links != null) for (int l = 0; l < links.length; l++) {
+                        Hyperlink link = links[l];
+                        String title = link.getTitle();
+                        String address = link.getAddress();
+                        System.out.println("  " + title);
+                        System.out.println("  " + address);
+                        String substring = text.substring(link.getStartIndex(), link.getEndIndex()-1);//in ppt end index is inclusive
+                        System.out.println("  " + substring);
+                    }
+                }
+
+                //in PowerPoint you can assign a hyperlink to a shape without text,
+                //for example to a Line object. The code below demonstrates how to
+                //read such hyperlinks
+                System.out.println("  reading hyperlinks from the slide's shapes");
+                Shape[] sh = slide[j].getShapes();
+                for (int k = 0; k < sh.length; k++) {
+                    Hyperlink link = sh[k].getHyperlink();
+                    if(link != null)  {
+                        String title = link.getTitle();
+                        String address = link.getAddress();
+                        System.out.println("  " + title);
+                        System.out.println("  " + address);
+                    }
+                }
+            }
+
+        }
+
+   }
+}

Added: jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Hyperlink.java
URL: http://svn.apache.org/viewvc/jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Hyperlink.java?view=auto&rev=542804
==============================================================================
--- jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Hyperlink.java (added)
+++ jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Hyperlink.java Wed May 30 04:56:46 2007
@@ -0,0 +1,168 @@
+
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+
+package org.apache.poi.hslf.model;
+
+import org.apache.poi.hslf.record.*;
+import org.apache.poi.hslf.usermodel.SlideShow;
+import org.apache.poi.ddf.EscherContainerRecord;
+import org.apache.poi.ddf.EscherRecord;
+import org.apache.poi.ddf.EscherClientDataRecord;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Iterator;
+
+/**
+ * Represents a hyperlink in a PowerPoint document
+ *
+ * @author Yegor Kozlov
+ */
+public class Hyperlink {
+
+    private int type;
+    private String address;
+    private String title;
+    private int startIndex, endIndex;
+
+    /**
+     * Gets the type of the hyperlink action.
+     * Must be a <code>ACTION_*</code>  constant defined in <code>InteractiveInfoAtom</code>
+     *
+     * @return the hyperlink URL
+     * @see InteractiveInfoAtom
+     */
+    public int getType() {
+        return type;
+    }
+
+    /**
+     * Gets the hyperlink URL
+     *
+     * @return the hyperlink URL
+     */
+    public String getAddress() {
+        return address;
+    }
+
+    /**
+     * Gets the hyperlink user-friendly title (if different from URL)
+     *
+     * @return the  hyperlink user-friendly title
+     */
+    public String getTitle() {
+        return title;
+    }
+
+    /**
+     * Gets the beginning character position
+     *
+     * @return the beginning character position
+     */
+    public int getStartIndex() {
+        return startIndex;
+    }
+
+    /**
+     * Gets the ending character position
+     *
+     * @return the ending character position
+     */
+    public int getEndIndex() {
+        return endIndex;
+    }
+
+    /**
+     * Find hyperlinks in a text run
+     *
+     * @param run  <code>TextRun</code> to lookup hyperlinks in
+     * @return found hyperlinks or <code>null</code> if not found
+     */
+    protected static Hyperlink[] find(TextRun run){
+        ArrayList lst = new ArrayList();
+        SlideShow ppt = run.getSheet().getSlideShow();
+        //document-level container which stores info about all links in a presentation
+        ExObjList exobj = ppt.getDocumentRecord().getExObjList();
+        if (exobj == null) {
+            return null;
+        }
+        Record[] records = run._records;
+        if(records != null) find(records, exobj, lst);
+
+        Hyperlink[] links = null;
+        if (lst.size() > 0){
+            links = new Hyperlink[lst.size()];
+            lst.toArray(links);
+        }
+        return links;
+    }
+
+    /**
+     * Find hyperlink assigned to the supplied shape
+     *
+     * @param shape  <code>Shape</code> to lookup hyperlink in
+     * @return found hyperlink or <code>null</code>
+     */
+    protected static Hyperlink find(Shape shape){
+        ArrayList lst = new ArrayList();
+        SlideShow ppt = shape.getSheet().getSlideShow();
+        //document-level container which stores info about all links in a presentation
+        ExObjList exobj = ppt.getDocumentRecord().getExObjList();
+        if (exobj == null) {
+            return null;
+        }
+
+        EscherContainerRecord spContainer = shape.getSpContainer();
+        List spchild = spContainer.getChildRecords();
+        for (Iterator it = spchild.iterator(); it.hasNext(); ) {
+            EscherRecord obj = (EscherRecord)it.next();
+            if (obj.getRecordId() ==  EscherClientDataRecord.RECORD_ID){
+                byte[] data = ((EscherContainerRecord)obj).serialize();
+                Record[] records = Record.findChildRecords(data, 8, data.length-8);
+                if(records != null) find(records, exobj, lst);
+            }
+        }
+
+        return lst.size() == 1 ? (Hyperlink)lst.get(0) : null;
+    }
+
+    private static void find(Record[] records, ExObjList exobj, List out){
+        for (int i = 0; i < records.length; i++) {
+            //see if we have InteractiveInfo in the textrun's records
+            if( records[i] instanceof InteractiveInfo){
+                InteractiveInfo hldr = (InteractiveInfo)records[i];
+                InteractiveInfoAtom info = hldr.getInteractiveInfoAtom();
+                int id = info.getHyperlinkID();
+                ExHyperlink linkRecord = exobj.get(id);
+                if (linkRecord != null){
+                    Hyperlink link = new Hyperlink();
+                    link.title = linkRecord.getLinkTitle();
+                    link.address = linkRecord.getLinkURL();
+                    link.type = info.getAction();
+
+                    if (++i < records.length && records[i] instanceof TxInteractiveInfoAtom){
+                        TxInteractiveInfoAtom txinfo = (TxInteractiveInfoAtom)records[i];
+                        link.startIndex = txinfo.getStartIndex();
+                        link.endIndex = txinfo.getEndIndex();
+                    }
+                    out.add(link);
+                }
+            }
+        }
+    }
+}

Modified: jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Shape.java
URL: http://svn.apache.org/viewvc/jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Shape.java?view=diff&rev=542804&r1=542803&r2=542804
==============================================================================
--- jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Shape.java (original)
+++ jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Shape.java Wed May 30 04:56:46 2007
@@ -45,7 +45,7 @@
 
     // For logging
     protected POILogger logger = POILogFactory.getLogger(this.getClass());
-    
+
     /**
      * In Escher absolute distances are specified in
      * English Metric Units (EMUs), occasionally referred to as A units;
@@ -307,6 +307,17 @@
      */
     public Fill getFill(){
         return new Fill(this);
+    }
+
+
+    /**
+     * Returns the hyperlink assigned to this shape
+     *
+     * @return the hyperlink assigned to this shape
+     * or <code>null</code> if not found.
+     */
+     public Hyperlink getHyperlink(){
+        return Hyperlink.find(this);
     }
 
 }

Modified: jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/ShapeGroup.java
URL: http://svn.apache.org/viewvc/jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/ShapeGroup.java?view=diff&rev=542804&r1=542803&r2=542804
==============================================================================
--- jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/ShapeGroup.java (original)
+++ jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/ShapeGroup.java Wed May 30 04:56:46 2007
@@ -211,4 +211,13 @@
         return spRecord.getOptions() >> 4;
     }
 
+    /**
+     * Returns <code>null</code> - shape groups can't have hyperlinks
+     *
+     * @return <code>null</code>.
+     */
+     public Hyperlink getHyperlink(){
+        return null;
+    }
+    
 }

Modified: jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Sheet.java
URL: http://svn.apache.org/viewvc/jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Sheet.java?view=diff&rev=542804&r1=542803&r2=542804
==============================================================================
--- jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Sheet.java (original)
+++ jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/Sheet.java Wed May 30 04:56:46 2007
@@ -21,6 +21,7 @@
 import org.apache.poi.ddf.EscherContainerRecord;
 import org.apache.poi.ddf.EscherDgRecord;
 import org.apache.poi.ddf.EscherRecord;
+import org.apache.poi.ddf.EscherSpRecord;
 import org.apache.poi.hslf.record.*;
 import org.apache.poi.hslf.usermodel.SlideShow;
 
@@ -127,7 +128,13 @@
         Vector runsV = new Vector();
         EscherTextboxWrapper[] wrappers = ppdrawing.getTextboxWrappers();
         for (int i = 0; i < wrappers.length; i++) {
+            int s1 = runsV.size();
             findTextRuns(wrappers[i].getChildRecords(), runsV);
+            int s2 = runsV.size();
+            if (s2 != s1){
+                TextRun t = (TextRun) runsV.get(runsV.size()-1);
+                t.setShapeId(wrappers[i].getShapeId());
+            }
         }
         TextRun[] runs = new TextRun[runsV.size()];
         for (int i = 0; i < runs.length; i++) {
@@ -176,6 +183,15 @@
                 }
 
                 if (trun != null) {
+                    ArrayList lst = new ArrayList();
+                    for (int j = i; j < records.length; j++) {
+                        if(j > i && records[j] instanceof TextHeaderAtom) break;
+                        lst.add(records[j]);
+                    }
+                    Record[] recs = new Record[lst.size()];
+                    lst.toArray(recs);
+                    trun._records = recs;
+                    
                     found.add(trun);
                     i++;
                 } else {
@@ -232,6 +248,11 @@
         EscherDgRecord dg = (EscherDgRecord) Shape.getEscherChild(dgContainer, EscherDgRecord.RECORD_ID);
         dg.setNumShapes(dg.getNumShapes() + 1);
 
+        int shapeId = dg.getLastMSOSPID()+1;
+        dg.setLastMSOSPID(shapeId);
+
+        EscherSpRecord sp = shape.getSpContainer().getChildById(EscherSpRecord.RECORD_ID);
+        if(sp != null) sp.setShapeId(shapeId);
         shape.setSheet(this);
         shape.afterInsert(this);
 

Modified: jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/TextBox.java
URL: http://svn.apache.org/viewvc/jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/TextBox.java?view=diff&rev=542804&r1=542803&r2=542804
==============================================================================
--- jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/TextBox.java (original)
+++ jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/TextBox.java Wed May 30 04:56:46 2007
@@ -28,7 +28,6 @@
 import java.awt.font.FontRenderContext;
 import java.awt.font.TextLayout;
 import java.io.IOException;
-import java.util.Vector;
 
 /**
  * Represents a TextFrame shape in PowerPoint.
@@ -170,7 +169,7 @@
      * @return the text string for this textbox.
      */
      public String getText(){
-        return _txtrun.getText();        
+        return _txtrun == null ? null : _txtrun.getText();
     }
 
     /**
@@ -452,56 +451,37 @@
     }
 
     private void initTextRun(){
-        TextHeaderAtom tha = null;
-        TextCharsAtom tca = null;
-        TextBytesAtom tba = null;
-        StyleTextPropAtom sta = null;
         OutlineTextRefAtom ota = null;
         
         // Find the interesting child records 
         Record[] child = _txtbox.getChildRecords();
         for (int i = 0; i < child.length; i++) {
-            if (child[i] instanceof TextHeaderAtom) tha = (TextHeaderAtom)child[i];
-            else if (child[i] instanceof TextBytesAtom) tba = (TextBytesAtom)child[i];
-            else if (child[i] instanceof StyleTextPropAtom) sta = (StyleTextPropAtom)child[i];
-            else if (child[i] instanceof OutlineTextRefAtom) ota = (OutlineTextRefAtom)child[i];
-            else if (child[i] instanceof TextCharsAtom) tca = (TextCharsAtom)child[i];
+            if (child[i] instanceof OutlineTextRefAtom) {
+                ota = (OutlineTextRefAtom)child[i];
+                break;
+            }
         }
 
-        // Special handling for cases where there's an OutlineTextRefAtom
+        Sheet sheet = getSheet();
+        TextRun[] runs = sheet.getTextRuns();
         if (ota != null) {
-            // TextHeaderAtom, TextBytesAtom and StyleTextPropAtom are
-        	//  stored outside of  EscherContainerRecord
             int idx = ota.getTextIndex();
-            Slide sl = (Slide)getSheet();
-            Record[] rec = sl.getSlideAtomsSet().getSlideRecords();
-            for (int i = 0, j = 0; i < rec.length; i++) {
-                if(rec[i].getRecordType() == RecordTypes.TextHeaderAtom.typeID){
-                    if(j++ == idx) { //we found j-th  TextHeaderAtom, read the text data
-                        for (int k = i; k < rec.length; k++) {
-                            if (rec[k] instanceof TextHeaderAtom) {
-                                if (tha != null) break;
-                                else tha = (TextHeaderAtom)rec[k];
-                            }
-                            else if (rec[k] instanceof TextBytesAtom) tba = (TextBytesAtom)rec[k];
-                            else if (rec[k] instanceof TextCharsAtom) tca = (TextCharsAtom)rec[k];
-                            else if (rec[k] instanceof StyleTextPropAtom) sta = (StyleTextPropAtom)rec[k];
-                        }
-                    }
-                }
+            if(idx < runs.length) _txtrun = runs[idx];
+            if(_txtrun == null) {
+                logger.log(POILogger.WARN, "text run not found for OutlineTextRefAtom.TextIndex=" + idx);
             }
-        }
-        
-        // If we found the records we needed, create a TextRun
-        if(tba != null) {
-        	// Bytes based Text Run
-        	_txtrun = new TextRun(tha,tba,sta);
-        } else if (tca != null) {
-        	// Characters (unicode) based Text Run
-        	_txtrun = new TextRun(tha,tca,sta);
         } else {
-        	// Empty text box
-        	logger.log(POILogger.WARN, "no text records found for TextBox");
+            int shapeId = _escherContainer.getChildById(EscherSpRecord.RECORD_ID).getShapeId();
+            if(runs != null) for (int i = 0; i < runs.length; i++) {
+                if(runs[i].getShapeId() == shapeId){
+                    _txtrun = runs[i];
+                    break;
+                }
+            }
+            if(_txtrun == null) {
+                logger.log(POILogger.WARN, "text run not found for shapeId=" + shapeId);
+            }
         }
+
     }
 }

Modified: jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/TextRun.java
URL: http://svn.apache.org/viewvc/jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/TextRun.java?view=diff&rev=542804&r1=542803&r2=542804
==============================================================================
--- jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/TextRun.java (original)
+++ jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/model/TextRun.java Wed May 30 04:56:46 2007
@@ -49,6 +49,12 @@
 	protected RichTextRun[] _rtRuns;
 	private SlideShow slideShow;
     private Sheet sheet;
+    private int shapeId;
+    /**
+     * all text run records that follow TextHeaderAtom.
+     * (there can be misc InteractiveInfo, TxInteractiveInfo and other records)
+     */
+    protected Record[] _records;
 
 	/**
 	* Constructs a Text Run from a Unicode text block
@@ -516,5 +522,29 @@
 
     public Sheet getSheet(){
         return this.sheet;        
+    }
+
+    /**
+     * @return  Shape ID
+     */
+    protected int getShapeId(){
+        return shapeId;
+    }
+
+    /**
+     *  @param id Shape ID
+     */
+    protected void setShapeId(int id){
+        shapeId = id;
+    }
+
+    /**
+     * Returns the array of all hyperlinks in this text run
+     *
+     * @return the array of all hyperlinks in this text run
+     * or <code>null</code> if not found.
+     */
+    public Hyperlink[] getHyperlinks(){
+        return Hyperlink.find(this);
     }
 }

Modified: jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/EscherTextboxWrapper.java
URL: http://svn.apache.org/viewvc/jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/EscherTextboxWrapper.java?view=diff&rev=542804&r1=542803&r2=542804
==============================================================================
--- jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/EscherTextboxWrapper.java (original)
+++ jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/EscherTextboxWrapper.java Wed May 30 04:56:46 2007
@@ -39,6 +39,7 @@
 {
 	private EscherTextboxRecord _escherRecord;
 	private long _type;
+    private int shapeId;
 
 	/**
 	 * Returns the underlying DDF Escher Record
@@ -93,4 +94,18 @@
 		// Save in the escher layer
 		_escherRecord.setData(data);
 	}
+
+    /**
+     * @return  Shape ID
+     */
+    public int getShapeId(){
+        return shapeId;
+    }
+
+    /**
+     *  @param id Shape ID
+     */
+    public void setShapeId(int id){
+        shapeId = id;
+    }
 }

Modified: jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/ExHyperlink.java
URL: http://svn.apache.org/viewvc/jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/ExHyperlink.java?view=diff&rev=542804&r1=542803&r2=542804
==============================================================================
--- jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/ExHyperlink.java (original)
+++ jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/ExHyperlink.java Wed May 30 04:56:46 2007
@@ -42,13 +42,22 @@
 	
 	/**
 	 * Returns the URL of the link.
-	 * TODO: Figure out which of detailsA or detailsB is the
-	 *  one that always holds it 
+     *
+     * @return the URL of the link
 	 */
 	public String getLinkURL() {
-		return linkDetailsA.getText();
+		return linkDetailsB == null ? null : linkDetailsB.getText();
 	}
-	
+
+    /**
+     * Returns the hyperlink's user-readable name
+     *
+     * @return the hyperlink's user-readable name
+     */
+    public String getLinkTitle() {
+        return linkDetailsA == null ? null : linkDetailsA.getText();
+    }
+
 	/**
 	 * Sets the URL of the link
 	 * TODO: Figure out if we should always set both
@@ -66,13 +75,13 @@
 	 * Get the link details (field A)
 	 */
 	public String _getDetailsA() {
-		return linkDetailsA.getText();
+		return linkDetailsA == null ? null : linkDetailsA.getText();
 	}
 	/**
 	 * Get the link details (field B)
 	 */
 	public String _getDetailsB() {
-		return linkDetailsB.getText();
+		return linkDetailsB == null ? null : linkDetailsB.getText();
 	}
 
 	/** 

Modified: jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/ExObjList.java
URL: http://svn.apache.org/viewvc/jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/ExObjList.java?view=diff&rev=542804&r1=542803&r2=542804
==============================================================================
--- jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/ExObjList.java (original)
+++ jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/ExObjList.java Wed May 30 04:56:46 2007
@@ -109,4 +109,21 @@
 		writeOut(_header[0],_header[1],_type,_children,out);
 	}
 
+    /**
+     * Lookup a hyperlink by its unique id
+     *
+     * @param id hyperlink id
+     * @return found <code>ExHyperlink</code> or <code>null</code>
+     */
+    public ExHyperlink get(int id){
+        for(int i=0; i<_children.length; i++) {
+            if(_children[i] instanceof ExHyperlink) {
+                ExHyperlink rec = (ExHyperlink)_children[i];
+                if (rec.getExHyperlinkAtom().getNumber() == id){
+                    return rec;
+                }
+            }
+        }
+        return null;
+    }
 }

Modified: jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/InteractiveInfoAtom.java
URL: http://svn.apache.org/viewvc/jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/InteractiveInfoAtom.java?view=diff&rev=542804&r1=542803&r2=542804
==============================================================================
--- jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/InteractiveInfoAtom.java (original)
+++ jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/InteractiveInfoAtom.java Wed May 30 04:56:46 2007
@@ -30,10 +30,37 @@
  * (The actual link is held Document.ExObjList.ExHyperlink)
  *
  * @author Nick Burch
+ * @author Yegor Kozlov
  */
 
 public class InteractiveInfoAtom extends RecordAtom
 {
+
+    /**
+     * Action Table
+     */
+    public static final int ACTION_NONE = 0;
+    public static final int ACTION_MACRO = 1;
+    public static final int ACTION_RUNPROGRAM = 2;
+    public static final int ACTION_JUMP = 3;
+    public static final int ACTION_HYPERLINK = 4;
+    public static final int ACTION_OLE = 5;
+    public static final int ACTION_MEDIA = 6;
+    public static final int ACTION_CUSTOMSHOW = 7;
+
+    /**
+     *  Jump Table
+     */
+    public static final int JUMP_NONE = 0;
+    public static final int JUMP_NEXTSLIDE = 1;
+    public static final int JUMP_PREVIOUSSLIDE = 2;
+    public static final int JUMP_FIRSTSLIDE = 3;
+    public static final int JUMP_LASTSLIDE = 4;
+    public static final int JUMP_LASTSLIDEVIEWED = 5;
+    public static final int JUMP_ENDSHOW = 6;
+
+
+
     /**
      * Record header.
      */
@@ -90,46 +117,138 @@
      *  ExHyperlink with this number to get the details.
      * @return the link number
      */
-    public int getNumber() {
+    public int getHyperlinkID() {
         return LittleEndian.getInt(_data,4);
     }
 
     /**
-     * Sets the link number
-     * @param number the link number.
+     * Sets the persistent unique identifier of the link
+     *
+     * @param number the persistent unique identifier of the link
      */
-    public void setNumber(int number) {
+    public void setHyperlinkID(int number) {
         LittleEndian.putInt(_data,4,number);
     }
     
     /**
-     * Get the first number - meaning unknown
+     * a reference to a sound in the sound collection.
      */
-    public int _getNumber1() { 
+    public int getSoundRef() {
         return LittleEndian.getInt(_data,0);
     }
-    protected void _setNumber1(int val) {
+    /**
+     * a reference to a sound in the sound collection.
+     *
+     * @param val a reference to a sound in the sound collection
+     */
+    public void setSoundRef(int val) {
     	LittleEndian.putInt(_data, 0, val);
     }
 
     /**
-     * Get the third number - meaning unknown
+     * Hyperlink Action.
+     * <p>
+     * see <code>ACTION_*</code> constants for the list of actions
+     * </p>
+     *
+     * @return hyperlink action.
+     */
+    public byte getAction() {
+        return _data[8];
+    }
+
+    /**
+     * Hyperlink Action
+     * <p>
+     * see <code>ACTION_*</code> constants for the list of actions
+     * </p>
+     *
+     * @param val hyperlink action.
+     */
+    public void setAction(byte val) {
+    	_data[8] = val;
+    }
+
+    /**
+     * Only valid when action == OLEAction. OLE verb to use, 0 = first verb, 1 = second verb, etc.
+     */
+    public byte getOleVerb() {
+        return _data[9];
+    }
+
+    /**
+     * Only valid when action == OLEAction. OLE verb to use, 0 = first verb, 1 = second verb, etc.
+     */
+    public void setOleVerb(byte val) {
+    	_data[9] = val;
+    }
+
+    /**
+     * Jump
+     * <p>
+     * see <code>JUMP_*</code> constants for the list of actions
+     * </p>
+     *
+     * @return jump
      */
-    public int _getNumber3() { 
-        return LittleEndian.getInt(_data,8);
+    public byte getJump() {
+        return _data[10];
     }
-    protected void _setNumber3(int val) {
-    	LittleEndian.putInt(_data, 8, val);
+
+    /**
+     * Jump
+     * <p>
+     * see <code>JUMP_*</code> constants for the list of actions
+     * </p>
+     *
+     * @param val jump
+     */
+    public void setJump(byte val) {
+    	_data[10] = val;
     }
 
     /**
-     * Get the fourth number - meaning unknown
+     * Flags
+     * <p>
+     * <li> Bit 1: Animated. If 1, then button is animated
+     * <li> Bit 2: Stop sound. If 1, then stop current sound when button is pressed.
+     * <li> Bit 3: CustomShowReturn. If 1, and this is a jump to custom show,
+     *   then return to this slide after custom show.
+     * </p>
      */
-    public int _getNumber4() { 
-        return LittleEndian.getInt(_data,12);
+    public byte getFlags() {
+        return _data[11];
     }
-    protected void _setNumber4(int val) {
-    	LittleEndian.putInt(_data, 12, val);
+
+    /**
+     * Flags
+     * <p>
+     * <li> Bit 1: Animated. If 1, then button is animated
+     * <li> Bit 2: Stop sound. If 1, then stop current sound when button is pressed.
+     * <li> Bit 3: CustomShowReturn. If 1, and this is a jump to custom show,
+     *   then return to this slide after custom show.
+     * </p>
+     */
+    public void setFlags(byte val) {
+    	_data[11] = val;
+    }
+
+    /**
+     * hyperlink type
+     *
+     * @return hyperlink type
+     */
+    public byte getHyperlinkType() {
+        return _data[12];
+    }
+
+    /**
+     * hyperlink type
+     *
+     * @param val hyperlink type
+     */
+    public void setHyperlinkType(byte val) {
+    	_data[12] = val;
     }
 
     /**

Modified: jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/PPDrawing.java
URL: http://svn.apache.org/viewvc/jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/PPDrawing.java?view=diff&rev=542804&r1=542803&r2=542804
==============================================================================
--- jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/PPDrawing.java (original)
+++ jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/PPDrawing.java Wed May 30 04:56:46 2007
@@ -147,6 +147,13 @@
 				EscherTextboxRecord tbr = (EscherTextboxRecord)toSearch[i];
 				EscherTextboxWrapper w = new EscherTextboxWrapper(tbr);
 				found.add(w);
+                for (int j = i; j >= 0; j--) {
+                    if(toSearch[j] instanceof EscherSpRecord){
+                        EscherSpRecord sp = (EscherSpRecord)toSearch[j];
+                        w.setShapeId(sp.getShapeId());
+                        break;
+                    }
+                }
 			} else {
 				// If it has children, walk them
 				if(toSearch[i].isContainerRecord()) {

Modified: jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/RecordTypes.java
URL: http://svn.apache.org/viewvc/jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/RecordTypes.java?view=diff&rev=542804&r1=542803&r2=542804
==============================================================================
--- jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/RecordTypes.java (original)
+++ jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/RecordTypes.java Wed May 30 04:56:46 2007
@@ -112,7 +112,7 @@
     public static final Type SlideNumberMCAtom = new Type(4056,null);
     public static final Type HeadersFooters = new Type(4057,null);
     public static final Type HeadersFootersAtom = new Type(4058,null);
-    public static final Type TxInteractiveInfoAtom = new Type(4063,null);
+    public static final Type TxInteractiveInfoAtom = new Type(4063,TxInteractiveInfoAtom.class);
     public static final Type CharFormatAtom = new Type(4066,null);
     public static final Type ParaFormatAtom = new Type(4067,null);
     public static final Type RecolorInfoAtom = new Type(4071,null);

Added: jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/TxInteractiveInfoAtom.java
URL: http://svn.apache.org/viewvc/jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/TxInteractiveInfoAtom.java?view=auto&rev=542804
==============================================================================
--- jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/TxInteractiveInfoAtom.java (added)
+++ jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/TxInteractiveInfoAtom.java Wed May 30 04:56:46 2007
@@ -0,0 +1,122 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+package org.apache.poi.hslf.record;
+
+import org.apache.poi.util.LittleEndian;
+
+import java.io.OutputStream;
+import java.io.IOException;
+
+/**
+ * Tne atom that holds starting and ending character positions of a hyperlink
+ *
+ * @author Yegor Kozlov
+ */
+public class TxInteractiveInfoAtom extends RecordAtom {
+    /**
+     * Record header.
+     */
+    private byte[] _header;
+
+    /**
+     * Record data.
+     */
+    private byte[] _data;
+
+    /**
+     * Constructs a brand new link related atom record.
+     */
+    protected TxInteractiveInfoAtom() {
+        _header = new byte[8];
+        _data = new byte[8];
+
+        LittleEndian.putShort(_header, 2, (short)getRecordType());
+        LittleEndian.putInt(_header, 4, _data.length);
+    }
+
+    /**
+     * Constructs the link related atom record from its
+     *  source data.
+     *
+     * @param source the source data as a byte array.
+     * @param start the start offset into the byte array.
+     * @param len the length of the slice in the byte array.
+     */
+    protected TxInteractiveInfoAtom(byte[] source, int start, int len) {
+        // Get the header.
+        _header = new byte[8];
+        System.arraycopy(source,start,_header,0,8);
+
+        // Get the record data.
+        _data = new byte[len-8];
+        System.arraycopy(source,start+8,_data,0,len-8);
+
+    }
+
+    /**
+     * Gets the beginning character position
+     *
+     * @return the beginning character position
+     */
+    public int getStartIndex() {
+        return LittleEndian.getInt(_data, 0);
+    }
+
+    /**
+     * Sets the beginning character position
+     * @param idx the beginning character position
+     */
+    public void setStartIndex(int idx) {
+        LittleEndian.putInt(_data, 0, idx);
+    }
+
+    /**
+     * Gets the ending character position
+     *
+     * @return the ending character position
+     */
+    public int getEndIndex() {
+        return LittleEndian.getInt(_data, 4);
+    }
+
+    /**
+     * Sets the ending character position
+     *
+     * @param idx the ending character position
+     */
+    public void setEndIndex(int idx) {
+        LittleEndian.putInt(_data, 4, idx);
+    }
+
+    /**
+     * Gets the record type.
+     * @return the record type.
+     */
+    public long getRecordType() { return RecordTypes.TxInteractiveInfoAtom.typeID; }
+
+    /**
+     * Write the contents of the record back, so it can be written
+     * to disk
+     *
+     * @param out the output stream to write to.
+     * @throws java.io.IOException if an error occurs.
+     */
+    public void writeOut(OutputStream out) throws IOException {
+        out.write(_header);
+        out.write(_data);
+    }
+}

Added: jakarta/poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/model/TestHyperlink.java
URL: http://svn.apache.org/viewvc/jakarta/poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/model/TestHyperlink.java?view=auto&rev=542804
==============================================================================
--- jakarta/poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/model/TestHyperlink.java (added)
+++ jakarta/poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/model/TestHyperlink.java Wed May 30 04:56:46 2007
@@ -0,0 +1,89 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+package org.apache.poi.hslf.model;
+
+import junit.framework.TestCase;
+
+import java.io.FileInputStream;
+import java.io.File;
+
+import org.apache.poi.hslf.usermodel.SlideShow;
+
+/**
+ * Test Hyperlink.
+ *
+ * @author Yegor Kozlov
+ */
+public class TestHyperlink extends TestCase {
+    protected String cwd = System.getProperty("HSLF.testdata.path");
+
+    public void testTextRunHyperlinks() throws Exception {
+        FileInputStream is = new FileInputStream(new File(cwd, "WithLinks.ppt"));
+        SlideShow ppt = new SlideShow(is);
+        is.close();
+
+        TextRun[] run;
+        Slide slide;
+        slide = ppt.getSlides()[0];
+        run = slide.getTextRuns();
+        for (int i = 0; i < run.length; i++) {
+            String text = run[i].getText();
+            if (text.equals(
+                    "This page has two links:\n" +
+                    "http://jakarta.apache.org/poi/\n" +
+                    "\n" +
+                    "http://slashdot.org/\n" +
+                    "\n" +
+                    "In addition, its notes has one link")){
+
+                Hyperlink[] links = run[i].getHyperlinks();
+                assertNotNull(links);
+                assertEquals(2, links.length);
+
+                assertEquals("http://jakarta.apache.org/poi/", links[0].getTitle());
+                assertEquals("http://jakarta.apache.org/poi/", links[0].getAddress());
+                assertEquals("http://jakarta.apache.org/poi/", text.substring(links[0].getStartIndex(), links[0].getEndIndex()-1));
+
+                assertEquals("http://slashdot.org/", links[1].getTitle());
+                assertEquals("http://slashdot.org/", links[1].getAddress());
+                assertEquals("http://slashdot.org/", text.substring(links[1].getStartIndex(), links[1].getEndIndex()-1));
+
+            }
+        }
+
+        slide = ppt.getSlides()[1];
+        run = slide.getTextRuns();
+        for (int i = 0; i < run.length; i++) {
+            String text = run[i].getText();
+            if (text.equals(
+                    "I have the one link:\n" +
+                    "Jakarta HSSF")){
+
+                Hyperlink[] links = run[i].getHyperlinks();
+                assertNotNull(links);
+                assertEquals(1, links.length);
+
+                assertEquals("http://jakarta.apache.org/poi/hssf/", links[0].getTitle());
+                assertEquals("http://jakarta.apache.org/poi/hssf/", links[0].getAddress());
+                assertEquals("Jakarta HSSF", text.substring(links[0].getStartIndex(), links[0].getEndIndex()-1));
+
+            }
+        }
+
+    }
+
+}

Modified: jakarta/poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/model/TestShapes.java
URL: http://svn.apache.org/viewvc/jakarta/poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/model/TestShapes.java?view=diff&rev=542804&r1=542803&r2=542804
==============================================================================
--- jakarta/poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/model/TestShapes.java (original)
+++ jakarta/poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/model/TestShapes.java Wed May 30 04:56:46 2007
@@ -161,7 +161,8 @@
         out.close();
 
         ppt = new SlideShow(new HSLFSlideShow(new ByteArrayInputStream(out.toByteArray())));
-
+        sl = ppt.getSlides()[0];
+        
         txtbox = (TextBox)sl.getShapes()[0];
         rt = txtbox.getTextRun().getRichTextRuns()[0];
 

Modified: jakarta/poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/record/TestInteractiveInfo.java
URL: http://svn.apache.org/viewvc/jakarta/poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/record/TestInteractiveInfo.java?view=diff&rev=542804&r1=542803&r2=542804
==============================================================================
--- jakarta/poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/record/TestInteractiveInfo.java (original)
+++ jakarta/poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/record/TestInteractiveInfo.java Wed May 30 04:56:46 2007
@@ -48,7 +48,7 @@
 		InteractiveInfo ii = new InteractiveInfo(data_a, 0, data_a.length);
 		InteractiveInfoAtom ia = ii.getInteractiveInfoAtom();
 		
-		assertEquals(1, ia.getNumber());
+		assertEquals(1, ia.getHyperlinkID());
     }
     
 	public void testWrite() throws Exception {
@@ -69,10 +69,10 @@
     	InteractiveInfoAtom ia = ii.getInteractiveInfoAtom();
     	
     	// Set values
-    	ia.setNumber(1);
-    	ia._setNumber1(0);
-    	ia._setNumber3(4);
-    	ia._setNumber4(8);
+    	ia.setHyperlinkID(1);
+    	ia.setSoundRef(0);
+    	ia.setAction((byte)4);
+    	ia.setHyperlinkType((byte)8);
     	
 		// Check it's now the same as a
 		ByteArrayOutputStream baos = new ByteArrayOutputStream();

Modified: jakarta/poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/record/TestInteractiveInfoAtom.java
URL: http://svn.apache.org/viewvc/jakarta/poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/record/TestInteractiveInfoAtom.java?view=diff&rev=542804&r1=542803&r2=542804
==============================================================================
--- jakarta/poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/record/TestInteractiveInfoAtom.java (original)
+++ jakarta/poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/record/TestInteractiveInfoAtom.java Wed May 30 04:56:46 2007
@@ -53,22 +53,22 @@
 		InteractiveInfoAtom ia = new InteractiveInfoAtom(data_a, 0, data_a.length);
 		InteractiveInfoAtom ib = new InteractiveInfoAtom(data_b, 0, data_b.length);
 		
-		assertEquals(1, ia.getNumber());
-		assertEquals(4, ib.getNumber());
+		assertEquals(1, ia.getHyperlinkID());
+		assertEquals(4, ib.getHyperlinkID());
     }
     
     public void testGetRest() throws Exception {
 		InteractiveInfoAtom ia = new InteractiveInfoAtom(data_a, 0, data_a.length);
 		InteractiveInfoAtom ib = new InteractiveInfoAtom(data_b, 0, data_b.length);
 		
-		assertEquals(0, ia._getNumber1());
-		assertEquals(0, ib._getNumber1());
+		assertEquals(0, ia.getSoundRef());
+		assertEquals(0, ib.getSoundRef());
 		
-		assertEquals(4, ia._getNumber3());
-		assertEquals(4, ib._getNumber3());
+		assertEquals(4, ia.getAction());
+		assertEquals(4, ib.getAction());
 		
-		assertEquals(8, ia._getNumber4());
-		assertEquals(8, ib._getNumber4());
+		assertEquals(8, ia.getHyperlinkType());
+		assertEquals(8, ib.getHyperlinkType());
     }
     
 	public void testWrite() throws Exception {
@@ -88,10 +88,10 @@
     	InteractiveInfoAtom ia = new InteractiveInfoAtom();
     	
     	// Set values
-    	ia.setNumber(1);
-    	ia._setNumber1(0);
-    	ia._setNumber3(4);
-    	ia._setNumber4(8);
+    	ia.setHyperlinkID(1);
+    	ia.setSoundRef(0);
+    	ia.setAction((byte)4);
+    	ia.setHyperlinkType((byte)8);
     	
 		// Check it's now the same as a
 		ByteArrayOutputStream baos = new ByteArrayOutputStream();
@@ -109,7 +109,7 @@
 		InteractiveInfoAtom ia = new InteractiveInfoAtom(data_a, 0, data_a.length);
 
 		// Change the number
-		ia.setNumber(4);
+		ia.setHyperlinkID(4);
 		
 		// Check bytes are now the same
 		ByteArrayOutputStream baos = new ByteArrayOutputStream();

Added: jakarta/poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/record/TestTxInteractiveInfoAtom.java
URL: http://svn.apache.org/viewvc/jakarta/poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/record/TestTxInteractiveInfoAtom.java?view=auto&rev=542804
==============================================================================
--- jakarta/poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/record/TestTxInteractiveInfoAtom.java (added)
+++ jakarta/poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/record/TestTxInteractiveInfoAtom.java Wed May 30 04:56:46 2007
@@ -0,0 +1,110 @@
+
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+        
+
+
+package org.apache.poi.hslf.record;
+
+
+import junit.framework.TestCase;
+import java.io.ByteArrayOutputStream;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+/**
+ * Tests that TxInteractiveInfoAtom works properly.
+ *
+ * @author Yegor Kozlov
+ */
+public class TestTxInteractiveInfoAtom extends TestCase {
+	// From WithLinks.ppt 
+	private byte[] data_a = new byte[] { 
+		00, 00, (byte)0xDF, 0x0F, 0x08, 00, 00, 00,
+		0x19, 00, 00, 00, 0x38, 00, 00, 00
+	};
+
+    private byte[] data_b = new byte[] {
+        00, 00, (byte)0xDF, 0x0F, 0x08, 00, 00, 00,
+        0x39, 00, 00, 00, 0x4E, 00, 00, 00
+    };
+
+    public void testRead() throws Exception {
+        TxInteractiveInfoAtom ia1 = new TxInteractiveInfoAtom(data_a, 0, data_a.length);
+
+        assertEquals(4063, ia1.getRecordType());
+		assertEquals(25, ia1.getStartIndex());
+		assertEquals(56, ia1.getEndIndex());
+
+        TxInteractiveInfoAtom ia2 = new TxInteractiveInfoAtom(data_b, 0, data_b.length);
+
+        assertEquals(4063, ia2.getRecordType());
+		assertEquals(57, ia2.getStartIndex());
+		assertEquals(78, ia2.getEndIndex());
+    }
+    
+	public void testWrite() throws Exception {
+		TxInteractiveInfoAtom atom = new TxInteractiveInfoAtom(data_a, 0, data_a.length);
+		ByteArrayOutputStream baos = new ByteArrayOutputStream();
+		atom.writeOut(baos);
+		byte[] b = baos.toByteArray();
+
+		assertEquals(data_a.length, b.length);
+		for(int i=0; i<data_a.length; i++) {
+			assertEquals(data_a[i],b[i]);
+		}
+	}
+
+	// Create A from scratch
+    public void testCreate() throws Exception {
+    	TxInteractiveInfoAtom ia = new TxInteractiveInfoAtom();
+    	
+    	// Set values
+        ia.setStartIndex(25);
+    	ia.setEndIndex(56);
+
+		// Check it's now the same as a
+		ByteArrayOutputStream baos = new ByteArrayOutputStream();
+		ia.writeOut(baos);
+		byte[] b = baos.toByteArray();
+		
+		assertEquals(data_a.length, b.length);
+		for(int i=0; i<data_a.length; i++) {
+			assertEquals(data_a[i],b[i]);
+		}
+    }
+
+	// Try to turn a into b
+	public void testChange() throws Exception {
+		TxInteractiveInfoAtom ia = new TxInteractiveInfoAtom(data_a, 0, data_a.length);
+
+		// Change the number
+		ia.setStartIndex(57);
+        ia.setEndIndex(78);
+
+		// Check bytes are now the same
+		ByteArrayOutputStream baos = new ByteArrayOutputStream();
+		ia.writeOut(baos);
+		byte[] b = baos.toByteArray();
+
+		// Should now be the same
+		assertEquals(data_b.length, b.length);
+		for(int i=0; i<data_b.length; i++) {
+			assertEquals(data_b[i],b[i]);
+		}
+	}
+}



---------------------------------------------------------------------
To unsubscribe, e-mail: poi-dev-unsubscribe@jakarta.apache.org
Mailing List:    http://jakarta.apache.org/site/mail2.html#poi
The Apache Jakarta POI Project: http://jakarta.apache.org/poi/