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