You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pdfbox.apache.org by ti...@apache.org on 2015/02/12 22:38:55 UTC
svn commit: r1659414 - in
/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/documentnavigation/outline:
PDDocumentOutline.java PDOutlineItem.java PDOutlineNode.java
Author: tilman
Date: Thu Feb 12 21:38:55 2015
New Revision: 1659414
URL: http://svn.apache.org/r1659414
Log:
PDFBOX-2677: redesign / fix bugs in outlines, by Andrea Vacondio
Modified:
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/documentnavigation/outline/PDDocumentOutline.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/documentnavigation/outline/PDOutlineItem.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/documentnavigation/outline/PDOutlineNode.java
Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/documentnavigation/outline/PDDocumentOutline.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/documentnavigation/outline/PDDocumentOutline.java?rev=1659414&r1=1659413&r2=1659414&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/documentnavigation/outline/PDDocumentOutline.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/documentnavigation/outline/PDDocumentOutline.java Thu Feb 12 21:38:55 2015
@@ -25,7 +25,7 @@ import org.apache.pdfbox.cos.COSName;
* @author <a href="mailto:ben@benlitchfield.com">Ben Litchfield</a>
* @version $Revision: 1.2 $
*/
-public class PDDocumentOutline extends PDOutlineNode
+public final class PDDocumentOutline extends PDOutlineNode
{
/**
@@ -33,8 +33,7 @@ public class PDDocumentOutline extends P
*/
public PDDocumentOutline()
{
- super();
- node.setName( COSName.TYPE, "Outlines" );
+ getCOSDictionary().setName(COSName.TYPE, COSName.OUTLINES.getName());
}
/**
@@ -45,5 +44,24 @@ public class PDDocumentOutline extends P
public PDDocumentOutline( COSDictionary dic )
{
super( dic );
+ getCOSDictionary().setName(COSName.TYPE, COSName.OUTLINES.getName());
+ }
+
+ @Override
+ public boolean isNodeOpen()
+ {
+ return true;
+ }
+
+ @Override
+ public void openNode()
+ {
+ // The root of the outline hierarchy is not an OutlineItem and cannot be opened or closed
+ }
+
+ @Override
+ public void closeNode()
+ {
+ // The root of the outline hierarchy is not an OutlineItem and cannot be opened or closed
}
}
Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/documentnavigation/outline/PDOutlineItem.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/documentnavigation/outline/PDOutlineItem.java?rev=1659414&r1=1659413&r2=1659414&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/documentnavigation/outline/PDOutlineItem.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/documentnavigation/outline/PDOutlineItem.java Thu Feb 12 21:38:55 2015
@@ -39,11 +39,11 @@ import org.apache.pdfbox.pdmodel.interac
import org.apache.pdfbox.pdmodel.interactive.documentnavigation.destination.PDPageXYZDestination;
/**
- * This represents an outline in a pdf document.
+ * This represents an outline item in a pdf document.
*
* @author <a href="mailto:ben@benlitchfield.com">Ben Litchfield</a>
*/
-public class PDOutlineItem extends PDOutlineNode
+public final class PDOutlineItem extends PDOutlineNode
{
private static final int ITALIC_FLAG = 1;
private static final int BOLD_FLAG = 2;
@@ -67,31 +67,57 @@ public class PDOutlineItem extends PDOut
}
/**
- * Insert a sibling after this node.
+ * Insert a single sibling after this node.
*
- * @param item The item to insert.
+ * @param newSibling The item to insert.
+ * @throws IllegalArgumentException if the given node is part of a list (i.e. if it has a previous or a next
+ * sibling)
*/
- public void insertSiblingAfter( PDOutlineItem item )
+ public void insertSiblingAfter(PDOutlineItem newSibling)
{
- item.setParent( getParent() );
+ requireSingleNode(newSibling);
+ PDOutlineNode parent = getParent();
+ newSibling.setParent(parent);
PDOutlineItem next = getNextSibling();
- setNextSibling( item );
- item.setPreviousSibling( this );
- if( next != null )
+ setNextSibling(newSibling);
+ newSibling.setPreviousSibling(this);
+ if (next != null)
{
- item.setNextSibling( next );
- next.setPreviousSibling( item );
+ newSibling.setNextSibling(next);
+ next.setPreviousSibling(newSibling);
}
- updateParentOpenCount( 1 );
+ else if (parent != null)
+ {
+ getParent().setLastChild(newSibling);
+ }
+ updateParentOpenCountForAddedChild(newSibling);
}
/**
- * {@inheritDoc}
+ * Insert a single sibling before this node.
+ *
+ * @param newSibling The item to insert.
+ * @throws IllegalArgumentException if the given node is part of a list (i.e. if it has a previous or a next
+ * sibling)
*/
- @Override
- public PDOutlineNode getParent()
+ public void insertSiblingBefore(PDOutlineItem newSibling)
{
- return super.getParent();
+ requireSingleNode(newSibling);
+ PDOutlineNode parent = getParent();
+ newSibling.setParent(parent);
+ PDOutlineItem previous = getPreviousSibling();
+ setPreviousSibling(newSibling);
+ newSibling.setNextSibling(this);
+ if (previous != null)
+ {
+ previous.setNextSibling(newSibling);
+ newSibling.setPreviousSibling(previous);
+ }
+ else if (parent != null)
+ {
+ getParent().setFirstChild(newSibling);
+ }
+ updateParentOpenCountForAddedChild(newSibling);
}
/**
@@ -101,13 +127,7 @@ public class PDOutlineItem extends PDOut
*/
public PDOutlineItem getPreviousSibling()
{
- PDOutlineItem last = null;
- COSDictionary lastDic = (COSDictionary)node.getDictionaryObject( COSName.PREV );
- if( lastDic != null )
- {
- last = new PDOutlineItem( lastDic );
- }
- return last;
+ return getOutlineItem(COSName.PREV);
}
/**
@@ -115,25 +135,17 @@ public class PDOutlineItem extends PDOut
*
* @param outlineNode The new previous sibling.
*/
- protected void setPreviousSibling( PDOutlineNode outlineNode )
+ void setPreviousSibling(PDOutlineNode outlineNode)
{
- node.setItem( COSName.PREV, outlineNode );
+ getCOSDictionary().setItem(COSName.PREV, outlineNode);
}
/**
- * Return the next sibling or null if there is no next sibling.
- *
- * @return The next sibling.
+ * @return The next sibling or null if there is no next sibling.
*/
public PDOutlineItem getNextSibling()
{
- PDOutlineItem last = null;
- COSDictionary lastDic = (COSDictionary)node.getDictionaryObject( COSName.NEXT );
- if( lastDic != null )
- {
- last = new PDOutlineItem( lastDic );
- }
- return last;
+ return getOutlineItem(COSName.NEXT);
}
/**
@@ -141,9 +153,9 @@ public class PDOutlineItem extends PDOut
*
* @param outlineNode The new next sibling.
*/
- protected void setNextSibling( PDOutlineNode outlineNode )
+ void setNextSibling(PDOutlineNode outlineNode)
{
- node.setItem( COSName.NEXT, outlineNode );
+ getCOSDictionary().setItem(COSName.NEXT, outlineNode);
}
/**
@@ -153,7 +165,7 @@ public class PDOutlineItem extends PDOut
*/
public String getTitle()
{
- return node.getString( COSName.TITLE );
+ return getCOSDictionary().getString(COSName.TITLE);
}
/**
@@ -161,9 +173,9 @@ public class PDOutlineItem extends PDOut
*
* @param title The new title for this node.
*/
- public void setTitle( String title )
+ public void setTitle(String title)
{
- node.setString( COSName.TITLE, title );
+ getCOSDictionary().setString(COSName.TITLE, title);
}
/**
@@ -174,7 +186,7 @@ public class PDOutlineItem extends PDOut
*/
public PDDestination getDestination() throws IOException
{
- return PDDestination.create( node.getDictionaryObject( COSName.DEST ) );
+ return PDDestination.create(getCOSDictionary().getDictionaryObject(COSName.DEST));
}
/**
@@ -182,9 +194,9 @@ public class PDOutlineItem extends PDOut
*
* @param dest The new page destination for this node.
*/
- public void setDestination( PDDestination dest )
+ public void setDestination(PDDestination dest)
{
- node.setItem( COSName.DEST, dest );
+ getCOSDictionary().setItem(COSName.DEST, dest);
}
/**
@@ -192,7 +204,7 @@ public class PDOutlineItem extends PDOut
*
* @param page The page to refer to.
*/
- public void setDestination( PDPage page )
+ public void setDestination(PDPage page)
{
PDPageXYZDestination dest = null;
if( page != null )
@@ -285,7 +297,7 @@ public class PDOutlineItem extends PDOut
*/
public PDAction getAction()
{
- return PDActionFactory.createAction( (COSDictionary)node.getDictionaryObject( COSName.A ) );
+ return PDActionFactory.createAction((COSDictionary) getCOSDictionary().getDictionaryObject(COSName.A));
}
/**
@@ -295,7 +307,7 @@ public class PDOutlineItem extends PDOut
*/
public void setAction( PDAction action )
{
- node.setItem( COSName.A, action );
+ getCOSDictionary().setItem(COSName.A, action);
}
/**
@@ -306,7 +318,7 @@ public class PDOutlineItem extends PDOut
public PDStructureElement getStructureElement()
{
PDStructureElement se = null;
- COSDictionary dic = (COSDictionary)node.getDictionaryObject( COSName.SE );
+ COSDictionary dic = (COSDictionary) getCOSDictionary().getDictionaryObject(COSName.SE);
if( dic != null )
{
se = new PDStructureElement( dic );
@@ -321,7 +333,7 @@ public class PDOutlineItem extends PDOut
*/
public void setStructuredElement( PDStructureElement structureElement )
{
- node.setItem( COSName.SE, structureElement );
+ getCOSDictionary().setItem(COSName.SE, structureElement);
}
/**
@@ -333,12 +345,12 @@ public class PDOutlineItem extends PDOut
public PDColor getTextColor()
{
PDColor retval = null;
- COSArray csValues = (COSArray)node.getDictionaryObject( COSName.C );
+ COSArray csValues = (COSArray) getCOSDictionary().getDictionaryObject(COSName.C);
if( csValues == null )
{
csValues = new COSArray();
csValues.growToSize( 3, new COSFloat( 0 ) );
- node.setItem( COSName.C, csValues );
+ getCOSDictionary().setItem( COSName.C, csValues );
}
retval = new PDColor(csValues.toFloatArray(), PDDeviceRGB.INSTANCE);
return retval;
@@ -351,7 +363,7 @@ public class PDOutlineItem extends PDOut
*/
public void setTextColor( PDColor textColor )
{
- node.setItem( COSName.C, textColor.toCOSArray() );
+ getCOSDictionary().setItem( COSName.C, textColor.toCOSArray() );
}
/**
@@ -365,7 +377,7 @@ public class PDOutlineItem extends PDOut
array.add( new COSFloat( textColor.getRed()/255f));
array.add( new COSFloat( textColor.getGreen()/255f));
array.add( new COSFloat( textColor.getBlue()/255f));
- node.setItem( COSName.C, array );
+ getCOSDictionary().setItem( COSName.C, array );
}
/**
@@ -375,7 +387,7 @@ public class PDOutlineItem extends PDOut
*/
public boolean isItalic()
{
- return node.getFlag( COSName.F, ITALIC_FLAG );
+ return getCOSDictionary().getFlag( COSName.F, ITALIC_FLAG );
}
/**
@@ -385,7 +397,7 @@ public class PDOutlineItem extends PDOut
*/
public void setItalic( boolean italic )
{
- node.setFlag( COSName.F, ITALIC_FLAG, italic );
+ getCOSDictionary().setFlag( COSName.F, ITALIC_FLAG, italic );
}
/**
@@ -395,7 +407,7 @@ public class PDOutlineItem extends PDOut
*/
public boolean isBold()
{
- return node.getFlag( COSName.F, BOLD_FLAG );
+ return getCOSDictionary().getFlag( COSName.F, BOLD_FLAG );
}
/**
@@ -405,7 +417,7 @@ public class PDOutlineItem extends PDOut
*/
public void setBold( boolean bold )
{
- node.setFlag( COSName.F, BOLD_FLAG, bold );
+ getCOSDictionary().setFlag( COSName.F, BOLD_FLAG, bold );
}
}
Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/documentnavigation/outline/PDOutlineNode.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/documentnavigation/outline/PDOutlineNode.java?rev=1659414&r1=1659413&r2=1659414&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/documentnavigation/outline/PDOutlineNode.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/documentnavigation/outline/PDOutlineNode.java Thu Feb 12 21:38:55 2015
@@ -16,156 +16,180 @@
*/
package org.apache.pdfbox.pdmodel.interactive.documentnavigation.outline;
-import org.apache.pdfbox.cos.COSBase;
import org.apache.pdfbox.cos.COSDictionary;
import org.apache.pdfbox.cos.COSName;
-
-import org.apache.pdfbox.pdmodel.common.COSObjectable;
+import org.apache.pdfbox.pdmodel.common.PDDictionaryWrapper;
/**
- * This represents an node in an outline in a pdf document.
+ * Base class for a node in the outline of a PDF document.
*
* @author <a href="mailto:ben@benlitchfield.com">Ben Litchfield</a>
* @version $Revision: 1.3 $
*/
-public class PDOutlineNode implements COSObjectable
+public abstract class PDOutlineNode extends PDDictionaryWrapper
{
- /**
- * The dictionary for this node.
- */
- protected COSDictionary node;
- /**
- * Default Constructor.
- */
public PDOutlineNode()
{
- node = new COSDictionary();
+ super();
}
/**
- * Default Constructor.
- *
* @param dict The dictionary storage.
*/
- public PDOutlineNode( COSDictionary dict)
+ public PDOutlineNode(COSDictionary dict)
{
- node = dict;
+ super(dict);
}
+ @Override
+ public COSDictionary getCOSDictionary()
+ {
+ return super.getCOSDictionary();
+ }
+
/**
- * Convert this standard java object to a COS object.
- *
- * @return The cos object that matches this Java object.
+ * @return The parent of this node or null if there is no parent.
*/
- @Override
- public COSBase getCOSObject()
+ PDOutlineNode getParent()
+ {
+ COSDictionary item = (COSDictionary) getCOSDictionary().getDictionaryObject(COSName.PARENT);
+ if (item != null)
+ {
+ if (COSName.OUTLINES.equals(item.getCOSName(COSName.TYPE)))
+ {
+ return new PDDocumentOutline(item);
+ }
+ return new PDOutlineItem(item);
+ }
+ return null;
+ }
+
+ void setParent(PDOutlineNode parent)
{
- return node;
+ getCOSDictionary().setItem(COSName.PARENT, parent);
}
/**
- * Convert this standard java object to a COS object.
+ * Adds the given node to the bottom of the children list.
*
- * @return The cos object that matches this Java object.
+ * @param newChild The node to add.
+ * @throws IllegalArgumentException if the given node is part of a list (i.e. if it has a previous or a next
+ * sibling)
*/
- public COSDictionary getCOSDictionary()
+ public void addLast(PDOutlineItem newChild)
{
- return node;
+ requireSingleNode(newChild);
+ append(newChild);
+ updateParentOpenCountForAddedChild(newChild);
}
/**
- * Get the parent of this object. This will either be a DocumentOutline or an OutlineItem.
- *
- * @return The parent of this object, or null if this is the document outline and there
- * is no parent.
+ * Adds the given node to the top of the children list.
+ *
+ * @param newChild
+ * @return the newly added child
+ * @throws IllegalArgumentException if the given node is part of a list (i.e. if it has a previous or a next
+ * sibling)
*/
- protected PDOutlineNode getParent()
+ public void addFirst(PDOutlineItem newChild)
{
- PDOutlineNode retval = null;
- COSDictionary parent = (COSDictionary) node.getDictionaryObject(COSName.PARENT);
- if (parent != null)
+ requireSingleNode(newChild);
+ prepend(newChild);
+ updateParentOpenCountForAddedChild(newChild);
+ }
+
+ /**
+ * @param node
+ * @throws IllegalArgumentException if the given node is part of a list (i.e. if it has a previous or a next
+ * sibling)
+ */
+ void requireSingleNode(PDOutlineItem node)
+ {
+ if (node.getNextSibling() != null || node.getPreviousSibling() != null)
{
- if (parent.getDictionaryObject(COSName.PARENT) == null)
- {
- retval = new PDDocumentOutline(parent);
- }
- else
- {
- retval = new PDOutlineItem(parent);
- }
+ throw new IllegalArgumentException("A single node with no siblings is required");
}
-
- return retval;
}
/**
- * Set the parent of this object, this is maintained by these objects and should not
- * be called by any clients of PDFBox code.
- *
- * @param parent The parent of this object.
+ * Appends the child to the linked list of children. This method only adjust pointers but doesn't take care of the
+ * Count key in the parent hierarchy.
+ *
+ * @param newChild
*/
- protected void setParent( PDOutlineNode parent )
+ private void append(PDOutlineItem newChild)
{
- node.setItem(COSName.PARENT, parent );
+ newChild.setParent(this);
+ if (!hasChildren())
+ {
+ setFirstChild(newChild);
+ }
+ else
+ {
+ PDOutlineItem previousLastChild = getLastChild();
+ previousLastChild.setNextSibling(newChild);
+ newChild.setPreviousSibling(previousLastChild);
+ }
+ setLastChild(newChild);
}
/**
- * append a child node to this node.
- *
- * @param outlineNode The node to add.
+ * Prepends the child to the linked list of children. This method only adjust pointers but doesn't take care of the
+ * Count key in the parent hierarchy.
+ *
+ * @param newChild
*/
- public void appendChild( PDOutlineItem outlineNode )
+ private void prepend(PDOutlineItem newChild)
{
- outlineNode.setParent( this );
- if( getFirstChild() == null )
+ newChild.setParent(this);
+ if (!hasChildren())
{
- int currentOpenCount = getOpenCount();
- setFirstChild( outlineNode );
- //1 for the the item we are adding;
- int numberOfOpenNodesWeAreAdding = 1;
- if( outlineNode.isNodeOpen() )
- {
- numberOfOpenNodesWeAreAdding += outlineNode.getOpenCount();
- }
- if( isNodeOpen() )
- {
- setOpenCount( currentOpenCount + numberOfOpenNodesWeAreAdding );
- }
- else
- {
- setOpenCount( currentOpenCount - numberOfOpenNodesWeAreAdding );
- }
- updateParentOpenCount( numberOfOpenNodesWeAreAdding );
+ setLastChild(newChild);
}
else
{
- PDOutlineItem previousLastChild = getLastChild();
- previousLastChild.insertSiblingAfter( outlineNode );
+ PDOutlineItem previousFirstChild = getFirstChild();
+ newChild.setNextSibling(previousFirstChild);
+ previousFirstChild.setPreviousSibling(newChild);
}
-
- PDOutlineItem lastNode = outlineNode;
- while(lastNode.getNextSibling() != null)
+ setFirstChild(newChild);
+ }
+
+ void updateParentOpenCountForAddedChild(PDOutlineItem newChild)
+ {
+ int delta = 1;
+ if (newChild.isNodeOpen())
{
- lastNode = lastNode.getNextSibling();
+ delta += newChild.getOpenCount();
}
- setLastChild( lastNode );
+ newChild.updateParentOpenCount(delta);
}
/**
- * Return the first child or null if there is no child.
- *
- * @return The first child.
+ * @return true if the node has at least one child
*/
- public PDOutlineItem getFirstChild()
+ public boolean hasChildren()
+ {
+ return getFirstChild() != null;
+ }
+
+ PDOutlineItem getOutlineItem(COSName name)
{
- PDOutlineItem first = null;
- COSDictionary firstDic = (COSDictionary)node.getDictionaryObject( "First" );
- if( firstDic != null )
+ COSDictionary item = (COSDictionary) getCOSDictionary().getDictionaryObject(name);
+ if (item != null)
{
- first = new PDOutlineItem( firstDic );
+ return new PDOutlineItem(item);
}
- return first;
+ return null;
+ }
+
+ /**
+ * @return The first child or null if there is no child.
+ */
+ public PDOutlineItem getFirstChild()
+ {
+ return getOutlineItem(COSName.FIRST);
}
/**
@@ -173,25 +197,17 @@ public class PDOutlineNode implements CO
*
* @param outlineNode The new first child.
*/
- protected void setFirstChild( PDOutlineNode outlineNode )
+ void setFirstChild(PDOutlineNode outlineNode)
{
- node.setItem(COSName.FIRST, outlineNode);
+ getCOSDictionary().setItem(COSName.FIRST, outlineNode);
}
/**
- * Return the last child or null if there is no child.
- *
- * @return The last child.
+ * @return The last child or null if there is no child.
*/
public PDOutlineItem getLastChild()
{
- PDOutlineItem last = null;
- COSDictionary lastDic = (COSDictionary)node.getDictionaryObject( "Last" );
- if( lastDic != null )
- {
- last = new PDOutlineItem( lastDic );
- }
- return last;
+ return getOutlineItem(COSName.LAST);
}
/**
@@ -199,59 +215,43 @@ public class PDOutlineNode implements CO
*
* @param outlineNode The new last child.
*/
- protected void setLastChild( PDOutlineNode outlineNode )
+ void setLastChild(PDOutlineNode outlineNode)
{
- node.setItem( "Last", outlineNode );
+ getCOSDictionary().setItem(COSName.LAST, outlineNode);
}
/**
- * Get the number of open nodes. Or a negative number if this node
- * is closed. See PDF Reference for more details. This value
- * is updated as you append children and siblings.
+ * Get the number of open nodes or a negative number if this node is closed.
+ * See PDF Reference 32000-1:2008 table 152 and 153 for more details. This
+ * value is updated as you append children and siblings.
*
* @return The Count attribute of the outline dictionary.
*/
public int getOpenCount()
{
- return node.getInt( "Count", 0 );
+ return getCOSDictionary().getInt(COSName.COUNT, 0);
}
/**
- * Set the open count. This number is automatically managed for you
- * when you add items to the outline.
+ * Set the open count. This number is automatically managed for you when you add items to the outline.
*
- * @param openCount The new open cound.
+ * @param openCount The new open count.
*/
- protected void setOpenCount( int openCount )
+ void setOpenCount(int openCount)
{
- node.setInt( "Count", openCount );
+ getCOSDictionary().setInt(COSName.COUNT, openCount);
}
/**
- * This will set this node to be open when it is shown in the viewer. By default, when
- * a new node is created it will be closed.
- * This will do nothing if the node is already open.
+ * This will set this node to be open when it is shown in the viewer. By default, when a new node is created it will
+ * be closed. This will do nothing if the node is already open.
*/
public void openNode()
{
//if the node is already open then do nothing.
if( !isNodeOpen() )
{
- int openChildrenCount = 0;
- PDOutlineItem currentChild = getFirstChild();
- while( currentChild != null )
- {
- //first increase by one for the current child
- openChildrenCount++;
- //then increase by the number of open nodes the child has
- if( currentChild.isNodeOpen() )
- {
- openChildrenCount += currentChild.getOpenCount();
- }
- currentChild = currentChild.getNextSibling();
- }
- setOpenCount( openChildrenCount );
- updateParentOpenCount( openChildrenCount );
+ switchNodeCount();
}
}
@@ -261,18 +261,21 @@ public class PDOutlineNode implements CO
*/
public void closeNode()
{
- //if the node is already closed then do nothing.
- if( isNodeOpen() )
+ if (isNodeOpen())
{
- int openCount = getOpenCount();
- updateParentOpenCount( -openCount );
- setOpenCount( -openCount );
+ switchNodeCount();
}
}
+ private void switchNodeCount()
+ {
+ int openCount = getOpenCount();
+ setOpenCount(-openCount);
+ updateParentOpenCount(-openCount);
+ }
+
/**
- * Node is open if the open count is greater than zero.
- * @return true if this node is open.
+ * @return true if this node count is greater than zero, false otherwise.
*/
public boolean isNodeOpen()
{
@@ -280,34 +283,23 @@ public class PDOutlineNode implements CO
}
/**
- * The count parameter needs to be updated when you add or remove elements to
- * the outline. When you add an element at a lower level then you need to
- * increase all of the parents.
+ * The count parameter needs to be updated when you add, remove, open or close outline items.
*
- * @param amount The amount to update by.
+ * @param delta The amount to update by.
*/
- protected void updateParentOpenCount( int amount )
+ void updateParentOpenCount(int delta)
{
PDOutlineNode parent = getParent();
- if( parent != null )
+ if (parent != null)
{
- int currentCount = parent.getOpenCount();
- //if the currentCount is negative or it is absent then
- //we will treat it as negative. The default is to be negative.
- boolean negative = currentCount < 0 ||
- parent.getCOSDictionary().getDictionaryObject( "Count" ) == null;
- currentCount = Math.abs( currentCount );
- currentCount += amount;
- if( negative )
+ if (parent.isNodeOpen())
{
- currentCount = -currentCount;
+ parent.setOpenCount(parent.getOpenCount() + delta);
+ parent.updateParentOpenCount(delta);
}
- parent.setOpenCount( currentCount );
- //recursively call parent to update count, but the parents count is only
- //updated if this is an open node
- if( !negative )
+ else
{
- parent.updateParentOpenCount( amount );
+ parent.setOpenCount(parent.getOpenCount() - delta);
}
}
}