001 package nl.cwi.sen1.gui.plugin;
002
003 import java.awt.Dimension;
004 import java.awt.event.MouseEvent;
005 import java.util.HashMap;
006 import java.util.Map;
007
008 import javax.swing.JComponent;
009 import javax.swing.JLabel;
010
011 import nl.cwi.sen1.configapi.types.ActionDescriptionList;
012 import nl.cwi.sen1.configapi.types.Event;
013 import nl.cwi.sen1.graph.Factory;
014 import nl.cwi.sen1.graph.types.Graph;
015 import nl.cwi.sen1.gui.CloseAbortedException;
016 import nl.cwi.sen1.gui.Studio;
017 import nl.cwi.sen1.gui.StudioImplWithPredefinedLayout;
018 import nl.cwi.sen1.gui.StudioWithPredefinedLayout;
019 import nl.cwi.sen1.gui.component.StudioComponent;
020 import nl.cwi.sen1.gui.component.StudioComponentImpl;
021 import nl.cwi.sen1.gui.plugin.data.Module;
022 import nl.cwi.sen1.gui.plugin.data.ModuleSelectionListener;
023 import nl.cwi.sen1.gui.plugin.data.ModuleTreeModel;
024 import nl.cwi.sen1.ioapi.types.File;
025 import nl.cwi.sen1.util.DefaultPopupImpl;
026 import nl.cwi.sen1.util.MouseAdapter;
027 import aterm.ATerm;
028 import aterm.ATermFactory;
029 import aterm.pure.PureFactory;
030
031 public class Navigator extends DefaultStudioPlugin implements NavigatorTif {
032 private static final String TOOL_NAME = "navigator";
033
034 private NavigatorBridge bridge;
035
036 private ModuleTreeModel moduleModel;
037
038 private Studio studio;
039
040 private Map<String, JComponent> statusBarComponents;
041
042 private JLabel status;
043
044 private Factory graphFactory;
045
046 private nl.cwi.sen1.ioapi.Factory ioFactory;
047
048 private boolean suspendSelectionNotification;
049
050 private StudioComponent navigatorComponent;
051
052 private nl.cwi.sen1.configapi.Factory configFactory;
053
054 private ModuleTree tree;
055
056 public Navigator() {
057 statusBarComponents = new HashMap<String, JComponent>();
058 status = new JLabel(" ");
059 status.setPreferredSize(new Dimension(100, 18));
060
061 statusBarComponents.put("Status", status);
062 createModel();
063 }
064
065 public void deleteModule(ATerm moduleId) {
066 tree.saveExpansionState();
067 moduleModel.removeModule(moduleId);
068 tree.loadExpansionState();
069 }
070
071 public void updateModule(ATerm moduleId, ATerm path) {
072 Module module = moduleModel.getModule(moduleId);
073
074 File file = ioFactory.FileFromTerm(path);
075 String label = file.getName();
076
077 if (tree != null) {
078 tree.saveExpansionState();
079 if (module != null) {
080 moduleModel.removeModule(moduleId);
081 }
082 module = new Module(moduleId, file, label);
083 moduleModel.addModule(module);
084 tree.loadExpansionState();
085 }
086 }
087
088 public void setModules(ATerm graphTerm) {
089 Graph graph = graphFactory.GraphFromTerm(graphTerm);
090
091 setModules(graph);
092 }
093
094 public void postPopupRequest(MouseEvent e, Module module) {
095 ATermFactory factory = studio.getATermFactory();
096 ATerm moduleId = module.getId();
097 bridge.postEvent(factory.make("request-popup-event(<term>)", moduleId));
098 }
099
100 public void showPopup(final ATerm id, final ATerm menu) {
101 nl.cwi.sen1.configapi.Factory f = nl.cwi.sen1.configapi.Factory
102 .getInstance((PureFactory) id.getFactory());
103 ActionDescriptionList list = f.ActionDescriptionListFromTerm(menu);
104 DefaultPopupImpl popup = new DefaultPopupImpl(bridge);
105 popup.showPopup(id, list);
106 }
107
108 public void recAckEvent(ATerm t0) {
109 }
110
111 public void recTerminate(ATerm t0) {
112 fireStudioPluginClosed();
113 }
114
115 public String getName() {
116 return TOOL_NAME;
117 }
118
119 private ATerm createEventId(ATerm moduleId) {
120 return studio.getATermFactory().make(TOOL_NAME + "(<term>)", moduleId);
121 }
122
123 public void initStudioPlugin(Studio studio) {
124 this.studio = studio;
125 graphFactory = Factory.getInstance((PureFactory) studio
126 .getATermFactory());
127 configFactory = nl.cwi.sen1.configapi.Factory
128 .getInstance((PureFactory) studio.getATermFactory());
129 ioFactory = nl.cwi.sen1.ioapi.Factory.getInstance((PureFactory) studio
130 .getATermFactory());
131 bridge = new NavigatorBridge(studio.getATermFactory(), this);
132 bridge.setLockObject(this);
133 studio.connect(getName(), bridge);
134
135 addNavigatorComponent();
136 }
137
138 private void createModel() {
139 moduleModel = new ModuleTreeModel();
140 moduleModel.addModuleSelectionListener(new ModuleSelectionListener() {
141 public void moduleSelected(Module module) {
142 if (!suspendSelectionNotification) {
143 if (module != null) {
144 status.setText(module.toString());
145 bridge.postEvent(studio.getATermFactory().make(
146 "module-selected(<term>)", module.getId()));
147 }
148 }
149 }
150 });
151 }
152
153 private void addNavigatorComponent() {
154 tree = new ModuleTree(this, moduleModel);
155 final ATerm id = configFactory.getPureFactory().parse(TOOL_NAME);
156 final Event popupAction = configFactory.makeEvent_Popup();
157
158 tree.addMouseListener(new MouseAdapter(id, bridge, popupAction) {
159 public void mousePressed(MouseEvent e) {
160 ATerm moduleId = tree.selectModule(e.getX(), e.getY());
161 if (moduleId != null) {
162 setId(createEventId(moduleId));
163 super.mousePressed(e);
164 }
165 }
166 });
167
168 navigatorComponent = new StudioComponentImpl("Modules", tree) {
169 public void requestClose() throws CloseAbortedException {
170 throw new CloseAbortedException();
171 }
172
173 public JComponent[] getStatusBarComponents() {
174 return new JComponent[] { status };
175 }
176 };
177 ((StudioWithPredefinedLayout) studio).addComponent(navigatorComponent,
178 StudioImplWithPredefinedLayout.TOP_LEFT);
179 // studio.addComponentMenu(navigatorComponent, new JMenu("Navigate"));
180 }
181
182 public void selectModule(ATerm moduleId) {
183 suspendSelectionNotification = true;
184 moduleModel.selectModule(moduleId);
185 suspendSelectionNotification = false;
186 }
187
188 public void markModuleError(ATerm moduleId) {
189 tree.saveExpansionState();
190 moduleModel.markError(moduleId);
191 tree.loadExpansionState();
192 }
193
194 public void markModuleNormal(ATerm moduleId) {
195 tree.saveExpansionState();
196 moduleModel.markNormal(moduleId);
197 tree.loadExpansionState();
198 }
199 }