/** * Gets the drawings. Called when copying sheets * * @return the drawings on this page */ public DrawingGroupObject[] getDrawings() { DrawingGroupObject[] dr = new DrawingGroupObject[drawings.Count]; int pos = 0; foreach (DrawingGroupObject record in drawings) { dr[pos++] = record; } return(dr); }
/** * Copy constructor used to copy drawings from read to write * * @param dgo the drawing group object * @param dg the drawing group */ protected Drawing2(DrawingGroupObject dgo, DrawingGroup dg) { Drawing2 d = (Drawing2)dgo; Assert.verify(d.origin == Origin.READ); msoDrawingRecord = d.msoDrawingRecord; initialized = false; origin = Origin.READ; drawingData = d.drawingData; drawingGroup = dg; drawingNumber = d.drawingNumber; drawingGroup.addDrawing(this); }
/** * Copy constructor used to copy drawings from read to write * * @param dgo the drawing group object * @param dg the drawing group * @param ws the workbook settings */ public ComboBox(DrawingGroupObject dgo, DrawingGroup dg, WorkbookSettings ws) { ComboBox d = (ComboBox)dgo; Assert.verify(d.origin == Origin.READ); msoDrawingRecord = d.msoDrawingRecord; objRecord = d.objRecord; initialized = false; origin = Origin.READ; drawingData = d.drawingData; drawingGroup = dg; drawingNumber = d.drawingNumber; drawingGroup.addDrawing(this); workbookSettings = ws; }
/** * Interface method to remove a drawing from the group * * @param d the drawing to remove */ public void remove(DrawingGroupObject d) { // Unless there are real images or some such, it is possible that // a BStoreContainer will not be present. In that case simply return if (getBStoreContainer() == null) { return; } if (origin == Origin.READ) { origin = Origin.READ_WRITE; numBlips = getBStoreContainer().getNumBlips(); Dgg dgg = (Dgg)escherData.getChildren()[0]; drawingGroupId = dgg.getCluster(1).drawingGroupId - numBlips - 1; } // Get the blip EscherRecord[] children = getBStoreContainer().getChildren(); BlipStoreEntry bse = (BlipStoreEntry)children[d.getBlipId() - 1]; bse.dereference(); if (bse.getReferenceCount() == 0) { // Remove the blip getBStoreContainer().remove(bse); // Adjust blipId on the other blips foreach (DrawingGroupObject drawing in drawings) { if (drawing.getBlipId() > d.getBlipId()) { drawing.setObjectId(drawing.getObjectId(), drawing.getBlipId() - 1, drawing.getShapeId()); } } numBlips--; } }
/** * Copy constructor used to copy drawings from read to write * * @param dgo the drawing group object * @param dg the drawing group * @param ws the workbook settings */ public Button(DrawingGroupObject dgo, DrawingGroup dg, WorkbookSettings ws) { Button d = (Button)dgo; Assert.verify(d.origin == Origin.READ); msoDrawingRecord = d.msoDrawingRecord; objRecord = d.objRecord; initialized = false; origin = Origin.READ; drawingData = d.drawingData; drawingGroup = dg; drawingNumber = d.drawingNumber; drawingGroup.addDrawing(this); mso = d.mso; txo = d.txo; text = d.text; formatting = d.formatting; workbookSettings = ws; }
/** * Copy constructor used to copy drawings from read to write * * @param dgo the drawing group object * @param dg the drawing group * @param ws the workbook settings */ /*protected*/ public Comment(DrawingGroupObject dgo, DrawingGroup dg, WorkbookSettings ws) { Comment d = (Comment)dgo; Assert.verify(d.origin == Origin.READ); msoDrawingRecord = d.msoDrawingRecord; objRecord = d.objRecord; initialized = false; origin = Origin.READ; drawingData = d.drawingData; drawingGroup = dg; drawingNumber = d.drawingNumber; drawingGroup.addDrawing(this); mso = d.mso; txo = d.txo; text = d.text; formatting = d.formatting; note = d.note; width = d.width; height = d.height; workbookSettings = ws; }
/** * Copy constructor used to copy drawings from read to write * * @param dgo the drawing group object * @param dg the drawing group */ protected Drawing2(DrawingGroupObject dgo,DrawingGroup dg) { Drawing2 d = (Drawing2)dgo; Assert.verify(d.origin == Origin.READ); msoDrawingRecord = d.msoDrawingRecord; initialized = false; origin = Origin.READ; drawingData = d.drawingData; drawingGroup = dg; drawingNumber = d.drawingNumber; drawingGroup.addDrawing(this); }
/** * Adds a drawing to this workbook * * @param d the drawing to add */ public void addDrawing(DrawingGroupObject d) { if (drawingGroup == null) { drawingGroup = new DrawingGroup(Origin.WRITE); } drawingGroup.add(d); }
/** * Constructor, used when copying sheets * * @param d the image to copy * @param dg the drawing group */ public WritableImage(DrawingGroupObject d, DrawingGroup dg) : base(d, dg) { }
/** * Writes out the MsoDrawing records and Obj records for each image * and chart on the sheet * * @param outputFile the output file * @exception IOException */ public void write(File outputFile) { // If there are no drawings or charts on this sheet then exit if (drawings.Count == 0 && charts.Length == 0) { return; } // See if any drawing has been modified bool modified = drawingsModified; int numImages = drawings.Count; foreach (DrawingGroupObject d in drawings) { if (d.getOrigin() != Origin.READ) { modified = true; } } // If the drawing order has been muddled at all, then we'll need // to regenerate the Escher drawing data if (numImages > 0 && !modified) { DrawingGroupObject d2 = (DrawingGroupObject)drawings[0]; if (!d2.isFirst()) { modified = true; } } // Check to see if this sheet consists of just a single chart. If so // there is no MsoDrawingRecord, so write out the data and exit if (numImages == 0 && charts.Length == 1 && charts[0].getMsoDrawingRecord() == null) { modified = false; // this sheet has not been modified } // If no drawing has been modified, then simply write them straight out // again and exit if (!modified) { writeUnmodified(outputFile); return; } object[] spContainerData = new object[numImages + charts.Length]; int length = 0; EscherContainer firstSpContainer = null; // Get all the spContainer byte data from the drawings // and store in an array for (int i = 0; i < numImages; i++) { DrawingGroupObject drawing = (DrawingGroupObject)drawings[i]; EscherContainer spc = drawing.getSpContainer(); if (spc != null) { byte[] data = spc.getData(); spContainerData[i] = data; if (i == 0) { firstSpContainer = spc; } else { length += data.Length; } } } // Get all the spContainer bytes from the charts and add to the array for (int i = 0; i < charts.Length; i++) { EscherContainer spContainer = charts[i].getSpContainer(); byte[] data = spContainer.getBytes(); //use getBytes instead of getData data = spContainer.setHeaderData(data); spContainerData[i + numImages] = data; if (i == 0 && numImages == 0) { firstSpContainer = spContainer; } else { length += data.Length; } } // Put the generalised stuff around the first item DgContainer dgContainer = new DgContainer(); Dg dg = new Dg(numImages + charts.Length); dgContainer.add(dg); SpgrContainer spgrContainer = new SpgrContainer(); SpContainer _spContainer = new SpContainer(); Spgr spgr = new Spgr(); _spContainer.add(spgr); Sp sp = new Sp(ShapeType.MIN, 1024, 5); _spContainer.add(sp); spgrContainer.add(_spContainer); spgrContainer.add(firstSpContainer); dgContainer.add(spgrContainer); byte[] firstMsoData = dgContainer.getData(); // Adjust the length of the DgContainer int len = IntegerHelper.getInt(firstMsoData[4], firstMsoData[5], firstMsoData[6], firstMsoData[7]); IntegerHelper.getFourBytes(len + length, firstMsoData, 4); // Adjust the length of the SpgrContainer len = IntegerHelper.getInt(firstMsoData[28], firstMsoData[29], firstMsoData[30], firstMsoData[31]); IntegerHelper.getFourBytes(len + length, firstMsoData, 28); // Now write out each MsoDrawing record // First MsoRecord // test hack for form objects, to remove the ClientTextBox record // from the end of the SpContainer if (numImages > 0 && ((DrawingGroupObject)drawings[0]).isFormObject()) { byte[] msodata2 = new byte[firstMsoData.Length - 8]; System.Array.Copy(firstMsoData, 0, msodata2, 0, msodata2.Length); firstMsoData = msodata2; } MsoDrawingRecord msoDrawingRecord = new MsoDrawingRecord(firstMsoData); outputFile.write(msoDrawingRecord); if (numImages > 0) { DrawingGroupObject firstDrawing = (DrawingGroupObject)drawings[0]; firstDrawing.writeAdditionalRecords(outputFile); } else { // first image is a chart Chart chart = charts[0]; ObjRecord objRecord = chart.getObjRecord(); outputFile.write(objRecord); outputFile.write(chart); } // Now do all the others for (int i = 1; i < spContainerData.Length; i++) { byte[] bytes = (byte[])spContainerData[i]; // test hack for form objects, to remove the ClientTextBox record // from the end of the SpContainer if (i < numImages && ((DrawingGroupObject)drawings[i]).isFormObject()) { byte[] bytes2 = new byte[bytes.Length - 8]; System.Array.Copy(bytes, 0, bytes2, 0, bytes2.Length); bytes = bytes2; } msoDrawingRecord = new MsoDrawingRecord(bytes); outputFile.write(msoDrawingRecord); if (i < numImages) { // Write anything else the object needs DrawingGroupObject d = (DrawingGroupObject)drawings[i]; d.writeAdditionalRecords(outputFile); } else { Chart chart = charts[i - numImages]; ObjRecord objRecord = chart.getObjRecord(); outputFile.write(objRecord); outputFile.write(chart); } } // Write any tail records that need to be written foreach (DrawingGroupObject dgo2 in drawings) { dgo2.writeTailRecords(outputFile); } }
/** * Adds a drawing from the public, writable interface * * @param d the drawing to add */ public void add(DrawingGroupObject d) { if (origin == Origin.READ) { origin = Origin.READ_WRITE; BStoreContainer bsc = getBStoreContainer(); // force initialization Dgg dgg = (Dgg)escherData.getChildren()[0]; drawingGroupId = dgg.getCluster(1).drawingGroupId - numBlips - 1; numBlips = bsc != null?bsc.getNumBlips() : 0; if (bsc != null) { Assert.verify(numBlips == bsc.getNumBlips()); } } if (!(d is Drawing)) { // Assign a new object id and add it to the list // drawings.add(d); maxobjectId++; maxShapeId++; d.setDrawingGroup(this); d.setObjectId(maxobjectId, numBlips + 1, maxShapeId); if (drawings.Count > maxobjectId) { //logger.warn("drawings length " + drawings.Count + // " exceeds the max object id " + maxobjectId); } // numBlips++; return; } Drawing drawing = (Drawing)d; // See if this is referenced elsewhere Drawing refImage = null; if (imageFiles.ContainsKey(d.getImageFilePath())) { refImage = imageFiles[d.getImageFilePath()]; } if (refImage == null) { // There are no other references to this drawing, so assign // a new object id and put it on the hash map maxobjectId++; maxShapeId++; drawings.Add(drawing); drawing.setDrawingGroup(this); drawing.setObjectId(maxobjectId, numBlips + 1, maxShapeId); numBlips++; imageFiles.Add(drawing.getImageFilePath(), drawing); } else { // This drawing is used elsewhere in the workbook. Increment the // reference count on the drawing, and set the object id of the drawing // passed in refImage.setReferenceCount(refImage.getReferenceCount() + 1); drawing.setDrawingGroup(this); drawing.setObjectId(refImage.getObjectId(), refImage.getBlipId(), refImage.getShapeId()); } }
/** * Adds a drawing to the drawing group * * @param d the drawing to add */ public void addDrawing(DrawingGroupObject d) { drawings.Add(d); maxobjectId = System.Math.Max(maxobjectId, d.getObjectId()); maxShapeId = System.Math.Max(maxShapeId, d.getShapeId()); }
/** * Writes out the drawings and the charts if nothing has been modified * * @param outputFile the output file * @exception IOException */ private void writeUnmodified(File outputFile) { if (charts.Length == 0 && drawings.Count == 0) { // No drawings or charts return; } else if (charts.Length == 0 && drawings.Count != 0) { // If there are no charts, then write out the drawings and return foreach (DrawingGroupObject d in drawings) { outputFile.write(d.getMsoDrawingRecord()); d.writeAdditionalRecords(outputFile); } foreach (DrawingGroupObject d in drawings) { d.writeTailRecords(outputFile); } return; } else if (drawings.Count == 0 && charts.Length != 0) { // If there are no drawings, then write out the charts and return Chart curChart = null; for (int i = 0; i < charts.Length; i++) { curChart = charts[i]; if (curChart.getMsoDrawingRecord() != null) { outputFile.write(curChart.getMsoDrawingRecord()); } if (curChart.getObjRecord() != null) { outputFile.write(curChart.getObjRecord()); } outputFile.write(curChart); } return; } // There are both charts and drawings - the output // drawing group records will need // to be re-jigged in order to write the drawings out first, then the // charts int numDrawings = drawings.Count; int length = 0; EscherContainer[] spContainers = new EscherContainer[numDrawings + charts.Length]; bool[] isFormobject = new bool[numDrawings + charts.Length]; for (int i = 0; i < numDrawings; i++) { DrawingGroupObject d = (DrawingGroupObject)drawings[i]; spContainers[i] = d.getSpContainer(); if (i > 0) { length += spContainers[i].getLength(); } if (d.isFormObject()) { isFormobject[i] = true; } } for (int i = 0; i < charts.Length; i++) { spContainers[i + numDrawings] = charts[i].getSpContainer(); length += spContainers[i + numDrawings].getLength(); } // Put the generalised stuff around the first item DgContainer dgContainer = new DgContainer(); Dg dg = new Dg(numDrawings + charts.Length); dgContainer.add(dg); SpgrContainer spgrContainer = new SpgrContainer(); SpContainer spContainer = new SpContainer(); Spgr spgr = new Spgr(); spContainer.add(spgr); Sp sp = new Sp(ShapeType.MIN, 1024, 5); spContainer.add(sp); spgrContainer.add(spContainer); spgrContainer.add(spContainers[0]); dgContainer.add(spgrContainer); byte[] firstMsoData = dgContainer.getData(); // Adjust the length of the DgContainer int len = IntegerHelper.getInt(firstMsoData[4], firstMsoData[5], firstMsoData[6], firstMsoData[7]); IntegerHelper.getFourBytes(len + length, firstMsoData, 4); // Adjust the length of the SpgrContainer len = IntegerHelper.getInt(firstMsoData[28], firstMsoData[29], firstMsoData[30], firstMsoData[31]); IntegerHelper.getFourBytes(len + length, firstMsoData, 28); // Now write out each MsoDrawing record and object record // Hack to remove the last eight bytes (text box escher record) // from the container if (isFormobject[0] == true) { byte[] cbytes = new byte[firstMsoData.Length - 8]; System.Array.Copy(firstMsoData, 0, cbytes, 0, cbytes.Length); firstMsoData = cbytes; } // First MsoRecord MsoDrawingRecord msoDrawingRecord = new MsoDrawingRecord(firstMsoData); outputFile.write(msoDrawingRecord); DrawingGroupObject dgo = (DrawingGroupObject)drawings[0]; dgo.writeAdditionalRecords(outputFile); // Now do all the others for (int i = 1; i < spContainers.Length; i++) { byte[] bytes = spContainers[i].getBytes(); byte[] bytes2 = spContainers[i].setHeaderData(bytes); // Hack to remove the last eight bytes (text box escher record) // from the container if (isFormobject[i] == true) { byte[] cbytes = new byte[bytes2.Length - 8]; System.Array.Copy(bytes2, 0, cbytes, 0, cbytes.Length); bytes2 = cbytes; } msoDrawingRecord = new MsoDrawingRecord(bytes2); outputFile.write(msoDrawingRecord); if (i < numDrawings) { dgo = (DrawingGroupObject)drawings[i]; dgo.writeAdditionalRecords(outputFile); } else { Chart chart = charts[i - numDrawings]; ObjRecord objRecord = chart.getObjRecord(); outputFile.write(objRecord); outputFile.write(chart); } } // Write any tail records that need to be written foreach (DrawingGroupObject dgo2 in drawings) { dgo2.writeTailRecords(outputFile); } }