KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > jxl > biff > drawing > Button


1 /*********************************************************************
2 *
3 * Copyright (C) 2002 Andrew Khan
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 ***************************************************************************/

19
20 package jxl.biff.drawing;
21
22 import java.io.IOException JavaDoc;
23 import java.io.FileInputStream JavaDoc;
24
25 import common.Assert;
26 import common.Logger;
27
28 import jxl.WorkbookSettings;
29 import jxl.biff.ByteData;
30 import jxl.biff.IntegerHelper;
31 import jxl.biff.StringHelper;
32 import jxl.biff.IndexMapping;
33 import jxl.biff.Type;
34 import jxl.biff.ContinueRecord;
35 import jxl.write.biff.File;
36
37 /**
38  * Contains the various biff records used to copy a Button (from the
39  * Form toolbox) between workbook
40  */

41 public class Button implements DrawingGroupObject
42 {
43   /**
44    * The logger
45    */

46   private static Logger logger = Logger.getLogger(Button.class);
47
48   /**
49    * The spContainer that was read in
50    */

51   private EscherContainer readSpContainer;
52
53   /**
54    * The spContainer that was generated
55    */

56   private EscherContainer spContainer;
57
58   /**
59    * The MsoDrawingRecord associated with the drawing
60    */

61   private MsoDrawingRecord msoDrawingRecord;
62
63   /**
64    * The ObjRecord associated with the drawing
65    */

66   private ObjRecord objRecord;
67
68   /**
69    * Initialized flag
70    */

71   private boolean initialized = false;
72
73   /**
74    * The object id, assigned by the drawing group
75    */

76   private int objectId;
77
78   /**
79    * The blip id
80    */

81   private int blipId;
82
83   /**
84    * The shape id
85    */

86   private int shapeId;
87
88   /**
89    * The column
90    */

91   private int column;
92
93   /**
94    * The row position of the image
95    */

96   private int row;
97
98   /**
99    * The width of the image in cells
100    */

101   private double width;
102
103   /**
104    * The height of the image in cells
105    */

106   private double height;
107
108   /**
109    * The number of places this drawing is referenced
110    */

111   private int referenceCount;
112
113   /**
114    * The top level escher container
115    */

116   private EscherContainer escherData;
117
118   /**
119    * Where this image came from (read, written or a copy)
120    */

121   private Origin origin;
122
123   /**
124    * The drawing group for all the images
125    */

126   private DrawingGroup drawingGroup;
127
128   /**
129    * The drawing data
130    */

131   private DrawingData drawingData;
132
133   /**
134    * The type of this drawing object
135    */

136   private ShapeType type;
137
138   /**
139    * The drawing position on the sheet
140    */

141   private int drawingNumber;
142
143   /**
144    * An mso drawing record, which sometimes appears
145    */

146   private MsoDrawingRecord mso;
147
148   /**
149    * The text object record
150    */

151   private TextObjectRecord txo;
152
153   /**
154    * Text data from the first continue record
155    */

156   private ContinueRecord text;
157
158   /**
159    * Formatting data from the second continue record
160    */

161   private ContinueRecord formatting;
162
163   /**
164    * The comment text
165    */

166   private String JavaDoc commentText;
167   
168   /**
169    * The workbook settings
170    */

171   private WorkbookSettings workbookSettings;
172
173   /**
174    * Constructor used when reading images
175    *
176    * @param mso the drawing record
177    * @param obj the object record
178    * @param dd the drawing data for all drawings on this sheet
179    * @param dg the drawing group
180    * @param ws the workbook settings
181    */

182   public Button(MsoDrawingRecord mso, ObjRecord obj, DrawingData dd,
183                 DrawingGroup dg, WorkbookSettings ws)
184   {
185     drawingGroup = dg;
186     msoDrawingRecord = mso;
187     drawingData = dd;
188     objRecord = obj;
189     initialized = false;
190     workbookSettings = ws;
191     origin = Origin.READ;
192     drawingData.addData(msoDrawingRecord.getData());
193     drawingNumber = drawingData.getNumDrawings() - 1;
194     drawingGroup.addDrawing(this);
195
196     Assert.verify(mso != null && obj != null);
197
198     initialize();
199   }
200
201   /**
202    * Copy constructor used to copy drawings from read to write
203    *
204    * @param d the drawing to copy
205    */

206   /*protected*/ public Button(DrawingGroupObject dgo,
207                               DrawingGroup dg,
208                               WorkbookSettings ws)
209   {
210     Button d = (Button) dgo;
211     Assert.verify(d.origin == Origin.READ);
212     msoDrawingRecord = d.msoDrawingRecord;
213     objRecord = d.objRecord;
214     initialized = false;
215     origin = Origin.READ;
216     drawingData = d.drawingData;
217     drawingGroup = dg;
218     drawingNumber = d.drawingNumber;
219     drawingGroup.addDrawing(this);
220     mso = d.mso;
221     txo = d.txo;
222     text = d.text;
223     formatting = d.formatting;
224     workbookSettings = ws;
225   }
226
227   /**
228    * Constructor invoked when writing the images
229    *
230    * @param text the comment text
231    * @param c the column
232    * @param r the row
233    * @param width the width in cells
234    * @param height the height in cells
235    */

236   /*
237   public Button(String text, int c, int r)
238   {
239     initialized = true;
240     origin = Origin.WRITE;
241     column = c;
242     row = r;
243     referenceCount = 1;
244     type = ShapeType.TEXT_BOX;
245     commentText = text;
246   }
247   */

248
249   /**
250    * Initializes the member variables from the Escher stream data
251    */

252   private void initialize()
253   {
254     readSpContainer = drawingData.getSpContainer(drawingNumber);
255     Assert.verify(readSpContainer != null);
256
257     EscherRecord[] children = readSpContainer.getChildren();
258
259     Sp sp = (Sp) readSpContainer.getChildren()[0];
260     objectId = objRecord.getObjectId();
261     shapeId = sp.getShapeId();
262     type = ShapeType.getType(sp.getShapeType());
263
264     if (type == ShapeType.UNKNOWN)
265     {
266       logger.warn("Unknown shape type");
267     }
268
269     Opt opt = (Opt) readSpContainer.getChildren()[1];
270
271     ClientAnchor clientAnchor = null;
272     for (int i = 0 ; i < children.length && clientAnchor == null ; i++)
273     {
274       if (children[i].getType() == EscherRecordType.CLIENT_ANCHOR)
275       {
276         clientAnchor = (ClientAnchor) children[i];
277       }
278     }
279     
280     if (clientAnchor == null)
281     {
282       logger.warn("Client anchor not found");
283     }
284     else
285     {
286       column = (int) clientAnchor.getX1() - 1;
287       row = (int) clientAnchor.getY1() + 1;
288     }
289
290     initialized = true;
291   }
292
293
294   /**
295    * Sets the object id. Invoked by the drawing group when the object is
296    * added to id
297    *
298    * @param objid the object id
299    * @param bip the blip id
300    * @param sid the shape id
301    */

302   public final void setObjectId(int objid, int bip, int sid)
303   {
304     objectId = objid;
305     blipId = bip;
306     shapeId = sid;
307
308     if (origin == Origin.READ)
309     {
310       origin = Origin.READ_WRITE;
311     }
312   }
313
314   /**
315    * Accessor for the object id
316    *
317    * @return the object id
318    */

319   public final int getObjectId()
320   {
321     if (!initialized)
322     {
323       initialize();
324     }
325
326     return objectId;
327   }
328
329   /**
330    * Accessor for the shape id
331    *
332    * @return the object id
333    */

334   public final int getShapeId()
335   {
336     if (!initialized)
337     {
338       initialize();
339     }
340
341     return shapeId;
342   }
343
344   /**
345    * Accessor for the blip id
346    *
347    * @return the blip id
348    */

349   public final int getBlipId()
350   {
351     if (!initialized)
352     {
353       initialize();
354     }
355
356     return blipId;
357   }
358
359   /**
360    * Gets the drawing record which was read in
361    *
362    * @return the drawing record
363    */

364   public MsoDrawingRecord getMsoDrawingRecord()
365   {
366     return msoDrawingRecord;
367   }
368   
369   /**
370    * Creates the main Sp container for the drawing
371    *
372    * @return the SP container
373    */

374   public EscherContainer getSpContainer()
375   {
376     if (!initialized)
377     {
378       initialize();
379     }
380
381     if (origin == Origin.READ)
382     {
383       return getReadSpContainer();
384     }
385
386     Assert.verify(false);
387
388     /*
389     if (spContainer == null)
390     {
391       spContainer = new SpContainer();
392       Sp sp = new Sp(type, shapeId, 2560);
393       spContainer.add(sp);
394       Opt opt = new Opt();
395       opt.addProperty(344, false, false, 0); // ?
396       opt.addProperty(385, false, false, 134217808); // fill colour
397       opt.addProperty(387, false, false, 134217808); // background colour
398       opt.addProperty(959, false, false, 131074); // hide
399       spContainer.add(opt);
400       
401       ClientAnchor clientAnchor = new ClientAnchor(column + 1.3,
402                                                    Math.max(0, row - 0.6),
403                                                    column+3, row + 4);
404
405       spContainer.add(clientAnchor);
406       
407       ClientData clientData = new ClientData();
408       spContainer.add(clientData);
409       
410       ClientTextBox clientTextBox = new ClientTextBox();
411       spContainer.add(clientTextBox);
412     }
413     */

414
415     return spContainer;
416   }
417
418   /**
419    * Sets the drawing group for this drawing. Called by the drawing group
420    * when this drawing is added to it
421    *
422    * @param dg the drawing group
423    */

424   public void setDrawingGroup(DrawingGroup dg)
425   {
426     drawingGroup = dg;
427   }
428
429   /**
430    * Accessor for the drawing group
431    *
432    * @return the drawing group
433    */

434   public DrawingGroup getDrawingGroup()
435   {
436     return drawingGroup;
437   }
438
439   /**
440    * Gets the origin of this drawing
441    *
442    * @return where this drawing came from
443    */

444   public Origin getOrigin()
445   {
446     return origin;
447   }
448   
449   /**
450    * Accessor for the reference count on this drawing
451    *
452    * @return the reference count
453    */

454   public int getReferenceCount()
455   {
456     return referenceCount;
457   }
458
459   /**
460    * Sets the new reference count on the drawing
461    *
462    * @param r the new reference count
463    */

464   public void setReferenceCount(int r)
465   {
466     referenceCount = r;
467   }
468
469   /**
470    * Accessor for the column of this drawing
471    *
472    * @return the column
473    */

474   public double getX()
475   {
476     if (!initialized)
477     {
478       initialize();
479     }
480     return column;
481   }
482
483   /**
484    * Sets the column position of this drawing. Used when inserting/removing
485    * columns from the spreadsheet
486    *
487    * @param x the column
488    */

489   public void setX(double x)
490   {
491     if (origin == Origin.READ)
492     {
493       if (!initialized)
494       {
495         initialize();
496       }
497       origin = Origin.READ_WRITE;
498     }
499
500     column = (int) x;
501   }
502
503   /**
504    * Accessor for the row of this drawing
505    *
506    * @return the row
507    */

508   public double getY()
509   {
510     if (!initialized)
511     {
512       initialize();
513     }
514
515     return row;
516   }
517
518   /**
519    * Accessor for the row of the drawing
520    *
521    * @param y the row
522    */

523   public void setY(double y)
524   {
525     if (origin == Origin.READ)
526     {
527       if (!initialized)
528       {
529         initialize();
530       }
531       origin = Origin.READ_WRITE;
532     }
533
534     row = (int) y;
535   }
536
537
538   /**
539    * Accessor for the width of this drawing
540    *
541    * @return the number of columns spanned by this image
542    */

543   public double getWidth()
544   {
545     if (!initialized)
546     {
547       initialize();
548     }
549
550     return width;
551   }
552
553   /**
554    * Accessor for the width
555    *
556    * @param w the number of columns to span
557    */

558   public void setWidth(double w)
559   {
560     if (origin == Origin.READ)
561     {
562       if (!initialized)
563       {
564         initialize();
565       }
566       origin = Origin.READ_WRITE;
567     }
568
569     width = w;
570   }
571
572   /**
573    * Accessor for the height of this drawing
574    *
575    * @return the number of rows spanned by this image
576    */

577   public double getHeight()
578   {
579     if (!initialized)
580     {
581       initialize();
582     }
583
584     return height;
585   }
586
587   /**
588    * Accessor for the height of this drawing
589    *
590    * @param h the number of rows spanned by this image
591    */

592   public void setHeight(double h)
593   {
594     if (origin == Origin.READ)
595     {
596       if (!initialized)
597       {
598         initialize();
599       }
600       origin = Origin.READ_WRITE;
601     }
602
603     height = h;
604   }
605
606   
607   /**
608    * Gets the SpContainer that was read in
609    *
610    * @return the read sp container
611    */

612   private EscherContainer getReadSpContainer()
613   {
614     if (!initialized)
615     {
616       initialize();
617     }
618
619     return readSpContainer;
620   }
621
622   /**
623    * Accessor for the image data
624    *
625    * @return the image data
626    */

627   public byte[] getImageData()
628   {
629     Assert.verify(origin == Origin.READ || origin == Origin.READ_WRITE);
630
631     if (!initialized)
632     {
633       initialize();
634     }
635     
636     return drawingGroup.getImageData(blipId);
637   }
638
639   /**
640    * Accessor for the type
641    *
642    * @return the type
643    */

644   public ShapeType getType()
645   {
646     return type;
647   }
648
649   /**
650    * Sets the text object
651    */

652   public void setTextObject(TextObjectRecord t)
653   {
654     txo = t;
655   }
656
657   /**
658    * Sets the text data
659    */

660   public void setText(ContinueRecord t)
661   {
662     text = t;
663   }
664
665   /**
666    * Sets the formatting
667    */

668   public void setFormatting(ContinueRecord t)
669   {
670     formatting = t;
671   }
672
673   /**
674    * Accessor for the image data
675    *
676    * @return the image data
677    */

678   public byte[] getImageBytes()
679   {
680     Assert.verify(false);
681     return null;
682   }
683
684   /**
685    * Accessor for the image file path. Normally this is the absolute path
686    * of a file on the directory system, but if this drawing was constructed
687    * using an byte[] then the blip id is returned
688    *
689    * @return the image file path, or the blip id
690    */

691   public String JavaDoc getImageFilePath()
692   {
693     Assert.verify(false);
694     return null;
695   }
696
697   public void addMso(MsoDrawingRecord d)
698   {
699     mso = d;
700     drawingData.addRawData(mso.getData());
701   }
702
703   public void writeAdditionalRecords(File outputFile) throws IOException JavaDoc
704   {
705     if (origin == Origin.READ)
706     {
707       outputFile.write(objRecord);
708
709       if (mso != null)
710       {
711         outputFile.write(mso);
712       }
713       outputFile.write(txo);
714       outputFile.write(text);
715       if (formatting != null)
716       {
717         outputFile.write(formatting);
718       }
719       return;
720     }
721
722     Assert.verify(false);
723
724     // Create the obj record
725
ObjRecord objRecord = new ObjRecord(objectId,
726                                         ObjRecord.EXCELNOTE);
727     
728     outputFile.write(objRecord);
729
730     // Create the mso data record. Write the text box record again,
731
// although it is already included in the SpContainer
732
ClientTextBox textBox = new ClientTextBox();
733     MsoDrawingRecord msod = new MsoDrawingRecord(textBox.getData());
734     outputFile.write(msod);
735
736     TextObjectRecord txo = new TextObjectRecord(getText());
737     outputFile.write(txo);
738
739     // Data for the first continue record
740
byte[] textData = new byte[commentText.length() * 2 + 1];
741     textData[0] = 0x1; // unicode indicator
742
StringHelper.getUnicodeBytes(commentText, textData, 1);
743     //StringHelper.getBytes(commentText, textData, 1);
744
ContinueRecord textContinue = new ContinueRecord(textData);
745     outputFile.write(textContinue);
746
747     // Data for the formatting runs
748

749     byte[] frData = new byte[16];
750
751     // First txo run (the user)
752
IntegerHelper.getTwoBytes(0, frData, 0); // index to the first character
753
IntegerHelper.getTwoBytes(0, frData, 2); // index to the font(default)
754
// Mandatory last txo run
755
IntegerHelper.getTwoBytes(commentText.length(), frData, 8);
756     IntegerHelper.getTwoBytes(0, frData, 10); // index to the font(default)
757

758     ContinueRecord frContinue = new ContinueRecord(frData);
759     outputFile.write(frContinue);
760   }
761
762   /**
763    * Writes any records that need to be written after all the drawing group
764    * objects have been written
765    * Writes out all the note records
766    */

767   public void writeTailRecords(File outputFile) throws IOException JavaDoc
768   {
769   }
770
771   /**
772    * Accessor for the row
773    */

774   public int getRow()
775   {
776     return 0;
777   }
778
779   /**
780    * Accessor for the column
781    */

782   public int getColumn()
783   {
784     return 0;
785   }
786
787   /**
788    * Accessor for the comment text
789    */

790   public String JavaDoc getText()
791   {
792     if (commentText == null)
793     {
794       Assert.verify(text != null);
795
796       byte[] td = text.getData();
797       if (td[0] == 0)
798       {
799         commentText = StringHelper.getString
800           (td, td.length-1, 1, workbookSettings);
801       }
802       else
803       {
804         commentText = StringHelper.getUnicodeString
805           (td, (td.length - 1)/2, 1);
806       }
807     }
808
809     return commentText;
810   }
811
812   /**
813    * Hashing algorithm
814    */

815   public int hashCode()
816   {
817     return commentText.hashCode();
818   }
819
820   /**
821    * Called when the comment text is changed during the sheet copy process
822    *
823    * @param t the new text
824    */

825   public void setButtonText(String JavaDoc t)
826   {
827     commentText = t;
828     
829     if (origin == Origin.READ)
830     {
831       origin = Origin.READ_WRITE;
832     }
833   }
834
835   /**
836    * Accessor for the first drawing on the sheet. This is used when
837    * copying unmodified sheets to indicate that this drawing contains
838    * the first time Escher gubbins
839    *
840    * @return TRUE if this MSORecord is the first drawing on the sheet
841    */

842   public boolean isFirst()
843   {
844     return mso.isFirst();
845   }
846
847   /**
848    * Queries whether this object is a form object. Form objects have their
849    * drawings records spread over TXO and CONTINUE records and
850    * require special handling
851    *
852    * @return TRUE if this is a form object, FALSE otherwise
853    */

854   public boolean isFormObject()
855   {
856     return true;
857   }
858 }
859
860
861
862
Popular Tags