1 /*
2 * $Id: PdfOutline.java 3373 2008-05-12 16:21:24Z xlv $
3 *
4 * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie
5 *
6 * The contents of this file are subject to the Mozilla Public License Version 1.1
7 * (the "License"); you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at http://www.mozilla.org/MPL/
9 *
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the License.
13 *
14 * The Original Code is 'iText, a free JAVA-PDF library'.
15 *
16 * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
17 * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
18 * All Rights Reserved.
19 * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
20 * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
21 *
22 * Contributor(s): all the names of the contributors are added in the source code
23 * where applicable.
24 *
25 * Alternatively, the contents of this file may be used under the terms of the
26 * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
27 * provisions of LGPL are applicable instead of those above. If you wish to
28 * allow use of your version of this file only under the terms of the LGPL
29 * License and not to allow others to use your version of this file under
30 * the MPL, indicate your decision by deleting the provisions above and
31 * replace them with the notice and other provisions required by the LGPL.
32 * If you do not delete the provisions above, a recipient may use your version
33 * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
34 *
35 * This library is free software; you can redistribute it and/or modify it
36 * under the terms of the MPL as stated above or under the terms of the GNU
37 * Library General Public License as published by the Free Software Foundation;
38 * either version 2 of the License, or any later version.
39 *
40 * This library is distributed in the hope that it will be useful, but WITHOUT
41 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
42 * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
43 * details.
44 *
45 * If you didn't download this code from the following link, you should check if
46 * you aren't using an obsolete version:
47 * http://www.lowagie.com/iText/
48 */
49
50 package com.lowagie.text.pdf;
51
52 import java.awt.Color;
53 import java.io.IOException;
54 import java.io.OutputStream;
55 import java.util.ArrayList;
56 import java.util.Iterator;
57
58 import com.lowagie.text.Chunk;
59 import com.lowagie.text.Font;
60 import com.lowagie.text.Paragraph;
61
62 /**
63 * <CODE>PdfOutline</CODE> is an object that represents a PDF outline entry.
64 * <P>
65 * An outline allows a user to access views of a document by name.<BR>
66 * This object is described in the 'Portable Document Format Reference Manual version 1.3'
67 * section 6.7 (page 104-106)
68 *
69 * @see PdfDictionary
70 */
71
72 public class PdfOutline extends PdfDictionary {
73
74 // membervariables
75
76 /** the <CODE>PdfIndirectReference</CODE> of this object */
77 private PdfIndirectReference reference;
78
79 /** value of the <B>Count</B>-key */
80 private int count = 0;
81
82 /** value of the <B>Parent</B>-key */
83 private PdfOutline parent;
84
85 /** value of the <B>Destination</B>-key */
86 private PdfDestination destination;
87
88 /** The <CODE>PdfAction</CODE> for this outline.
89 */
90 private PdfAction action;
91
92 protected ArrayList kids = new ArrayList();
93
94 protected PdfWriter writer;
95
96 /** Holds value of property tag. */
97 private String tag;
98
99 /** Holds value of property open. */
100 private boolean open;
101
102 /** Holds value of property color. */
103 private Color color;
104
105 /** Holds value of property style. */
106 private int style = 0;
107
108 // constructors
109
110 /**
111 * Constructs a <CODE>PdfOutline</CODE>.
112 * <P>
113 * This is the constructor for the <CODE>outlines object</CODE>.
114 *
115 * @param writer The PdfWriter you are adding the outline to
116 */
117
118 PdfOutline(PdfWriter writer) {
119 super(OUTLINES);
120 open = true;
121 parent = null;
122 this.writer = writer;
123 }
124
125 /**
126 * Constructs a <CODE>PdfOutline</CODE>.
127 * <P>
128 * This is the constructor for an <CODE>outline entry</CODE>. The open mode is
129 * <CODE>true</CODE>.
130 *
131 * @param parent the parent of this outline item
132 * @param action the <CODE>PdfAction</CODE> for this outline item
133 * @param title the title of this outline item
134 */
135
136 public PdfOutline(PdfOutline parent, PdfAction action, String title) {
137 this(parent, action, title, true);
138 }
139
140 /**
141 * Constructs a <CODE>PdfOutline</CODE>.
142 * <P>
143 * This is the constructor for an <CODE>outline entry</CODE>.
144 *
145 * @param parent the parent of this outline item
146 * @param action the <CODE>PdfAction</CODE> for this outline item
147 * @param title the title of this outline item
148 * @param open <CODE>true</CODE> if the children are visible
149 */
150 public PdfOutline(PdfOutline parent, PdfAction action, String title, boolean open) {
151 super();
152 this.action = action;
153 initOutline(parent, title, open);
154 }
155
156 /**
157 * Constructs a <CODE>PdfOutline</CODE>.
158 * <P>
159 * This is the constructor for an <CODE>outline entry</CODE>. The open mode is
160 * <CODE>true</CODE>.
161 *
162 * @param parent the parent of this outline item
163 * @param destination the destination for this outline item
164 * @param title the title of this outline item
165 */
166
167 public PdfOutline(PdfOutline parent, PdfDestination destination, String title) {
168 this(parent, destination, title, true);
169 }
170
171 /**
172 * Constructs a <CODE>PdfOutline</CODE>.
173 * <P>
174 * This is the constructor for an <CODE>outline entry</CODE>.
175 *
176 * @param parent the parent of this outline item
177 * @param destination the destination for this outline item
178 * @param title the title of this outline item
179 * @param open <CODE>true</CODE> if the children are visible
180 */
181 public PdfOutline(PdfOutline parent, PdfDestination destination, String title, boolean open) {
182 super();
183 this.destination = destination;
184 initOutline(parent, title, open);
185 }
186
187 /**
188 * Constructs a <CODE>PdfOutline</CODE>.
189 * <P>
190 * This is the constructor for an <CODE>outline entry</CODE>. The open mode is
191 * <CODE>true</CODE>.
192 *
193 * @param parent the parent of this outline item
194 * @param action the <CODE>PdfAction</CODE> for this outline item
195 * @param title the title of this outline item
196 */
197 public PdfOutline(PdfOutline parent, PdfAction action, PdfString title) {
198 this(parent, action, title, true);
199 }
200
201 /**
202 * Constructs a <CODE>PdfOutline</CODE>.
203 * <P>
204 * This is the constructor for an <CODE>outline entry</CODE>.
205 *
206 * @param parent the parent of this outline item
207 * @param action the <CODE>PdfAction</CODE> for this outline item
208 * @param title the title of this outline item
209 * @param open <CODE>true</CODE> if the children are visible
210 */
211 public PdfOutline(PdfOutline parent, PdfAction action, PdfString title, boolean open) {
212 this(parent, action, title.toString(), open);
213 }
214
215 /**
216 * Constructs a <CODE>PdfOutline</CODE>.
217 * <P>
218 * This is the constructor for an <CODE>outline entry</CODE>. The open mode is
219 * <CODE>true</CODE>.
220 *
221 * @param parent the parent of this outline item
222 * @param destination the destination for this outline item
223 * @param title the title of this outline item
224 */
225
226 public PdfOutline(PdfOutline parent, PdfDestination destination, PdfString title) {
227 this(parent, destination, title, true);
228 }
229
230 /**
231 * Constructs a <CODE>PdfOutline</CODE>.
232 * <P>
233 * This is the constructor for an <CODE>outline entry</CODE>.
234 *
235 * @param parent the parent of this outline item
236 * @param destination the destination for this outline item
237 * @param title the title of this outline item
238 * @param open <CODE>true</CODE> if the children are visible
239 */
240 public PdfOutline(PdfOutline parent, PdfDestination destination, PdfString title, boolean open) {
241 this(parent, destination, title.toString(), true);
242 }
243
244 /**
245 * Constructs a <CODE>PdfOutline</CODE>.
246 * <P>
247 * This is the constructor for an <CODE>outline entry</CODE>. The open mode is
248 * <CODE>true</CODE>.
249 *
250 * @param parent the parent of this outline item
251 * @param action the <CODE>PdfAction</CODE> for this outline item
252 * @param title the title of this outline item
253 */
254
255 public PdfOutline(PdfOutline parent, PdfAction action, Paragraph title) {
256 this(parent, action, title, true);
257 }
258
259 /**
260 * Constructs a <CODE>PdfOutline</CODE>.
261 * <P>
262 * This is the constructor for an <CODE>outline entry</CODE>.
263 *
264 * @param parent the parent of this outline item
265 * @param action the <CODE>PdfAction</CODE> for this outline item
266 * @param title the title of this outline item
267 * @param open <CODE>true</CODE> if the children are visible
268 */
269 public PdfOutline(PdfOutline parent, PdfAction action, Paragraph title, boolean open) {
270 super();
271 StringBuffer buf = new StringBuffer();
272 for (Iterator i = title.getChunks().iterator(); i.hasNext(); ) {
273 Chunk chunk = (Chunk) i.next();
274 buf.append(chunk.getContent());
275 }
276 this.action = action;
277 initOutline(parent, buf.toString(), open);
278 }
279
280 /**
281 * Constructs a <CODE>PdfOutline</CODE>.
282 * <P>
283 * This is the constructor for an <CODE>outline entry</CODE>. The open mode is
284 * <CODE>true</CODE>.
285 *
286 * @param parent the parent of this outline item
287 * @param destination the destination for this outline item
288 * @param title the title of this outline item
289 */
290
291 public PdfOutline(PdfOutline parent, PdfDestination destination, Paragraph title) {
292 this(parent, destination, title, true);
293 }
294
295 /**
296 * Constructs a <CODE>PdfOutline</CODE>.
297 * <P>
298 * This is the constructor for an <CODE>outline entry</CODE>.
299 *
300 * @param parent the parent of this outline item
301 * @param destination the destination for this outline item
302 * @param title the title of this outline item
303 * @param open <CODE>true</CODE> if the children are visible
304 */
305 public PdfOutline(PdfOutline parent, PdfDestination destination, Paragraph title, boolean open) {
306 super();
307 StringBuffer buf = new StringBuffer();
308 for (Iterator i = title.getChunks().iterator(); i.hasNext(); ) {
309 Chunk chunk = (Chunk) i.next();
310 buf.append(chunk.getContent());
311 }
312 this.destination = destination;
313 initOutline(parent, buf.toString(), open);
314 }
315
316
317 // methods
318
319 /** Helper for the constructors.
320 * @param parent the parent outline
321 * @param title the title for this outline
322 * @param open <CODE>true</CODE> if the children are visible
323 */
324 void initOutline(PdfOutline parent, String title, boolean open) {
325 this.open = open;
326 this.parent = parent;
327 writer = parent.writer;
328 put(PdfName.TITLE, new PdfString(title, PdfObject.TEXT_UNICODE));
329 parent.addKid(this);
330 if (destination != null && !destination.hasPage()) // bugfix Finn Bock
331 setDestinationPage(writer.getCurrentPage());
332 }
333
334 /**
335 * Sets the indirect reference of this <CODE>PdfOutline</CODE>.
336 *
337 * @param reference the <CODE>PdfIndirectReference</CODE> to this outline.
338 */
339
340 public void setIndirectReference(PdfIndirectReference reference) {
341 this.reference = reference;
342 }
343
344 /**
345 * Gets the indirect reference of this <CODE>PdfOutline</CODE>.
346 *
347 * @return the <CODE>PdfIndirectReference</CODE> to this outline.
348 */
349
350 public PdfIndirectReference indirectReference() {
351 return reference;
352 }
353
354 /**
355 * Gets the parent of this <CODE>PdfOutline</CODE>.
356 *
357 * @return the <CODE>PdfOutline</CODE> that is the parent of this outline.
358 */
359
360 public PdfOutline parent() {
361 return parent;
362 }
363
364 /**
365 * Set the page of the <CODE>PdfDestination</CODE>-object.
366 *
367 * @param pageReference indirect reference to the page
368 * @return <CODE>true</CODE> if this page was set as the <CODE>PdfDestination</CODE>-page.
369 */
370
371 public boolean setDestinationPage(PdfIndirectReference pageReference) {
372 if (destination == null) {
373 return false;
374 }
375 return destination.addPage(pageReference);
376 }
377
378 /**
379 * Gets the destination for this outline.
380 * @return the destination
381 */
382 public PdfDestination getPdfDestination() {
383 return destination;
384 }
385
386 int getCount() {
387 return count;
388 }
389
390 void setCount(int count) {
391 this.count = count;
392 }
393
394 /**
395 * returns the level of this outline.
396 *
397 * @return a level
398 */
399
400 public int level() {
401 if (parent == null) {
402 return 0;
403 }
404 return (parent.level() + 1);
405 }
406
407 /**
408 * Returns the PDF representation of this <CODE>PdfOutline</CODE>.
409 *
410 * @param writer the encryption information
411 * @param os
412 * @throws IOException
413 */
414
415 public void toPdf(PdfWriter writer, OutputStream os) throws IOException {
416 if (color != null && !color.equals(Color.black)) {
417 put(PdfName.C, new PdfArray(new float[]{color.getRed()/255f,color.getGreen()/255f,color.getBlue()/255f}));
418 }
419 int flag = 0;
420 if ((style & Font.BOLD) != 0)
421 flag |= 2;
422 if ((style & Font.ITALIC) != 0)
423 flag |= 1;
424 if (flag != 0)
425 put(PdfName.F, new PdfNumber(flag));
426 if (parent != null) {
427 put(PdfName.PARENT, parent.indirectReference());
428 }
429 if (destination != null && destination.hasPage()) {
430 put(PdfName.DEST, destination);
431 }
432 if (action != null)
433 put(PdfName.A, action);
434 if (count != 0) {
435 put(PdfName.COUNT, new PdfNumber(count));
436 }
437 super.toPdf(writer, os);
438 }
439
440 /**
441 * Adds a kid to the outline
442 * @param outline
443 */
444 public void addKid(PdfOutline outline) {
445 kids.add(outline);
446 }
447
448 /**
449 * Returns the kids of this outline
450 * @return an ArrayList with PdfOutlines
451 */
452 public ArrayList getKids() {
453 return kids;
454 }
455
456 /**
457 * Sets the kids of this outline
458 * @param kids
459 */
460 public void setKids(ArrayList kids) {
461 this.kids = kids;
462 }
463
464 /** Getter for property tag.
465 * @return Value of property tag.
466 */
467 public String getTag() {
468 return tag;
469 }
470
471 /** Setter for property tag.
472 * @param tag New value of property tag.
473 */
474 public void setTag(String tag) {
475 this.tag = tag;
476 }
477
478 /**
479 * Gets the title of this outline
480 * @return the title as a String
481 */
482 public String getTitle() {
483 PdfString title = (PdfString)get(PdfName.TITLE);
484 return title.toString();
485 }
486
487 /**
488 * Sets the title of this outline
489 * @param title
490 */
491 public void setTitle(String title) {
492 put(PdfName.TITLE, new PdfString(title, PdfObject.TEXT_UNICODE));
493 }
494
495 /** Getter for property open.
496 * @return Value of property open.
497 */
498 public boolean isOpen() {
499 return open;
500 }
501
502 /** Setter for property open.
503 * @param open New value of property open.
504 */
505 public void setOpen(boolean open) {
506 this.open = open;
507 }
508
509 /** Getter for property color.
510 * @return Value of property color.
511 *
512 */
513 public Color getColor() {
514 return this.color;
515 }
516
517 /** Setter for property color.
518 * @param color New value of property color.
519 *
520 */
521 public void setColor(Color color) {
522 this.color = color;
523 }
524
525 /** Getter for property style.
526 * @return Value of property style.
527 *
528 */
529 public int getStyle() {
530 return this.style;
531 }
532
533 /** Setter for property style.
534 * @param style New value of property style.
535 *
536 */
537 public void setStyle(int style) {
538 this.style = style;
539 }
540
541 }