/// <summary> /// Creates the low-level records for a comment. /// </summary> /// <param name="hssfShape">The highlevel shape.</param> /// <param name="shapeId">The shape id to use for this shape.</param> public CommentShape(HSSFComment hssfShape, int shapeId) : base(hssfShape, shapeId) { note = CreateNoteRecord(hssfShape, shapeId); ObjRecord obj = ObjRecord; List<SubRecord> records = obj.SubRecords; int cmoIdx = 0; for (int i = 0; i < records.Count; i++) { Object r = records[i]; if (r is CommonObjectDataSubRecord) { //modify autoFill attribute inherited from <c>TextObjectRecord</c> CommonObjectDataSubRecord cmo = (CommonObjectDataSubRecord)r; cmo.IsAutoFill=(false); cmoIdx = i; } } //Add NoteStructure sub record //we don't know it's format, for now the record data Is empty NoteStructureSubRecord u = new NoteStructureSubRecord(); obj.AddSubRecord(cmoIdx + 1, u); }
/// <summary> /// Creates the low level NoteRecord /// which holds the comment attributes. /// </summary> /// <param name="shape">The shape.</param> /// <param name="shapeId">The shape id.</param> /// <returns></returns> private NoteRecord CreateNoteRecord(HSSFComment shape, int shapeId) { NoteRecord note = new NoteRecord(); note.Column = shape.Column; note.Row = shape.Row; note.Flags = (shape.Visible ? NoteRecord.NOTE_VISIBLE : NoteRecord.NOTE_HIDDEN); note.ShapeId = shapeId; note.Author = (shape.Author == null ? "" : shape.Author); return note; }
public void TestDefaultShapeType() { HSSFComment comment = new HSSFComment((HSSFShape)null, new HSSFClientAnchor()); Assert.AreEqual(HSSFSimpleShape.OBJECT_TYPE_COMMENT, comment.ShapeType); }
/// <summary> /// Constructs a cell comment. /// </summary> /// <param name="anchor">the client anchor describes how this comment is attached /// to the sheet.</param> /// <returns>the newly created comment.</returns> public HSSFComment CreateComment(HSSFAnchor anchor) { HSSFComment shape = new HSSFComment(null, anchor); shape.Anchor = anchor; shapes.Add(shape); return shape; }
public static CommentShape CreateCommentShape(int shapeId, HSSFComment comment) { return new CommentShape(comment, shapeId); }
/// <summary> /// Constructs a cell comment. /// </summary> /// <param name="anchor">the client anchor describes how this comment is attached /// to the sheet.</param> /// <returns>the newly created comment.</returns> public NPOI.SS.UserModel.Comment CreateCellComment(NPOI.SS.UserModel.ClientAnchor anchor) { HSSFComment shape = new HSSFComment(null, (HSSFAnchor)anchor); shape.Anchor = (HSSFAnchor)anchor; shapes.Add(shape); return shape; }
/** * build shape tree from escher container * @param container root escher container from which escher records must be taken * @param agg - EscherAggregate * @param out - shape container to which shapes must be added * @param root - node to create HSSFObjectData shapes */ public static void CreateShapeTree(EscherContainerRecord container, EscherAggregate agg, HSSFShapeContainer out1, DirectoryNode root) { if (container.RecordId == EscherContainerRecord.SPGR_CONTAINER) { ObjRecord obj = null; EscherClientDataRecord clientData = (EscherClientDataRecord)((EscherContainerRecord)container.GetChild(0)).GetChildById(EscherClientDataRecord.RECORD_ID); if (null != clientData) { obj = (ObjRecord)agg.GetShapeToObjMapping()[clientData]; } HSSFShapeGroup group = new HSSFShapeGroup(container, obj); IList <EscherContainerRecord> children = container.ChildContainers; // skip the first child record, it is group descriptor for (int i = 0; i < children.Count; i++) { EscherContainerRecord spContainer = children[(i)]; if (i != 0) { CreateShapeTree(spContainer, agg, group, root); } } out1.AddShape(group); } else if (container.RecordId == EscherContainerRecord.SP_CONTAINER) { Dictionary <EscherRecord, Record.Record> shapeToObj = agg.GetShapeToObjMapping(); ObjRecord objRecord = null; TextObjectRecord txtRecord = null; foreach (EscherRecord record in container.ChildRecords) { switch (record.RecordId) { case EscherClientDataRecord.RECORD_ID: objRecord = (ObjRecord)shapeToObj[(record)]; break; case EscherTextboxRecord.RECORD_ID: txtRecord = (TextObjectRecord)shapeToObj[(record)]; break; default: break; } } if (IsEmbeddedObject(objRecord)) { HSSFObjectData objectData = new HSSFObjectData(container, objRecord, root); out1.AddShape(objectData); return; } CommonObjectDataSubRecord cmo = (CommonObjectDataSubRecord)objRecord.SubRecords[0]; HSSFShape shape; switch (cmo.ObjectType) { case CommonObjectType.Picture: shape = new HSSFPicture(container, objRecord); break; case CommonObjectType.Rectangle: shape = new HSSFSimpleShape(container, objRecord, txtRecord); break; case CommonObjectType.Line: shape = new HSSFSimpleShape(container, objRecord); break; case CommonObjectType.ComboBox: shape = new HSSFCombobox(container, objRecord); break; case CommonObjectType.MicrosoftOfficeDrawing: EscherOptRecord optRecord = (EscherOptRecord)container.GetChildById(EscherOptRecord.RECORD_ID); if (optRecord == null) { shape = new HSSFSimpleShape(container, objRecord, txtRecord); } else { EscherProperty property = optRecord.Lookup(EscherProperties.GEOMETRY__VERTICES); if (null != property) { shape = new HSSFPolygon(container, objRecord, txtRecord); } else { shape = new HSSFSimpleShape(container, objRecord, txtRecord); } } break; case CommonObjectType.Text: shape = new HSSFTextbox(container, objRecord, txtRecord); break; case CommonObjectType.Comment: shape = new HSSFComment(container, objRecord, txtRecord, agg.GetNoteRecordByObj(objRecord)); break; default: shape = new HSSFSimpleShape(container, objRecord, txtRecord); break; } out1.AddShape(shape); } }
/** * build shape tree from escher container * @param container root escher container from which escher records must be taken * @param agg - EscherAggregate * @param out - shape container to which shapes must be added * @param root - node to create HSSFObjectData shapes */ public static void CreateShapeTree(EscherContainerRecord container, EscherAggregate agg, HSSFShapeContainer out1, DirectoryNode root) { if (container.RecordId == EscherContainerRecord.SPGR_CONTAINER) { ObjRecord obj = null; EscherClientDataRecord clientData = (EscherClientDataRecord)((EscherContainerRecord)container.GetChild(0)).GetChildById(EscherClientDataRecord.RECORD_ID); if (null != clientData) { obj = (ObjRecord)agg.GetShapeToObjMapping()[clientData]; } HSSFShapeGroup group = new HSSFShapeGroup(container, obj); IList<EscherContainerRecord> children = container.ChildContainers; // skip the first child record, it is group descriptor for (int i = 0; i < children.Count; i++) { EscherContainerRecord spContainer = children[(i)]; if (i != 0) { CreateShapeTree(spContainer, agg, group, root); } } out1.AddShape(group); } else if (container.RecordId == EscherContainerRecord.SP_CONTAINER) { Dictionary<EscherRecord, Record.Record> shapeToObj = agg.GetShapeToObjMapping(); ObjRecord objRecord = null; TextObjectRecord txtRecord = null; foreach (EscherRecord record in container.ChildRecords) { switch (record.RecordId) { case EscherClientDataRecord.RECORD_ID: objRecord = (ObjRecord)shapeToObj[(record)]; break; case EscherTextboxRecord.RECORD_ID: txtRecord = (TextObjectRecord)shapeToObj[(record)]; break; } } if (IsEmbeddedObject(objRecord)) { HSSFObjectData objectData = new HSSFObjectData(container, objRecord, root); out1.AddShape(objectData); return; } CommonObjectDataSubRecord cmo = (CommonObjectDataSubRecord)objRecord.SubRecords[0]; HSSFShape shape; switch (cmo.ObjectType) { case CommonObjectType.Picture: shape = new HSSFPicture(container, objRecord); break; case CommonObjectType.Rectangle: shape = new HSSFSimpleShape(container, objRecord, txtRecord); break; case CommonObjectType.Line: shape = new HSSFSimpleShape(container, objRecord); break; case CommonObjectType.ComboBox: shape = new HSSFCombobox(container, objRecord); break; case CommonObjectType.MicrosoftOfficeDrawing: EscherOptRecord optRecord = (EscherOptRecord)container.GetChildById(EscherOptRecord.RECORD_ID); EscherProperty property = optRecord.Lookup(EscherProperties.GEOMETRY__VERTICES); if (null != property) { shape = new HSSFPolygon(container, objRecord, txtRecord); } else { shape = new HSSFSimpleShape(container, objRecord, txtRecord); } break; case CommonObjectType.Text: shape = new HSSFTextbox(container, objRecord, txtRecord); break; case CommonObjectType.Comment: shape = new HSSFComment(container, objRecord, txtRecord, agg.GetNoteRecordByObj(objRecord)); break; default: shape = new HSSFSimpleShape(container, objRecord, txtRecord); break; } out1.AddShape(shape); } }
/// <summary> /// Cell comment Finder. /// Returns cell comment for the specified sheet, row and column. /// </summary> /// <param name="sheet">The sheet.</param> /// <param name="row">The row.</param> /// <param name="column">The column.</param> /// <returns>cell comment or /// <c>null</c> /// if not found</returns> public static HSSFComment FindCellComment(Sheet sheet, int row, int column) { HSSFComment comment = null; Hashtable txshapes = new Hashtable(); //map shapeId and TextObjectRecord for (IEnumerator it = sheet.Records.GetEnumerator(); it.MoveNext(); ) { RecordBase rec = (RecordBase)it.Current; if (rec is NoteRecord) { NoteRecord note = (NoteRecord)rec; if (note.Row == row && note.Column == column) { TextObjectRecord txo = (TextObjectRecord)txshapes[note.ShapeId]; comment = new HSSFComment(note, txo); comment.Row = note.Row; comment.Column = note.Column; comment.Author = (note.Author); comment.Visible = (note.Flags == NoteRecord.NOTE_VISIBLE); comment.String = txo.Str; break; } } else if (rec is ObjRecord) { ObjRecord obj = (ObjRecord)rec; SubRecord sub = (SubRecord)obj.GetSubRecords()[0]; if (sub is CommonObjectDataSubRecord) { CommonObjectDataSubRecord cmo = (CommonObjectDataSubRecord)sub; if (cmo.ObjectType == CommonObjectDataSubRecord.OBJECT_TYPE_COMMENT) { //Find the nearest TextObjectRecord which holds comment's text and map it to its shapeId while (it.MoveNext()) { rec = (Record)it.Current; if (rec is TextObjectRecord) { txshapes[cmo.ObjectId] = rec; break; } } } } } } return comment; }
/// <summary> /// Removes the comment for this cell, if /// there is one. /// </summary> /// <remarks>WARNING - some versions of excel will loose /// all comments after performing this action!</remarks> public void RemoveCellComment() { HSSFComment comment = FindCellComment(sheet.Sheet, record.Row, record.Column); this.comment = null; if (comment == null) { // Nothing to do return; } // Zap the underlying NoteRecord IList sheetRecords = sheet.Sheet.Records; sheetRecords.Remove(comment.NoteRecord); // If we have a TextObjectRecord, is should // be proceeed by: // MSODRAWING with container // OBJ // MSODRAWING with EscherTextboxRecord if (comment.TextObjectRecord != null) { TextObjectRecord txo = comment.TextObjectRecord; int txoAt = sheetRecords.IndexOf(txo); if (sheetRecords[txoAt - 3] is DrawingRecord && sheetRecords[txoAt - 2] is ObjRecord && sheetRecords[txoAt - 1] is DrawingRecord) { // Zap these, in reverse order sheetRecords.RemoveAt(txoAt - 1); sheetRecords.RemoveAt(txoAt - 2); sheetRecords.RemoveAt(txoAt - 3); } else { throw new InvalidOperationException("Found the wrong records before the TextObjectRecord, can't Remove comment"); } // Now Remove the text record sheetRecords.Remove(txo); } }
/** * Constructs a cell comment. * * @param anchor the client anchor describes how this comment is attached * to the sheet. * @return the newly created comment. */ public HSSFComment CreateComment(HSSFAnchor anchor) { HSSFComment shape = new HSSFComment(null, anchor); AddShape(shape); OnCreate(shape); return shape; }
/** * Converts the Records into UserModel * objects on the bound HSSFPatriarch */ public void ConvertRecordsToUserModel() { if (patriarch == null) { throw new InvalidOperationException("Must call SetPatriarch() first"); } // The top level container ought to have // the DgRecord and the container of one container // per shape Group (patriach overall first) EscherContainerRecord topContainer = (EscherContainerRecord)GetEscherContainer(); if (topContainer == null) { return; } topContainer = (EscherContainerRecord) topContainer.ChildContainers[0]; IList<EscherContainerRecord> tcc = topContainer.ChildContainers; if (tcc.Count == 0) { throw new InvalidOperationException("No child escher containers at the point that should hold the patriach data, and one container per top level shape!"); } // First up, Get the patriach position // This Is in the first EscherSpgrRecord, in // the first container, with a EscherSRecord too EscherContainerRecord patriachContainer = (EscherContainerRecord)tcc[0]; EscherSpgrRecord spgr = null; for (IEnumerator it = patriachContainer.ChildRecords.GetEnumerator(); it.MoveNext(); ) { EscherRecord r = (EscherRecord)it.Current; if (r is EscherSpgrRecord) { spgr = (EscherSpgrRecord)r; break; } } if (spgr != null) { patriarch.SetCoordinates( spgr.RectX1, spgr.RectY1, spgr.RectX2, spgr.RectY2 ); } // Now Process the containers for each Group // and objects for (int i = 1; i < tcc.Count; i++) { EscherContainerRecord shapeContainer = (EscherContainerRecord)tcc[i]; //Console.Error.WriteLine("\n\n*****\n\n"); //Console.Error.WriteLine(shapeContainer); // Could be a Group, or a base object if (shapeContainer.RecordId == EscherContainerRecord.SPGR_CONTAINER) { if(shapeContainer.ChildRecords.Count>0) { // Group HSSFShapeGroup group = new HSSFShapeGroup(null, new HSSFClientAnchor()); patriarch.Children.Add(group); EscherContainerRecord groupContainer = (EscherContainerRecord)shapeContainer.GetChild(0); ConvertRecordsToUserModel(groupContainer, group); } } else if (shapeContainer.RecordId == EscherContainerRecord.SP_CONTAINER) { EscherSpRecord spRecord = (EscherSpRecord)shapeContainer.GetChildById(EscherSpRecord.RECORD_ID); int type = spRecord.ShapeType; switch (type) { case ST_TEXTBOX: HSSFSimpleShape box; TextObjectRecord textrec = (TextObjectRecord)shapeToObj[GetEscherChild(shapeContainer, EscherTextboxRecord.RECORD_ID)]; EscherClientAnchorRecord anchorRecord1 = (EscherClientAnchorRecord)GetEscherChild(shapeContainer, EscherClientAnchorRecord.RECORD_ID); HSSFClientAnchor anchor1 = new HSSFClientAnchor(); anchor1.Col1 = anchorRecord1.Col1; anchor1.Col2 = anchorRecord1.Col2; anchor1.Dx1 = anchorRecord1.Dx1; anchor1.Dx2 = anchorRecord1.Dx2; anchor1.Dy1 = anchorRecord1.Dy1; anchor1.Dy2 = anchorRecord1.Dy2; anchor1.Row1 = anchorRecord1.Row1; anchor1.Row2 = anchorRecord1.Row2; if (tailRec.Count>=i && tailRec[i-1] is NoteRecord) { NoteRecord noterec=(NoteRecord)tailRec[i - 1]; // comment box = new HSSFComment(null, anchor1); HSSFComment comment=(HSSFComment)box; comment.Author = noterec.Author; comment.Row = noterec.Row; comment.Column = noterec.Column; comment.Visible = (noterec.Flags == NoteRecord.NOTE_VISIBLE); comment.String = textrec.Str; } else { // TextBox box = new HSSFTextbox(null, anchor1); ((HSSFTextbox)box).String = textrec.Str; } patriarch.AddShape(box); ConvertRecordsToUserModel(shapeContainer, box); break; case ST_PICTUREFRAME: // Duplicated from // org.apache.poi.hslf.model.Picture.getPictureIndex() EscherOptRecord opt = (EscherOptRecord)GetEscherChild(shapeContainer, EscherOptRecord.RECORD_ID); EscherSimpleProperty prop = (EscherSimpleProperty)opt.Lookup(EscherProperties.BLIP__BLIPTODISPLAY); if (prop != null) { int pictureIndex = prop.PropertyValue; EscherClientAnchorRecord anchorRecord = (EscherClientAnchorRecord)GetEscherChild(shapeContainer, EscherClientAnchorRecord.RECORD_ID); HSSFClientAnchor anchor = new HSSFClientAnchor(); anchor.Col1 = anchorRecord.Col1; anchor.Col2 = anchorRecord.Col2; anchor.Dx1 = anchorRecord.Dx1; anchor.Dx2 = anchorRecord.Dx2; anchor.Dy1 = anchorRecord.Dy1; anchor.Dy2 = anchorRecord.Dy2; anchor.Row1 = anchorRecord.Row1; anchor.Row2 = anchorRecord.Row2; HSSFPicture picture = new HSSFPicture(null, anchor); picture.PictureIndex = pictureIndex; patriarch.AddShape(picture); } break; } } else { // Base level ConvertRecordsToUserModel(shapeContainer, patriarch); } } // Now, clear any trace of what records make up // the patriarch // Otherwise, everything will go horribly wrong // when we try to Write out again.... // clearEscherRecords(); drawingManager.GetDgg().FileIdClusters=new EscherDggRecord.FileIdCluster[0]; // TODO: Support Converting our records // back into shapes log.Log(POILogger.WARN, "Not Processing objects into Patriarch!"); }