1 31 package org.pdfbox.pdmodel.interactive.documentnavigation.outline; 32 33 import org.pdfbox.cos.COSBase; 34 import org.pdfbox.cos.COSDictionary; 35 36 import org.pdfbox.pdmodel.common.COSObjectable; 37 38 44 public class PDOutlineNode implements COSObjectable 45 { 46 49 protected COSDictionary node; 50 51 54 public PDOutlineNode() 55 { 56 node = new COSDictionary(); 57 } 58 59 64 public PDOutlineNode( COSDictionary dict) 65 { 66 node = dict; 67 } 68 69 74 public COSBase getCOSObject() 75 { 76 return node; 77 } 78 79 84 public COSDictionary getCOSDictionary() 85 { 86 return node; 87 } 88 89 95 public PDOutlineNode getParent() 96 { 97 PDOutlineNode retval = null; 98 COSDictionary parent = (COSDictionary)node.getDictionaryObject( "Parent", "P" ); 99 if( parent != null ) 100 { 101 if( parent.getDictionaryObject( "Parent", "P" ) == null ) 102 { 103 retval = new PDDocumentOutline( parent ); 104 } 105 else 106 { 107 retval = new PDOutlineItem( parent ); 108 } 109 } 110 111 return retval; 112 } 113 114 120 protected void setParent( PDOutlineNode parent ) 121 { 122 node.setItem( "Parent", parent ); 123 } 124 125 130 public void appendChild( PDOutlineItem outlineNode ) 131 { 132 outlineNode.setParent( this ); 133 if( getFirstChild() == null ) 134 { 135 int currentOpenCount = getOpenCount(); 136 setFirstChild( outlineNode ); 137 int numberOfOpenNodesWeAreAdding = 1; 139 if( outlineNode.isNodeOpen() ) 140 { 141 numberOfOpenNodesWeAreAdding += outlineNode.getOpenCount(); 142 } 143 if( isNodeOpen() ) 144 { 145 setOpenCount( currentOpenCount + numberOfOpenNodesWeAreAdding ); 146 } 147 else 148 { 149 setOpenCount( currentOpenCount - numberOfOpenNodesWeAreAdding ); 150 } 151 updateParentOpenCount( numberOfOpenNodesWeAreAdding ); 152 } 153 else 154 { 155 PDOutlineItem previousLastChild = getLastChild(); 156 previousLastChild.insertSiblingAfter( outlineNode ); 157 } 158 setLastChild( outlineNode ); 159 } 160 161 166 public PDOutlineItem getFirstChild() 167 { 168 PDOutlineItem last = null; 169 COSDictionary lastDic = (COSDictionary)node.getDictionaryObject( "First" ); 170 if( lastDic != null ) 171 { 172 last = new PDOutlineItem( lastDic ); 173 } 174 return last; 175 } 176 177 182 protected void setFirstChild( PDOutlineNode outlineNode ) 183 { 184 node.setItem( "First", outlineNode ); 185 } 186 187 192 public PDOutlineItem getLastChild() 193 { 194 PDOutlineItem last = null; 195 COSDictionary lastDic = (COSDictionary)node.getDictionaryObject( "Last" ); 196 if( lastDic != null ) 197 { 198 last = new PDOutlineItem( lastDic ); 199 } 200 return last; 201 } 202 203 208 protected void setLastChild( PDOutlineNode outlineNode ) 209 { 210 node.setItem( "Last", outlineNode ); 211 } 212 213 220 public int getOpenCount() 221 { 222 return node.getInt( "Count", 0 ); 223 } 224 225 231 protected void setOpenCount( int openCount ) 232 { 233 node.setInt( "Count", openCount ); 234 } 235 236 241 public void openNode() 242 { 243 if( !isNodeOpen() ) 245 { 246 int openChildrenCount = 0; 247 PDOutlineItem currentChild = getFirstChild(); 248 while( currentChild != null ) 249 { 250 openChildrenCount++; 252 if( currentChild.isNodeOpen() ) 254 { 255 openChildrenCount += currentChild.getOpenCount(); 256 } 257 currentChild = currentChild.getNextSibling(); 258 } 259 setOpenCount( openChildrenCount ); 260 updateParentOpenCount( openChildrenCount ); 261 } 262 } 263 264 268 public void closeNode() 269 { 270 if( isNodeOpen() ) 272 { 273 int openCount = getOpenCount(); 274 updateParentOpenCount( -openCount ); 275 setOpenCount( -openCount ); 276 } 277 } 278 279 283 public boolean isNodeOpen() 284 { 285 return getOpenCount() > 0; 286 } 287 288 295 protected void updateParentOpenCount( int amount ) 296 { 297 PDOutlineNode parent = getParent(); 298 if( parent != null ) 299 { 300 int currentCount = parent.getOpenCount(); 301 boolean negative = currentCount < 0 || 304 parent.getCOSDictionary().getDictionaryObject( "Count" ) == null; 305 currentCount = Math.abs( currentCount ); 306 currentCount += amount; 307 if( negative ) 308 { 309 currentCount = -currentCount; 310 } 311 parent.setOpenCount( currentCount ); 312 if( !negative ) 315 { 316 parent.updateParentOpenCount( amount ); 317 } 318 } 319 } 320 } 321 | Popular Tags |