]> _ Git - cubeextranet.git/blob
c52854fe8036372ba7577ce793afff606acbaeb8
[cubeextranet.git] /
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements.  See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License.  You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 package org.apache.pdfbox.pdmodel.interactive.documentnavigation.outline;
18
19 import java.awt.Color;
20 import java.io.IOException;
21 import java.util.List;
22
23 import org.apache.pdfbox.cos.COSArray;
24 import org.apache.pdfbox.cos.COSDictionary;
25 import org.apache.pdfbox.cos.COSFloat;
26 import org.apache.pdfbox.cos.COSName;
27 import org.apache.pdfbox.exceptions.OutlineNotLocalException;
28 import org.apache.pdfbox.pdmodel.PDDestinationNameTreeNode;
29 import org.apache.pdfbox.pdmodel.PDDocument;
30 import org.apache.pdfbox.pdmodel.PDDocumentNameDictionary;
31 import org.apache.pdfbox.pdmodel.PDPage;
32 import org.apache.pdfbox.pdmodel.documentinterchange.logicalstructure.PDStructureElement;
33 import org.apache.pdfbox.pdmodel.graphics.color.PDColorState;
34 import org.apache.pdfbox.pdmodel.graphics.color.PDDeviceRGB;
35 import org.apache.pdfbox.pdmodel.interactive.action.PDActionFactory;
36 import org.apache.pdfbox.pdmodel.interactive.action.type.PDAction;
37 import org.apache.pdfbox.pdmodel.interactive.action.type.PDActionGoTo;
38 import org.apache.pdfbox.pdmodel.interactive.documentnavigation.destination.PDDestination;
39 import org.apache.pdfbox.pdmodel.interactive.documentnavigation.destination.PDNamedDestination;
40 import org.apache.pdfbox.pdmodel.interactive.documentnavigation.destination.PDPageDestination;
41 import org.apache.pdfbox.pdmodel.interactive.documentnavigation.destination.PDPageXYZDestination;
42 import org.apache.pdfbox.util.BitFlagHelper;
43
44 /**
45  * This represents an outline in a pdf document.
46  *
47  * @author <a href="mailto:ben@benlitchfield.com">Ben Litchfield</a>
48  * @version $Revision: 1.7 $
49  */
50 public class PDOutlineItem extends PDOutlineNode
51 {
52
53     private static final int ITALIC_FLAG = 1;
54     private static final int BOLD_FLAG = 2;
55
56     /**
57      * Default Constructor.
58      */
59     public PDOutlineItem()
60     {
61         super();
62     }
63
64     /**
65      * Constructor for an existing outline item.
66      *
67      * @param dic The storage dictionary.
68      */
69     public PDOutlineItem( COSDictionary dic )
70     {
71         super( dic );
72     }
73
74     /**
75      * Insert a sibling after this node.
76      *
77      * @param item The item to insert.
78      */
79     public void insertSiblingAfter( PDOutlineItem item )
80     {
81         item.setParent( getParent() );
82         PDOutlineItem next = getNextSibling();
83         setNextSibling( item );
84         item.setPreviousSibling( this );
85         if( next != null )
86         {
87             item.setNextSibling( next );
88             next.setPreviousSibling( item );
89         }
90         updateParentOpenCount( 1 );
91     }
92
93     /**
94      * {@inheritDoc}
95      */
96     public PDOutlineNode getParent()
97     {
98         return super.getParent();
99     }
100
101     /**
102      * Return the previous sibling or null if there is no sibling.
103      *
104      * @return The previous sibling.
105      */
106     public PDOutlineItem getPreviousSibling()
107     {
108         PDOutlineItem last = null;
109         COSDictionary lastDic = (COSDictionary)node.getDictionaryObject( COSName.PREV );
110         if( lastDic != null )
111         {
112             last = new PDOutlineItem( lastDic );
113         }
114         return last;
115     }
116
117     /**
118      * Set the previous sibling, this will be maintained by this class.
119      *
120      * @param outlineNode The new previous sibling.
121      */
122     protected void setPreviousSibling( PDOutlineNode outlineNode )
123     {
124         node.setItem( COSName.PREV, outlineNode );
125     }
126
127     /**
128      * Return the next sibling or null if there is no next sibling.
129      *
130      * @return The next sibling.
131      */
132     public PDOutlineItem getNextSibling()
133     {
134         PDOutlineItem last = null;
135         COSDictionary lastDic = (COSDictionary)node.getDictionaryObject( COSName.NEXT );
136         if( lastDic != null )
137         {
138             last = new PDOutlineItem( lastDic );
139         }
140         return last;
141     }
142
143     /**
144      * Set the next sibling, this will be maintained by this class.
145      *
146      * @param outlineNode The new next sibling.
147      */
148     protected void setNextSibling( PDOutlineNode outlineNode )
149     {
150         node.setItem( COSName.NEXT, outlineNode );
151     }
152
153     /**
154      * Get the title of this node.
155      *
156      * @return The title of this node.
157      */
158     public String getTitle()
159     {
160         return node.getString( COSName.TITLE );
161     }
162
163     /**
164      * Set the title for this node.
165      *
166      * @param title The new title for this node.
167      */
168     public void setTitle( String title )
169     {
170         node.setString( COSName.TITLE, title );
171     }
172
173     /**
174      * Get the page destination of this node.
175      *
176      * @return The page destination of this node.
177      * @throws IOException If there is an error creating the destination.
178      */
179     public PDDestination getDestination() throws IOException
180     {
181         return PDDestination.create( node.getDictionaryObject( COSName.DEST ) );
182     }
183
184     /**
185      * Set the page destination for this node.
186      *
187      * @param dest The new page destination for this node.
188      */
189     public void setDestination( PDDestination dest )
190     {
191         node.setItem( COSName.DEST, dest );
192     }
193
194     /**
195      * A convenience method that will create an XYZ destination using only the defaults.
196      *
197      * @param page The page to refer to.
198      */
199     public void setDestination( PDPage page )
200     {
201         PDPageXYZDestination dest = null;
202         if( page != null )
203         {
204             dest = new PDPageXYZDestination();
205             dest.setPage( page );
206         }
207         setDestination( dest );
208     }
209
210     /**
211      * This method will attempt to find the page in this PDF document that this outline points to.
212      * If the outline does not point to anything then this method will return null.  If the outline
213      * is an action that is not a GoTo action then this methods will throw the OutlineNotLocationException
214      *
215      * @param doc The document to get the page from.
216      *
217      * @return The page that this outline will go to when activated or null if it does not point to anything.
218      * @throws IOException If there is an error when trying to find the page.
219      */
220     public PDPage findDestinationPage( PDDocument doc ) throws IOException
221     {
222         PDPage page = null;
223         PDDestination rawDest = getDestination();
224         if( rawDest == null )
225         {
226             PDAction outlineAction = getAction();
227             if( outlineAction instanceof PDActionGoTo )
228             {
229                 rawDest = ((PDActionGoTo)outlineAction).getDestination();
230             }
231             else if( outlineAction == null )
232             {
233                 //if the outline action is null then this outline does not refer
234                 //to anything and we will just return null.
235             }
236             else
237             {
238                 throw new OutlineNotLocalException( "Error: Outline does not reference a local page." );
239             }
240         }
241
242         PDPageDestination pageDest = null;
243         if( rawDest instanceof PDNamedDestination )
244         {
245             //if we have a named destination we need to lookup the PDPageDestination
246             PDNamedDestination namedDest = (PDNamedDestination)rawDest;
247             PDDocumentNameDictionary namesDict = doc.getDocumentCatalog().getNames();
248             if( namesDict != null )
249             {
250                 PDDestinationNameTreeNode destsTree = namesDict.getDests();
251                 if( destsTree != null )
252                 {
253                     pageDest = (PDPageDestination)destsTree.getValue( namedDest.getNamedDestination() );
254                 }
255             }
256         }
257         else if( rawDest instanceof PDPageDestination)
258         {
259             pageDest = (PDPageDestination) rawDest;
260         }
261         else if( rawDest == null )
262         {
263             //if the destination is null then we will simply return a null page.
264         }
265         else
266         {
267             throw new IOException( "Error: Unknown destination type " + rawDest );
268         }
269
270         if( pageDest != null )
271         {
272             page = pageDest.getPage();
273             if( page == null )
274             {
275                 int pageNumber = pageDest.getPageNumber();
276                 if( pageNumber != -1 )
277                 {
278                     List allPages = doc.getDocumentCatalog().getAllPages();
279                     page = (PDPage)allPages.get( pageNumber );
280                 }
281             }
282         }
283
284         return page;
285     }
286
287     /**
288      * Get the action of this node.
289      *
290      * @return The action of this node.
291      */
292     public PDAction getAction()
293     {
294         return PDActionFactory.createAction( (COSDictionary)node.getDictionaryObject( COSName.A ) );
295     }
296
297     /**
298      * Set the action for this node.
299      *
300      * @param action The new action for this node.
301      */
302     public void setAction( PDAction action )
303     {
304         node.setItem( COSName.A, action );
305     }
306
307     /**
308      * Get the structure element of this node.
309      *
310      * @return The structure element of this node.
311      */
312     public PDStructureElement getStructureElement()
313     {
314         PDStructureElement se = null;
315         COSDictionary dic = (COSDictionary)node.getDictionaryObject( COSName.SE );
316         if( dic != null )
317         {
318             se = new PDStructureElement( dic );
319         }
320         return se;
321     }
322
323     /**
324      * Set the structure element for this node.
325      *
326      * @param structureElement The new structure element for this node.
327      */
328     public void setStructuredElement( PDStructureElement structureElement )
329     {
330         node.setItem( COSName.SE, structureElement );
331     }
332
333     /**
334      * Get the text color of this node.  Default is black and this method
335      * will never return null.
336      *
337      * @return The structure element of this node.
338      */
339     public PDColorState getTextColor()
340     {
341         PDColorState retval = null;
342         COSArray csValues = (COSArray)node.getDictionaryObject( COSName.C );
343         if( csValues == null )
344         {
345             csValues = new COSArray();
346             csValues.growToSize( 3, new COSFloat( 0 ) );
347             node.setItem( COSName.C, csValues );
348         }
349         retval = new PDColorState(csValues);
350         retval.setColorSpace( PDDeviceRGB.INSTANCE );
351         return retval;
352     }
353
354     /**
355      * Set the text color for this node.  The colorspace must be a PDDeviceRGB.
356      *
357      * @param textColor The text color for this node.
358      */
359     public void setTextColor( PDColorState textColor )
360     {
361         node.setItem( COSName.C, textColor.getCOSColorSpaceValue() );
362     }
363
364     /**
365      * Set the text color for this node.  The colorspace must be a PDDeviceRGB.
366      *
367      * @param textColor The text color for this node.
368      */
369     public void setTextColor( Color textColor )
370     {
371         COSArray array = new COSArray();
372         array.add( new COSFloat( textColor.getRed()/255f));
373         array.add( new COSFloat( textColor.getGreen()/255f));
374         array.add( new COSFloat( textColor.getBlue()/255f));
375         node.setItem( COSName.C, array );
376     }
377
378     /**
379      * A flag telling if the text should be italic.
380      *
381      * @return The italic flag.
382      */
383     public boolean isItalic()
384     {
385         return BitFlagHelper.getFlag( node, COSName.F, ITALIC_FLAG );
386     }
387
388     /**
389      * Set the italic property of the text.
390      *
391      * @param italic The new italic flag.
392      */
393     public void setItalic( boolean italic )
394     {
395         BitFlagHelper.setFlag( node, COSName.F, ITALIC_FLAG, italic );
396     }
397
398     /**
399      * A flag telling if the text should be bold.
400      *
401      * @return The bold flag.
402      */
403     public boolean isBold()
404     {
405         return BitFlagHelper.getFlag( node, COSName.F, BOLD_FLAG );
406     }
407
408     /**
409      * Set the bold property of the text.
410      *
411      * @param bold The new bold flag.
412      */
413     public void setBold( boolean bold )
414     {
415         BitFlagHelper.setFlag( node, COSName.F, BOLD_FLAG, bold );
416     }
417
418 }