1 16 17 package org.apache.poi.hssf.record; 18 19 import org.apache.poi.ddf.*; 20 import org.apache.poi.hssf.usermodel.*; 21 import org.apache.poi.hssf.model.AbstractShape; 22 import org.apache.poi.hssf.model.TextboxShape; 23 import org.apache.poi.hssf.model.DrawingManager; 24 import org.apache.poi.hssf.model.ConvertAnchor; 25 26 import java.util.*; 27 28 45 public class EscherAggregate extends AbstractEscherHolderRecord 46 { 47 public static final short sid = 9876; 48 49 public static final short ST_MIN = (short) 0; 50 public static final short ST_NOT_PRIMATIVE = ST_MIN; 51 public static final short ST_RECTANGLE = (short) 1; 52 public static final short ST_ROUNDRECTANGLE = (short) 2; 53 public static final short ST_ELLIPSE = (short) 3; 54 public static final short ST_DIAMOND = (short) 4; 55 public static final short ST_ISOCELESTRIANGLE = (short) 5; 56 public static final short ST_RIGHTTRIANGLE = (short) 6; 57 public static final short ST_PARALLELOGRAM = (short) 7; 58 public static final short ST_TRAPEZOID = (short) 8; 59 public static final short ST_HEXAGON = (short) 9; 60 public static final short ST_OCTAGON = (short) 10; 61 public static final short ST_PLUS = (short) 11; 62 public static final short ST_STAR = (short) 12; 63 public static final short ST_ARROW = (short) 13; 64 public static final short ST_THICKARROW = (short) 14; 65 public static final short ST_HOMEPLATE = (short) 15; 66 public static final short ST_CUBE = (short) 16; 67 public static final short ST_BALLOON = (short) 17; 68 public static final short ST_SEAL = (short) 18; 69 public static final short ST_ARC = (short) 19; 70 public static final short ST_LINE = (short) 20; 71 public static final short ST_PLAQUE = (short) 21; 72 public static final short ST_CAN = (short) 22; 73 public static final short ST_DONUT = (short) 23; 74 public static final short ST_TEXTSIMPLE = (short) 24; 75 public static final short ST_TEXTOCTAGON = (short) 25; 76 public static final short ST_TEXTHEXAGON = (short) 26; 77 public static final short ST_TEXTCURVE = (short) 27; 78 public static final short ST_TEXTWAVE = (short) 28; 79 public static final short ST_TEXTRING = (short) 29; 80 public static final short ST_TEXTONCURVE = (short) 30; 81 public static final short ST_TEXTONRING = (short) 31; 82 public static final short ST_STRAIGHTCONNECTOR1 = (short) 32; 83 public static final short ST_BENTCONNECTOR2 = (short) 33; 84 public static final short ST_BENTCONNECTOR3 = (short) 34; 85 public static final short ST_BENTCONNECTOR4 = (short) 35; 86 public static final short ST_BENTCONNECTOR5 = (short) 36; 87 public static final short ST_CURVEDCONNECTOR2 = (short) 37; 88 public static final short ST_CURVEDCONNECTOR3 = (short) 38; 89 public static final short ST_CURVEDCONNECTOR4 = (short) 39; 90 public static final short ST_CURVEDCONNECTOR5 = (short) 40; 91 public static final short ST_CALLOUT1 = (short) 41; 92 public static final short ST_CALLOUT2 = (short) 42; 93 public static final short ST_CALLOUT3 = (short) 43; 94 public static final short ST_ACCENTCALLOUT1 = (short) 44; 95 public static final short ST_ACCENTCALLOUT2 = (short) 45; 96 public static final short ST_ACCENTCALLOUT3 = (short) 46; 97 public static final short ST_BORDERCALLOUT1 = (short) 47; 98 public static final short ST_BORDERCALLOUT2 = (short) 48; 99 public static final short ST_BORDERCALLOUT3 = (short) 49; 100 public static final short ST_ACCENTBORDERCALLOUT1 = (short) 50; 101 public static final short ST_ACCENTBORDERCALLOUT2 = (short) 51; 102 public static final short ST_ACCENTBORDERCALLOUT3 = (short) 52; 103 public static final short ST_RIBBON = (short) 53; 104 public static final short ST_RIBBON2 = (short) 54; 105 public static final short ST_CHEVRON = (short) 55; 106 public static final short ST_PENTAGON = (short) 56; 107 public static final short ST_NOSMOKING = (short) 57; 108 public static final short ST_SEAL8 = (short) 58; 109 public static final short ST_SEAL16 = (short) 59; 110 public static final short ST_SEAL32 = (short) 60; 111 public static final short ST_WEDGERECTCALLOUT = (short) 61; 112 public static final short ST_WEDGERRECTCALLOUT = (short) 62; 113 public static final short ST_WEDGEELLIPSECALLOUT = (short) 63; 114 public static final short ST_WAVE = (short) 64; 115 public static final short ST_FOLDEDCORNER = (short) 65; 116 public static final short ST_LEFTARROW = (short) 66; 117 public static final short ST_DOWNARROW = (short) 67; 118 public static final short ST_UPARROW = (short) 68; 119 public static final short ST_LEFTRIGHTARROW = (short) 69; 120 public static final short ST_UPDOWNARROW = (short) 70; 121 public static final short ST_IRREGULARSEAL1 = (short) 71; 122 public static final short ST_IRREGULARSEAL2 = (short) 72; 123 public static final short ST_LIGHTNINGBOLT = (short) 73; 124 public static final short ST_HEART = (short) 74; 125 public static final short ST_PICTUREFRAME = (short) 75; 126 public static final short ST_QUADARROW = (short) 76; 127 public static final short ST_LEFTARROWCALLOUT = (short) 77; 128 public static final short ST_RIGHTARROWCALLOUT = (short) 78; 129 public static final short ST_UPARROWCALLOUT = (short) 79; 130 public static final short ST_DOWNARROWCALLOUT = (short) 80; 131 public static final short ST_LEFTRIGHTARROWCALLOUT = (short) 81; 132 public static final short ST_UPDOWNARROWCALLOUT = (short) 82; 133 public static final short ST_QUADARROWCALLOUT = (short) 83; 134 public static final short ST_BEVEL = (short) 84; 135 public static final short ST_LEFTBRACKET = (short) 85; 136 public static final short ST_RIGHTBRACKET = (short) 86; 137 public static final short ST_LEFTBRACE = (short) 87; 138 public static final short ST_RIGHTBRACE = (short) 88; 139 public static final short ST_LEFTUPARROW = (short) 89; 140 public static final short ST_BENTUPARROW = (short) 90; 141 public static final short ST_BENTARROW = (short) 91; 142 public static final short ST_SEAL24 = (short) 92; 143 public static final short ST_STRIPEDRIGHTARROW = (short) 93; 144 public static final short ST_NOTCHEDRIGHTARROW = (short) 94; 145 public static final short ST_BLOCKARC = (short) 95; 146 public static final short ST_SMILEYFACE = (short) 96; 147 public static final short ST_VERTICALSCROLL = (short) 97; 148 public static final short ST_HORIZONTALSCROLL = (short) 98; 149 public static final short ST_CIRCULARARROW = (short) 99; 150 public static final short ST_NOTCHEDCIRCULARARROW = (short) 100; 151 public static final short ST_UTURNARROW = (short) 101; 152 public static final short ST_CURVEDRIGHTARROW = (short) 102; 153 public static final short ST_CURVEDLEFTARROW = (short) 103; 154 public static final short ST_CURVEDUPARROW = (short) 104; 155 public static final short ST_CURVEDDOWNARROW = (short) 105; 156 public static final short ST_CLOUDCALLOUT = (short) 106; 157 public static final short ST_ELLIPSERIBBON = (short) 107; 158 public static final short ST_ELLIPSERIBBON2 = (short) 108; 159 public static final short ST_FLOWCHARTPROCESS = (short) 109; 160 public static final short ST_FLOWCHARTDECISION = (short) 110; 161 public static final short ST_FLOWCHARTINPUTOUTPUT = (short) 111; 162 public static final short ST_FLOWCHARTPREDEFINEDPROCESS = (short) 112; 163 public static final short ST_FLOWCHARTINTERNALSTORAGE = (short) 113; 164 public static final short ST_FLOWCHARTDOCUMENT = (short) 114; 165 public static final short ST_FLOWCHARTMULTIDOCUMENT = (short) 115; 166 public static final short ST_FLOWCHARTTERMINATOR = (short) 116; 167 public static final short ST_FLOWCHARTPREPARATION = (short) 117; 168 public static final short ST_FLOWCHARTMANUALINPUT = (short) 118; 169 public static final short ST_FLOWCHARTMANUALOPERATION = (short) 119; 170 public static final short ST_FLOWCHARTCONNECTOR = (short) 120; 171 public static final short ST_FLOWCHARTPUNCHEDCARD = (short) 121; 172 public static final short ST_FLOWCHARTPUNCHEDTAPE = (short) 122; 173 public static final short ST_FLOWCHARTSUMMINGJUNCTION = (short) 123; 174 public static final short ST_FLOWCHARTOR = (short) 124; 175 public static final short ST_FLOWCHARTCOLLATE = (short) 125; 176 public static final short ST_FLOWCHARTSORT = (short) 126; 177 public static final short ST_FLOWCHARTEXTRACT = (short) 127; 178 public static final short ST_FLOWCHARTMERGE = (short) 128; 179 public static final short ST_FLOWCHARTOFFLINESTORAGE = (short) 129; 180 public static final short ST_FLOWCHARTONLINESTORAGE = (short) 130; 181 public static final short ST_FLOWCHARTMAGNETICTAPE = (short) 131; 182 public static final short ST_FLOWCHARTMAGNETICDISK = (short) 132; 183 public static final short ST_FLOWCHARTMAGNETICDRUM = (short) 133; 184 public static final short ST_FLOWCHARTDISPLAY = (short) 134; 185 public static final short ST_FLOWCHARTDELAY = (short) 135; 186 public static final short ST_TEXTPLAINTEXT = (short) 136; 187 public static final short ST_TEXTSTOP = (short) 137; 188 public static final short ST_TEXTTRIANGLE = (short) 138; 189 public static final short ST_TEXTTRIANGLEINVERTED = (short) 139; 190 public static final short ST_TEXTCHEVRON = (short) 140; 191 public static final short ST_TEXTCHEVRONINVERTED = (short) 141; 192 public static final short ST_TEXTRINGINSIDE = (short) 142; 193 public static final short ST_TEXTRINGOUTSIDE = (short) 143; 194 public static final short ST_TEXTARCHUPCURVE = (short) 144; 195 public static final short ST_TEXTARCHDOWNCURVE = (short) 145; 196 public static final short ST_TEXTCIRCLECURVE = (short) 146; 197 public static final short ST_TEXTBUTTONCURVE = (short) 147; 198 public static final short ST_TEXTARCHUPPOUR = (short) 148; 199 public static final short ST_TEXTARCHDOWNPOUR = (short) 149; 200 public static final short ST_TEXTCIRCLEPOUR = (short) 150; 201 public static final short ST_TEXTBUTTONPOUR = (short) 151; 202 public static final short ST_TEXTCURVEUP = (short) 152; 203 public static final short ST_TEXTCURVEDOWN = (short) 153; 204 public static final short ST_TEXTCASCADEUP = (short) 154; 205 public static final short ST_TEXTCASCADEDOWN = (short) 155; 206 public static final short ST_TEXTWAVE1 = (short) 156; 207 public static final short ST_TEXTWAVE2 = (short) 157; 208 public static final short ST_TEXTWAVE3 = (short) 158; 209 public static final short ST_TEXTWAVE4 = (short) 159; 210 public static final short ST_TEXTINFLATE = (short) 160; 211 public static final short ST_TEXTDEFLATE = (short) 161; 212 public static final short ST_TEXTINFLATEBOTTOM = (short) 162; 213 public static final short ST_TEXTDEFLATEBOTTOM = (short) 163; 214 public static final short ST_TEXTINFLATETOP = (short) 164; 215 public static final short ST_TEXTDEFLATETOP = (short) 165; 216 public static final short ST_TEXTDEFLATEINFLATE = (short) 166; 217 public static final short ST_TEXTDEFLATEINFLATEDEFLATE = (short) 167; 218 public static final short ST_TEXTFADERIGHT = (short) 168; 219 public static final short ST_TEXTFADELEFT = (short) 169; 220 public static final short ST_TEXTFADEUP = (short) 170; 221 public static final short ST_TEXTFADEDOWN = (short) 171; 222 public static final short ST_TEXTSLANTUP = (short) 172; 223 public static final short ST_TEXTSLANTDOWN = (short) 173; 224 public static final short ST_TEXTCANUP = (short) 174; 225 public static final short ST_TEXTCANDOWN = (short) 175; 226 public static final short ST_FLOWCHARTALTERNATEPROCESS = (short) 176; 227 public static final short ST_FLOWCHARTOFFPAGECONNECTOR = (short) 177; 228 public static final short ST_CALLOUT90 = (short) 178; 229 public static final short ST_ACCENTCALLOUT90 = (short) 179; 230 public static final short ST_BORDERCALLOUT90 = (short) 180; 231 public static final short ST_ACCENTBORDERCALLOUT90 = (short) 181; 232 public static final short ST_LEFTRIGHTUPARROW = (short) 182; 233 public static final short ST_SUN = (short) 183; 234 public static final short ST_MOON = (short) 184; 235 public static final short ST_BRACKETPAIR = (short) 185; 236 public static final short ST_BRACEPAIR = (short) 186; 237 public static final short ST_SEAL4 = (short) 187; 238 public static final short ST_DOUBLEWAVE = (short) 188; 239 public static final short ST_ACTIONBUTTONBLANK = (short) 189; 240 public static final short ST_ACTIONBUTTONHOME = (short) 190; 241 public static final short ST_ACTIONBUTTONHELP = (short) 191; 242 public static final short ST_ACTIONBUTTONINFORMATION = (short) 192; 243 public static final short ST_ACTIONBUTTONFORWARDNEXT = (short) 193; 244 public static final short ST_ACTIONBUTTONBACKPREVIOUS = (short) 194; 245 public static final short ST_ACTIONBUTTONEND = (short) 195; 246 public static final short ST_ACTIONBUTTONBEGINNING = (short) 196; 247 public static final short ST_ACTIONBUTTONRETURN = (short) 197; 248 public static final short ST_ACTIONBUTTONDOCUMENT = (short) 198; 249 public static final short ST_ACTIONBUTTONSOUND = (short) 199; 250 public static final short ST_ACTIONBUTTONMOVIE = (short) 200; 251 public static final short ST_HOSTCONTROL = (short) 201; 252 public static final short ST_TEXTBOX = (short) 202; 253 public static final short ST_NIL = (short) 0x0FFF; 254 255 protected HSSFPatriarch patriarch; 256 257 258 private Map shapeToObj = new HashMap(); 259 private DrawingManager drawingManager; 260 private short drawingGroupId; 261 262 public EscherAggregate( DrawingManager drawingManager ) 263 { 264 this.drawingManager = drawingManager; 265 } 266 267 270 public short getSid() 271 { 272 return sid; 273 } 274 275 280 protected void fillFields( byte[] data, short size, int offset ) 281 { 282 throw new IllegalStateException ( "Should not reach here" ); 283 } 284 285 289 public String toString() 290 { 291 String nl = System.getProperty( "line.separtor" ); 292 293 StringBuffer result = new StringBuffer (); 294 result.append( '[' ).append( getRecordName() ).append( ']' + nl ); 295 for ( Iterator iterator = getEscherRecords().iterator(); iterator.hasNext(); ) 296 { 297 EscherRecord escherRecord = (EscherRecord) iterator.next(); 298 result.append( escherRecord.toString() ); 299 } 300 result.append( "[/" ).append( getRecordName() ).append( ']' + nl ); 301 302 return result.toString(); 303 } 304 305 308 public static EscherAggregate createAggregate( List records, int locFirstDrawingRecord, DrawingManager drawingManager ) 309 { 310 final List shapeRecords = new ArrayList(); 313 EscherRecordFactory recordFactory = new DefaultEscherRecordFactory() 314 { 315 public EscherRecord createRecord( byte[] data, int offset ) 316 { 317 EscherRecord r = super.createRecord( data, offset ); 318 if ( r.getRecordId() == EscherClientDataRecord.RECORD_ID || r.getRecordId() == EscherTextboxRecord.RECORD_ID ) 319 { 320 shapeRecords.add( r ); 321 } 322 return r; 323 } 324 }; 325 326 EscherAggregate agg = new EscherAggregate(drawingManager); 328 int loc = locFirstDrawingRecord; 329 int dataSize = 0; 330 while ( loc + 1 < records.size() 331 && sid( records, loc ) == DrawingRecord.sid 332 && isObjectRecord( records, loc + 1 ) ) 333 { 334 dataSize += ( (DrawingRecord) records.get( loc ) ).getData().length; 335 loc += 2; 336 } 337 338 byte buffer[] = new byte[dataSize]; 340 int offset = 0; 341 loc = locFirstDrawingRecord; 342 while ( loc + 1 < records.size() 343 && sid( records, loc ) == DrawingRecord.sid 344 && isObjectRecord( records, loc + 1 ) ) 345 { 346 DrawingRecord drawingRecord = (DrawingRecord) records.get( loc ); 347 System.arraycopy( drawingRecord.getData(), 0, buffer, offset, drawingRecord.getData().length ); 348 offset += drawingRecord.getData().length; 349 loc += 2; 350 } 351 352 int pos = 0; 355 while ( pos < dataSize ) 356 { 357 EscherRecord r = recordFactory.createRecord( buffer, pos ); 358 int bytesRead = r.fillFields( buffer, pos, recordFactory ); 359 agg.addEscherRecord( r ); 360 pos += bytesRead; 361 } 362 363 loc = locFirstDrawingRecord; 365 int shapeIndex = 0; 366 agg.shapeToObj = new HashMap(); 367 while ( loc + 1 < records.size() 368 && sid( records, loc ) == DrawingRecord.sid 369 && isObjectRecord( records, loc + 1 ) ) 370 { 371 Record objRecord = (Record) records.get( loc + 1 ); 372 agg.shapeToObj.put( shapeRecords.get( shapeIndex++ ), objRecord ); 373 loc += 2; 374 } 375 376 return agg; 377 378 } 379 380 388 public int serialize( int offset, byte[] data ) 389 { 390 convertUserModelToRecords(); 391 392 List records = getEscherRecords(); 394 int size = getEscherRecordSize( records ); 395 byte[] buffer = new byte[size]; 396 397 398 final List spEndingOffsets = new ArrayList(); 400 final List shapes = new ArrayList(); 401 int pos = 0; 402 for ( Iterator iterator = records.iterator(); iterator.hasNext(); ) 403 { 404 EscherRecord e = (EscherRecord) iterator.next(); 405 pos += e.serialize( pos, buffer, new EscherSerializationListener() 406 { 407 public void beforeRecordSerialize( int offset, short recordId, EscherRecord record ) 408 { 409 } 410 411 public void afterRecordSerialize( int offset, short recordId, int size, EscherRecord record ) 412 { 413 if ( recordId == EscherClientDataRecord.RECORD_ID || recordId == EscherTextboxRecord.RECORD_ID ) 414 { 415 spEndingOffsets.add( new Integer ( offset ) ); 416 shapes.add( record ); 417 } 418 } 419 } ); 420 } 421 shapes.add( 0, null ); 423 spEndingOffsets.add( 0, null ); 424 425 pos = offset; 428 for ( int i = 1; i < shapes.size(); i++ ) 429 { 430 int endOffset = ( (Integer ) spEndingOffsets.get( i ) ).intValue() - 1; 431 int startOffset; 432 if ( i == 1 ) 433 startOffset = 0; 434 else 435 startOffset = ( (Integer ) spEndingOffsets.get( i - 1 ) ).intValue(); 436 437 DrawingRecord drawing = new DrawingRecord(); 439 byte[] drawingData = new byte[endOffset - startOffset + 1]; 440 System.arraycopy( buffer, startOffset, drawingData, 0, drawingData.length ); 441 drawing.setData( drawingData ); 442 int temp = drawing.serialize( pos, data ); 443 pos += temp; 444 445 Record obj = (Record) shapeToObj.get( shapes.get( i ) ); 447 temp = obj.serialize( pos, data ); 448 pos += temp; 449 450 } 451 452 int bytesWritten = pos - offset; 453 if ( bytesWritten != getRecordSize() ) 454 throw new RecordFormatException( bytesWritten + " bytes written but getRecordSize() reports " + getRecordSize() ); 455 return bytesWritten; 456 } 457 458 463 private int getEscherRecordSize( List records ) 464 { 465 int size = 0; 466 for ( Iterator iterator = records.iterator(); iterator.hasNext(); ) 467 size += ( (EscherRecord) iterator.next() ).getRecordSize(); 468 return size; 469 } 470 471 474 public int getRecordSize() 475 { 476 convertUserModelToRecords(); 477 List records = getEscherRecords(); 478 int rawEscherSize = getEscherRecordSize( records ); 479 int drawingRecordSize = rawEscherSize + ( shapeToObj.size() ) * 4; 480 int objRecordSize = 0; 481 for ( Iterator iterator = shapeToObj.values().iterator(); iterator.hasNext(); ) 482 { 483 Record r = (Record) iterator.next(); 484 objRecordSize += r.getRecordSize(); 485 } 486 return drawingRecordSize + objRecordSize; 487 } 488 489 492 public Object assoicateShapeToObjRecord( EscherRecord r, Record objRecord ) 493 { 494 return shapeToObj.put( r, objRecord ); 495 } 496 497 public HSSFPatriarch getPatriarch() 498 { 499 return patriarch; 500 } 501 502 public void setPatriarch( HSSFPatriarch patriarch ) 503 { 504 this.patriarch = patriarch; 505 } 506 507 public void clear() 508 { 509 clearEscherRecords(); 510 shapeToObj.clear(); 511 } 513 514 protected String getRecordName() 515 { 516 return "ESCHERAGGREGATE"; 517 } 518 519 521 private static boolean isObjectRecord( List records, int loc ) 522 { 523 return sid( records, loc ) == ObjRecord.sid || sid( records, loc ) == TextObjectRecord.sid; 524 } 525 526 private void convertUserModelToRecords() 527 { 528 if ( patriarch != null ) 529 { 530 shapeToObj.clear(); 531 clearEscherRecords(); 532 if ( patriarch.getChildren().size() != 0 ) 533 { 534 convertPatriarch( patriarch ); 535 EscherContainerRecord dgContainer = (EscherContainerRecord) getEscherRecord( 0 ); 536 EscherContainerRecord spgrContainer = null; 537 for ( int i = 0; i < dgContainer.getChildRecords().size(); i++ ) 538 if ( dgContainer.getChild( i ).getRecordId() == EscherContainerRecord.SPGR_CONTAINER ) 539 spgrContainer = (EscherContainerRecord) dgContainer.getChild( i ); 540 convertShapes( patriarch, spgrContainer, shapeToObj ); 541 542 patriarch = null; 543 } 544 } 545 } 546 547 private void convertShapes( HSSFShapeContainer parent, EscherContainerRecord escherParent, Map shapeToObj ) 548 { 549 if ( escherParent == null ) throw new IllegalArgumentException ( "Parent record required" ); 550 551 List shapes = parent.getChildren(); 552 for ( Iterator iterator = shapes.iterator(); iterator.hasNext(); ) 553 { 554 HSSFShape shape = (HSSFShape) iterator.next(); 555 if ( shape instanceof HSSFShapeGroup ) 556 { 557 convertGroup( (HSSFShapeGroup) shape, escherParent, shapeToObj ); 558 } 559 else 560 { 561 AbstractShape shapeModel = AbstractShape.createShape( 562 shape, 563 drawingManager.allocateShapeId(drawingGroupId) ); 564 shapeToObj.put( findClientData( shapeModel.getSpContainer() ), shapeModel.getObjRecord() ); 565 if ( shapeModel instanceof TextboxShape ) 566 { 567 EscherRecord escherTextbox = ( (TextboxShape) shapeModel ).getEscherTextbox(); 568 shapeToObj.put( escherTextbox, ( (TextboxShape) shapeModel ).getTextObjectRecord() ); 569 } 571 escherParent.addChildRecord( shapeModel.getSpContainer() ); 572 } 573 } 574 } 575 576 private void convertGroup( HSSFShapeGroup shape, EscherContainerRecord escherParent, Map shapeToObj ) 577 { 578 EscherContainerRecord spgrContainer = new EscherContainerRecord(); 579 EscherContainerRecord spContainer = new EscherContainerRecord(); 580 EscherSpgrRecord spgr = new EscherSpgrRecord(); 581 EscherSpRecord sp = new EscherSpRecord(); 582 EscherOptRecord opt = new EscherOptRecord(); 583 EscherRecord anchor; 584 EscherClientDataRecord clientData = new EscherClientDataRecord(); 585 586 spgrContainer.setRecordId( EscherContainerRecord.SPGR_CONTAINER ); 587 spgrContainer.setOptions( (short) 0x000F ); 588 spContainer.setRecordId( EscherContainerRecord.SP_CONTAINER ); 589 spContainer.setOptions( (short) 0x000F ); 590 spgr.setRecordId( EscherSpgrRecord.RECORD_ID ); 591 spgr.setOptions( (short) 0x0001 ); 592 spgr.setRectX1( shape.getX1() ); 593 spgr.setRectY1( shape.getY1() ); 594 spgr.setRectX2( shape.getX2() ); 595 spgr.setRectY2( shape.getY2() ); 596 sp.setRecordId( EscherSpRecord.RECORD_ID ); 597 sp.setOptions( (short) 0x0002 ); 598 int shapeId = drawingManager.allocateShapeId(drawingGroupId); 599 sp.setShapeId( shapeId ); 600 if (shape.getAnchor() instanceof HSSFClientAnchor) 601 sp.setFlags( EscherSpRecord.FLAG_GROUP | EscherSpRecord.FLAG_HAVEANCHOR ); 602 else 603 sp.setFlags( EscherSpRecord.FLAG_GROUP | EscherSpRecord.FLAG_HAVEANCHOR | EscherSpRecord.FLAG_CHILD ); 604 opt.setRecordId( EscherOptRecord.RECORD_ID ); 605 opt.setOptions( (short) 0x0023 ); 606 opt.addEscherProperty( new EscherBoolProperty( EscherProperties.PROTECTION__LOCKAGAINSTGROUPING, 0x00040004 ) ); 607 opt.addEscherProperty( new EscherBoolProperty( EscherProperties.GROUPSHAPE__PRINT, 0x00080000 ) ); 608 609 anchor = ConvertAnchor.createAnchor( shape.getAnchor() ); 610 clientData.setRecordId( EscherClientDataRecord.RECORD_ID ); 619 clientData.setOptions( (short) 0x0000 ); 620 621 spgrContainer.addChildRecord( spContainer ); 622 spContainer.addChildRecord( spgr ); 623 spContainer.addChildRecord( sp ); 624 spContainer.addChildRecord( opt ); 625 spContainer.addChildRecord( anchor ); 626 spContainer.addChildRecord( clientData ); 627 628 ObjRecord obj = new ObjRecord(); 629 CommonObjectDataSubRecord cmo = new CommonObjectDataSubRecord(); 630 cmo.setObjectType( CommonObjectDataSubRecord.OBJECT_TYPE_GROUP ); 631 cmo.setObjectId( (short) ( shapeId ) ); 632 cmo.setLocked( true ); 633 cmo.setPrintable( true ); 634 cmo.setAutofill( true ); 635 cmo.setAutoline( true ); 636 GroupMarkerSubRecord gmo = new GroupMarkerSubRecord(); 637 EndSubRecord end = new EndSubRecord(); 638 obj.addSubRecord( cmo ); 639 obj.addSubRecord( gmo ); 640 obj.addSubRecord( end ); 641 shapeToObj.put( clientData, obj ); 642 643 escherParent.addChildRecord( spgrContainer ); 644 645 convertShapes( shape, spgrContainer, shapeToObj ); 646 647 } 648 649 private EscherRecord findClientData( EscherContainerRecord spContainer ) 650 { 651 for ( Iterator iterator = spContainer.getChildRecords().iterator(); iterator.hasNext(); ) 652 { 653 EscherRecord r = (EscherRecord) iterator.next(); 654 if ( r.getRecordId() == EscherClientDataRecord.RECORD_ID ) 655 return r; 656 } 657 throw new IllegalArgumentException ( "Can not find client data record" ); 658 } 659 660 private void convertPatriarch( HSSFPatriarch patriarch ) 661 { 662 EscherContainerRecord dgContainer = new EscherContainerRecord(); 663 EscherDgRecord dg; 664 EscherContainerRecord spgrContainer = new EscherContainerRecord(); 665 EscherContainerRecord spContainer1 = new EscherContainerRecord(); 666 EscherSpgrRecord spgr = new EscherSpgrRecord(); 667 EscherSpRecord sp1 = new EscherSpRecord(); 668 669 dgContainer.setRecordId( EscherContainerRecord.DG_CONTAINER ); 670 dgContainer.setOptions( (short) 0x000F ); 671 dg = drawingManager.createDgRecord(); 672 drawingGroupId = dg.getDrawingGroupId(); 673 spgrContainer.setRecordId( EscherContainerRecord.SPGR_CONTAINER ); 677 spgrContainer.setOptions( (short) 0x000F ); 678 spContainer1.setRecordId( EscherContainerRecord.SP_CONTAINER ); 679 spContainer1.setOptions( (short) 0x000F ); 680 spgr.setRecordId( EscherSpgrRecord.RECORD_ID ); 681 spgr.setOptions( (short) 0x0001 ); spgr.setRectX1( patriarch.getX1() ); 683 spgr.setRectY1( patriarch.getY1() ); 684 spgr.setRectX2( patriarch.getX2() ); 685 spgr.setRectY2( patriarch.getY2() ); 686 sp1.setRecordId( EscherSpRecord.RECORD_ID ); 687 sp1.setOptions( (short) 0x0002 ); 688 sp1.setShapeId( drawingManager.allocateShapeId(dg.getDrawingGroupId()) ); 689 sp1.setFlags( EscherSpRecord.FLAG_GROUP | EscherSpRecord.FLAG_PATRIARCH ); 690 691 dgContainer.addChildRecord( dg ); 692 dgContainer.addChildRecord( spgrContainer ); 693 spgrContainer.addChildRecord( spContainer1 ); 694 spContainer1.addChildRecord( spgr ); 695 spContainer1.addChildRecord( sp1 ); 696 697 addEscherRecord( dgContainer ); 698 } 699 700 701 706 private static short sid( List records, int loc ) 707 { 708 return ( (Record) records.get( loc ) ).getSid(); 709 } 710 711 712 } 713 | Popular Tags |