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 }