001: package abbot.editor.recorder;
002:
003: import java.awt.*;
004: import java.awt.event.WindowEvent;
005: import java.util.Iterator;
006: import java.util.Map;
007: import java.util.HashMap;
008:
009: import abbot.script.*;
010:
011: /**
012: * Recorder for the java.awt.FileDialog. Since this is a native component and
013: * no java events are generated other than window open/close, the only things
014: * to take note of are the following:<br>
015: * <ul>
016: * <li>Changes to the directory
017: * <li>Changes to the file
018: * <li>Whether the user hits OK or Cancel
019: * </ul>
020: * @author Vrata Venet, European Space Agency, Madrid-Spain (av@iso.vilspa.esa.es)
021: */
022: public class FileDialogRecorder extends DialogRecorder {
023:
024: private FileDialog dialog;
025: // must make a ref immediately, since once the dialog is dismissed it
026: // is no longer considered in the hierarchy and prevents us making a ref
027: private ComponentReference ref;
028: private Map newRefs = new HashMap();
029: private String originalFile;
030: private String originalDir;
031:
032: /** Create a FileDialogRecorder for use in capturing the semantics of a GUI
033: * action.
034: */
035: public FileDialogRecorder(Resolver resolver) {
036: super (resolver);
037: }
038:
039: protected void init(int type) {
040: super .init(type);
041: dialog = null;
042: ref = null;
043: newRefs.clear();
044: originalFile = null;
045: originalDir = null;
046: }
047:
048: /** Override the default window parsing to consume everything between
049: dialog open and close.
050: */
051: protected boolean parseWindowEvent(AWTEvent event) {
052: boolean consumed = true;
053: if (event.getSource() instanceof FileDialog) {
054: if (isOpen(event)) {
055: dialog = (FileDialog) event.getSource();
056: ref = ComponentReference.getReference(getResolver(),
057: dialog, newRefs);
058: originalFile = dialog.getFile();
059: originalDir = dialog.getDirectory();
060: }
061: // The FileDialogTester uses some event listener hacks to set the
062: // correct state on dialog close; make sure we record after that
063: // listener is finished.
064: if (event instanceof FileDialogTerminator)
065: setFinished(true);
066: else if (event.getSource() == dialog && isClose(event)) {
067: AWTEvent terminator = new FileDialogTerminator(dialog,
068: event.getID());
069: dialog.getToolkit().getSystemEventQueue().postEvent(
070: terminator);
071: }
072: }
073: return consumed;
074: }
075:
076: /** Create one or more steps corresponding to what was done to the file
077: dialog. If the directory is non-null, the directory was changed. If
078: the file is non-null, the file was accepted.
079: */
080: protected Step createFileDialogEvents(FileDialog d, String oldDir,
081: String oldFile) {
082: String file = d.getFile();
083: boolean accepted = file != null;
084: boolean fileChanged = accepted && !file.equals(oldFile);
085: String dir = d.getDirectory();
086: boolean dirChanged = dir != oldDir
087: && (dir == null || !dir.equals(oldDir));
088:
089: String desc = d.getMode() == FileDialog.SAVE ? "Save File"
090: : "Load File";
091: if (accepted)
092: desc += " (" + file + ")";
093: else
094: desc += " (canceled)";
095:
096: getResolver().addComponentReference(ref);
097: for (Iterator i = newRefs.values().iterator(); i.hasNext();) {
098: getResolver().addComponentReference(
099: (ComponentReference) i.next());
100: }
101: Sequence seq = new Sequence(getResolver(), desc);
102: if (dirChanged) {
103: seq.addStep(new Action(getResolver(), null,
104: "actionSetDirectory", new String[] { ref.getID(),
105: dir }, FileDialog.class));
106: }
107: if (accepted) {
108: Step accept = new Action(getResolver(), null,
109: "actionAccept", new String[] { ref.getID() },
110: FileDialog.class);
111: if (fileChanged) {
112: seq.addStep(new Action(getResolver(), null,
113: "actionSetFile", new String[] { ref.getID(),
114: file }, FileDialog.class));
115: seq.addStep(accept);
116: } else {
117: return accept;
118: }
119: } else {
120: Step cancel = new Action(getResolver(), null,
121: "actionCancel", new String[] { ref.getID() },
122: FileDialog.class);
123: if (dirChanged)
124: seq.addStep(cancel);
125: else
126: return cancel;
127: }
128: return seq;
129: }
130:
131: protected Step createStep() {
132: if (getRecordingType() == SE_WINDOW) {
133: return createFileDialogEvents(dialog, originalDir,
134: originalFile);
135: }
136: return super .createStep();
137: }
138:
139: private class FileDialogTerminator extends WindowEvent {
140: public FileDialogTerminator(FileDialog fd, int id) {
141: super(fd, id);
142: }
143: }
144: }
|