001: /*
002: * $Id: GenericCommand.java,v 1.12 2002/07/17 05:13:37 skavish Exp $
003: *
004: * ===========================================================================
005: *
006: * The JGenerator Software License, Version 1.0
007: *
008: * Copyright (c) 2000 Dmitry Skavish (skavish@usa.net). All rights reserved.
009: *
010: * Redistribution and use in source and binary forms, with or without
011: * modification, are permitted provided that the following conditions are met:
012: *
013: * 1. Redistributions of source code must retain the above copyright
014: * notice, this list of conditions and the following disclaimer.
015: *
016: * 2. Redistributions in binary form must reproduce the above copyright
017: * notice, this list of conditions and the following disclaimer in
018: * the documentation and/or other materials provided with the
019: * distribution.
020: *
021: * 3. The end-user documentation included with the redistribution, if
022: * any, must include the following acknowlegement:
023: * "This product includes software developed by Dmitry Skavish
024: * (skavish@usa.net, http://www.flashgap.com/)."
025: * Alternately, this acknowlegement may appear in the software itself,
026: * if and wherever such third-party acknowlegements normally appear.
027: *
028: * 4. The name "The JGenerator" must not be used to endorse or promote
029: * products derived from this software without prior written permission.
030: * For written permission, please contact skavish@usa.net.
031: *
032: * 5. Products derived from this software may not be called "The JGenerator"
033: * nor may "The JGenerator" appear in their names without prior written
034: * permission of Dmitry Skavish.
035: *
036: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
037: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
038: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
039: * DISCLAIMED. IN NO EVENT SHALL DMITRY SKAVISH OR THE OTHER
040: * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
041: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
042: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
043: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
044: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
045: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
046: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
047: * SUCH DAMAGE.
048: *
049: */
050:
051: package org.openlaszlo.iv.flash.commands;
052:
053: import java.io.*;
054: import java.awt.geom.*;
055: import java.lang.reflect.*;
056:
057: import org.openlaszlo.iv.flash.parser.*;
058: import org.openlaszlo.iv.flash.api.*;
059: import org.openlaszlo.iv.flash.api.action.*;
060: import org.openlaszlo.iv.flash.api.shape.*;
061: import org.openlaszlo.iv.flash.api.text.*;
062: import org.openlaszlo.iv.flash.util.*;
063:
064: import org.openlaszlo.iv.flash.cache.*;
065: import org.openlaszlo.iv.flash.context.Context;
066: import org.openlaszlo.iv.flash.context.ContextFactory;
067:
068: /**
069: * Generic Generator command. All commands have to subclass it.
070: */
071:
072: public class GenericCommand extends FlashObject {
073:
074: public static final int TYPE_MOVIE = 0x01;
075: public static final int TYPE_BUTTON = 0x02;
076: public static final int TYPE_GRAPHICS = 0x04;
077: public static final int TYPE_GLOBAL = 0x08;
078:
079: private int type;
080: private int depth;
081: private int flags;
082: private int frameNum;
083:
084: private IVVector names = new IVVector();
085: private IVVector values = new IVVector();
086: private Instance instance;
087:
088: /** Needed to track if the command was created from a MX component */
089: private boolean isComponent = false;
090:
091: private static final String MACROMEDIACLASS = "com.macromedia.generator.commands.";
092: private static final String MXCOMPONENT_CMDNAME = "JGeneratorCommand";
093:
094: public GenericCommand() {
095: }
096:
097: public void doCommand(FlashFile file, Context context,
098: Script parent, int frame) throws IVException {
099: }
100:
101: /**
102: * Sets the isComponent flag
103: *
104: * @param isComponent boolean
105: */
106: public void setIsComponent(boolean isComponent) {
107: this .isComponent = isComponent;
108: }
109:
110: /**
111: * Gets the isComponent flag
112: *
113: * @retun boolean
114: */
115: public boolean isComponent() {
116: return isComponent;
117: }
118:
119: public boolean isGlobal() {
120: return (type & TYPE_GLOBAL) != 0;
121: }
122:
123: /**
124: * Returns command name
125: *
126: * @return command name
127: */
128: public String getCommandName() {
129: String name = getClass().getName();
130: int idx = name.lastIndexOf('.');
131: return name.substring(idx + 1);
132: }
133:
134: /**
135: * Returns instance
136: *
137: * @return
138: */
139: public Instance getInstance() {
140: return instance;
141: }
142:
143: public void setInstance(Instance instance) {
144: this .instance = instance;
145: }
146:
147: /**
148: * Returns an instance which is associated with commands modifying instances (like Replicate)
149: * <P>
150: * <OL>
151: * <LI>if this command is MX component then
152: * <OL>
153: * <LI>get parameter "instancename"
154: * <LI>if this parameter is specified then search for an instance in the file with this name
155: * <LI>if found then use it
156: * <LI>if not found search in parent script for an instance which encloses this command.
157: * by enclosing I mean that its bounds encloses the comamnd bounds
158: * </OL>
159: * <LI>if this command is not an MX component then just use this command instance as an instance
160: * </OL>
161: *
162: * @param file current flash file
163: * @param context current context
164: * @param parent parent script (where the command is placed)
165: * @param frameNum frame number where the command is instantiated
166: * @return the instance to which this command has to be applied
167: * @exception IVException
168: */
169: public Instance getCommandInstance(FlashFile file, Context context,
170: Script parent, int frameNum) throws IVException {
171: Instance inst = null;
172: if (isComponent()) {
173: String instancename = getParameter(context, "instancename");
174: if (instancename != null) {
175: instancename = instancename.trim();
176: if (instancename.length() != 0) {
177: Script main = file.getMainScript();
178: inst = main.findInstance(instancename);
179: }
180: }
181: if (inst == null) {
182: // find enclosure
183:
184: IVVector defs = new IVVector();
185: IVVector instances = new IVVector();
186:
187: Timeline timeline = parent.getTimeline();
188: int maxFrameNum = Math.min(timeline.getFrameCount(),
189: frameNum + 1);
190: for (int i = 0; i < maxFrameNum; i++) {
191: Frame frame = timeline.getFrameAt(i);
192: for (int k = 0; k < frame.size(); k++) {
193: FlashObject fo = frame.getFlashObjectAt(k);
194: if (fo instanceof Instance) {
195: Instance myInst = (Instance) fo;
196: int layer = myInst.depth;
197: FlashDef def = myInst.def;
198: if (def != null) {
199: defs.setElementAt(def, layer);
200: }
201: instances.setElementAt(myInst, layer);
202: } else if (fo instanceof RemoveObject) {
203: RemoveObject ro = (RemoveObject) fo;
204: int layer = ro.depth;
205: defs.setElementAt(null, layer);
206: instances.setElementAt(null, layer);
207: }
208: }
209: }
210:
211: Point2D ptCmd = new Point2D.Double(-1024, -1024);
212: instance.matrix.transform(ptCmd, ptCmd);
213:
214: int myDepth = instance.depth; // depth of this command instance
215: for (int i = myDepth; --i >= 0;) {
216: Instance myInst = (Instance) instances.elementAt(i);
217: if (myInst == null)
218: continue;
219: FlashDef def = (FlashDef) defs.elementAt(i);
220: if (def == null || !(def instanceof Script))
221: continue; // ??? error
222: Rectangle2D bounds = def.getBounds();
223: if (bounds != null && myInst.matrix != null) {
224: bounds = GeomHelper.calcBounds(myInst.matrix,
225: bounds);
226: }
227: if (bounds == null)
228: continue;
229: if (bounds.contains(ptCmd)) {
230: inst = myInst;
231: break;
232: }
233: }
234: }
235: } else {
236: inst = instance;
237: }
238:
239: if (inst == null) {
240: throw new IVException(Resource.CMDINSTNOTFOUND,
241: new Object[] { getCommandName() });
242: } else {
243: inst.setCommand(this );
244: }
245:
246: return inst;
247: }
248:
249: public IVVector getParameterNames() {
250: return names;
251: }
252:
253: public void setParameter(String name, String value) {
254: for (int i = 0; i < names.size(); i++) {
255: String n = (String) names.elementAt(i);
256: if (n.equals(name)) {
257: values.setElementAt(value, i);
258: return;
259: }
260: }
261: addParameter(name, value);
262: }
263:
264: public void addParameter(String name, String value) {
265: names.addElement(name);
266: values.addElement(value);
267: }
268:
269: public String getParameter(String name) {
270: for (int i = 0; i < names.size(); i++) {
271: String n = (String) names.elementAt(i);
272: if (n.equals(name)) {
273: String value = (String) values.elementAt(i);
274: if (value == null || value.trim().length() == 0)
275: return null;
276: else
277: return value;
278: }
279: }
280: return null;
281: }
282:
283: public String getParameter(String name, String defaultValue) {
284: String res = getParameter(name);
285: if (res != null)
286: return res;
287: return defaultValue;
288: }
289:
290: public boolean getBoolParameter(String name) {
291: return Util.toBool(getParameter(name), false);
292: }
293:
294: public boolean getBoolParameter(String name, boolean def) {
295: return Util.toBool(getParameter(name), def);
296: }
297:
298: public String getParameter(Context context, String name, String def) {
299: return context.apply(getParameter(name, def));
300: }
301:
302: public String getParameter(Context context, String name) {
303: return context.apply(getParameter(name));
304: }
305:
306: public boolean getBoolParameter(Context context, String name,
307: boolean def) {
308: String v = context.apply(getParameter(name));
309: return Util.toBool(v, def);
310: }
311:
312: public AlphaColor getColorParameter(Context context, String name,
313: AlphaColor def) {
314: String v = context.apply(getParameter(name));
315: return Util.toColor(v, def);
316: }
317:
318: public int getIntParameter(Context context, String name, int def) {
319: String v = context.apply(getParameter(name));
320: return Util.toInt(v, def);
321: }
322:
323: public double getDoubleParameter(Context context, String name,
324: double def) {
325: String v = context.apply(getParameter(name));
326: return Util.toDouble(v, def);
327: }
328:
329: protected int findColumn(String columnName, String[][] data) {
330: for (int i = 0; i < data[0].length; i++) {
331: String name = data[0][i];
332: if (name.equalsIgnoreCase(columnName))
333: return i;
334: }
335: return -1;
336: }
337:
338: protected boolean isDefault(String s) {
339: return Util.isDefault(s);
340: }
341:
342: /**
343: * Creates rectangular shape with default fill&line styles.
344: *
345: * @param r rectangle to be used for the shape
346: * @return rectangular shape
347: */
348: protected Shape getMask(Rectangle2D r) {
349: Shape s = new Shape();
350: s.setFillStyle0(FillStyle.newSolid(AlphaColor.white));
351: s.setFillStyle1(0);
352: s.setLineStyle(new LineStyle(1, AlphaColor.white));
353: s.drawRectangle(r);
354: s.setBounds(r);
355: return s;
356: }
357:
358: /**
359: * Adds mask for specified instance to specified script
360: * <P>
361: * Shifts all layers of all instances beginning from specified one,
362: * then adds mask to specified frame and then searches when specified
363: * instance gets removed from the timeline and if found removes the mask
364: * in the same frame.
365: * <P>
366: * The mask inherits transformation of the specified instance.
367: *
368: * @param script script to insert the mask to
369: * @param frameNum frame number to put the mask in
370: * @param inst instance to be masked
371: * @param width width of the mask
372: * @param height height of the mask
373: */
374: protected void addMask(Script script, int frameNum, Instance inst,
375: int width, int height) {
376: addMask(script, frameNum, inst, GeomHelper.newRectangle(0, 0,
377: width, height));
378: }
379:
380: protected void addMask(Script script, int frameNum, Instance inst,
381: Rectangle2D maskRect) {
382: //System.out.println( "addMask: frame="+frameNum+", inst.depth="+inst.depth );
383: int maskLayer = inst.depth;
384: script.reserveLayers(maskLayer, 1);
385: int instLayer = maskLayer + 1;
386: //System.out.println( " after reserve: maskLayer="+maskLayer+", new inst.depth="+inst.depth );
387: Frame frame = script.getFrameAt(frameNum);
388: Instance maskInst = frame.addInstance(getMask(maskRect),
389: maskLayer,
390: (AffineTransform) (inst.matrix != null ? inst.matrix
391: .clone() : null), null);
392: maskInst.clip = instLayer;
393:
394: // searches when the instance gets removed and if found remove the mask at the same time
395: int cnt = script.getFrameCount();
396: main: for (int i = frameNum + 1; i < cnt; i++) {
397: Frame f = script.getFrameAt(i);
398: int fsz = f.size();
399: for (int j = 0; j < fsz; j++) {
400: FlashObject o = (FlashObject) f.getFlashObjectAt(j);
401: if (o instanceof Instance) {
402: Instance inst1 = (Instance) o;
403: if (inst1.depth == instLayer && inst1.isMove
404: && inst1.def != inst.def
405: && inst1.def != null) {
406: //System.out.println( " frame="+i+", found instance: inst1.depth="+inst1.depth+", inst1.def="+inst1.def );
407: f.addFlashObject(new RemoveObject(maskLayer));
408: break main;
409: }
410: } else if (o instanceof RemoveObject) {
411: RemoveObject ro = (RemoveObject) o;
412: if (ro.depth == instLayer) {
413: //System.out.println( " frame="+i+", found remove object: ro.depth="+ro.depth );
414: f.addFlashObject(new RemoveObject(maskLayer));
415: break main;
416: }
417: }
418: }
419: }
420: }
421:
422: protected Font getFont(FlashFile file, String fontName) {
423: FlashFile defFile = file.getDefaultSymbolFile();
424: if (defFile != null) {
425: return defFile.getFont(fontName);
426: }
427: return null;
428: }
429:
430: /**
431: * Creates simple text and calculates its bounds
432: * <P>
433: * Text should not contain newlines
434: *
435: * @param txt text
436: * @param font font
437: * @param height font height
438: * @param color text color
439: * @return created text
440: */
441: protected LazyText newSimpleText(String txt, Font font, int height,
442: AlphaColor color) {
443: LazyText text = new LazyText(true);
444:
445: TextStyleChangeRecord tsr = new TextStyleChangeRecord(font,
446: height, color);
447: tsr.setX(0);
448: tsr.setY(font.ascent);
449: text.addTextStyleChangeRecord(tsr);
450:
451: TextRecord tr = new TextRecord(txt.length());
452: int l = txt.length();
453: int x = 0;
454: for (int i = 0; i < l; i++) {
455: char ch = txt.charAt(i);
456: int idx = font.getIndex(ch);
457: if (idx == -1)
458: idx = 0;
459: int adv = font.getAdvanceValue(idx);
460: if (i < l - 1) {
461: char ch_next = txt.charAt(i + 1);
462: int kern = font.getKerning(ch, ch_next);
463: adv += kern;
464: }
465: tr.add(ch, idx, adv);
466: x += adv;
467: }
468:
469: text.setBounds(GeomHelper.newRectangle(0, 0, x, font.ascent
470: + font.descent));
471:
472: return text;
473: }
474:
475: protected Text newText(FlashFile file, String msg, Font font,
476: int size, AlphaColor color, Rectangle2D rect) {
477: Text text = Text.newText();
478: TextItem item = new TextItem(msg, font, size, color);
479: text.addTextItem(item);
480: text.setBounds(rect);
481: return text;
482: }
483:
484: protected Text newText(FlashFile file, String msg, Font font,
485: int size, AlphaColor color, int width, int height) {
486: return newText(file, msg, font, size, color, GeomHelper
487: .newRectangle(0, 0, width, height));
488: }
489:
490: protected Text newText(FlashFile file, String msg, String fontName,
491: int size, AlphaColor color, Rectangle2D rect) {
492: Font font = getFont(file, fontName);
493: if (font == null)
494: return null;
495: return newText(file, msg, font, size, color, rect);
496: }
497:
498: protected void processFlashDef(Instance inst, FlashFile file,
499: Context context) throws IVException {
500: if (inst.def != null) {
501: inst.def.process(file, context);
502: }
503: }
504:
505: protected Context makeContext(Context context, String[][] data,
506: int row) throws IVException {
507: return ContextFactory.createContext(context, data, row);
508: }
509:
510: public void setDepth(int depth) {
511: this .depth = depth;
512: }
513:
514: public void setFlags(int flags) {
515: this .flags = flags;
516: }
517:
518: public void setFrameNum(int frameNum) {
519: this .frameNum = frameNum;
520: }
521:
522: public int getDepth() {
523: return depth;
524: }
525:
526: public int getFlags() {
527: return flags;
528: }
529:
530: public int getFrameNum() {
531: return frameNum;
532: }
533:
534: /**
535: * Sets command type
536: * <P>
537: * One of the following:
538: * <UL>
539: * <LI>TYPE_MOVIE
540: * <LI>TYPE_BUTTON
541: * <LI>TYPE_GRAPHICS
542: * <LI>TYPE_GLOBAL
543: * </UL>
544: *
545: * @param type command type
546: */
547: public void setType(int type) {
548: this .type = type;
549: }
550:
551: /**
552: * Returns command type
553: * <P>
554: * One of the following:
555: * <UL>
556: * <LI>TYPE_MOVIE
557: * <LI>TYPE_BUTTON
558: * <LI>TYPE_GRAPHICS
559: * <LI>TYPE_GLOBAL
560: * </UL>
561: *
562: * @return command type
563: */
564: public int getType() {
565: return type;
566: }
567:
568: public void printContent(PrintStream out, String indent) {
569: out.println(indent + "Generator Command: "
570: + getClass().getName());
571: out.println(indent + " Parameters: ");
572: for (int i = 0; i < values.size(); i++) {
573: String name = (String) names.elementAt(i);
574: String value = (String) values.elementAt(i);
575: out.println(indent + " " + name + "='" + value + "'");
576: }
577: }
578:
579: public void write(FlashOutput fob) {
580: int tagpos = fob.getPos();
581: fob.skip(6); // skip tag
582:
583: fob.writeByte(type);
584: fob.writeByte(0);
585: fob.writeWord(depth);
586:
587: if ((type & TYPE_GRAPHICS) != 0) {
588: fob.writeWord(flags);
589: fob.writeWord(frameNum);
590: }
591:
592: StringBuffer sb = new StringBuffer(100);
593: sb.append(getClass().getName());
594:
595: // add parameters
596: for (int i = 0; i < names.size(); i++) {
597: String n = (String) names.elementAt(i);
598: String v = (String) values.elementAt(i);
599: sb.append(' ');
600: sb.append(n);
601: sb.append("=\"");
602: if (v != null) {
603: for (int j = 0; j < v.length(); j++) {
604: char ch = v.charAt(j);
605: switch (ch) {
606: case '\n':
607: sb.append("/n/r");
608: break;
609: case '"':
610: sb.append("\\\"");
611: break;
612: default:
613: sb.append(ch);
614: break;
615: }
616: }
617: }
618: sb.append('"');
619: }
620:
621: fob.writeStringZ(sb.toString());
622:
623: fob.writeLongTagAt(getTag(), fob.getPos() - tagpos - 6, tagpos);
624: }
625:
626: public static GenericCommand parse(Parser p) {
627: // 0x01 - movie
628: // 0x02 - button
629: // 0x04 - graphics
630: // 0x08 - global
631: int type = p.getUByte();
632:
633: p.getUByte(); // skip 1 byte
634:
635: int depth = p.getUWord();
636: int flags = 0;
637: int frameNum = 0;
638: if ((type & TYPE_GRAPHICS) != 0) { // graphics
639: // 0x0010 - loop
640: // 0x0020 - play once
641: // 0x0040 - single frame
642: flags = p.getUWord();
643: frameNum = p.getUWord();
644: }
645:
646: String command = p.getString();
647: int clen = command.length();
648: int idx = command.indexOf(' ');
649: String className;
650: if (idx == -1) {
651: className = command;
652: idx = clen;
653: } else {
654: className = command.substring(0, idx);
655: }
656:
657: if (className.startsWith(MACROMEDIACLASS)) {
658: className = "org.openlaszlo.iv.flash.commands."
659: + className.substring(MACROMEDIACLASS.length());
660: }
661: Class cmdClazz = CommandCache.getCommandClass(className);
662: if (cmdClazz == null) {
663: Log.logRB(Resource.CMDNOTFOUND, new Object[] { className });
664: return null;
665: }
666: GenericCommand cmd = null;
667: try {
668: cmd = (GenericCommand) cmdClazz.newInstance();
669: } catch (Exception e) {
670: Log.logRB(Resource.CMDNOTCREATED,
671: new Object[] { className }, e);
672: return null;
673: }
674:
675: cmd.setType(type);
676: cmd.setDepth(depth);
677: cmd.setFlags(flags);
678: cmd.setFrameNum(frameNum);
679:
680: /* parse parameters, idx = index of blank
681: *
682: * format:
683: * commandname name1="value1" name2="value/n/rvalue/n/rvalue\"value\"" name3="value3"
684: */
685: StringBuffer sb = new StringBuffer();
686: for (; idx + 1 < clen;) {
687: int startName = idx + 1;
688: int endName = command.indexOf('=', startName);
689: String name = command.substring(startName, endName);
690: idx = endName + 1;
691: sb.setLength(0);
692: boolean quotes = false;
693: ValueLoop: while (idx < clen) {
694: char ch = command.charAt(idx);
695: switch (ch) {
696: case '\\':
697: sb.append(command.charAt(idx + 1));
698: idx += 2;
699: break;
700: case '/':
701: if (clen - idx >= 4
702: && command.charAt(idx + 2) == '/'
703: && ((command.charAt(idx + 1) == 'n' && command
704: .charAt(idx + 3) == 'r') || (command
705: .charAt(idx + 1) == 'r' && command
706: .charAt(idx + 3) == 'n'))) {
707: sb.append('\n');
708: idx += 4;
709: } else {
710: sb.append(ch);
711: idx++;
712: }
713: break;
714: case '"':
715: quotes = !quotes;
716: idx++;
717: break;
718: case ' ':
719: if (!quotes)
720: break ValueLoop;
721: default:
722: sb.append(ch);
723: idx++;
724: break;
725: }
726: }
727: String value = new String(sb);
728: cmd.addParameter(name, value);
729: }
730:
731: return cmd;
732: }
733:
734: /**
735: * Check the ClipActions to retrieve variable of Commands<br>
736: * if JGeneratorCommand variable exists in the clipEvent action
737: *
738: * @param actions ClipActions the ClipActions of the instance to test
739: * @return java.util.Hashtable the variables
740: */
741: public static GenericCommand checkAndParseMX(Instance instance) {
742: if (instance.actions == null)
743: return null;
744:
745: IVVector acts = instance.actions.getActions();
746:
747: GenericCommand cmd = null;
748:
749: // collect variables
750: for (int i = 0; i < acts.size(); i++) {
751: ClipAction action = (ClipAction) acts.elementAt(i);
752:
753: if (action.getFlags() == ClipAction.MXCOMPONENT) {
754:
755: Program prog = action.getProgram();
756:
757: FlashBuffer body = prog.body();
758: body.setPos(0);
759: boolean firstAction = true;
760: String[] strings = null;
761:
762: String name = null;
763: String value = null;
764:
765: // loop to retrieve all the variables
766: mainLoop: for (;;) {
767: int offset = body.getPos();
768: int code = body.getUByte();
769: boolean hasLength = (code & 0x80) != 0;
770: int length = hasLength ? body.getUWord() : 0;
771: int nextPos = body.getPos() + length;
772:
773: switch (code) {
774: case Actions.None:
775: body.setPos(nextPos);
776: break mainLoop;
777: case Actions.PushData: {
778: for (int l = length; l > 0;) {
779: int type = body.getUByte();
780: l--;
781: switch (type) {
782: case 0:
783: String ss = body.getString();
784: if (name == null)
785: name = ss;
786: else
787: value = ss;
788: l -= ss.length() + 1;
789: break;
790: case 1:
791: value = new Float(Float
792: .intBitsToFloat(body
793: .getUDWord()))
794: .toString();
795: l -= 4;
796: break;
797: case 2:
798: case 3:
799: break;
800: case 4:
801: l--;
802: break;
803: case 5:
804: value = new Boolean(
805: body.getUByte() != 0)
806: .toString();
807: l--;
808: break;
809: case 6:
810: long dbits = (((long) body.getUDWord()) << 32)
811: | (((long) body.getUDWord()) & 0xffffffffL);
812: value = new Double(Double
813: .longBitsToDouble(dbits))
814: .toString();
815: l -= 8;
816: break;
817: case 7:
818: value = new Integer(body.getUDWord())
819: .toString();
820: l -= 4;
821: break;
822: case 8:
823: int index = body.getUByte();
824: if (strings != null
825: && index < strings.length) {
826: if (name == null)
827: name = strings[index];
828: else
829: value = strings[index];
830: }
831: l--;
832: break;
833: }
834: }
835: // if this is first action it has to be: push "JGeneratorCommand", otherwise
836: // this is not our component
837: if (firstAction
838: && !MXCOMPONENT_CMDNAME.equals(name))
839: break mainLoop;
840: break;
841: }
842: case Actions.ConstantPool: {
843: int num = body.getUWord();
844: strings = new String[num];
845: for (int j = 0; j < num; j++) {
846: strings[j] = body.getString();
847: }
848: // if this is first action it has to have "JGeneratorCommand" in first element,
849: // otherwise this is not our component
850: if (firstAction
851: && !MXCOMPONENT_CMDNAME
852: .equals(strings[0]))
853: break mainLoop;
854: break;
855: }
856: case Actions.SetVariable:
857: if (MXCOMPONENT_CMDNAME.equals(name)) {
858: // create jgenerator command from its name
859: String className = "org.openlaszlo.iv.flash.commands."
860: + value + "Command";
861:
862: Class cmdClazz = CommandCache
863: .getCommandClass(className);
864: if (cmdClazz == null) {
865: Log.logRB(Resource.CMDNOTFOUND,
866: new Object[] { className });
867: return null;
868: }
869:
870: // instanciate it
871: try {
872: cmd = (GenericCommand) cmdClazz
873: .newInstance();
874: } catch (Exception e) {
875: Log.logRB(Resource.CMDNOTCREATED,
876: new Object[] { className }, e);
877: return null;
878: }
879:
880: cmd.setDepth(instance.depth);
881: cmd.setType(cmd.isGlobal() ? TYPE_GLOBAL
882: : TYPE_MOVIE);
883: // indicate we created it from a MX component
884: cmd.setIsComponent(true);
885:
886: // Embed it inside a MovieClip
887: Script script = new Script(1);
888: instance.def = script;
889: // we must translate the instance matrix because it is 2048x2048 centered
890: instance.matrix.translate(1024, 1024);
891:
892: // set the command
893: instance.setCommand(cmd);
894: cmd.setInstance(instance);
895:
896: } else {
897: if (cmd != null)
898: cmd.setParameter(name, value);
899: else
900: break mainLoop;
901: }
902: name = null;
903: break;
904: default:
905: // all other actions mean this is not our component
906: break mainLoop;
907: }
908: firstAction = false;
909: }
910: }
911:
912: if (cmd != null) {
913: // this actions represented jgenerator mx component, remove it from list of clipactions
914: acts.removeElementAt(i);
915: instance.actions.setMask(instance.actions.getMask()
916: & ~ClipAction.MXCOMPONENT);
917: break; // no need for further processing
918: }
919: }
920:
921: if (acts.size() == 0)
922: instance.actions = null;
923:
924: return cmd;
925: }
926:
927: public int getTag() {
928: return Tag.TEMPLATECOMMAND;
929: }
930:
931: protected FlashItem copyInto(FlashItem item, ScriptCopier copier) {
932: super .copyInto(item, copier);
933: ((GenericCommand) item).type = type;
934: ((GenericCommand) item).depth = depth;
935: ((GenericCommand) item).flags = flags;
936: ((GenericCommand) item).frameNum = frameNum;
937: ((GenericCommand) item).instance = instance;
938: ((GenericCommand) item).isComponent = isComponent;
939: ((GenericCommand) item).names = new IVVector(names);
940: ((GenericCommand) item).values = new IVVector(values);
941: return item;
942: }
943:
944: public FlashItem getCopy(ScriptCopier copier) {
945: try {
946: Constructor c = getClass().getConstructor(new Class[] {});
947: GenericCommand o = (GenericCommand) c
948: .newInstance(new Object[] {});
949: return copyInto(o, copier);
950: } catch (Exception e) {
951: Log.log(e);
952: return null;
953: }
954:
955: }
956:
957: }
|