// Copyright (c)2005 Holobloc Inc.
// Contributed to the OOONEIDA FBench project under the Common Public License.
// Copyright (c) 2007 University of Auckland
// Contributed to the FBench extension of the OOONEIDA Workbench project under the Common Public License
package fbench;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Hashtable;
import java.util.Properties;
import java.util.StringTokenizer;
import java.util.Vector;
import javax.swing.AbstractAction;
import javax.swing.AbstractButton;
import javax.swing.Action;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.JToolBar;
import javax.swing.JTree;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.WindowConstants;
import javax.swing.event.MenuEvent;
import javax.swing.event.MenuListener;
import javax.swing.tree.TreeSelectionModel;
import fbench.dom.DOMTranslationModel;
import fbench.dom.DocumentSource;
import fbench.graph.GraphViewTransfer;
import fbench.plugin.PluginManager;
import fbench.translate.JavaToJava;
import fbench.translate.JavaToSRC;
import fbench.translate.STtoJava;
import fbench.translate.STtoSRC;
import fbench.translate.TranslatorSource;
import fbench.tree.LibraryTreeNode;
import fbench.ui.TabPanel;
import org.w3c.dom.Document;
import fb.rt.FBInstance;
// import fb.rt.tools.SystemLogger;
// import fb.rt.tools.SystemManager;
// import fb.tools.FBELibrarySpec;
// import fb.tools.FileLibrary;
// import fb.tools.swing.editor.FBJPreferences;
/**
* A desktop for multiple Editors.
*
* @author WD,AS,JHC,JP
*
* @version 20070422/JP - Separated plug-in features from the kernel parts
* @version 20061127/WD - Remove Left Tree,Add open function to the menu
* @version 20060914/WD - Added System Configurations Debugging
* @version 20051129/JHC - Eliminated use of DTDs; ElementTableModel now sets up own attribute names.
* @version 20051128/JHC - Set up main pane as JSplitPane with library view as left element.
* @version 20050810/JHC - First OOONEIDA version.
* @version 20050803/JHC - Changed desktop to JTabbedPane.
* @version 20050709/JHC
*/
public class FBench extends JFrame implements DocumentSource, ActionListener, MenuListener {
private static final long serialVersionUID = -2684239640734884416L;
public static final String productID = "IEC 61499 FBench";
public static final String version = "v1.0 Build 20070820";
public static Hashtable<String, Process> processes = new Hashtable<String, Process>();
public static FBench theBench = null;
private static String rtPathRoot = "";
public static String getRTPathRoot() {
return rtPathRoot;
}
private Hashtable<String, Object> instances = new Hashtable<String, Object>();
/** The TransferHandler for dragging components into GraphViews. */
private GraphViewTransfer gvhandler;
private Properties preferences = new Properties();
// private Properties debugPreferences = new Properties();
private JTabbedPane desktop = new JTabbedPane();
// private CloseTabbedPane desktop = new CloseTabbedPane();
private JToolBar toolBar = new JToolBar(1);
/** For View Menu */
private JFrame viewFrame = new JFrame("FBench Library");
private JPopupMenu refresh_view = new JPopupMenu();
private JMenuItem refresh_viewwini =
createMenuItem("Refresh", "reloadLibraryTree", "Refresh16", "Refresh", 'R', null);
private JMenuBar mb = new JMenuBar();
private JMenu fileMenu = new JMenu("File");
private JMenu fileNewMenu = new JMenu("New");
private JMenu fileNewFBMenu = new JMenu("FB Type");
private JMenu fileNewDataMenu = new JMenu("Data Type");
private JMenuItem newBFB =
createMenuItem("Basic FB", "fbench.FBench.newBFB", "New16", "Create a basic function block", 'B',
null);
private JMenuItem newCFB =
createMenuItem("Composite FB", "fbench.FBench.newCFB", "New16", "Create a composite block", 'C',
null);
private JMenuItem newProxy =
createMenuItem("Proxy FB", "fbench.FBench.newProxy", "New16", "Create a proxy", 'P', null);
private JMenuItem newSI =
createMenuItem("Service Interface FB", "fbench.FBench.newSI", "New16",
"Create a service interface function block", 'S', null);
private JMenuItem newSimple =
createMenuItem("Simple FB", "fbench.FBench.newSimple", "New16", "Create a simple function block",
'I', null);
private JMenuItem newAdapt =
createMenuItem("Adapter Type", "fbench.FBench.newAdapt", "New16", "Create an adapter", 'A', null);
private JMenuItem newRes =
createMenuItem("Resource Type", "fbench.FBench.newRes", "New16", "Create a resource", 'N', null);
private JMenuItem newDev =
createMenuItem("Device Type", "fbench.FBench.newDev", "New16", "Create a device", 'D', null);
private JMenuItem newSys =
createMenuItem("System", "fbench.FBench.newSys", "New16", "Create a system configuration", 'Y',
null);
private JMenuItem fileOpen =
createMenuItem("Open...", "fbench.FBench.FileOpen", "Open16", "Open an existing file", 'O',
InputEvent.CTRL_MASK);
private JMenu fileSaveAsMenu = new JMenu("Save As");
private JMenuItem fileSaveAsXMLItem =
createMenuItem("XML...", "fbench.FBench.fileSaveAsXML", "xmlObject",
"Save current document as XML file", 'S', InputEvent.CTRL_MASK);
// private JMenuItem ProjectEnv =
// createMenuItem("New16", "Project Environment",
// "fbench.FBench.projectenv");
private JMenuItem fileExitItem =
createMenuItem("Exit", "fbench.FBench.fileExit", "Close", "Exit FBench", null);
private JMenu editMenu = new JMenu("Edit");
private JMenuItem editUndoItem =
createMenuItem("Undo", "fbench.FBench.editAction", "Undo16", "Undo last action", 'Z',
InputEvent.CTRL_MASK);
private JMenuItem editRedoItem =
createMenuItem("Redo", "fbench.FBench.editAction", "Redo16", "Redo last action", 'Y',
InputEvent.CTRL_MASK);
private JMenuItem editCutItem =
createMenuItem("Cut", "fbench.FBench.editAction", "Cut16", "Move selected text to clipboard",
null);
private JMenuItem editCopyItem =
createMenuItem("Copy", "fbench.FBench.editAction", "Copy16", "Copy text to clipboard", null, null);
private JMenuItem editPasteItem =
createMenuItem("Paste", "fbench.FBench.editAction", "Paste16",
"Replace selected text with clipboard contents", null);
private JMenuItem editDeleteItem =
createMenuItem("Delete", "fbench.FBench.editAction", "Delete16",
"Permanently delete selected text", null);
private JMenuItem editFindReplaceItem =
createMenuItem("Find/Replace...", "fbench.FBench.editAction", "Find16",
"Open Find/Replace Dialog", null);
private JMenuItem editSelectAllItem =
createMenuItem("Select All", "fbench.FBench.editAction", null, "Select all text", 'A',
InputEvent.CTRL_MASK);
private JMenu viewMenu = new JMenu("View");
private JCheckBoxMenuItem treeViewMenu =
new JCheckBoxMenuItem("Display Library Tree Window", IconFactory.getIcon("Open16"));
private JMenu compileMenu = new JMenu("Compile");
private JMenuItem compiletoJava =
createMenuItem("Compile to Java", "fbench.FBench.fileSaveAsJava", "compile16", "Compile to Java",
KeyStroke.getKeyStroke(KeyEvent.VK_F5, 0));
private JMenuItem compiletoJavaDebug =
createMenuItem("Compile to Java with Debug", "fbench.FBench.fileSaveAsJavaDebug", "compile16",
"Compile to Java with remote debugging(FBRT)", KeyStroke
.getKeyStroke(KeyEvent.VK_F6, 0));
private JMenu runMenu = new JMenu("Run");
private JMenu runLaunchMenu = new JMenu("Launch");
private JMenuItem runLaunchItem =
createMenuItem("Launch", "fbench.FBench.runLaunch", "fb",
"Launches a system configuration or an instance of an FB type.", KeyStroke
.getKeyStroke(KeyEvent.VK_F7, 0));
private JMenu helpMenu = new JMenu("Help");
private JMenuItem helpItem =
createMenuItem("User Manual", "fbench.FBench.help", "Help16", "FBench Help", KeyStroke
.getKeyStroke(KeyEvent.VK_F1, 0));
private JMenuItem helpHowToItem =
createMenuItem("Developer's Guide", "fbench.FBench.help", "Help16", "FBench tutorial", null);
private JMenuItem helpAboutItem =
createMenuItem("About FBench", "fbench.FBench.help", "Help16", "Contact Information", null);
// gsha041: Speed fix for JFileChooser... (known problem / issue @ sun)
// it takes AAAAAAAAAGES to create this... so init 1ce use many times :D
// using java.awt.FileChooser...
private final JFileChooser select_item = new JFileChooser("src");
// gsha041: Hashtable of Avaliable ElementModels...(string "name", string
// className)
/** Avaliable GraphModel Classes for Visualisation */
private static Hashtable<String, String> graphModels = new Hashtable<String, String>(32);
/** Avaliable GraphElement Classes for Visualisation */
private static Hashtable<String, String> graphElements = new Hashtable<String, String>(32);
/** Avaliable mutationListener Classes for 'listening' */
private static Hashtable<String, String> mutationListeners = new Hashtable<String, String>(32);
/** Avaliable treeNode Classes for Visualisation in DOMTree */
private static Hashtable<String, String> treeNodes = new Hashtable<String, String>(32);
/**
* Avaliable treeMenu Classes for ContextMenus in DOMTree String = Element Type String[] = Strings of
* Context Menu Options
*/
private static Hashtable<String, String[]> treeMenus = new Hashtable<String, String[]>(32);
/**
* Avaliable (tree)MenuAction Dialogs / Classes String = Element Type String = Class name of Action /
* Dialog
*/
private static Hashtable<String, String> treeMenuActions = new Hashtable<String, String>(32);
private PluginManager plugin;
private JPanel statusJPanel = new JPanel();
private JLabel statusJLabel = new JLabel("Ready");;
public void setStatusText(String message) {
this.statusJLabel.setText(message);
}
public FBench() {
super();
theBench = this;
Library.setDocumentSource(this);
setupPreferences();
setTitle(FBench.productID);
setIconImage(IconFactory.getIcon("fbench0.jpg").getImage());
setLayout(new BorderLayout());
desktop.setFont(new Font("SansSerif", Font.PLAIN, 10));
desktop.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
checkToolBar();
}
});
instances.put("fbench.FBench", this);
final FBench me = this;
setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent evt) {
me.windowClosing(evt);
}
});
menuBarInit();
toolBar.setBorder(BorderFactory.createEtchedBorder());
toolBar.setFloatable(true);
String[] newFunctions = {"Parse XML", "Save Now", "Close Tab", "Previous Tab", "Next Tab"};
String[] newPics =
{"fbench/images/Refresh16.gif", "fbench/images/SaveAs16.gif", "fbench/images/Close16.gif",
"fbench/images/arrow15l.gif", "fbench/images/arrow15r.gif"};
buildToolButton(toolBar, newFunctions, newPics);
getContentPane().add(toolBar, BorderLayout.WEST);
getContentPane().add(desktop, BorderLayout.CENTER);
statusJLabel.setFont(new Font("SansSerif", Font.PLAIN, 12));
statusJPanel.setLayout(new BorderLayout(10, 3));
statusJPanel.add(statusJLabel);
getContentPane().add(statusJPanel, BorderLayout.SOUTH);
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
int screenWidth = screenSize.width;
int screenHeight = screenSize.height;
setBounds(screenWidth / 8, screenHeight / 8, 3 * screenWidth / 4, 3 * screenHeight / 4);
Vector<String> helpArg = new Vector<String>();
helpArg.add(new String("About"));
if(help(helpArg) != JOptionPane.OK_OPTION)
System.exit(-1);
setVisible(true);
TranslatorSource.getInstance().addTranslator(STtoJava.class, "ST", "Java");
TranslatorSource.getInstance().addTranslator(STtoSRC.class, "ST", "SRC");
TranslatorSource.getInstance().addTranslator(JavaToJava.class, "Java", "Java");
TranslatorSource.getInstance().addTranslator(JavaToSRC.class, "Java", "SRC");
String openfiles = preferences.getProperty("openfiles");
if(openfiles != null) {
StringTokenizer toker = new StringTokenizer(openfiles, ",");
while(toker.hasMoreElements())
open(toker.nextToken());
}
}
/**
* Use reflection to refresh the items under plug-in menus
*
* @param evt MenuEvent
*/
public void menuSelected(MenuEvent evt) {
Object src = evt.getSource();
if(src == editMenu)
editMenuSelected();
else if(src == runMenu)
runMenuSelected();
else if(src == compileMenu)
CompileSelected();
else {
String actionCommand = ((JMenu) evt.getSource()).getActionCommand();
String callerName = actionCommand.substring(0, actionCommand.lastIndexOf("."));
String methodName = actionCommand.substring(actionCommand.lastIndexOf(".") + 1);
Vector<Object> args = new Vector<Object>();
args.add((JMenu) evt.getSource());
args.add(this);
try {
Class<?> caller = Class.forName(callerName);
Method method = caller.getMethod(methodName, Vector.class);
java.util.Hashtable<String, Object> instances = getInstances();
Object instance = instances.get(callerName);
if(instance == null) {
instance = caller.newInstance();
instances.put(callerName, instance);
}
method.invoke(instance, args);
}
catch(ClassNotFoundException e) {
e.printStackTrace();
}
catch(SecurityException e) {
e.printStackTrace();
}
catch(NoSuchMethodException e) {
e.printStackTrace();
}
catch(InstantiationException e) {
e.printStackTrace();
}
catch(IllegalAccessException e) {
e.printStackTrace();
}
catch(InvocationTargetException e) {
e.printStackTrace();
}
}
}
/**
* Use reflection to invoke the action associated with the selected menu item
*
* @param evt ActionEvent
*/
public void actionPerformed(ActionEvent evt) {
String cmd = ((AbstractButton) evt.getSource()).getText();
String actionCommand = evt.getActionCommand();
String callerName = actionCommand.substring(0, actionCommand.lastIndexOf("."));
String methodName = actionCommand.substring(actionCommand.lastIndexOf(".") + 1);
Class<?>[] parameterTypes = new Class[1];
parameterTypes[0] = Vector.class;
Vector<Object> args = new Vector<Object>();
args.add(cmd);
args.add(this);
String cmdtxt = methodName + "(\"" + cmd + "\")\n";
try {
Class<?> caller = Class.forName(callerName);
Method method = caller.getMethod(methodName, parameterTypes);
Object instance = instances.get(callerName);
if(instance == null) {
instance = caller.newInstance();
instances.put(callerName, instance);
}
method.invoke(instance, args);
}
catch(IllegalArgumentException e) {
e.printStackTrace();
System.err.println(cmdtxt + e);
}
catch(SecurityException e) {
e.printStackTrace();
System.err.println(cmdtxt + e);
}
catch(IllegalAccessException e) {
e.printStackTrace();
System.err.println(cmdtxt + e);
}
catch(InvocationTargetException e) {
e.printStackTrace();
System.err.println(cmdtxt + e);
System.err.println("Cause: " + e.getCause());
}
catch(NoSuchMethodException e) {
e.printStackTrace();
System.err.println(cmdtxt + e);
}
catch(Exception e) {
System.err.print(e);
}
}
/**
*
*/
private void menuBarInit() {
plugin = new PluginManager(this);
mb.add(fileMenu);
fileMenu.add(fileNewMenu);
fileNewMenu.add(fileNewFBMenu);
fileNewFBMenu.add(newBFB);
fileNewFBMenu.add(newCFB);
fileNewFBMenu.add(newProxy);
fileNewFBMenu.add(newSI);
fileNewFBMenu.add(newSimple);
fileNewMenu.add(fileNewDataMenu);
fileNewMenu.add(newAdapt);
fileNewMenu.add(newRes);
fileNewMenu.add(newDev);
fileNewMenu.add(newSys);
fileNewMenu.setIcon(IconFactory.getIcon("New16"));
fileMenu.add(fileOpen);
fileMenu.addSeparator();
fileMenu.add(fileSaveAsMenu);
fileSaveAsMenu.add(this.fileSaveAsXMLItem);
fileSaveAsMenu.setIcon(IconFactory.getIcon("SaveAs16"));
// fileMenu.addSeparator();
// fileMenu.add(ProjectEnv);
fileMenu.addSeparator();
fileMenu.add(fileExitItem);
mb.add(editMenu);
editMenu.addMenuListener(this);
editMenu.add(editUndoItem);
editMenu.add(editRedoItem);
editMenu.addSeparator();
editCutItem.setAccelerator(KeyStroke.getKeyStroke("control X"));
editMenu.add(editCutItem);
editCopyItem.setAccelerator(KeyStroke.getKeyStroke("control C"));
editMenu.add(editCopyItem);
editPasteItem.setAccelerator(KeyStroke.getKeyStroke("control V"));
editMenu.add(editPasteItem);
editDeleteItem.setAccelerator(KeyStroke.getKeyStroke("DELETE"));
editMenu.add(editDeleteItem);
editMenu.addSeparator();
editFindReplaceItem.setAccelerator(KeyStroke.getKeyStroke("control F"));
editMenu.add(editFindReplaceItem);
editMenu.addSeparator();
editMenu.add(editSelectAllItem);
mb.add(viewMenu);
viewMenu.add(treeViewMenu);
treeViewMenu.addActionListener(this);
treeViewMenu.setActionCommand("fbench.FBench.runViewMenu");
refresh_viewwini.setIcon(new ImageIcon("fbench/images/Refresh16.gif"));
refresh_view.add(refresh_viewwini);
mb.add(compileMenu);
compileMenu.add(compiletoJava);
compileMenu.add(compiletoJavaDebug);
compileMenu.addMenuListener(this);
mb.add(runMenu);
runLaunchMenu.setIcon(IconFactory.getIcon("Play16"));
runLaunchMenu.add(runLaunchItem);
runMenu.add(runLaunchMenu);
runMenu.addMenuListener(this);
// Resourced from:
// http://jug.org.ua/wiki/display/JavaAlmanac/Getting+the+Currently+Selected+Menu+or+Menu+Item
/*
* TODO: A JMenu can contain four kinds of items: JMenu, JMenuItem, JCheckBoxMenuItem, and
* JRadioButtonMenuItem. However, JMenuItem is the direct super class of the other three items. In the
* PluginSchema.xsd, JMenu maps Menu, JMenuItem maps MenuItem, JCheckBoxMenuItem maps CheckBox, and
* JRadioButtonMenuItem maps RadioButton. Therefore, for each of them we need to parse them
* differently and perhaps merge them accordingly. For the time being, only JMenuItem and JMenu are
* supported.
*/
for(JMenu jMenu : this.plugin.loadMenuItems()) {
// System.out.println("[FB] item menu name: " + item.getText());
JMenu parentMenu = getExistJMenu(jMenu);
if(parentMenu == null) {
// System.out.println("JMenu: {" + item.getText() + "} does not
// exist.");
mb.add(jMenu);
}
else {
// System.out.println("JMenu: {" + item.getText() + "} already
// exists.");
mergeMenuWithParent(jMenu, parentMenu);
}
}
mb.add(helpMenu);
// If the preferred browse is not set, use the system default one
// boolean canbrowse = (preferences.getProperty("browser") != null);
boolean canbrowse = true;
helpMenu.add(helpItem);
helpItem.setEnabled(canbrowse);
helpMenu.add(helpHowToItem);
helpHowToItem.setEnabled(canbrowse);
helpMenu.addSeparator();
helpMenu.add(helpAboutItem);
setJMenuBar(mb);
}
/**
* Check whether the given JMenu instance has already been added to the menu bar. If the target JMenu has
* not been added, return it otherwise return null
*
* @param target JMenu
* @return JMenu or <TT>null</TT>
*/
private JMenu getExistJMenu(JMenu target) {
for(int i = 0; i < mb.getMenuCount(); i++) {
JMenu jMenu = mb.getMenu(i);
String label = jMenu.getText();
if(label.equalsIgnoreCase(target.getText())) {
return jMenu;
}
}
return null;
}
/**
* Check whether the given JMenuItem resides in the given JMenu. Only return the item in sourceJMenu if it
* has the same name as that of targetItem
*
* @param targetItem JMenuItem, can be JMenuItem, JCheckBoxMenuItem, or JRadioButtonMenuItem
* @param sourceJMenu JMenu
* @return JMenuItem or <TT>null</TT>
*/
private JMenuItem getExistJMenuItem(JMenuItem targetItem, JMenu sourceJMenu) {
// System.out.println("Locating " + targetItem.getText() + " within " + sourceJMenu.getText());
String targetItemLabel = targetItem.getText();
for(int i = 0; i < sourceJMenu.getItemCount(); i++) {
JMenuItem item = sourceJMenu.getItem(i);
if(targetItemLabel.equalsIgnoreCase(item.getText())) {
return item;
}
}
return null;
}
/**
* Recursively merge the target menu to the parent menu. Only the first non-exist menu item will be added
*
* @param item JMenuItem
* @param parentMenu JMenu
*/
private void mergeMenuWithParent(JMenuItem item, JMenu parentMenu) {
JMenuItem newParent = null;
// TODO: When merging newJMenu with oldJMenu, we actually check the items within the JMenu's, however
// we didn't change anything about the oldJMenu itself. That's why the ActionCommand, typically the
// refreshMenu method, associated with the newJMenu is never added to the oldJMenu.
if(item instanceof JMenu) {
// System.out.println(" [Megering] JMenu name: " + item.getText());
// System.out.println(" old action command: " + parentMenu.getActionCommand());
// System.out.println(" new action command: " + item.getActionCommand());
// parentMenu.setActionCommand(item.getActionCommand());
// System.out.println(" new added action command: " + parentMenu.getActionCommand());
JMenu jMenu = (JMenu) item;
for(int i = 0; i < jMenu.getItemCount(); i++) {
JMenuItem subMenuItem = jMenu.getItem(i);
newParent = getExistJMenuItem(subMenuItem, parentMenu);
if(newParent == null) {
parentMenu.add(subMenuItem);
// must decrement the i counter as the subMenuItem has been removed from jMenu, which also
// decrement the value of jMenu.getItemCount()
i--;
}
else {
// if the newParent item exists and its not a JMenu, then don't add it, otherwise merge
// the newParent with subMenuItem again
if(newParent instanceof JMenu) {
mergeMenuWithParent(subMenuItem, (JMenu) newParent);
}
}
}
}
else { // All other kinds of menu items: JMenuItem, JCheckBoxMenuItem, etc
newParent = getExistJMenuItem(item, parentMenu);
if(newParent == null) {
parentMenu.add(item);
}
}
}
private void buildToolButton(JToolBar toolBar, String[] functions, String[] pics) {
JButton button;
for(int i = 0; i < functions.length; i++) {
ActionSet action = new ActionSet(functions[i], new ImageIcon(pics[i]));
button = toolBar.add(action);
button.setActionCommand(functions[i]);
button.setToolTipText((String) action.getValue(Action.NAME));
button.setEnabled(false);
}
}
private void checkToolBar() {
int count = desktop.getTabCount();
int selected = desktop.getSelectedIndex();
boolean enabled = count > 0;
toolBar.getComponent(0).setEnabled(enabled);
toolBar.getComponent(1).setEnabled(enabled);
toolBar.getComponent(2).setEnabled(enabled);
toolBar.getComponent(3).setEnabled(enabled && selected > 0);
toolBar.getComponent(4).setEnabled(enabled && selected < count - 1);
}
protected void windowClosing(WindowEvent evt) {
// Check if All Files have been saved
if(unsavedFiles())
return;
for(Process proc : processes.values())
proc.destroy();
dispose();
System.exit(0);
}
private boolean unsavedFiles() {
for(int i = 0; i < desktop.getComponentCount(); i++) {
Component c = desktop.getComponent(i);
if(c instanceof LibraryElementView) {
LibraryElementView doc = ((LibraryElementView) c);
if(!doc.safeToClose()) {
return true;
}
}
}
return false;
}
public void closeTab(Component c) {
if(c instanceof LibraryElementView) {
LibraryElementView doc = ((LibraryElementView) c);
if(doc.safeToClose()) {
desktop.remove(c);
doc.unload();
}
}
else
desktop.remove(c);
this.checkToolBar();
}
// public void fileExit(String s) {
public void fileExit(Vector<Object> v) {
if(unsavedFiles())
return;
dispose();
}
/**
* Answers an InputSource on a file with the given name and suffix in the <B>src </B> subdirectory tree;
* if none is found, shows an error dialog and answers <TT>null</TT>.
*
* @param docname The document name in the form <TT>filename.suffix</TT>.
*/
public File getSource(String docname) {
// System.out.println("[FB] getSource " + docname);
// long stime = System.currentTimeMillis();
File src = getSource(new File("src"), docname);
// if(src == null)
// JOptionPane.showMessageDialog(this, "Can't find source for " + docname + '.', "File Open Failed",
// JOptionPane.WARNING_MESSAGE);
// long etime = System.currentTimeMillis();
// long ttime = etime - stime;
// System.out.println("[FB] TOTAL getSource " + ttime + "ms");
return src;
}
/**
* Answers an InputSource on a file with the given name and suffix in the given subdirectory tree. If none
* is found, answers <TT>null</TT>.
*
* @param dir The full directory of the file...
* @param docname The document name in the form <TT>filename.suffix</TT>.
*/
public static File getSource(File dir, String docname) {
// TODO: THIS IS WHY FILES TAKE A WHILE to load.. ~1+ seconds JUST ON
// THIS (give full path == 0ms vs 500ms!
// long stime = System.currentTimeMillis();
for(int i = 0; i < Constants.fbtTemplates.length; i++) {
if(docname.equals(Constants.fbtTemplates[i])) {
return new File(Constants.fbtTemplateFolder + docname);
}
}
// try {
// return new InputSource(new FileInputStream(new File(dir,docname)));
File src = new File(dir, docname);
if(src.exists())
return src;
// } catch (Exception e){//FileNotFoundException e) {
// e.printStackTrace();
File[] dirs = dir.listFiles(new FileFilter() {
public boolean accept(File fl) {
return fl.isDirectory();
}
});
if(dirs != null) {
for(int i = 0; i < dirs.length; i++) {
if(!dirs[i].getName().equals("template") && !dirs[i].getPath().contains(".svn")) {
src = getSource(dirs[i], docname);
if(src != null) {
// long etime = System.currentTimeMillis();
// long ttime = etime - stime;
// System.out.println("[FB] slower getSource end: " + ttime
// +
// "ms");
return src;
}
}
}
}
// e.printStackTrace();
// }
return null;
}
public static void main(String[] args) {
// System.out.println(Constants.currentWorkingDirectory);
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}
catch(ClassNotFoundException e) {
e.printStackTrace();
}
catch(InstantiationException e) {
e.printStackTrace();
}
catch(IllegalAccessException e) {
e.printStackTrace();
}
catch(UnsupportedLookAndFeelException e) {
e.printStackTrace();
}
// FBench fBench =
new FBench();
}
/**
* Create a JMenuItem
*
* @param label Menu item name
* @param actionCommand Action to be performed
* @param iconName Icon to be displayed
* @param toolTip Tool tip text
* @param keyStroke
* @return
*/
private JMenuItem createMenuItem(String label, String actionCommand, String iconName, String toolTip,
KeyStroke keyStroke) {
JMenuItem item = new JMenuItem(label);
item.addActionListener(this);
item.setActionCommand(actionCommand);
if(iconName != null && !iconName.isEmpty()) {
item.setIcon(IconFactory.getIcon(iconName));
}
if(toolTip != null && !toolTip.isEmpty()) {
item.setToolTipText(toolTip);
}
if(keyStroke != null) {
item.setAccelerator(keyStroke);
}
return item;
}
/**
* Create a JMenuItem
*
* @param label Menu item name
* @param actionCommand Action to be performed
* @param iconName Icon to be displayed
* @param toolTip Tool tip text
* @param accelerator
* @param keyMask
* @return
*/
private JMenuItem createMenuItem(String label, String actionCommand, String iconName, String toolTip,
Character accelerator, Integer keyMask) {
JMenuItem item = null;
if(accelerator != null && keyMask != null) {
int keyMaskInt = Integer.valueOf(keyMask);
item =
createMenuItem(label, actionCommand, iconName, toolTip, KeyStroke
.getKeyStroke(accelerator.charValue(), keyMaskInt));
}
else if(accelerator != null && keyMask == null) {
item =
createMenuItem(label, actionCommand, iconName, toolTip, KeyStroke
.getKeyStroke(accelerator.charValue(), InputEvent.ALT_MASK));
}
else {
item = createMenuItem(label, actionCommand, iconName, toolTip, null);
}
return item;
}
// TODO: Never USED
public JCheckBoxMenuItem createMenuCheckBox(String label, String actionCommand) {
JCheckBoxMenuItem item = new JCheckBoxMenuItem(label);
item.addActionListener(this);
item.setActionCommand(actionCommand);
return item;
}
private void CompileSelected() {
JTextArea textArea = getTextArea();
boolean notNull = (textArea != null);
compiletoJava.setEnabled(false);
compiletoJavaDebug.setEnabled(false);
if(notNull) {
try {
LibraryElementView launchView = (LibraryElementView) desktop.getSelectedComponent();
if(launchView.getDocument().getDocumentElement().getNodeName().equals("FBType")) {
compiletoJava.setEnabled(true);
compiletoJavaDebug.setEnabled(true);
}
}
catch(Exception e) {
}
}
}
private void runMenuSelected() {
JTextArea textArea = getTextArea();
boolean notNull = (textArea != null);
runLaunchItem.setEnabled(notNull);
}
// private void DebugSelected() {
// JTextArea textArea = getTextArea();
// boolean notNull = (textArea != null);
// debugItem.setEnabled(notNull);
// debugPBItem.setEnabled(notNull);
// }
private void editMenuSelected() {
JTextArea textArea = getTextArea();
boolean notNull = (textArea != null);
boolean textSelected = notNull && (textArea.getSelectionEnd() > textArea.getSelectionStart());
editCutItem.setEnabled(textSelected);
editCopyItem.setEnabled(textSelected);
editPasteItem.setEnabled(notNull);
editDeleteItem.setEnabled(textSelected);
editFindReplaceItem.setEnabled(notNull);
editSelectAllItem.setEnabled(notNull);
// TODO: The undo and redo buttons are always disabled temporarily
editUndoItem.setEnabled(false);
editRedoItem.setEnabled(false);
}
/**
* Returns the name of a suitable icon for use in menu items as determined by the suffix of the given file
* name. If no suitable icon is found, returns the empty String.
*/
public static String getIconForFile(String flnm) {
int n = flnm.lastIndexOf('.');
if((n <= 0) || (n >= flnm.length()))
return "";
String suffix = flnm.substring(n);
String[] sfxs = getFileSuffixes();
String[] icons = {"fb16", "fb16", "res16", "dev16", "system", "file_obj", "xmlObject", "file_obj"};
for(int i = 0; i < Math.min(sfxs.length, icons.length); i++) {
if(suffix.equals(sfxs[i]))
return icons[i];
}
return "";
}
/** Returns a list of suitable suffixes for IEC 61499 LibraryElement files. */
public static String[] getFileSuffixes() {
String[] ans = {".fbt", ".adp", ".res", ".dev", ".sys", ".dtp", ".xml", ".src", ".db", ".trace"};
return ans;
}
/**
* Opens the document with the given filename in a new EditorFrame unless already open; in any case
* transfers focus to the EditorFrame of the given file. If none can be found or created, exits with all
* frames iconified.
*/
public void open(String filename) {
if(show(filename))
return;
Document doc = Library.getDocument(filename);
if(doc == null) {
JOptionPane.showMessageDialog(this, "Can't find source for " + Library.getFullDocPath(filename)
+ '.', "File Open Failed", JOptionPane.WARNING_MESSAGE);
return;
}
final LibraryElementView newView = new LibraryElementView(doc);
newView.getGraphView().setTransferHandler(gvhandler);
desktop.addTab(newView.getName(), newView);
desktop.setSelectedComponent(newView);
final TabPanel newTabPanel = new TabPanel(newView.getName(), desktop, newView);
newTabPanel.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
if(e.getClickCount() == 1) {
desktop.setSelectedComponent(newView);
}
else if(e.getClickCount() > 1) {
if(newView.safeToClose()) {
desktop.remove(desktop.getSelectedComponent());
}
checkToolBar();
}
}
});
desktop.setTabComponentAt(desktop.getSelectedIndex(), newTabPanel);
checkToolBar();
}
// public void FileOpen(String txt){
public void FileOpen(Vector<Object> v) {
select_item.setDialogTitle("Open A File (IEC 61499 Compatible)");
select_item.setFileFilter(new FBLibrary());
select_item.setFileView(new FBIconLibrary());
int choice = select_item.showOpenDialog(this);
if(choice != 0)
return;
File f = select_item.getSelectedFile();
if(f == null)
return;
open(f);
}
// TODO Name of the file = Name in the first element of the document
// TODO Location of the file = specified in CompilerInfo - Somehow related
// with Project?
// public void fileSaveAsXML(String s) {
public void fileSaveAsXML(Vector<String> v) {
LibraryElementView launchView = (LibraryElementView) desktop.getSelectedComponent();
if(launchView == null)
return;
launchView.saveXML();
desktop.repaint();
}
/** gsha041: Strip a file path to give the classPath only */
public static String stripPath(String s) {
int start = s.indexOf("src" + File.separator) + 4;
int end = s.lastIndexOf(File.separator);
if(start != -1 && end != -1) {
if(start < end)
return new String(s.substring(start, end));
else
return new String(s.substring(end + 1));
}
else if(start > end)
return new String();
else
return new String(s);
}
/** gsha041: Strip Compiler info attribute to give the classPath only */
public static String stripCompilerInfo(String s) {
int start = s.indexOf("fb.rt") + 5;
int end = s.indexOf(";");
if(s.charAt(start) == '.')
start += 1;
return new String(s.substring(start, end));
}
public static String getSourceType(Document document) {
String clist = document.getFirstChild().getNodeName();
String type = "";
if(clist.equals("FBType")) {
type = ".fbt";
}
else if(clist.equals("Device")) {
type = ".dev";
}
else if(clist.equals("System")) {
type = ".sys";
}
else if(clist.equals("DataType")) {
type = ".dtp";
}
else if(clist.equals("AdapterType")) {
type = ".adp";
}
else if(clist.equals("ResourceType")) {
type = ".res";
}
return type;
}
public static Hashtable<String, String> getGraphModels() {
return graphModels;
}
public static void putGraphModel(String name, String className) {
graphModels.put(name, className);
}
public static String getGraphModel(String name) {
return graphModels.get(name);
}
public static Hashtable<String, String> getGraphElements() {
return graphElements;
}
public static void putGraphElement(String name, String className) {
graphElements.put(name, className);
}
public static String getGraphElement(String name) {
return graphElements.get(name);
}
public static Hashtable<String, String> getMutationListeners() {
return mutationListeners;
}
public static void putMutationListener(String name, String className) {
mutationListeners.put(name, className);
}
public static String getMutationListener(String name) {
return mutationListeners.get(name);
}
public static Hashtable<String, String> getTreeNodes() {
return treeNodes;
}
public static void putTreeNode(String name, String className) {
treeNodes.put(name, className);
}
public static String getTreeNode(String name) {
return treeNodes.get(name);
}
public static Hashtable<String, String[]> getTreeMenus() {
return treeMenus;
}
public static void putTreeMenu(String name, String[] menuOptions) {
treeMenus.put(name, menuOptions);
}
public static String[] getTreeMenu(String name) {
return treeMenus.get(name);
}
public static Hashtable<String, String> getTreeMenuActions() {
return treeMenuActions;
}
public static void putTreeMenuAction(String name, String className) {
treeMenuActions.put(name, className);
}
public static String getTreeMenuAction(String name) {
return treeMenuActions.get(name);
}
public String getSourceType(LibraryElementView launchView) {
String clist = launchView.getDocument().getFirstChild().getNodeName();
String type = "";
if(clist.equals("FBType")) {
type = ".fbt";
}
else if(clist.equals("Device")) {
type = ".dev";
}
else if(clist.equals("System")) {
type = ".sys";
}
else if(clist.equals("DataType")) {
type = ".dtp";
}
else if(clist.equals("AdapterType")) {
type = ".adp";
}
else if(clist.equals("ResourceType")) {
type = ".res";
}
return type;
}
public Document getSelectedDoc() {
LibraryElementView launchView = (LibraryElementView) desktop.getSelectedComponent();
if(launchView == null)
return null;
return launchView.getDocument();
}
public LibraryElementView getSelectedView() {
LibraryElementView launchView = (LibraryElementView) desktop.getSelectedComponent();
return launchView;
}
public void fileSaveAsJavaDebug(Vector<Object> v) {
LibraryElementView launchView = (LibraryElementView) desktop.getSelectedComponent();
String contents =
new DOMTranslationModel(launchView.getDocument(), null, "DOMtoJavaDebug.xsl", "Java")
.performTranslation();
saveJava(launchView, contents);
}
// public void fileSaveAsJava(String s) {
public void fileSaveAsJava(Vector<Object> v) {
LibraryElementView launchView = (LibraryElementView) desktop.getSelectedComponent();
int selectedRow = launchView.getSelectedTreeRow(); // Save the selected
// element so we can
// put it back
launchView.setSelectedTreeRow(0); // Select the first treenode so the
// full source is compiled.
String contents = launchView.getJavaArea().getText();
saveJava(launchView, contents);
launchView.setSelectedTreeRow(selectedRow);
}
private void saveJava(LibraryElementView launchView, String contents) {
String filename = launchView.getDocument().getDocumentElement().getAttribute("Name") + ".java";
String path =
launchView.getDocument().getElementsByTagName("CompilerInfo").item(0).getAttributes()
.getNamedItem("header").getNodeValue();
contents = removeHTML(contents);
path = removePath(path);
// String rtPath = "rt" + File.separator + "fb" + File.separator + "rt" + File.separator;
String rtPath = adjustCommand(preferences.getProperty("rtPath"));
if(rtPath == null)
rtPath = "rt\\fb\\rt".replace('\\', File.separatorChar);
File path_check = new File(rtPath + path);
if(!path_check.exists())
path_check.mkdirs(); // Should also create any non-exist directories as well
File f = new File(rtPath + path, filename);
try {
if(f.exists()) {
f.delete();
f.createNewFile();
}
FileWriter fw = new FileWriter(f);
fw.write(contents);
fw.close();
Compiler cdlg = new Compiler(this);
cdlg.showCentered();
preferences.load(new FileInputStream("preferences.ini"));
// String cmd = adjustCommand(preferences.getProperty("javac") + " -classpath ./rt;./fbrt.jar;.;
// ");
rtPathRoot = rtPath.subSequence(0, rtPath.indexOf(File.separatorChar)).toString();
String cmd =
adjustCommand(preferences.getProperty("javac"))
// commented out by VV: reason command line in preferences.ini can explicitly include ./lib
+ " -classpath " + preferences.getProperty("classpath") ;
//+ ";./fbrt.jar;.; ");
cdlg.compile(f, cmd);
}
catch(IOException e) {
System.err.println(e.getMessage());
System.err.println("File " + f.getPath() + " FILE NOT SAVED.");
}
}
public static String adjustCommand(String cmd) {
String ans = cmd.replace(';', File.pathSeparatorChar);
ans = ans.replace(':', File.pathSeparatorChar);
ans = ans.replace('\\', File.separatorChar);
ans = ans.replace('/', File.separatorChar);
ans = ans.replaceFirst("\\;\\\\", "\\:\\\\");
return ans;
}
public String removePath(String s) {
if(s.contains("fb.rt.")) {
int start = s.indexOf("fb.rt.") + 6;
int end = s.indexOf(";");
return new String(s.substring(start, end));
}
return s;
}
public static String removeHTML(String s) {
s = s.replace("<br>", "\n");
s = s.replace("<BR>", "\n");
s = s.replace(""", "\"");
s = s.replace(">", ">");
s = s.replace("<", "<");
s = s.replace("&", "&");
s = s.replace(""", "\"");
s = s.replace(" ", "\n");
s = s.replace("<", "<");
s = s.replace(">", ">");
s = s.replace("&", "&");
s = new String(s);
if(s.contains("<body>")) {
int start = s.indexOf("<body>") + 6;
int end = s.indexOf("</body>");
s = s.substring(start, end);
}
return s;
}
public void launch(String cmd) {
try {
Process p = Runtime.getRuntime().exec(cmd);
p.waitFor();
processes.put(cmd, p);
}
catch(IOException iox) {
String msg[] = {"Can't open the Java runtime."};
JOptionPane.showMessageDialog(this, msg, "Can't open Java runtime", 2);
}
catch(InterruptedException e) {
}
}
public void teminate(Process p) {
p.destroy();
p = null;
}
String launchPath = null;
public void runLaunch(Vector<Object> v) {
LibraryElementView launchView = (LibraryElementView) desktop.getSelectedComponent();
Document document = launchView.getDocument();
String keyword = document.getDocumentElement().getNodeName();
String file = document.getDocumentElement().getAttribute("Name");
if(keyword.equals("FBType"))
file = file + ".fbt";
else if(keyword.equals("System"))
file = file + ".sys";
else {
System.out.println("UNSUPPORTED TYPE FOR LAUNCH");
return;
}
// String path = Library.getFilePath(document);
File f = this.getSource(file);
// if(path == null) {
// System.out.println("Invalid path.");
// return;
// }
String path = f.getPath();
if(f.isAbsolute())
path = path.replace(System.getProperty("user.dir") + File.separatorChar, "");
if(!path.startsWith("src"))
path = "src/".replace('/', File.separatorChar) + path;
launchPath = path;
int port = 61502;
String hostIp = "localhost";
try {
Properties debugPreferences = new Properties();
debugPreferences.load(new FileInputStream("debug.ini"));
port = Integer.parseInt(debugPreferences.getProperty("port", "61502"));
hostIp = debugPreferences.getProperty("host", "localhost");
}
catch(FileNotFoundException e1) {
}
catch(IOException e1) {
}
FBInstance.debugHost = hostIp + ":" + port;
try {
Runnable runnable = new Runnable() {
public void run() {
try {
String file = new File(launchPath).getName();
int port = 61502;
String hostIp = "localhost";
try {
Properties debugPreferences = new Properties();
debugPreferences.load(new FileInputStream("debug.ini"));
port = Integer.parseInt(debugPreferences.getProperty("port", "61502"));
hostIp = debugPreferences.getProperty("host", "localhost");
}
catch(FileNotFoundException e1) {
}
catch(IOException e1) {
}
// FBInstance.localDebugHost = hostIp + ":" + port;
// FBInstance.debugHost = hostIp + ":" + port;
// Process proc =
// Runtime.getRuntime().exec("java -classpath ./rt;./fbrt.jar;
// fb.rt.tools.SystemManager "
// + launchPath);
String rtPath = adjustCommand(preferences.getProperty("rtPath"));
String rtPathRoot =
rtPath.subSequence(0, rtPath.indexOf(File.separatorChar)).toString();
String cmd =
"java -classpath " + "\"" + "./" + rtPathRoot + ";./fbrt.jar;"
+ System.getProperty("java.class.path") + "\" "
+ "fbench.FBenchSystemManager -d " + hostIp + ":" + port + " "
+ launchPath;
Process proc = Runtime.getRuntime().exec(cmd);
StreamLogger out = new StreamLogger(proc.getInputStream(), false, file + " output");
StreamLogger err = new StreamLogger(proc.getErrorStream(), true, file + " error");
out.start();
err.start();
processes.put(launchPath, proc);
int exitCode = proc.waitFor();
System.out.println(file + " Launch process exited: " + exitCode);
out.stop = true;
err.stop = true;
out.interrupt();
err.interrupt();
}
catch(Exception e) {
e.printStackTrace();
}
}
};
if(processes.containsKey(launchPath)) {
processes.get(launchPath).destroy();
processes.remove(launchPath);
}
new Thread(runnable, file + " Launch process").start();
}
catch(Exception e) {
// logger.log(e);
// System.exit(-1);
}
}
public void log(String s) {
}
public void log(Exception e) {
}
/**
* Opens a document from the given file in a new EditorFrame unless already open; in any case transfers
* focus to the EditorFrame of the given file. If none can be found or created, exits with all frames
* iconified.
*/
public void open(File f) {
if(!f.isFile()) {
JOptionPane.showMessageDialog(this, f.getAbsolutePath() + " is not a File.", "No Such File",
JOptionPane.WARNING_MESSAGE);
return;
}
String flnm = f.getName();
if(show(flnm))
return;
Library.load(f);
open(flnm);
}
public void createViewFrame() {
LibraryTreeNode libraryRoot = new LibraryTreeNode(new File("src"), null);
final JTree libraryTree = new JTree(libraryRoot);
gvhandler = new GraphViewTransfer(libraryTree);
libraryTree.setCellRenderer(libraryRoot);
libraryTree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
libraryTree.setDragEnabled(true);
libraryTree.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
if(e.getClickCount() == 2) {
Object obj = null;
if(libraryTree.getLeadSelectionPath() != null)
obj = libraryTree.getLeadSelectionPath().getLastPathComponent();
if(obj instanceof LibraryTreeNode)
open(((LibraryTreeNode) obj).getFile());
}
else if(e.getButton() == 3) {
refresh_view.setLocation(e.getX() + viewFrame.getX(), e.getY() + viewFrame.getY());
refresh_view.setVisible(true);
}
else {
refresh_view.setVisible(false);
}
}
});
JScrollPane libraryView = new JScrollPane(libraryTree);
viewFrame.setIconImage(IconFactory.getIcon("fbench24.png").getImage());
viewFrame.setBounds(900, 100, 250, 600);
viewFrame.getContentPane().add(libraryView);
viewFrame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent evt) {
treeViewMenu.setSelected(false);
}
});
viewFrame.setVisible(true);
}
public void reloadLibraryTree(Vector<Object> v) {
refresh_view.setVisible(false);
viewFrame.dispose();
createViewFrame();
}
public void runViewMenu(Vector<Object> v) {
if(viewFrame.getContentPane().getComponentCount() == 0 && treeViewMenu.isSelected()) {
createViewFrame();
}
else if(treeViewMenu.isSelected()) {
viewFrame.setVisible(true);
}
else if(!treeViewMenu.isSelected()) {
viewFrame.setVisible(false);
}
}
public void menuDeselected(MenuEvent e) {
}
public void menuCanceled(MenuEvent e) {
}
// public void editAction(String lbl) {
public void editAction(Vector<Object> v) {
String lbl = (String) v.get(0);
JTextArea textarea = getTextArea();
if(textarea == null)
return;
if(lbl.equals("Cut")) {
textarea.cut();
}
else if(lbl.equals("Copy")) {
textarea.copy();
}
else if(lbl.equals("Paste")) {
textarea.paste();
}
else if(lbl.equals("Delete")) {
textarea.replaceSelection("");
}
else if(lbl.startsWith("Find")) {
System.out.println("Find/Replace");
}
else if(lbl.equals("Undo")) {
System.out.println("Undo");
}
else if(lbl.equals("Redo")) {
System.out.println("Redo");
}
}
/*
* public void EventChanged(DebugEvent event) { debugFBs(event.getdebugname()); }
*/
/**
* If an EditorFrame is selected and not iconified, return its text area; otherwise return <TT>null</TT>.
*/
public JTextArea getTextArea() {
Component fr = desktop.getSelectedComponent();
return (fr == null) ? null : ((LibraryElementView) fr).getXmlArea();
}
public JTabbedPane getDesktop() {
return desktop;
}
public Hashtable<String, Object> getInstances() {
return instances;
}
private void setupPreferences() {
try {
preferences.load(new FileInputStream("preferences.ini"));
}
catch(IOException e) {
System.out.println("Error reading preferences: " + e.getMessage());
}
// preferences.list(System.out);
}
public void newCFB(Vector<Object> v) {
open("Composite.fbt");
}
public void newBFB(Vector<Object> v) {
open("Basic.fbt");
}
public void newProxy(Vector<Object> v) {
open("Proxy.fbt");
}
public void newSI(Vector<Object> v) {
open("ServiceInterface.fbt");
}
public void newSimple(Vector<Object> v) {
open("Simple.fbt");
}
public void newAdapt(Vector<Object> v) {
open("AdapterType.adp");
}
public void newRes(Vector<Object> v) {
open("ResourceType.res");
}
public void newDev(Vector<Object> v) {
open("DeviceType.dev");
}
public void newSys(Vector<Object> v) {
open("System.sys");
}
public void newArray(Vector<Object> v) {
open("Array.dtp");
}
public void newDirect(Vector<Object> v) {
open("Direct.dtp");
}
public void newEnu(Vector<Object> v) {
open("Enumerated.dtp");
}
public void newStruct(Vector<Object> v) {
open("Structured.dtp");
}
public void newSubrange(Vector<Object> v) {
open("Subrange.dtp");
}
class StreamLogger extends Thread {
private InputStream is;
private PrintStream out;
public boolean stop = false;
public StreamLogger(InputStream stream, boolean error, String threadName) {
super(threadName);
this.is = stream;
if(error)
out = System.err;
else
out = System.out;
}
public void run() {
try {
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line = null;
while(!stop && (line = br.readLine()) != null)
out.println(line);
}
catch(IOException e) {
e.printStackTrace();
}
}
}
private class simpleMouseAdapter extends MouseAdapter {
private String link = null;
public simpleMouseAdapter(String link) {
this.link = link;
}
public void mousePressed(MouseEvent e) {
// JOptionPane.showMessageDialog(null, link);
try {
Runtime.getRuntime().exec("rundll32 url.dll,FileProtocolHandler " + link);
}
catch(IOException ex) {
JOptionPane.showMessageDialog(null, ex.getMessage(), "Error opening " + link,
JOptionPane.WARNING_MESSAGE);
}
}
}
public void showHelpOperation(String preferredBrowser, String manualURL) {
String osName = System.getProperty("os.name");
try {
if(preferredBrowser != null) {
Runtime.getRuntime().exec(new String[]{preferredBrowser, manualURL});
}
else {
if(osName.startsWith("Mac OS")) {
Class<?> fileMgr = Class.forName("com.apple.eio.FileManager");
Method openURL = fileMgr.getDeclaredMethod("openURL", new Class<?>[]{String.class});
openURL.invoke(null, new Object[]{manualURL});
}
else if(osName.startsWith("Windows"))
Runtime.getRuntime().exec("rundll32 url.dll,FileProtocolHandler " + manualURL);
else { // assume Unix or Linux
String[] browsers = {"firefox", "opera", "konqueror", "epiphany", "mozilla", "netscape"};
String browser = null;
for(int count = 0; count < browsers.length && browser == null; count++) {
if(Runtime.getRuntime().exec(new String[]{"which", browsers[count]}).waitFor() == 0) {
browser = browsers[count];
}
}
if(browser == null) {
JOptionPane
.showMessageDialog(this,
"Can't locate an browser, please manually open the ViEd Manual.htm inside the ViEd folder");
}
else {
Runtime.getRuntime().exec(new String[]{browser, manualURL});
}
}
}
}
catch(Exception e) {
JOptionPane.showMessageDialog(this, e.getMessage(), "Error opening " + manualURL,
JOptionPane.WARNING_MESSAGE);
}
}
public int help(Vector<String> v) {
String topic = (String) v.get(0);
if(topic.startsWith("About")) {
// JLabel msg =
// new JLabel(
// "<HTML><CENTER><P>"
// + FBench.productID
// + " Version "
// + FBench.version
// + "<BR><BR>An Open Source Project of the OOONEIDA"
// + "<BR>Developed By The University of Auckland"
// + "<BR><A HREF=\"http://www.ece.auckland.ac.nz\">Department of
// Electrical and Computer Engineering</A></P>"
// + "<BR><BR>By clicking "OK" you agree to use this
// software"
// + "<BR>under the provisions of the Common Public License"
// + "<BR><A
// HREF=\"http://opensource.org/licenses/cpl1.0.php\"><http://www.opensource.org/cpl1.0.php></A>."
// + "<BR><BR>To contribute to this project go to"
// + "<BR><A
// HREF=\"http://sourceforge.net/projects/oooneida-fbench/\">FBench
// Project</A>."
// + "</CENTER></HTML>");
// msg.setBackground(Color.lightGray);
JLabel aboutMsg1 =
new JLabel("<HTML><CENTER><P><BR><BR><BR>" + FBench.productID + " Version "
+ FBench.version + "<BR><BR>An Open Source Project of the OOONEIDA"
+ "<BR>Developed By The University of Auckland" + "</P></CENTER></HTML>");
JLabel aboutMsg2 =
new JLabel(
"<HTML><CENTER><BR><BR>By clicking "OK" you agree to use this software"
+ "<BR>under the provisions of the Common Public License"
+ "</CENTER></HTML>");
JLabel aboutMsg3 =
new JLabel(
"<HTML><CENTER><BR><BR> To contribute to this project go to"
+ "</CENTER></HTML>");
String cplURL = "http://opensource.org/licenses/cpl1.0.php";
String eceURL = "http://www2.ece.auckland.ac.nz/";
String fbURL = "http://sourceforge.net/projects/oooneida-fbench/";
JLabel cpLicence =
new JLabel("<HTML><CENTER><A HREF=\"" + cplURL + "\">" + cplURL + "</A></CENTER></HTML>");
JLabel eceDepartment =
new JLabel("<HTML><CENTER><A HREF=\"" + eceURL
+ "\">Department of Electrical and Computer Engineering</A></CENTER></HTML>");
JLabel fbProject =
new JLabel("<HTML><CENTER><A HREF=\"" + fbURL + "\">" + fbURL + "</A></CENTER></HTML>");
aboutMsg1.setBackground(Color.lightGray);
aboutMsg2.setBackground(Color.lightGray);
aboutMsg3.setBackground(Color.lightGray);
eceDepartment.setBackground(Color.lightGray);
cpLicence.setBackground(Color.lightGray);
fbProject.setBackground(Color.lightGray);
JPanel aboutJPanel = new JPanel();
aboutJPanel.setLayout(new BoxLayout(aboutJPanel, BoxLayout.Y_AXIS));
aboutJPanel.add(aboutMsg1);
aboutJPanel.add(eceDepartment);
aboutJPanel.add(aboutMsg2);
aboutJPanel.add(cpLicence);
aboutJPanel.add(aboutMsg3);
aboutJPanel.add(fbProject);
cpLicence.addMouseListener(new simpleMouseAdapter(cplURL));
cpLicence.setCursor(new Cursor(Cursor.HAND_CURSOR));
eceDepartment.addMouseListener(new simpleMouseAdapter(eceURL));
eceDepartment.setCursor(new Cursor(Cursor.HAND_CURSOR));
fbProject.addMouseListener(new simpleMouseAdapter(fbURL));
fbProject.setCursor(new Cursor(Cursor.HAND_CURSOR));
return JOptionPane.showConfirmDialog(this, aboutJPanel, "About " + FBench.productID,
JOptionPane.PLAIN_MESSAGE, JOptionPane.OK_OPTION,
IconFactory.getIcon("fbench0.jpg"));
}
if(topic.equals("User Manual"))
topic = Constants.fbenchUserManual;
else if(topic.equals("Developer's Guide"))
topic = Constants.fbenchDevelopersGuide;
String[] cmd = new String[2];
cmd[0] = preferences.getProperty("browser");
cmd[1] = topic;
showHelpOperation(cmd[0], cmd[1]);
return 0;
}
/**
* If a file with the given name is already open in a tabbed pane, brings that tab to the top.
*
* @param filename, e.g., <TT>X2Y2.fbt</TT> (the suffix is ignored).
* @return <TT>true</TT> if an open file was found.
*/
protected boolean show(String filename) {
int n = filename.indexOf('.');
if(n > 0) {
filename = filename.substring(0, n);
}
for(int i = 0; i < desktop.getComponentCount(); i++) {
Component c = desktop.getComponent(i);
String cName = c.getName();
if(cName != null && c.getName().equals(filename)) {
desktop.setSelectedComponent(c);
return true;
}
}
return false;
}
class ActionSet extends AbstractAction {
private static final long serialVersionUID = 3178916632987292161L;
public ActionSet(String name, Icon icon) {
super(name, icon);
}
public void actionPerformed(ActionEvent e) {
String command = e.getActionCommand();
if(command.equals("Parse XML")) {
setStatusText("Parsing XML");
((LibraryElementView) desktop.getSelectedComponent()).reparse();
setStatusText("Parsed");
}
else if(command.equals("Close Tab")) {
// // See if modified
// if (desktop.getSelectedComponent() instanceof
// LibraryElementView) {
// LibraryElementView docView = (LibraryElementView) desktop
// .getSelectedComponent();
// if (docView.modified()) {
// int value = JOptionPane.showConfirmDialog(null,
// "Save before close?", "Save before close?",
// JOptionPane.YES_NO_CANCEL_OPTION);
// if (value == JOptionPane.CANCEL_OPTION) {
// // Do nothing
// return;
// }
// if (value == JOptionPane.YES_OPTION) {
// // if yes.. save it
// Vector<String> args = new Vector<String>();
// args.add(desktop.getSelectedComponent().getName());
// fileSaveAsXML(args);
// }
// // if no just close
// }
// // TODO: Redo!!!!
// // docView.unload();
// }
// // if no just close
// desktop.remove(desktop.getSelectedComponent());
// checkToolBar();
closeTab(desktop.getSelectedComponent());
}
else if(command.equals("Save Now")) {
Vector<String> args = new Vector<String>();
LibraryElementView doc = (LibraryElementView) desktop.getSelectedComponent();
args.add(desktop.getSelectedComponent().getName());
fileSaveAsXML(args);
setStatusText("File saved in " + doc.getSavePath());
}
else if(command.equals("Next Tab")) {
int selectedIndex = desktop.getSelectedIndex();
if(selectedIndex < desktop.getTabCount() - 1)
desktop.setSelectedIndex(selectedIndex + 1);
checkToolBar();
}
else if(command.equals("Previous Tab")) {
int selectedIndex = desktop.getSelectedIndex();
if(selectedIndex > 0)
desktop.setSelectedIndex(selectedIndex - 1);
checkToolBar();
}
}
}
public Properties getProps() {
return preferences;
}
public PluginManager getPluginManager() {
return plugin;
}
public static String chooseFolderPath() {
FBench fbench = FBench.theBench;
fbench.select_item.setDialogTitle("Open A File (IEC 61499 Compatible)");
fbench.select_item.setFileFilter(new FBLibrary());
fbench.select_item.setFileView(new FBIconLibrary());
fbench.select_item.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
int choice = fbench.select_item.showOpenDialog(fbench);
fbench.select_item.setFileSelectionMode(JFileChooser.FILES_ONLY);
if(choice != 0)
return null;
File f = fbench.select_item.getSelectedFile();
if(f != null)
return f.getPath();
return null;
}
}