view src/MPipeline2/src/mpipeline/main/MainWindow.java @ 29:54f14716c721 database-connection-manager

Update Java code
author Daniele Nicolodi <nicolodi@science.unitn.it>
date Mon, 05 Dec 2011 16:20:06 +0100
parents f0afece42f48
children
line wrap: on
line source

/*
 * Copyright (c) 2009 Max-Planck-Gesellschaft, Martin Hewitson <martin.hewitson at aei.mpg.de>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 *
 */
package mpipeline.main;

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FileDialog;
import java.awt.Point;
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.MouseEvent;
import java.beans.PropertyVetoException;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.io.StringReader;
import java.io.StringWriter;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.Iterator;
import java.util.Observable;
import java.util.Observer;
import java.util.UUID;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.AbstractAction;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JDesktopPane;
import javax.swing.JFileChooser;
import javax.swing.JInternalFrame;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPopupMenu;
import javax.swing.JSeparator;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.JTree;
import javax.swing.KeyStroke;
import javax.swing.Timer;
import javax.swing.ToolTipManager;
import javax.swing.event.TableModelListener;
import javax.swing.filechooser.FileFilter;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
import javax.swing.text.Position.Bias;
import javax.swing.tree.TreePath;
import javax.swing.undo.CannotRedoException;
import javax.swing.undo.CannotUndoException;
import javax.swing.undo.UndoManager;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import mpipeline.canvas.BlockDiagram;
import mpipeline.canvas.MBlock;
import mpipeline.canvas.MCanvas;
import mpipeline.canvas.MConstant;
import mpipeline.canvas.MElement;
import mpipeline.canvas.MElementSelectable;
import mpipeline.canvas.MElementWithPorts;
import mpipeline.canvas.MPipe;
import mpipeline.canvas.MNode;
import mpipeline.canvas.MPort;
import mpipeline.canvas.MSubsystem;
import mpipeline.canvas.PipelineBlock;
import mpipeline.console.ConsoleDialog;
import mpipeline.dialogs.AboutDialog;
import mpipeline.dialogs.ElementSearchDialog;
import mpipeline.dialogs.ExecutionPlan;
import mpipeline.dialogs.ExecutionPlanView;
import mpipeline.dialogs.HelpDialog;
import mpipeline.dialogs.LWBpreferences;
import mpipeline.dialogs.MBlockInfoDialog;
import mpipeline.dialogs.PreferencesDialog;
import mpipeline.dialogs.QuickBlock;
import mpipeline.dialogs.SimpleInputDialog;
import mpipeline.jltpda.LTPDALibraryModel;
import mpipeline.ltpdapreferences.DisplayPrefGroup;
import mpipeline.ltpdapreferences.LTPDAPreferences;
import mpipeline.parametersoverview.ParametersOverviewDialog;
import mpipeline.repository.SubmissionInfo;
import mpipeline.pipelinelist.PipelineList;
import mpipeline.pipelinelist.PipelineListTree;
import mpipeline.pipelinelist.PipelineListTreeModel;
import mpipeline.plisttable.JParam;
import mpipeline.plisttable.JParamValue;
import mpipeline.plisttable.JPlist;
import mpipeline.plisttable.PlistTable;
import mpipeline.plisttable.PlistTableModel;
import mpipeline.shelf.Shelf;
import mpipeline.shelf.ShelfCategory;
import mpipeline.shelf.ShelfController;
import mpipeline.shelf.ShelfTree;
import mpipeline.jltpda.LTPDAModel;
import mpipeline.jltpda.LTPDAalgorithm;
import mpipeline.jltpda.LTPDAcategory;
import mpipeline.jltpda.LTPDAlibrary;
import mpipeline.utils.Utils;
import mpipeline.utils.XMLUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

/**
 * Implements the main window of an LTPDA workbench.
 * 
 * @author  hewitson
 */
public class MainWindow extends javax.swing.JFrame implements Serializable, Observer {

//  private static float version = 0.3f;
  private static float version = 0.4f; // moved to new JPlist etc
  private static String workbenchFileExtension = "lwb";
  private LTPDAlibrary lib = new LTPDAlibrary("LTPDA");
  private LTPDALibraryModel libmodel;
  private String context = null;
  /** pipeline list **/
  private PipelineList pipelineList = new PipelineList();
  private PipelineListTreeModel pipelineListTreeModel = null;
  /** shelf **/
  private Shelf shelf = new Shelf("Default");
  private ShelfController shelfController = null;
  private File shelfFile = null;
  private ArrayList<BlockDiagram> documents = new ArrayList<BlockDiagram>();
  private ArrayList<MTextDocument> txtdocs = new ArrayList<MTextDocument>();
  private boolean saved = true;
  private File workbenchFilePath = null;
  private File pipelineFilePath = null;
  private String lastSearchTxt = "";
  private File lastSavePath = null;
  private File lastLoadPath = null;
  /** File Menu **/
  private JMenuItem WBSaveMenuItem = new JMenuItem();
  private JMenuItem WBSaveAsMenuItem = new JMenuItem();
  private JMenuItem WBLoadMenuItem = new JMenuItem();
  private JMenuItem WBSavePipelineMenuItem = new JMenuItem();
  private JMenuItem WBOpenMenuItem = new JMenuItem();
  private JMenuItem WBOpenFromObjectMenuItem = new JMenuItem();
  private JMenu PlanMenu = new JMenu("Plan");
  private JMenuItem planEditMenuItem = new JMenuItem("Edit");
  private JMenuItem planRunMenuItem = new JMenuItem("Run");
  private JMenuItem newTextDocMenuItem = new JMenuItem("New Text Document");
  private JMenu recentFilesMenu = new JMenu("Recent Files");
  private JMenuItem ImportFromMfileMenuItem = new JMenuItem();
  private JMenuItem ImportFromWorkspaceMenuItem = new JMenuItem();
  private JMenuItem WBCloseMenuItem = new JMenuItem();
  private JMenuItem resetWorkbench = new JMenuItem("Reset workbench");
  private JMenuItem preferencesMenuItem = new JMenuItem();
  /** Edit menu **/
  private JMenuItem CopyMenuItem = new JMenuItem();
  private JMenuItem PasteMenuItem = new JMenuItem();
  private JMenuItem UndoMenuItem = new JMenuItem();
  private JMenuItem DuplicateMenuItem = new JMenuItem();
  private JMenuItem RedoMenuItem = new JMenuItem();
  private JMenuItem DeleteMenuItem = new JMenuItem();
  private JMenuItem SelectAllMenuItem = new JMenuItem();
  private JMenuItem toggleCommentSelectedMenuItem = new JMenuItem();
  /** View menu **/
  private JMenuItem ZoomInMenuItem = new JMenuItem();
  private JMenuItem ZoomOutMenuItem = new JMenuItem();
  /** Tools menu **/
  private JMenuItem RebuildLibraryMenuItem = new JMenuItem();
  private JMenuItem PlotSelectedMenuItem = new JMenuItem();
  private JMenuItem ltpdaPreferencesMenuItem = new JMenuItem();
  private JMenuItem ltpdaPZmodelHelperMenuItem = new JMenuItem();
  private JMenuItem ltpdaSpecwinViewerMenuItem = new JMenuItem();
  private JMenuItem ltpdaConstructorHelperMenuItem = new JMenuItem();
  private JMenuItem ltpdaSignalBuilderMenuItem = new JMenuItem();
  private JMenuItem ExploreSelectedMenuItem = new JMenuItem();
  /** Format menu **/
  private JMenuItem AlignLeftMenuItem = new JMenuItem();
  private JMenuItem AlignRightMenuItem = new JMenuItem();
  private JMenuItem AlignTopMenuItem = new JMenuItem();
  private JMenuItem AlignBottonMenuItem = new JMenuItem();
  private JMenuItem SameSizeMenuItem = new JMenuItem();
  /** Pipeline Menu **/
  private JMenuItem NewMenuItem = new JMenuItem(); // New Pipeline
  private JMenuItem RenamePipelineMenuItem = new JMenuItem(); // Rename Pipeline
  private JMenuItem ExportToMFileMenuItem = new JMenuItem(); // export current top-level diagram to m-file
  private JMenuItem ExportToTerminalMenuItem = new JMenuItem(); // export current top-level diagram to MATLAB terminal
  private JMenuItem ExportToImageMenuItem = new JMenuItem(); // export current top-level diagram to image
  private JMenuItem CreateSubsystemPipelineMenuItem = new JMenuItem();
  private JMenuItem showQuickBlockMenuItem = new JMenuItem();
  private JMenuItem editCanvasInfoMenuItem = new JMenuItem();
  private JMenuItem searchCanvasMenuItem = new JMenuItem();
  private JMenuItem RemovePipelineMenuItem = new JMenuItem();
  private JMenuItem ClosePipelineMenuItem = new JMenuItem(); // Close Pipeline
  private JMenuItem CloseAllPipelinesMenuItem = new JMenuItem();
  /** Help menu **/
  private JMenuItem HelpBlockHelpMenuItem = new JMenuItem(); // Close Pipeline
  private JMenuItem HelpBlockDocMenuItem = new JMenuItem();
  private JMenuItem HelpAboutMenuItem = new JMenuItem();
  /** LTPDA Toolbox information **/
  private ArrayList<String> windowTypes = new ArrayList<String>();
  private ArrayList<LTPDAModel> aoModels = new ArrayList<LTPDAModel>();
  private ArrayList<LTPDAModel> ssmModels = new ArrayList<LTPDAModel>();
  private ArrayList<LTPDAModel> builtinModels = new ArrayList<LTPDAModel>();
  private ArrayList<String> unitPrefixes = new ArrayList<String>();
  private ArrayList<String> units = new ArrayList<String>();
  // File chooser for saving as...
  JFileChooser saveChooser = new JFileChooser("Save As...");
  // Repository stuff
  private SubmissionInfo submissionInfo = null;
  // Preferences object
  private LWBpreferences preferences = new LWBpreferences();
  private File prefFile = null;
  private PreferencesDialog prefsDialog = null;
  private LTPDAPreferences ltpdaPreferences2 = null;
  private AboutDialog aboutDialog = new AboutDialog(this, saved, version);
  private ExecutionPlan execPlan = new ExecutionPlan();
  private ExecutionPlanView execPlanView = new ExecutionPlanView(this, saved);
  private Timer autosaveTimer = null;
  private boolean preferencesApplied = false;
  /** Parameters overview **/
  private ParametersOverviewDialog parametersOverviewDialog = null;
  private ConsoleDialog console = null;
  private final int keyModifier;
  //
  private String instanceIdentifier = "unknown";
  public final boolean isMacOSX;
  public boolean executing = false;

  /** Define the key modifier for the different OS */
  {
    if (System.getProperty("os.name").equals("Mac OS X")) {
      keyModifier = KeyEvent.META_DOWN_MASK;

    } else {
      keyModifier = KeyEvent.CTRL_DOWN_MASK;
    }
    String systemName = System.getProperty("os.name");
    if (systemName.equals("Mac OS X")) {
      isMacOSX = true;
    } else {
      isMacOSX = false;
    }
  }

  /** Help menu **/
  /** Creates new form MainWindow
   * @param userPrefsDir
   */
  public MainWindow(String userPrefsDir, LTPDAPreferences prefs) {

    this.ltpdaPreferences2 = prefs;
    initComponents();

    this.setInstanceIdentifier("unknown");

    ToolTipManager.sharedInstance().setInitialDelay(2000);

    // set up submission info
    submissionInfo = new SubmissionInfo(this);

    // load preferences
    if (userPrefsDir.equals("")) {
      prefFile = new File(System.getProperty("user.home") + File.separator + "LTPDAworkbench.prefs");
    } else {
      prefFile = new File(userPrefsDir + File.separator + "LTPDAworkbench.prefs");
    }
    readPreferences();
    setLocationRelativeTo(null);
    if (preferences.getGeneralPreferences().getMainWindowDimension() != null) {
      setSize(preferences.getGeneralPreferences().getMainWindowDimension());
      validate();
    }
    if (preferences.getGeneralPreferences().getMainWindowLocationOnScreen() != null) {
      setLocation(preferences.getGeneralPreferences().getMainWindowLocationOnScreen());
    }
    // create console and set window location and size from the preferences
    if (console == null) {
      console = new ConsoleDialog(this);
    }
    if (preferences.getGeneralPreferences().getConsoleDimension() != null) {
      console.setSize(preferences.getGeneralPreferences().getConsoleDimension());
      console.validate();
    }
    if (preferences.getGeneralPreferences().getConsoleLocationOnScreen() != null) {
      console.setLocation(preferences.getGeneralPreferences().getConsoleLocationOnScreen());
    }

    // setup autosave timer
    setupAutosave();

    // shelf file
    if (userPrefsDir.equals("")) {
      shelfFile = new File(System.getProperty("user.home") + File.separator + "LTPDAworkbench.shelf");
    } else {
      shelfFile = new File(userPrefsDir + File.separator + "LTPDAworkbench.shelf");
    }

    // Set up lots of things
    setupLibrary();
    setupParamTable();
    setupBlockPropertyTable();
    setupSetsPopup();
    setupMenus();
    setupToolbar();
    setupShelf();

    this.setTitle("Untitled");
    setSaved(false);

    // put a couple of windows in the windowTypes for getting things started
    windowTypes.add("Hanning");
    windowTypes.add("Kaiser");
    windowTypes.add("BH92");
    // .. later this is filled from MATLAB


    // put some units in place for testing
    units.add("m");
    units.add("V");
    units.add("N");
    unitPrefixes.add("m");
    unitPrefixes.add("k");
    unitPrefixes.add("u");

    buildPipelineList();

    refreshRecentFilesList();

    // switch menu context
    switchMenuFocus("none");

    // A the key binding Ctrl-1
    KeyStroke keyStroke1 = KeyStroke.getKeyStroke(KeyEvent.VK_1, keyModifier);
    rootPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(keyStroke1, "CTRL_1");
    rootPane.getActionMap().put("CTRL_1", new ActionCtrl_1());

    // A the key binding Ctrl-2
    KeyStroke keyStroke2 = KeyStroke.getKeyStroke(KeyEvent.VK_2, keyModifier);
    rootPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(keyStroke2, "CTRL_2");
    rootPane.getActionMap().put("CTRL_2", new ActionCtrl_2());

    // A the key binding Ctrl-3
    KeyStroke keyStroke3 = KeyStroke.getKeyStroke(KeyEvent.VK_3, keyModifier);
    rootPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(keyStroke3, "CTRL_3");
    rootPane.getActionMap().put("CTRL_3", new ActionCtrl_3());

    // A the key binding Ctrl-4
    KeyStroke keyStroke4 = KeyStroke.getKeyStroke(KeyEvent.VK_4, keyModifier);
    rootPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(keyStroke4, "CTRL_4");
    rootPane.getActionMap().put("CTRL_4", new ActionCtrl_4());

    // A the key binding Ctrl-5
    KeyStroke keyStroke5 = KeyStroke.getKeyStroke(KeyEvent.VK_5, keyModifier);
    rootPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(keyStroke5, "CTRL_5");
    rootPane.getActionMap().put("CTRL_5", new ActionCtrl_5());

    // A the key binding Ctrl-R
    KeyStroke keyStrokeR = KeyStroke.getKeyStroke(KeyEvent.VK_R, keyModifier);
    rootPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(keyStrokeR, "CTRL_R");
    rootPane.getActionMap().put("CTRL_R", new ActionCtrl_5());

    // A the key binding Shift-Ctrl-R
    KeyStroke keyStrokeSR = KeyStroke.getKeyStroke(KeyEvent.VK_R, keyModifier | InputEvent.SHIFT_DOWN_MASK);
    rootPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(keyStrokeSR, "CTRL_SR");
    rootPane.getActionMap().put("CTRL_SR", new ActionCtrl_Run());

    this.addMessage("Welcome to the LTPDA Workbench!");

    // If the LTPDA preferences doesn't exist then load them from a file
    String newPrefFile;
    if (userPrefsDir.equals("")) {
      newPrefFile = System.getProperty("user.home") + File.separator + "LTPDAworkbench.prefs2";
    } else {
      newPrefFile = userPrefsDir + File.separator + "LTPDAworkbench.prefs2";
    }
    if (ltpdaPreferences2 == null) {
      ltpdaPreferences2 = LTPDAPreferences.loadFromDisk(newPrefFile, version);
    }

    // Add a Observer to the preferences
    // This is necessary if a user make some changes to the verbose level in
    // the preferences GUI.
    ltpdaPreferences2.getDisplayPrefs().addObserver(this);

    plistTable.getModel().addTableModelListener((TableModelListener) parametersOverviewDialog.getParametersTable().getModel());
    parametersOverviewDialog.getParametersTable().getModel().addTableModelListener((TableModelListener) plistTable.getModel());
  }

  @Override
  public void update(Observable o, Object o1) {
    if (o instanceof DisplayPrefGroup) {
      DisplayPrefGroup displayPrefs = (DisplayPrefGroup) o;
      if (this != null && displayPrefs != null) {
        getVebosityCombo().setSelectedIndex(displayPrefs.getDisplayVerboseLevel() + 1);
      } else {
        System.err.println("Mainwindow is null");
      }
    }
  }

  private class ActionCtrl_1 extends AbstractAction {

    public void actionPerformed(ActionEvent e) {
      if (mainTabPanel.isEnabledAt(0)) {
        mainTabPanel.setSelectedComponent(pipelineTab);
      }
    }
  }

  private class ActionCtrl_2 extends AbstractAction {

    public void actionPerformed(ActionEvent e) {
      if (mainTabPanel.isEnabledAt(1)) {
        mainTabPanel.setSelectedComponent(libraryTab);
      }
    }
  }

  private class ActionCtrl_3 extends AbstractAction {

    public void actionPerformed(ActionEvent e) {
      if (mainTabPanel.isEnabledAt(2)) {
        mainTabPanel.setSelectedComponent(shelfTab);
      }
    }
  }

  private class ActionCtrl_4 extends AbstractAction {

    public void actionPerformed(ActionEvent e) {
      if (mainTabPanel.isEnabledAt(3)) {
        mainTabPanel.setSelectedComponent(paramsTab);
      }
    }
  }

  private class ActionCtrl_5 extends AbstractAction {

    public void actionPerformed(ActionEvent e) {
      if (mainTabPanel.isEnabledAt(4)) {
        mainTabPanel.setSelectedComponent(controlsTab);
      }
    }
  }

  private class ActionCtrl_Run extends AbstractAction {

    public void actionPerformed(ActionEvent e) {
      if (mainTabPanel.isEnabledAt(4)) {
        mainTabPanel.setSelectedComponent(controlsTab);
        RunBtn.doClick();
      }
    }
  }

  private void addRecentFile(File f) {
    addMessage("Adding recent file: " + f.getAbsolutePath());
    preferences.addRecentFile(f);
    refreshRecentFilesList();
  }

  private void autosave() {

    if (this.isVisible()) {
      if (getTitle().startsWith("Untitled") || workbenchFilePath == null) { // save as
        addWarning("skipping autosave; this workbench was never saved.");
      } else {
        try {
          String autosaveFile = Utils.removeFileExtension(workbenchFilePath.getAbsolutePath()) + "." + workbenchFileExtension + preferences.getGeneralPreferences().getAutosaveExtension();
          //System.out.println("Autosaving to " + autosaveFile);
          XMLUtils.serializeXML(this.toXMLdom(true, getTitle()), new File(autosaveFile));
          if (preferences.getGeneralPreferences().getAutosaveExtension().length() == 0) {
            setSaved(true);
          }
        } catch (Exception ex) {
          String msg = "Error in autosaving: " + ex.getMessage();
          System.err.println(msg);
          addError(msg);
        }
      }
    }
  }

  public void setupAutosave() {

    int interval = preferences.getGeneralPreferences().getAutosaveInterval();

//    System.out.println("autosave interval is " + interval);

    ActionListener taskPerformer = new ActionListener() {

      public void actionPerformed(ActionEvent evt) {
        //...Perform a task...
        addMessage("Autosaving.");
        autosave();
      }
    };

    if (autosaveTimer == null) {
      autosaveTimer = new Timer(interval * 1000, taskPerformer);
    }
    autosaveTimer.setRepeats(true);
    autosaveTimer.setDelay(interval * 1000);

    if (preferences.getGeneralPreferences().isAutosaveActive()) {
      autosaveTimer.start();
    } else {
      autosaveTimer.stop();
    }
  }

  private void readPreferences() {

    Utils.msg("Reading preferences: " + prefFile.getAbsolutePath());

    if (prefFile.exists()) {
      try {
        DocumentBuilderFactory parserFactory = DocumentBuilderFactory.newInstance();
        parserFactory.setValidating(false);
        DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
        try {
          Document doc = db.parse(prefFile);

          Element root = doc.getDocumentElement();
          preferences = new LWBpreferences(root, version);

          // set recent file list
          refreshRecentFilesList();

        } catch (SAXException ex) {
          Logger.getLogger(PreferencesDialog.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
          Logger.getLogger(PreferencesDialog.class.getName()).log(Level.SEVERE, null, ex);
        }
      } catch (ParserConfigurationException ex) {
        Logger.getLogger(PreferencesDialog.class.getName()).log(Level.SEVERE, null, ex);
      }
    } else {
      System.err.println("Preference file not found: " + prefFile);
    }
  }

  private void writePreferences() {

    if (prefFile != null) {
      try {

        preferences.getGeneralPreferences().setMainWindowDimension(getSize());
        if (isShowing()) {
          preferences.getGeneralPreferences().setMainWindowLocationOnScreen(getLocationOnScreen());
        } else {
          preferences.getGeneralPreferences().setMainWindowLocationOnScreen(getLocation());
        }
        if (console != null) {
          preferences.getGeneralPreferences().setConsoleDimension(console.getSize());
          if (console.isShowing()) {
            preferences.getGeneralPreferences().setConsoleLocationOnScreen(console.getLocationOnScreen());
          } else {
            preferences.getGeneralPreferences().setConsoleLocationOnScreen(console.getLocation());
          }
        }

        Document doc = XMLUtils.createDocument("LTPDAworkbenchPreferences");
        Element root = doc.getDocumentElement();
        root.setAttribute("version", "" + version);
        preferences.attachToDom(doc, root);
        XMLUtils.serializeXML(doc, prefFile);

      } catch (Exception ex) {
        Logger.getLogger(PreferencesDialog.class.getName()).log(Level.SEVERE, null, ex);
      }
    }
  }

  /**
   *
   */
  public void refreshRecentFilesList() {

    // read recent file list from the prefs and display it here

    recentFilesMenu.removeAll();
    ArrayList<File> rfiles = preferences.getRecentFiles().getFiles();
    for (int kk = rfiles.size() - 1; kk >= 0; kk--) {
      final File f = rfiles.get(kk);
//      Utils.msg("adding: " + f.getAbsolutePath());
      JMenuItem wi = new JMenuItem(f.getName());
      wi.setToolTipText(f.getAbsolutePath());
      wi.addActionListener(new java.awt.event.ActionListener() {

        public void actionPerformed(java.awt.event.ActionEvent evt) {

          if (workbenchFilePath != null) {
            Utils.msg("MyFilePath: " + workbenchFilePath.getAbsolutePath());
          }
          Utils.msg("loading: " + f.getAbsolutePath());


          // check if any of the loaded pipelines come from that file
          boolean alreadyLoaded = false;
          Iterator it = documents.iterator();
          while (it.hasNext()) {
            BlockDiagram bd = (BlockDiagram) it.next();
            File bdf = bd.getFilepath();
            if (bdf != null) {
              if (f.getAbsoluteFile().equals(bdf.getAbsoluteFile())) {
                alreadyLoaded = true;
                break;
              }
            }
          }
          // only load if this document is not already loaded
          if (alreadyLoaded) {
            JOptionPane.showMessageDialog(null,
                    "At least one of the loaded pipelines comes from the same file.",
                    "Load error",
                    JOptionPane.ERROR_MESSAGE);
          } else {

            // load this file again
            Utils.msg("Loading: " + f.getAbsolutePath());
            try {
              loadFromXML(f.getAbsolutePath());
            } catch (ParserConfigurationException ex) {
              Logger.getLogger(MainWindow.class.getName()).log(Level.SEVERE, null, ex);
            } catch (SAXException ex) {
              Logger.getLogger(MainWindow.class.getName()).log(Level.SEVERE, null, ex);
            } catch (IOException ex) {
              Logger.getLogger(MainWindow.class.getName()).log(Level.SEVERE, null, ex);
            }
          }
        }
      });
      recentFilesMenu.add(wi);
    }

  }

  /**
   *
   * @param fpath
   */
  public void setWorkingDir(String fpath) {

    Utils.msg("Setting working dir: " + fpath);
    lastSavePath = new File(fpath, "");
    lastLoadPath = new File(fpath, "");
    Utils.msg("   set last save path to: " + lastSavePath.getAbsolutePath());
    Utils.msg("   set last load path to: " + lastLoadPath.getAbsolutePath());

  }

  /**
   * Record a change of state of the workbench.
   * @param msg
   */
  public void stateChanged(String msg) {

    if (this.isVisible()) {
      if (parametersOverviewDialog == null) {
        parametersOverviewDialog = new ParametersOverviewDialog(this);
      }
      parametersOverviewDialog.reloadParameters();
    }

    Utils.dmsg("*** Workbench state changed: " + msg);
    // save the canvas
    setSaved(false);

  }

  /**
   * Undo a change of state.
   */
  public void undo() {

    BlockDiagram diag = (BlockDiagram) DocumentPane.getSelectedFrame();
    if (diag != null) {
      MCanvas c = diag.getCanvas();
      if (c != null) {
        UndoManager m = c.getManager();
        Utils.dmsg("Trying to undo...");
        try {
          c.manager.undo();
        } catch (CannotUndoException e) {
          Toolkit.getDefaultToolkit().beep();
        }
      }
    }
  }

  /**
   * Redo a state change.
   */
  public void redo() {

    BlockDiagram diag = (BlockDiagram) DocumentPane.getSelectedFrame();
    if (diag != null) {
      MCanvas c = diag.getCanvas();
      if (c != null) {
        Utils.dmsg("Trying to redo...");
        try {
          c.manager.redo();
        } catch (CannotRedoException e) {
          Toolkit.getDefaultToolkit().beep();
        }
      }
    }
  }

  /**
   * Delete the given diagram.
   * @param diag
   */
  public void deleteDiagram(BlockDiagram diag) {
    if (diag != null) {
      Utils.dmsg("Deleting diagram: " + diag.getTitle());

      // what's the index of this document?
      int index = documents.indexOf(diag);

      Utils.dmsg("document index: " + index);

      documents.remove(diag);
      diag.dispose();
      DocumentPane.remove(diag);
      setSaved(false);
      // remove the document from the execution plan
      execPlan.removeStep(diag);

      // make the next document active
      if (index >= 1) {
        index--;
      } else {
        index = 0;
      }

      Utils.dmsg("document list size: " + documents.size());
      if (index < documents.size() && index >= 0) {
        diag = documents.get(index);
        try {
          diag.setIcon(false);
        } catch (PropertyVetoException ex) {
          Logger.getLogger(MainWindow.class.getName()).log(Level.SEVERE, null, ex);
        }
        diag.requestFocusInWindow();
        Utils.dmsg("Trying to select document window.");
        try {
          diag.setSelected(true);
          diag.revalidate();
          DocumentPane.revalidate();
          Utils.dmsg("Revalidating document pane");
        } catch (PropertyVetoException ex) {
          Utils.dmsg(" ... failed");
          Logger.getLogger(MainWindow.class.getName()).log(Level.SEVERE, null, ex);
        }
      }
      this.repaint();

      // rebuild pipeline tree
      buildPipelineList();

      if (documents.isEmpty()) {
        // then try to switch to any remaining text document that's open
        JInternalFrame[] frames = DocumentPane.getAllFrames();
        if (frames.length > 0) {
          DocumentPane.setSelectedFrame(frames[frames.length - 1]);
          switchMenuFocus("document");
        } else {
          switchMenuFocus("none");
        }
      }

    }
    activatePipelineTabButtons();
  }

  /**
   *
   * @param oldCanvas
   */
  public void deleteOrphanedDocumentViews(MCanvas oldCanvas) {
    Iterator it = documents.iterator();
    while (it.hasNext()) {
      BlockDiagram diag = (BlockDiagram) it.next();
      if (diag.isSubsystem()) {
        MCanvas c = diag.getCanvas();
        if (c.equals(oldCanvas)) {
          deleteDiagram(diag);
        }
      }
    }
  }

  /**
   * Return the saved state of the main window.
   * @return
   */
  public boolean isSaved() {
    return saved;
  }

  /**
   * Set the saved state of the workbench.
   * @param saved
   */
  public void setSaved(boolean saved) {

    if (this.saved && !saved) { // go from saved to not saved
      setTitle(getTitle() + "*");
    } else if (!this.saved && saved) { // go from not saved to saved
      String title = getTitle();
      if (title.charAt(title.length() - 1) == '*') {
        setTitle(title.substring(0, title.length() - 1));
      } else {
        setTitle(title.substring(0, title.length()));
      }
    } else if (!this.saved && !saved) {
      // make sure there is a * on the end
      if (getTitle().charAt(getTitle().length() - 1) != '*') {
        setTitle(getTitle() + "*");
      }
    }
    this.saved = saved;

    if (saved) {
      saveWorkbenchTBB.setEnabled(false);
    } else {
      saveWorkbenchTBB.setEnabled(true);
    }

  }

  /**
   * Return the sets combo box
   * @return
   */
  public JComboBox getSetsCombo() {
    return setCombo;
  }

  /**
   * Return the block property table
   * @return
   */
  public JTable getBlockPropertyTabel() {
    return BlockPropertyTable;
  }

  /**
   *
   * @param aThis
   * @return
   */
  public int getDiagramNumber(BlockDiagram aThis) {
    return documents.indexOf(aThis);
  }

  /**
   * Setup the toolbar action listeners
   */
  private void setupToolbar() {
    /** New pipeline **/
    newPipelineTBB.addActionListener(new ActionListener() {

      public void actionPerformed(java.awt.event.ActionEvent evt) {
        newDocument();
      }
    });

    /** save workbench **/
    saveWorkbenchTBB.addActionListener(new ActionListener() {

      public void actionPerformed(ActionEvent evt) {
        try {
          if (saveWorkbench()) {
            lastSavePath = workbenchFilePath;
          }
        } catch (Exception ex) {
          Logger.getLogger(MainWindow.class.getName()).log(Level.SEVERE, null, ex);
        }
      }
    });

    /** save workbench as **/
    saveWorkbenchAsTBB.addActionListener(new ActionListener() {

      public void actionPerformed(ActionEvent evt) {
        try {
          if (saveWorkbenchAs(true)) {
            lastSavePath = workbenchFilePath;
          }
        } catch (Exception ex) {
          Logger.getLogger(MainWindow.class.getName()).log(Level.SEVERE, null, ex);
        }
      }
    });

    /** import workbench **/
    importTBB.addActionListener(new ActionListener() {

      public void actionPerformed(ActionEvent evt) {
        try {
          boolean success = loadCanvases();
          if (success) {
            lastLoadPath = workbenchFilePath;
          }
        } catch (FileNotFoundException ex) {
          Logger.getLogger(MainWindow.class.getName()).log(Level.SEVERE, null, ex);
        } catch (ParserConfigurationException ex) {
          Logger.getLogger(MainWindow.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SAXException ex) {
          Logger.getLogger(MainWindow.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
          Logger.getLogger(MainWindow.class.getName()).log(Level.SEVERE, null, ex);
        }
      }
    });

    /** copy **/
    copyTBB.addActionListener(new ActionListener() {

      public void actionPerformed(ActionEvent evt) {
        try {
          BlockDiagram d = (BlockDiagram) DocumentPane.getSelectedFrame();
          if (d != null) {
            MCanvas c = d.getCanvas();
            c.copyElementsToClipBoard();
          }
        } catch (ClassCastException e) {
        }

        try {
          MTextDocument td = (MTextDocument) DocumentPane.getSelectedFrame();
          if (td != null) {
            td.getTextArea().copy();
          }
        } catch (ClassCastException e) {
        }
      }
    });

    /** paste **/
    pasteTBB.addActionListener(new ActionListener() {

      public void actionPerformed(ActionEvent evt) {

        try {
          BlockDiagram d = (BlockDiagram) DocumentPane.getSelectedFrame();
          if (d != null) {
            MCanvas c = d.getCanvas();
            boolean res = c.pasteElementsFromClipBoard(120, 120, true);
          }
        } catch (ClassCastException e) {
        }

        try {
          MTextDocument td = (MTextDocument) DocumentPane.getSelectedFrame();
          if (td != null) {
            td.getTextArea().paste();
          }
        } catch (ClassCastException e) {
        }
      }
    });

    /** undo **/
    undoTBB.addActionListener(new ActionListener() {

      public void actionPerformed(ActionEvent evt) {
        undo();
      }
    });

    /** redo **/
    redoTBB.addActionListener(new ActionListener() {

      public void actionPerformed(ActionEvent evt) {
        redo();
      }
    });

    /** delete selected **/
    deleteSelectedTBB.addActionListener(new ActionListener() {

      public void actionPerformed(ActionEvent evt) {
        BlockDiagram d = (BlockDiagram) DocumentPane.getSelectedFrame();
        if (d != null) {
          MCanvas c = d.getCanvas();
          if (c != null) {
            // Don't register the "delete" action to the undo manager if the selected element is empty.
            if (c.getSelectedElements().isEmpty() && c.getSelectedPipes().isEmpty()) {
              return;
            }
            c.postDeleteEvent(c.getSelectedElements(), c.getSelectedPipes());
            c.deleteSelectedElements();
            c.clearSelection();
          }
        }
      }
    });

    /** zoom in **/
    zoomInTBB.addActionListener(new ActionListener() {

      public void actionPerformed(ActionEvent evt) {
        BlockDiagram d = (BlockDiagram) DocumentPane.getSelectedFrame();
        if (d != null) {
          MCanvas c = d.getCanvas();
          if (c != null) {
            c.zoomIn();
          }
        }
      }
    });

    /** zoom out **/
    zoomOutTBB.addActionListener(new ActionListener() {

      public void actionPerformed(ActionEvent evt) {
        BlockDiagram d = (BlockDiagram) DocumentPane.getSelectedFrame();
        if (d != null) {
          MCanvas c = d.getCanvas();
          if (c != null) {
            c.zoomOut();
          }
        }
      }
    });


    /** block search **/
    searchTBB.addActionListener(new ActionListener() {

      public void actionPerformed(ActionEvent evt) {
        showSearchDialog();
      }
    });

    /** block help **/
    helpTBB.addActionListener(new ActionListener() {

      public void actionPerformed(ActionEvent evt) {
        BlockDiagram d = (BlockDiagram) DocumentPane.getSelectedFrame();
        if (d != null) {
          MCanvas c = d.getCanvas();
          if (c != null) {
            ArrayList<MBlock> blocks = c.getSelectedBlocks();
            if (!blocks.isEmpty()) {
              MBlock b = blocks.get(0);
              b.help();
            }
          }
        }
      }
    });

    /** block info **/
    infoTBB.addActionListener(new ActionListener() {

      public void actionPerformed(ActionEvent evt) {

        // get selected blocks and choose which dialog to show
        showInfoDialogsForSelected();
      }
    });


    /** move left **/
    leftTBB.addActionListener(new ActionListener() {

      public void actionPerformed(ActionEvent evt) {
        BlockDiagram d = (BlockDiagram) DocumentPane.getSelectedFrame();
        if (d != null) {
          MCanvas c = d.getCanvas();
          if (c != null) {
            c.recordStartPoints();
            c.moveSelectedLeft();
            c.recordEndPoints();
            c.postMoveEvent();
          }
        }
      }
    });

    /** move right **/
    rightTBB.addActionListener(new ActionListener() {

      public void actionPerformed(ActionEvent evt) {
        BlockDiagram d = (BlockDiagram) DocumentPane.getSelectedFrame();
        if (d != null) {
          MCanvas c = d.getCanvas();
          if (c != null) {
            c.recordStartPoints();
            c.moveSelectedRight();
            c.recordEndPoints();
            c.postMoveEvent();
          }
        }
      }
    });

    /** move up **/
    upTBB.addActionListener(new ActionListener() {

      public void actionPerformed(ActionEvent evt) {
        BlockDiagram d = (BlockDiagram) DocumentPane.getSelectedFrame();
        if (d != null) {
          MCanvas c = d.getCanvas();
          if (c != null) {
            c.recordStartPoints();
            c.moveSelectedUp();
            c.recordEndPoints();
            c.postMoveEvent();
          }
        }
      }
    });

    /** move down **/
    downTBB.addActionListener(new ActionListener() {

      public void actionPerformed(ActionEvent evt) {
        BlockDiagram d = (BlockDiagram) DocumentPane.getSelectedFrame();
        if (d != null) {
          MCanvas c = d.getCanvas();
          if (c != null) {
            c.recordStartPoints();
            c.moveSelectedDown();
            c.recordEndPoints();
            c.postMoveEvent();
          }
        }
      }
    });
  }

  private void showInfoDialogsForSelected() {

    MCanvas c = getActiveCanvas();
    ArrayList<MElementSelectable> els = c.getSelectedElements();

    boolean openWindows = true;
    if (els.size() > 10) {
      int response = JOptionPane.showConfirmDialog(this, "More than 10 windows will be opened; are you sure you want to do this?", "Potentially many windows", JOptionPane.WARNING_MESSAGE);
      if (response != JOptionPane.OK_OPTION) {
        openWindows = false;
      }
    }
    if (openWindows) {
      Iterator it = els.iterator();
      while (it.hasNext()) {
        MElementSelectable el = (MElementSelectable) it.next();
        if (el instanceof MBlock) {
          MBlock b = (MBlock) el;
          MBlockInfoDialog id = new MBlockInfoDialog(this, false, b);
          id.setVisible(true);
        }
      }
    }
  }

  private void showSearchDialog() {

    ElementSearchDialog es = new ElementSearchDialog(this, false, this);
    es.setVisible(true);
  }

  /**
   *
   */
  public void applyPreferences() {

    // loop over all documents and apply preferences
    Iterator it = documents.iterator();
    while (it.hasNext()) {
      BlockDiagram diag = (BlockDiagram) it.next();
      diag.applyPreferences();
    }

    // update autosave timer
    setupAutosave();

    this.applyLTPDApreferences();
  }

  public void applyLTPDApreferences() {

    System.out.println("Applying prefs!!!");
    this.firePropertyChange("preferencesApplied", preferencesApplied, !preferencesApplied);
  }

  private void openPreferencesDialog() {
    if (prefsDialog == null) {
      prefsDialog = new PreferencesDialog(this, true, ltpdaPreferences2, version);
    }
    prefsDialog.setPreferences(preferences);
    prefsDialog.refreshPreferencesView();
    prefsDialog.setVisible(true);

    if (!prefsDialog.isCancelled()) {
      Utils.msg("Setting preferences.");
      preferences = prefsDialog.getPreferences();
      applyPreferences();
    }
  }

  /**
   *
   */
  public void updateProgressOfCurrentDiagram() {

    BlockDiagram diag = (BlockDiagram) DocumentPane.getSelectedFrame();
    if (diag != null) {
      if (diag.isSubsystem()) {
        diag = diag.getTopLevelDiagram();
      }
      diag.updateProgress();
    }
  }

  /**
   *
   * @param ext
   * @param filename
   * @return
   */
  public File getFileToLoad(String[] ext, String filename) {

    Utils.dmsg("Getting file to load...");
    File f = null;

    final String[] lext = ext;

    if (isMacOSX) {
      Utils.dmsg("   ... with OS X file dialog");
      System.setProperty("apple.awt.fileDialogForDirectories", "false");
      FileDialog chooser = new FileDialog(this);

      chooser.setMode(FileDialog.LOAD);
//            System.err.println("Last load path: " + lastLoadPath.getAbsolutePath());
//            System.err.println("Input filename: " + filename);

      if (lastLoadPath != null && filename == null) {
//                Utils.msg("Setting file path from last load: " + lastLoadPath.getAbsolutePath());
        chooser.setDirectory(lastLoadPath.getAbsolutePath());
      }
      chooser.setFilenameFilter(new FilenameFilter() {

        public boolean accept(File dir, String name) {
          for (int kk = 0; kk < lext.length; kk++) {
            if (name.endsWith(lext[kk])) {
              return true;
            }
          }
          return false;
        }
      });

      if (filename != null) {
//                Utils.msg("Setting file path: " + filename);
        File nf = new File(filename);
        chooser.setDirectory(Utils.removeFileName(filename));
        chooser.setFile(nf.getName());
      }
      chooser.setVisible(true);
      String selecteddir = chooser.getDirectory();
      String selectedFile = chooser.getFile();
      if (selectedFile != null) {
        f = new File(selecteddir + File.separator + selectedFile);
      }
    } else {
      JFileChooser chooser = new JFileChooser("Load...");

      chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
      chooser.setMultiSelectionEnabled(false);
      if (filename != null) {
        chooser.setSelectedFile(new File(filename));
      } else {
        chooser.setCurrentDirectory(lastLoadPath);
      }
      chooser.setFileFilter(new FileFilter() {

        @Override
        public boolean accept(File f) {
          if (f.isDirectory()) {
            return true;
          }
          for (int kk = 0; kk < lext.length; kk++) {
            if (f.getAbsolutePath().endsWith(lext[kk])) {
              return true;
            }
          }
          return false;
        }

        @Override
        public String getDescription() {
          String s = "";
          for (int kk = 0; kk < lext.length; kk++) {
            s += "*." + lext[kk] + ",";
          }
          if (s.length() == 0) {
            return s;
          }

          return s.substring(0, s.length() - 1);
        }
      });
      int retVal = chooser.showOpenDialog(this);
      if (retVal == JFileChooser.APPROVE_OPTION) {

        f = chooser.getSelectedFile();
      }
    }

    if (f != null) {
      if (Utils.getExtension(f) == null && lext.length > 0 && !lext[0].equals("")) {
        f = new File(f.getAbsolutePath() + "." + lext[0]);
      }
    }

    return f;
  }

  /**
   *
   * @param ext
   * @param filename
   * @return
   */
  public File getDirectory(String directory) {

    Utils.dmsg("Getting directory ...");
    File f = null;

    if (isMacOSX) {
      Utils.dmsg("   ... with OS X file dialog");
      System.setProperty("apple.awt.fileDialogForDirectories", "true");
      FileDialog chooser = new FileDialog(this);

      chooser.setMode(FileDialog.LOAD);

      if (directory != null) {
//                Utils.msg("Setting file path from last load: " + lastLoadPath.getAbsolutePath());
        chooser.setDirectory(directory);
      }
      chooser.setVisible(true);
      String selecteddir = chooser.getDirectory();
      String selectedFile = chooser.getFile();
      if (selectedFile != null) {
        f = new File(selecteddir + File.separator + selectedFile);
      }
    } else {
      JFileChooser chooser = new JFileChooser("Load...");

      chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
      chooser.setMultiSelectionEnabled(false);
      chooser.setCurrentDirectory(new File(directory));
      int retVal = chooser.showOpenDialog(this);
      if (retVal == JFileChooser.APPROVE_OPTION) {
        f = chooser.getSelectedFile();
      }
    }


    return f;
  }

  /**
   *
   * @param ext
   * @param filename
   * @return
   */
  public File getFileToSave(String[] ext, String filename) {

    Utils.dmsg("Getting file to save...");

    File f = null;

    final String[] lext = ext;

    if (isMacOSX) {
      Utils.dmsg("   ... with OS X file dialog");
      System.setProperty("apple.awt.fileDialogForDirectories", "false");
      FileDialog chooser = new FileDialog(this);

      chooser.setMode(FileDialog.SAVE);
      if (lastSavePath != null && filename == null) {
        chooser.setDirectory(lastSavePath.getAbsolutePath());
      }
      chooser.setFilenameFilter(new FilenameFilter() {

        public boolean accept(File dir, String name) {
          for (int kk = 0; kk < lext.length; kk++) {
            String cext = lext[kk];
            if (cext.startsWith(".")) {
              cext = cext.substring(1);
            }
            if (name.endsWith(cext)) {
              return true;
            }
          }
          return false;
        }
      });

      if (filename != null) {
        File nf = new File(filename);
        chooser.setDirectory(Utils.removeFileName(filename));
        chooser.setFile(nf.getName());
      }
      chooser.setVisible(true);
      String selecteddir = chooser.getDirectory();
      String selectedFile = chooser.getFile();

      if (selectedFile != null) {
        f = new File(selecteddir + File.separator + selectedFile);
      }
    } else {
      JFileChooser chooser = new JFileChooser("Save as...");

      chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
      chooser.setMultiSelectionEnabled(false);
      if (filename != null) {
        chooser.setSelectedFile(new File(filename));
      } else {
        chooser.setCurrentDirectory(lastSavePath);
      }
      chooser.setFileFilter(new FileFilter() {

        @Override
        public boolean accept(File f) {
          if (f.isDirectory()) {
            return true;
          }
          for (int kk = 0; kk < lext.length; kk++) {
            if (f.getAbsolutePath().endsWith(lext[kk])) {
              return true;
            }
          }
          return false;
        }

        @Override
        public String getDescription() {
          String s = "";
          for (int kk = 0; kk < lext.length; kk++) {
            s += "*." + lext[kk] + ",";
          }
          if (s.length() == 0) {
            return s;
          }

          return s.substring(0, s.length() - 1);
        }
      });
      int retVal = chooser.showSaveDialog(this);
      if (retVal == JFileChooser.APPROVE_OPTION) {
        f = chooser.getSelectedFile();
      }
    }


    if (f != null) {
      if (Utils.getExtension(f) == null && lext.length > 0) {
        f = new File(f.getAbsolutePath() + "." + lext[0]);
      }
      Utils.dmsg(" ... got: " + f.getAbsolutePath());
    }


    return f;
  }

  /**
   *
   * @param lines
   * @return
   */
  public ArrayList<String> readCommands(ArrayList<String> lines) {

    ArrayList<String> commands = new ArrayList<String>();

    Iterator it = lines.iterator();
    while (it.hasNext()) {
      String line = (String) it.next();
      line = line.trim();
      if (!line.startsWith("%") && line.length() > 0 && !line.equals(" ")) {
        String nextLine = null;
        while (line.endsWith("...")) {
          line = line.substring(0, line.length() - 3);
          nextLine = (String) it.next();
          line += nextLine.trim();
        }

        // then we may have a command, but we should split at ;
        String[] cmds = line.split(";");


        for (int kk = 0; kk < cmds.length; kk++) {
          commands.add(cmds[kk].trim());
        }
      }
    }


    return commands;
  }

  /**
   *
   * @param filename
   * @return
   * @throws Exception
   */
  public ArrayList<String> readLines(String filename) throws Exception {
    FileReader fr = new FileReader(filename);
    BufferedReader br = new BufferedReader(fr);
    ArrayList<String> lines = new ArrayList<String>();
    String s;
    while ((s = br.readLine()) != null) {
      lines.add(s);
    }
    fr.close();
    return lines;
  }

  private void buildPipelineFromMfile() {
    // get file name from user
    String[] exts = {".m"};
    File f = getFileToLoad(exts, null);
    if (f != null) {
      try {
        // read lines
        ArrayList<String> lines = readLines(f.getAbsolutePath());

        // parse commands
        ArrayList<String> commands = readCommands(lines);
        ArrayList<Command> commandObjs = new ArrayList<Command>();
        Iterator it = commands.iterator();
        while (it.hasNext()) {
          String cmd = (String) it.next();

          Command c = new Command(cmd);
          c.display();

          commandObjs.add(c);

        }

        // build pipeline from the commands
        BlockDiagram newDiag = new BlockDiagram(this, commandObjs);
        documents.add(newDiag);
        DocumentPane.add(newDiag);
        newDiag.setLocation(10 * documents.size(), 10 * documents.size());
        DocumentPane.setComponentZOrder(newDiag, 0);
        newDiag.requestFocusInWindow();
        try {
          newDiag.setSelected(true);
          newDiag.maximise(true);
        } catch (PropertyVetoException ex) {
          Logger.getLogger(MainWindow.class.getName()).log(Level.SEVERE, null, ex);
        }

//        System.out.println("  now have " + documents.size() + " documents");
//        dit = documents.iterator();
//        while (dit.hasNext()) {
//            BlockDiagram d = (BlockDiagram) dit.next();
//            System.out.println("  diagram: " + d.getTitle());
//        }

        setSaved(false);
        stateChanged("New Document");

        buildPipelineList();

        // parse out commands
      } catch (Exception ex) {
        Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
      }
    }
  }

  private void showPlanEditDialog() {

    execPlanView.setup(documents, execPlan);
    execPlanView.setVisible(true);

  }

  /**
   * Set up the menus
   */
  private void setupMenus() {

    /** ------ File ------ */
    /** Save Workbench **/
    WBSaveMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, keyModifier));
    WBSaveMenuItem.setText("Save Workbench");
    WBSaveMenuItem.addActionListener(new ActionListener() {

      public void actionPerformed(ActionEvent evt) {
        try {
          if (saveWorkbench()) {
            lastSavePath = workbenchFilePath;
          }
        } catch (Exception ex) {
          Logger.getLogger(MainWindow.class.getName()).log(Level.SEVERE, null, ex);
        }
      }
    });
    MainMenuFile.add(WBSaveMenuItem);

    /** SaveAs Workbench **/
    WBSaveAsMenuItem.setText("Save Workbench As...");
    WBSaveAsMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, keyModifier | InputEvent.SHIFT_DOWN_MASK));
    WBSaveAsMenuItem.addActionListener(new ActionListener() {

      public void actionPerformed(ActionEvent evt) {
        try {
          if (saveWorkbenchAs(true)) {
            lastSavePath = workbenchFilePath;
          }
        } catch (Exception ex) {
          Logger.getLogger(MainWindow.class.getName()).log(Level.SEVERE, null, ex);
        }
      }
    });
    MainMenuFile.add(WBSaveAsMenuItem);


    /** Load Workbench **/
    WBLoadMenuItem.setText("Load Workbench...");
    WBLoadMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, keyModifier));
    WBLoadMenuItem.addActionListener(new ActionListener() {

      public void actionPerformed(ActionEvent evt) {
        try {
          loadWorkbench();
        } catch (Exception ex) {
          Logger.getLogger(MainWindow.class.getName()).log(Level.SEVERE, null, ex);
        }
      }
    });
    MainMenuFile.add(WBLoadMenuItem);






    // seperator
    MainMenuFile.add(new JSeparator());

    /** Open Workbench **/
    JMenu om = new JMenu("Import pipelines");

    // from file
    WBOpenMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, keyModifier | InputEvent.SHIFT_DOWN_MASK));
    WBOpenMenuItem.setText("From Workbench file...");
    WBOpenMenuItem.addActionListener(new ActionListener() {

      public void actionPerformed(ActionEvent evt) {
        try {
          boolean success = loadCanvases();
          if (success) {
            lastLoadPath = workbenchFilePath;
          }
        } catch (FileNotFoundException ex) {
          Logger.getLogger(MainWindow.class.getName()).log(Level.SEVERE, null, ex);
        } catch (ParserConfigurationException ex) {
          Logger.getLogger(MainWindow.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SAXException ex) {
          Logger.getLogger(MainWindow.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
          Logger.getLogger(MainWindow.class.getName()).log(Level.SEVERE, null, ex);
        }
      }
    });
    om.add(WBOpenMenuItem);

    // from object
    WBOpenFromObjectMenuItem.setText("From LTPDA object...");
    // the callback is done in MATLAB
    om.add(WBOpenFromObjectMenuItem);

    MainMenuFile.add(om);

    /** Recent files menu **/
    MainMenuFile.add(recentFilesMenu);

    /** Import from M-file **/
    ImportFromMfileMenuItem.setText("Import from M-file...");
    ImportFromMfileMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_M, keyModifier));
    ImportFromMfileMenuItem.addActionListener(new ActionListener() {

      public void actionPerformed(ActionEvent evt) {
//                buildPipelineFromMfile();
      }
    });
//        MainMenuFile.add(ImportFromMfileMenuItem);

    /** Import from workspace **/
    ImportFromWorkspaceMenuItem.setText("Import from Workspace...");
//        MainMenuFile.add(ImportFromWorkspaceMenuItem);

    // seperator
    MainMenuFile.add(new JSeparator());

    planEditMenuItem.addActionListener(new ActionListener() {

      public void actionPerformed(ActionEvent evt) {
        showPlanEditDialog();
      }
    });

    PlanMenu.add(planEditMenuItem);
    PlanMenu.add(planRunMenuItem);

    MainMenuFile.add(PlanMenu);


    newTextDocMenuItem.addActionListener(new ActionListener() {

      public void actionPerformed(ActionEvent e) {
        newTextDocument();
      }
    });
    MainMenuFile.add(newTextDocMenuItem);

    // seperator
    MainMenuFile.add(new JSeparator());

    /** Close workbench **/
    WBCloseMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_W, keyModifier));
    WBCloseMenuItem.setText("Close Workbench");
    WBCloseMenuItem.addActionListener(new ActionListener() {

      public void actionPerformed(ActionEvent evt) {
        handleWindowClosing();
      }
    });
    MainMenuFile.add(WBCloseMenuItem);

    // seperator
    MainMenuFile.add(new JSeparator());

    resetWorkbench.setText("Reset workbench");
    resetWorkbench.setToolTipText("Closes all pipelines and resets to an empty workbench file.");
    resetWorkbench.addActionListener(new java.awt.event.ActionListener() {

      public void actionPerformed(java.awt.event.ActionEvent evt) {
        // are we sure we want to close?
        int n = JOptionPane.showConfirmDialog(null,
                "<html><b>Are you sure you want to reset the workbench?</b><br>"
                + "All pipelines will be closed and the workbench filename<br>will be "
                + "reset.</html>",
                "Confirm", JOptionPane.YES_NO_OPTION);

        if (n == JOptionPane.YES_OPTION) {
          resetWorkbench();
        }
      }
    });
    MainMenuFile.add(resetWorkbench);

    // seperator
    MainMenuFile.add(new JSeparator());

    preferencesMenuItem.setText("Preferences...");
    preferencesMenuItem.addActionListener(new java.awt.event.ActionListener() {

      public void actionPerformed(java.awt.event.ActionEvent evt) {
        openPreferencesDialog();
      }
    });
    MainMenuFile.add(preferencesMenuItem);


    /** ------ Edit ------ */
    /** Copy Selected **/
    CopyMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, keyModifier));
    CopyMenuItem.setText("Copy");
    CopyMenuItem.addActionListener(new ActionListener() {

      public void actionPerformed(ActionEvent evt) {
        try {
          BlockDiagram d = (BlockDiagram) DocumentPane.getSelectedFrame();
          if (d != null) {
            MCanvas c = d.getCanvas();
            c.copyElementsToClipBoard();
          }
        } catch (ClassCastException e) {
        }

        try {
          MTextDocument td = (MTextDocument) DocumentPane.getSelectedFrame();
          if (td != null) {
            td.getTextArea().copy();
          }
        } catch (ClassCastException e) {
        }

      }
    });
    MainMenuEdit.add(CopyMenuItem);

    /** Paste **/
    PasteMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_V, keyModifier));
    PasteMenuItem.setText("Paste");
    PasteMenuItem.addActionListener(new ActionListener() {

      public void actionPerformed(ActionEvent evt) {
        try {
          BlockDiagram d = (BlockDiagram) DocumentPane.getSelectedFrame();
          if (d != null) {
            MCanvas c = d.getCanvas();
            boolean res = c.pasteElementsFromClipBoard(120, 120, true);
          }
        } catch (ClassCastException e) {
        }

        try {
          MTextDocument td = (MTextDocument) DocumentPane.getSelectedFrame();
          if (td != null) {
            td.getTextArea().paste();
          }
        } catch (ClassCastException e) {
        }
      }
    });
    MainMenuEdit.add(PasteMenuItem);

    /** Duplicate **/
    DuplicateMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_D, keyModifier));
    DuplicateMenuItem.setText("Duplicate");
    DuplicateMenuItem.addActionListener(new ActionListener() {

      public void actionPerformed(ActionEvent evt) {
        try {
          BlockDiagram d = (BlockDiagram) DocumentPane.getSelectedFrame();
          if (d != null) {
            MCanvas c = d.getCanvas();
            c.copyElementsToClipBoard();
            boolean res = c.pasteElementsFromClipBoard(120, 120, true);
          }
        } catch (ClassCastException e) {
        }
        try {
          MTextDocument td = (MTextDocument) DocumentPane.getSelectedFrame();
          if (td != null) {
            td.getTextArea().paste();
          }
        } catch (ClassCastException e) {
        }
      }
    });
    MainMenuEdit.add(DuplicateMenuItem);

    /** Undo **/
    UndoMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Z, keyModifier));
    UndoMenuItem.setText("Undo");
    UndoMenuItem.addActionListener(new ActionListener() {

      public void actionPerformed(ActionEvent evt) {
        undo();
      }
    });
    MainMenuEdit.add(UndoMenuItem);

    /** Redo **/
    RedoMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Z, keyModifier | InputEvent.SHIFT_DOWN_MASK));
    RedoMenuItem.setText("Redo");
    RedoMenuItem.addActionListener(new ActionListener() {

      public void actionPerformed(ActionEvent evt) {
        redo();
      }
    });
    MainMenuEdit.add(RedoMenuItem);

    // separator
    MainMenuEdit.add(new JSeparator());

    /** Delete Selected **/
//        DeleteMenuItem.setAccelerator(javaKeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_DELETE));
    DeleteMenuItem.setText("Delete Selected");
    DeleteMenuItem.addActionListener(new ActionListener() {

      public void actionPerformed(ActionEvent evt) {
        BlockDiagram d = (BlockDiagram) DocumentPane.getSelectedFrame();
        if (d != null) {
          MCanvas c = d.getCanvas();
          // Don't register the "delete" action to the undo manager if the selected element is empty.
          if (c.getSelectedElements().isEmpty() && c.getSelectedPipes().isEmpty()) {
            return;
          }
          c.postDeleteEvent(c.getSelectedElements(), c.getSelectedPipes());
          int ne = c.deleteSelectedElements();
          int np = c.deleteSelectedPipes();
        }
      }
    });
    MainMenuEdit.add(DeleteMenuItem);

    /** Select All **/
    SelectAllMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_A, keyModifier));
    SelectAllMenuItem.setText("Select All");
    SelectAllMenuItem.addActionListener(new ActionListener() {

      public void actionPerformed(ActionEvent evt) {
        try {
          BlockDiagram d = (BlockDiagram) DocumentPane.getSelectedFrame();
          if (d != null) {
            MCanvas c = d.getCanvas();
            c.selectAll();
          }
        } catch (ClassCastException e) {
        }

        try {
          MTextDocument td = (MTextDocument) DocumentPane.getSelectedFrame();
          if (td != null) {
            td.getTextArea().selectAll();
          }
        } catch (ClassCastException e) {
        }


      }
    });
    MainMenuEdit.add(SelectAllMenuItem);

    /** Toggle comment out selected **/
    toggleCommentSelectedMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_T, keyModifier));
    toggleCommentSelectedMenuItem.setText("Activate/Deactivate selected");
    toggleCommentSelectedMenuItem.addActionListener(new ActionListener() {

      public void actionPerformed(ActionEvent evt) {
        try {
          BlockDiagram d = (BlockDiagram) DocumentPane.getSelectedFrame();
          if (d != null) {
            MCanvas c = d.getCanvas();
            c.toggleCommentStateOfSelected();
          }
        } catch (ClassCastException e) {
        }
      }
    });
    MainMenuEdit.add(toggleCommentSelectedMenuItem);



    /** ------ View ------ */
    /** Zoom in **/
    ZoomInMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_EQUALS, InputEvent.SHIFT_MASK | keyModifier));
    ZoomInMenuItem.setText("Zoom In");
    ZoomInMenuItem.addActionListener(new ActionListener() {

      public void actionPerformed(ActionEvent evt) {
        zoomInCanvas();
      }
    });
    MainMenuView.add(ZoomInMenuItem);
    /** Zoom out **/
    ZoomOutMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_MINUS, keyModifier));
    ZoomOutMenuItem.setText("Zoom Out");
    ZoomOutMenuItem.addActionListener(new ActionListener() {

      public void actionPerformed(ActionEvent evt) {
        zoomOutCanvas();
      }
    });
    MainMenuView.add(ZoomOutMenuItem);

    /** Set all curves bezier **/
//        BezierMenuItem.setText("All pipes bezier");
//        BezierMenuItem.setState(true);
//        BezierMenuItem.addActionListener(new ActionListener() {
//
//            public void actionPerformed(ActionEvent evt) {
//
//                // get selected diagram
//                MCanvas c = getActiveCanvas();
//                if (c != null) {
//                    // change all pipes on the canvas
//                    ArrayList<MPipe> pipes = c.getMpipes();
//                    Iterator it = pipes.iterator();
//                    while (it.hasNext()) {
//                        MPipe p = (MPipe) it.next();
//                        p.setDrawBezier(BezierMenuItem.getState());
//                    }
//                    // and keep the state for future pipes
//                    c.setDrawBezierPipes(BezierMenuItem.getState());
//                    // repaint
//                    c.repaint();
//                }
//            }
//        });
//        MainMenuView.add(BezierMenuItem);
    /** Format menu **/
    // align left
    AlignLeftMenuItem.setText("Align left");
    AlignLeftMenuItem.addActionListener(new ActionListener() {

      public void actionPerformed(ActionEvent evt) {
        MCanvas c = getActiveCanvas();
        c.recordStartPoints();
        c.alignSelectedElementsLeft();
        c.recordEndPoints();
        c.postMoveEvent();
      }
    });
    MainMenuFormat.add(AlignLeftMenuItem);

    // align right
    AlignRightMenuItem.setText("Align right");
    AlignRightMenuItem.addActionListener(new ActionListener() {

      public void actionPerformed(ActionEvent evt) {
        MCanvas c = getActiveCanvas();
        c.recordStartPoints();
        c.alignSelectedElementsRight();
        c.recordEndPoints();
        c.postMoveEvent();
      }
    });
    MainMenuFormat.add(AlignRightMenuItem);

    // align top
    AlignTopMenuItem.setText("Align top");
    AlignTopMenuItem.addActionListener(new ActionListener() {

      public void actionPerformed(ActionEvent evt) {
        MCanvas c = getActiveCanvas();
        c.recordStartPoints();
        c.alignSelectedElementsTop();
        c.recordEndPoints();
        c.postMoveEvent();
      }
    });
    MainMenuFormat.add(AlignTopMenuItem);

    // align bottom
    AlignBottonMenuItem.setText("Align bottom");
    AlignBottonMenuItem.addActionListener(new ActionListener() {

      public void actionPerformed(ActionEvent evt) {
        MCanvas c = getActiveCanvas();
        c.recordStartPoints();
        c.alignSelectedElementsBottom();
        c.recordEndPoints();
        c.postMoveEvent();
      }
    });
    MainMenuFormat.add(AlignBottonMenuItem);

    // same size
    SameSizeMenuItem.setText("Make same size");
    SameSizeMenuItem.addActionListener(new ActionListener() {

      public void actionPerformed(ActionEvent evt) {
        MCanvas c = getActiveCanvas();
        c.makeSelectedElementsSameSize();
      }
    });
    MainMenuFormat.add(SameSizeMenuItem);


    /** ------ Tools ------ */
    /** plot selected **/
    PlotSelectedMenuItem.setText("Plot Selected");
    MainMenuTools.add(PlotSelectedMenuItem);

    /** Explore selected **/
    ExploreSelectedMenuItem.setText("Explore Selected");
    MainMenuTools.add(ExploreSelectedMenuItem);

    MainMenuTools.add(new JSeparator());

    /** GUIs **/
    ltpdaPreferencesMenuItem.setText("LTPDA Preferences");
    MainMenuTools.add(ltpdaPreferencesMenuItem);


    ltpdaPZmodelHelperMenuItem.setText("Pole/zero Model Helper");
    MainMenuTools.add(ltpdaPZmodelHelperMenuItem);

    ltpdaSpecwinViewerMenuItem.setText("Spectral Window Viewer");
    MainMenuTools.add(ltpdaSpecwinViewerMenuItem);

    ltpdaConstructorHelperMenuItem.setText("Object Constructor Helper");
    MainMenuTools.add(ltpdaConstructorHelperMenuItem);

    ltpdaSignalBuilderMenuItem.setText("LTPDA Signal Builder");
    MainMenuTools.add(ltpdaSignalBuilderMenuItem);

    MainMenuTools.add(new JSeparator());

    /** rebuild library **/
    RebuildLibraryMenuItem.setText("Rebuild LTPDA Library");
    MainMenuTools.add(RebuildLibraryMenuItem);

    /** ------ Pipeline ------ */
    /** New Document **/
    NewMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N, keyModifier));
    NewMenuItem.setText("New Pipeline");
    NewMenuItem.addActionListener(new ActionListener() {

      public void actionPerformed(ActionEvent evt) {
        newDocument();
      }
    });
    MainMenuPipeline.add(NewMenuItem);



    /** Rename pipeline **/
    RenamePipelineMenuItem.setText("Rename Pipeline...");
    RenamePipelineMenuItem.addActionListener(new ActionListener() {

      public void actionPerformed(ActionEvent evt) {
        BlockDiagram d = (BlockDiagram) DocumentPane.getSelectedFrame();
        if (d != null) {
          MCanvas c = d.getCanvas();
          if (c != null) {
            c.renamePipeline();
          }
        }
      }
    });
    MainMenuPipeline.add(RenamePipelineMenuItem);


    MainMenuPipeline.add(new JSeparator());

    /** Create subsystem **/
    CreateSubsystemPipelineMenuItem.setText("Create subsystem");
    CreateSubsystemPipelineMenuItem.setToolTipText("Create a subsystem from the selected elements in the current pipeline.");
    CreateSubsystemPipelineMenuItem.addActionListener(new ActionListener() {

      public void actionPerformed(ActionEvent evt) {
        BlockDiagram d = (BlockDiagram) DocumentPane.getSelectedFrame();

        if (d != null) {
          MCanvas c = d.getCanvas();
          if (c != null) {
            c.createSubsystemEvent();
          }
        }
      }
    });
    MainMenuPipeline.add(CreateSubsystemPipelineMenuItem);

    MainMenuPipeline.add(new JSeparator());

    /** show quick block **/
    showQuickBlockMenuItem.setText("Show QuickBlock...");
    showQuickBlockMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_B, keyModifier));
    showQuickBlockMenuItem.addActionListener(new ActionListener() {

      public void actionPerformed(ActionEvent evt) {
        showQuickBlock();
      }
    });
    MainMenuPipeline.add(showQuickBlockMenuItem);

    /** edit canvas info **/
    editCanvasInfoMenuItem.setText("Edit canvas info...");
    editCanvasInfoMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_I, keyModifier));
    editCanvasInfoMenuItem.addActionListener(new ActionListener() {

      public void actionPerformed(ActionEvent evt) {
        BlockDiagram d = (BlockDiagram) DocumentPane.getSelectedFrame();
        if (d != null) {
          MCanvas c = d.getCanvas();
          if (c != null) {
            c.editCanvasInfo();
          }
        }
      }
    });
    MainMenuPipeline.add(editCanvasInfoMenuItem);


    /** search **/
    searchCanvasMenuItem.setText("Search...");
    searchCanvasMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F, keyModifier));
    searchCanvasMenuItem.addActionListener(new ActionListener() {

      public void actionPerformed(ActionEvent evt) {
        showSearchDialog();
      }
    });
    MainMenuPipeline.add(searchCanvasMenuItem);


    MainMenuPipeline.add(new JSeparator());

    WBSavePipelineMenuItem.setText("Export Pipeline As...");
    WBSavePipelineMenuItem.addActionListener(new ActionListener() {

      public void actionPerformed(ActionEvent evt) {
        try {
          if (saveActivePipelineAs()) {
            lastSavePath = pipelineFilePath;
          }
        } catch (Exception ex) {
          Logger.getLogger(MainWindow.class.getName()).log(Level.SEVERE, null, ex);
        }
      }
    });
    MainMenuPipeline.add(WBSavePipelineMenuItem);

    /** Export pipeline to mfile **/
    ExportToMFileMenuItem.setText("Export to M-file...");
    MainMenuPipeline.add(ExportToMFileMenuItem);

    /** Export pipeline to mfile **/
    ExportToTerminalMenuItem.setText("Export to terminal");
    MainMenuPipeline.add(ExportToTerminalMenuItem);

    /** Export pipeline to image **/
    ExportToImageMenuItem.setText("Export to image");
    ExportToImageMenuItem.addActionListener(new ActionListener() {

      public void actionPerformed(ActionEvent evt) {
        togifTBBActionPerformed(evt);
      }
    });
    MainMenuPipeline.add(ExportToImageMenuItem);

    MainMenuPipeline.add(new JSeparator());

    /** Remove pipeline **/
    RemovePipelineMenuItem.setText("Delete active Pipeline");
    RemovePipelineMenuItem.addActionListener(new ActionListener() {

      public void actionPerformed(ActionEvent evt) {
        BlockDiagram d = (BlockDiagram) DocumentPane.getSelectedFrame();
        if (d != null) {
          promptAnddeletePipeline(d);
        }
      }
    });
    MainMenuPipeline.add(RemovePipelineMenuItem);

    /** Close pipeline **/
    ClosePipelineMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_W, InputEvent.SHIFT_MASK | keyModifier));
    ClosePipelineMenuItem.setText("Close active Pipeline");
    ClosePipelineMenuItem.addActionListener(new ActionListener() {

      public void actionPerformed(ActionEvent evt) {
        BlockDiagram d = (BlockDiagram) DocumentPane.getSelectedFrame();
        if (d != null) {
          d.handleClosePipeline();
        }

      }
    });
    MainMenuPipeline.add(ClosePipelineMenuItem);

    /** Close all pipelines **/
    CloseAllPipelinesMenuItem.setText("Close All Pipelines");
    CloseAllPipelinesMenuItem.addActionListener(new ActionListener() {

      public void actionPerformed(ActionEvent evt) {
        // are we sure we want to close?
        int n = JOptionPane.showConfirmDialog(null,
                "Are you sure you want to close all pipelines?",
                "Confirm", JOptionPane.YES_NO_OPTION);

        if (n == JOptionPane.YES_OPTION) {

          while (documents.size() > 0) {
            deleteDiagram(documents.get(0));
          }
          documents.clear();

          // reset the workbench?
          n = JOptionPane.showConfirmDialog(null,
                  "Reset the workbench?",
                  "Confirm", JOptionPane.YES_NO_OPTION);
          if (n == JOptionPane.YES_OPTION) {
            workbenchFilePath = null;
            setTitle("Untitled");
            setSaved(false);
          }
        }
        buildPipelineList();

      }
    });
    MainMenuPipeline.add(CloseAllPipelinesMenuItem);


    /** ------ Help ------ */
    /** Help on block **/
    HelpBlockHelpMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F1, InputEvent.SHIFT_MASK));
    HelpBlockHelpMenuItem.setText("Help on selected blocks");
    HelpBlockHelpMenuItem.addActionListener(new ActionListener() {

      public void actionPerformed(ActionEvent evt) {
        BlockDiagram d = (BlockDiagram) DocumentPane.getSelectedFrame();
        if (d != null) {
          MCanvas c = d.getCanvas();
          // get first selected block
          ArrayList<MBlock> blocks = c.getSelectedBlocks();
          if (!blocks.isEmpty()) {
            Iterator it = blocks.iterator();
            while (it.hasNext()) {
              MBlock b = (MBlock) it.next();
              b.help();
            }
          }
        }

      }
    });
    MainMenuHelp.add(HelpBlockHelpMenuItem);

    /** Help on block **/
    HelpBlockDocMenuItem.setText("Documentation on selected block");
    MainMenuHelp.add(HelpBlockDocMenuItem);

    MainMenuHelp.add(new JSeparator());

    HelpAboutMenuItem.setText("About LTPDA Workbench");
    HelpAboutMenuItem.addActionListener(new ActionListener() {

      public void actionPerformed(ActionEvent evt) {

        aboutDialog.setVisible(true);
      }
    });
    MainMenuHelp.add(HelpAboutMenuItem);

  }

//  public void showSearchDialog() {
//
//    ElementSearchDialog es = new ElementSearchDialog(this, false, this);
//    es.setVisible(true);
//
//  }
  public void showQuickBlock() {
    if (documents.size() > 0) {
      QuickBlock qb = new QuickBlock(this, true, this);
      qb.setVisible(true);
      qb.setLocation(getX() + getWidth() / 2 - qb.getWidth() / 2, getY() + getHeight() / 2 - qb.getHeight() / 2);
    }
  }

  private void zoomOutCanvas() {
    BlockDiagram diag = (BlockDiagram) DocumentPane.getSelectedFrame();
    if (diag != null) {
      MCanvas mc = diag.getCanvas();
      mc.zoomOut();
    }

  }

  private void zoomInCanvas() {
    BlockDiagram diag = (BlockDiagram) DocumentPane.getSelectedFrame();
    if (diag != null) {
      MCanvas mc = diag.getCanvas();
      mc.zoomIn();
    }

  }

  private void newTextDocument() {
    MTextDocument mtd = new MTextDocument(this, "Text Document " + (txtdocs.size() + 1));
    txtdocs.add(mtd);
    DocumentPane.add(mtd);
    mtd.setLocation(10 * txtdocs.size(), 10 * txtdocs.size());
    DocumentPane.setComponentZOrder(mtd, 0);
    mtd.requestFocusInWindow();
    try {
      mtd.setSelected(true);
      mtd.maximise(true);
    } catch (PropertyVetoException ex) {
      Logger.getLogger(MainWindow.class.getName()).log(Level.SEVERE, null, ex);
    }

    setSaved(false);
    stateChanged("New Text Document");
  }

  /** This method is called from within the constructor to
   * initialize the form.
   * WARNING: Do NOT modify this code. The content of this method is
   * always regenerated by the Form Editor.
   */
  @SuppressWarnings("unchecked")
  // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
  private void initComponents() {

    BlocktreeContextMenu = new javax.swing.JPopupMenu();
    AddBlockMenuItem = new javax.swing.JMenuItem();
    BlockHelpMenuItem = new javax.swing.JMenuItem();
    MainToolbar = new javax.swing.JToolBar();
    newPipelineTBB = new javax.swing.JButton();
    saveWorkbenchTBB = new javax.swing.JButton();
    saveWorkbenchAsTBB = new javax.swing.JButton();
    importTBB = new javax.swing.JButton();
    jSeparator1 = new javax.swing.JToolBar.Separator();
    copyTBB = new javax.swing.JButton();
    pasteTBB = new javax.swing.JButton();
    undoTBB = new javax.swing.JButton();
    redoTBB = new javax.swing.JButton();
    deleteSelectedTBB = new javax.swing.JButton();
    jSeparator2 = new javax.swing.JToolBar.Separator();
    leftTBB = new javax.swing.JButton();
    rightTBB = new javax.swing.JButton();
    upTBB = new javax.swing.JButton();
    downTBB = new javax.swing.JButton();
    jSeparator4 = new javax.swing.JToolBar.Separator();
    zoomInTBB = new javax.swing.JButton();
    zoomOutTBB = new javax.swing.JButton();
    jSeparator3 = new javax.swing.JToolBar.Separator();
    searchTBB = new javax.swing.JButton();
    paramsOverviewBtn = new javax.swing.JButton();
    showConsoleBtn = new javax.swing.JButton();
    helpTBB = new javax.swing.JButton();
    infoTBB = new javax.swing.JButton();
    togifTBB = new javax.swing.JButton();
    jSeparator5 = new javax.swing.JToolBar.Separator();
    repoSubmitTBB = new javax.swing.JButton();
    repoSearchTBB = new javax.swing.JButton();
    jPanel5 = new javax.swing.JPanel();
    jSplitPane1 = new javax.swing.JSplitPane();
    DocumentPane = new javax.swing.JDesktopPane();
    mainTabPanel = new javax.swing.JTabbedPane();
    pipelineTab = new javax.swing.JPanel();
    jScrollPane6 = new javax.swing.JScrollPane();
    pipelineListTree = new PipelineListTree(this);
    mvPipelineUpBtn = new javax.swing.JButton();
    mvPipelineDownBtn = new javax.swing.JButton();
    deletePipelineBtn = new javax.swing.JButton();
    libraryTab = new javax.swing.JPanel();
    jScrollPane1 = new javax.swing.JScrollPane();
    blockLibraryTree = new LibraryTree();
    BlockSearchTxt = new javax.swing.JTextField();
    jLabel1 = new javax.swing.JLabel();
    librarySearchPrevious = new javax.swing.JButton();
    librarySearchNext = new javax.swing.JButton();
    shelfTab = new javax.swing.JPanel();
    jScrollPane2 = new javax.swing.JScrollPane();
    shelfTree = new ShelfTree();
    paramsTab = new javax.swing.JPanel();
    jSplitPane2 = new javax.swing.JSplitPane();
    jPanel1 = new javax.swing.JPanel();
    jScrollPane3 = new javax.swing.JScrollPane();
    BlockPropertyTable = new mpipeline.propertytable.BlockPropertyTable();
    jPanel2 = new javax.swing.JPanel();
    ParamRmvBtn = new javax.swing.JButton();
    ParamAddBtn = new javax.swing.JButton();
    setCombo = new javax.swing.JComboBox();
    ApplyBtn = new javax.swing.JButton();
    jScrollPane5 = new javax.swing.JScrollPane();
    controlsTab = new javax.swing.JPanel();
    jSeparator6 = new javax.swing.JSeparator();
    jSeparator7 = new javax.swing.JSeparator();
    jPanel3 = new javax.swing.JPanel();
    StepBackwardsBtn = new javax.swing.JButton();
    ResetBtn = new javax.swing.JButton();
    RunBtn = new javax.swing.JButton();
    StepForwardBtn = new javax.swing.JButton();
    SkipForwardBtn = new javax.swing.JButton();
    jPanel4 = new javax.swing.JPanel();
    saveObjectBtn = new javax.swing.JButton();
    ExploreBtn = new javax.swing.JButton();
    HistoryBtn = new javax.swing.JButton();
    tableBtn = new javax.swing.JButton();
    reportBtn = new javax.swing.JButton();
    DisplayBtn = new javax.swing.JButton();
    PlotBtn = new javax.swing.JButton();
    exportWorkspaceBtn = new javax.swing.JButton();
    jPanel6 = new javax.swing.JPanel();
    vebosityCombo = new javax.swing.JComboBox();
    jLabel2 = new javax.swing.JLabel();
    instanceIdLabel = new javax.swing.JLabel();
    jLabel4 = new javax.swing.JLabel();
    statusLabel = new javax.swing.JLabel();
    MainMenuBar = new javax.swing.JMenuBar();
    MainMenuFile = new javax.swing.JMenu();
    MainMenuEdit = new javax.swing.JMenu();
    MainMenuView = new javax.swing.JMenu();
    MainMenuFormat = new javax.swing.JMenu();
    MainMenuPipeline = new javax.swing.JMenu();
    MainMenuTools = new javax.swing.JMenu();
    MainMenuWindow = new javax.swing.JMenu();
    MainMenuHelp = new javax.swing.JMenu();

    AddBlockMenuItem.setText("Add block(s)");
    AddBlockMenuItem.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        AddBlockMenuItemActionPerformed(evt);
      }
    });
    BlocktreeContextMenu.add(AddBlockMenuItem);

    BlockHelpMenuItem.setText("Help");
    BlockHelpMenuItem.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        BlockHelpMenuItemActionPerformed(evt);
      }
    });
    BlocktreeContextMenu.add(BlockHelpMenuItem);

    setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE);
    setTitle("LTPDA Workbench");
    setName("MainFrame"); // NOI18N
    addWindowListener(new java.awt.event.WindowAdapter() {
      public void windowClosing(java.awt.event.WindowEvent evt) {
        formWindowClosing(evt);
      }
    });
    addKeyListener(new java.awt.event.KeyAdapter() {
      public void keyPressed(java.awt.event.KeyEvent evt) {
        formKeyPressed(evt);
      }
    });

    MainToolbar.setFloatable(false);
    MainToolbar.setRollover(true);

    newPipelineTBB.setIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/add_page.png"))); // NOI18N
    newPipelineTBB.setToolTipText("New pipeline");
    newPipelineTBB.setFocusable(false);
    newPipelineTBB.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
    newPipelineTBB.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/add_page_ro.png"))); // NOI18N
    newPipelineTBB.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
    MainToolbar.add(newPipelineTBB);

    saveWorkbenchTBB.setIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/save.png"))); // NOI18N
    saveWorkbenchTBB.setToolTipText("Save workbench");
    saveWorkbenchTBB.setFocusable(false);
    saveWorkbenchTBB.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
    saveWorkbenchTBB.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/save_ro.png"))); // NOI18N
    saveWorkbenchTBB.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
    MainToolbar.add(saveWorkbenchTBB);

    saveWorkbenchAsTBB.setIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/save_as.png"))); // NOI18N
    saveWorkbenchAsTBB.setToolTipText("Save workbench as...");
    saveWorkbenchAsTBB.setFocusable(false);
    saveWorkbenchAsTBB.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
    saveWorkbenchAsTBB.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/save_as_ro.png"))); // NOI18N
    saveWorkbenchAsTBB.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
    MainToolbar.add(saveWorkbenchAsTBB);

    importTBB.setIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/green_arrow_down.png"))); // NOI18N
    importTBB.setToolTipText("Import pipelines from workbench");
    importTBB.setFocusable(false);
    importTBB.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
    importTBB.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/green_arrow_down_ro.png"))); // NOI18N
    importTBB.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
    MainToolbar.add(importTBB);
    MainToolbar.add(jSeparator1);

    copyTBB.setIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/copy_paste.png"))); // NOI18N
    copyTBB.setToolTipText("Copy selected blocks");
    copyTBB.setFocusable(false);
    copyTBB.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
    copyTBB.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/copy_paste_ro.png"))); // NOI18N
    copyTBB.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
    MainToolbar.add(copyTBB);

    pasteTBB.setIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/note.png"))); // NOI18N
    pasteTBB.setToolTipText("Paste blocks from clipboard");
    pasteTBB.setFocusable(false);
    pasteTBB.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
    pasteTBB.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/note_ro.png"))); // NOI18N
    pasteTBB.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
    MainToolbar.add(pasteTBB);

    undoTBB.setIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/page_down.png"))); // NOI18N
    undoTBB.setToolTipText("Undo");
    undoTBB.setFocusable(false);
    undoTBB.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
    undoTBB.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/page_down_ro.png"))); // NOI18N
    undoTBB.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
    MainToolbar.add(undoTBB);

    redoTBB.setIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/page_up.png"))); // NOI18N
    redoTBB.setToolTipText("Redo");
    redoTBB.setFocusable(false);
    redoTBB.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
    redoTBB.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/page_up_ro.png"))); // NOI18N
    redoTBB.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
    MainToolbar.add(redoTBB);

    deleteSelectedTBB.setIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/delete.png"))); // NOI18N
    deleteSelectedTBB.setToolTipText("Delete selected blocks");
    deleteSelectedTBB.setFocusable(false);
    deleteSelectedTBB.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
    deleteSelectedTBB.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/delete_ro.png"))); // NOI18N
    deleteSelectedTBB.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
    MainToolbar.add(deleteSelectedTBB);
    MainToolbar.add(jSeparator2);

    leftTBB.setIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/back.png"))); // NOI18N
    leftTBB.setToolTipText("Move selected blocks left");
    leftTBB.setFocusable(false);
    leftTBB.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
    leftTBB.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/back_ro.png"))); // NOI18N
    leftTBB.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
    MainToolbar.add(leftTBB);

    rightTBB.setIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/next.png"))); // NOI18N
    rightTBB.setToolTipText("Move selected blocks right");
    rightTBB.setFocusable(false);
    rightTBB.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
    rightTBB.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/next_ro.png"))); // NOI18N
    rightTBB.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
    MainToolbar.add(rightTBB);

    upTBB.setIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/up.png"))); // NOI18N
    upTBB.setToolTipText("Move selected blocks up");
    upTBB.setFocusable(false);
    upTBB.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
    upTBB.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/up_ro.png"))); // NOI18N
    upTBB.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
    MainToolbar.add(upTBB);

    downTBB.setIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/download.png"))); // NOI18N
    downTBB.setToolTipText("Move selected blocks down");
    downTBB.setFocusable(false);
    downTBB.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
    downTBB.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/download_ro.png"))); // NOI18N
    downTBB.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
    MainToolbar.add(downTBB);
    MainToolbar.add(jSeparator4);

    zoomInTBB.setIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/zoom_in.png"))); // NOI18N
    zoomInTBB.setToolTipText("Zoom in");
    zoomInTBB.setFocusable(false);
    zoomInTBB.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
    zoomInTBB.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/zoom_in_ro.png"))); // NOI18N
    zoomInTBB.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
    MainToolbar.add(zoomInTBB);

    zoomOutTBB.setIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/zoom_out.png"))); // NOI18N
    zoomOutTBB.setToolTipText("Zoom out");
    zoomOutTBB.setFocusable(false);
    zoomOutTBB.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
    zoomOutTBB.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/zoom_out_ro.png"))); // NOI18N
    zoomOutTBB.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
    MainToolbar.add(zoomOutTBB);
    MainToolbar.add(jSeparator3);

    searchTBB.setIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/search.png"))); // NOI18N
    searchTBB.setToolTipText("Search for a block");
    searchTBB.setFocusable(false);
    searchTBB.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
    searchTBB.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/search_ro.png"))); // NOI18N
    searchTBB.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
    MainToolbar.add(searchTBB);

    paramsOverviewBtn.setIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/paramsOverview.png"))); // NOI18N
    paramsOverviewBtn.setToolTipText("View an overview of the block parameters set on this canvas.");
    paramsOverviewBtn.setFocusable(false);
    paramsOverviewBtn.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
    paramsOverviewBtn.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/paramsOverview_ro.png"))); // NOI18N
    paramsOverviewBtn.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
    paramsOverviewBtn.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        paramsOverviewBtnActionPerformed(evt);
      }
    });
    MainToolbar.add(paramsOverviewBtn);

    showConsoleBtn.setIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/console.png"))); // NOI18N
    showConsoleBtn.setToolTipText("Show the message console.");
    showConsoleBtn.setFocusable(false);
    showConsoleBtn.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
    showConsoleBtn.setMaximumSize(new java.awt.Dimension(36, 36));
    showConsoleBtn.setMinimumSize(new java.awt.Dimension(36, 36));
    showConsoleBtn.setPreferredSize(new java.awt.Dimension(36, 36));
    showConsoleBtn.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/console_ro.png"))); // NOI18N
    showConsoleBtn.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
    showConsoleBtn.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        showConsoleBtnActionPerformed(evt);
      }
    });
    MainToolbar.add(showConsoleBtn);

    helpTBB.setIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/help.png"))); // NOI18N
    helpTBB.setToolTipText("Help on selected block");
    helpTBB.setFocusable(false);
    helpTBB.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
    helpTBB.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/help_ro.png"))); // NOI18N
    helpTBB.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
    MainToolbar.add(helpTBB);

    infoTBB.setIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/info.png"))); // NOI18N
    infoTBB.setToolTipText("Show block info");
    infoTBB.setFocusable(false);
    infoTBB.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
    infoTBB.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/info_ro.png"))); // NOI18N
    infoTBB.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
    MainToolbar.add(infoTBB);

    togifTBB.setIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/jpg_file.png"))); // NOI18N
    togifTBB.setFocusable(false);
    togifTBB.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
    togifTBB.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/jpg_file_ro.png"))); // NOI18N
    togifTBB.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
    togifTBB.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        togifTBBActionPerformed(evt);
      }
    });
    MainToolbar.add(togifTBB);
    MainToolbar.add(jSeparator5);

    repoSubmitTBB.setIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/add_to_database.png"))); // NOI18N
    repoSubmitTBB.setToolTipText("Submit the output of the selected blocks to the repository.");
    repoSubmitTBB.setEnabled(false);
    repoSubmitTBB.setFocusable(false);
    repoSubmitTBB.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
    repoSubmitTBB.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/add_to_database_ro.png"))); // NOI18N
    repoSubmitTBB.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
    MainToolbar.add(repoSubmitTBB);

    repoSearchTBB.setIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/search_database.png"))); // NOI18N
    repoSearchTBB.setToolTipText("Search an LTPDA Repository");
    repoSearchTBB.setFocusable(false);
    repoSearchTBB.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
    repoSearchTBB.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/search_database_ro.png"))); // NOI18N
    repoSearchTBB.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
    MainToolbar.add(repoSearchTBB);

    jSplitPane1.setBorder(null);
    jSplitPane1.setDividerLocation(280);
    jSplitPane1.setMinimumSize(new java.awt.Dimension(10, 41));
    jSplitPane1.setRightComponent(DocumentPane);

    mainTabPanel.setTabPlacement(javax.swing.JTabbedPane.LEFT);
    mainTabPanel.setFont(new java.awt.Font("Lucida Grande", 0, 11));

    pipelineTab.setOpaque(false);

    jScrollPane6.setBorder(null);

    pipelineListTree.addMouseListener(new java.awt.event.MouseAdapter() {
      public void mouseClicked(java.awt.event.MouseEvent evt) {
        pipelineListTreeMouseClicked(evt);
      }
      public void mousePressed(java.awt.event.MouseEvent evt) {
        pipelineListTreeMousePressed(evt);
      }
      public void mouseReleased(java.awt.event.MouseEvent evt) {
        pipelineListTreeMouseReleased(evt);
      }
    });
    jScrollPane6.setViewportView(pipelineListTree);

    mvPipelineUpBtn.setIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/up.png"))); // NOI18N
    mvPipelineUpBtn.setToolTipText("Move top level pipeline up");
    mvPipelineUpBtn.setEnabled(false);
    mvPipelineUpBtn.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/up_ro.png"))); // NOI18N
    mvPipelineUpBtn.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        mvPipelineUpBtnActionPerformed(evt);
      }
    });

    mvPipelineDownBtn.setIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/download.png"))); // NOI18N
    mvPipelineDownBtn.setToolTipText("Move top level pipeline down");
    mvPipelineDownBtn.setEnabled(false);
    mvPipelineDownBtn.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/download_ro.png"))); // NOI18N
    mvPipelineDownBtn.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        mvPipelineDownBtnActionPerformed(evt);
      }
    });

    deletePipelineBtn.setIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/delete.png"))); // NOI18N
    deletePipelineBtn.setToolTipText("Delete selected pipeline");
    deletePipelineBtn.setEnabled(false);
    deletePipelineBtn.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/delete_ro.png"))); // NOI18N
    deletePipelineBtn.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        deletePipelineBtnActionPerformed(evt);
      }
    });

    org.jdesktop.layout.GroupLayout pipelineTabLayout = new org.jdesktop.layout.GroupLayout(pipelineTab);
    pipelineTab.setLayout(pipelineTabLayout);
    pipelineTabLayout.setHorizontalGroup(
      pipelineTabLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
      .add(jScrollPane6, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 197, Short.MAX_VALUE)
      .add(org.jdesktop.layout.GroupLayout.TRAILING, pipelineTabLayout.createSequentialGroup()
        .addContainerGap()
        .add(pipelineTabLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
          .add(pipelineTabLayout.createSequentialGroup()
            .add(mvPipelineUpBtn, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 36, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
            .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, 101, Short.MAX_VALUE)
            .add(deletePipelineBtn, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 36, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
          .add(mvPipelineDownBtn, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 36, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
        .addContainerGap())
    );

    pipelineTabLayout.linkSize(new java.awt.Component[] {deletePipelineBtn, mvPipelineDownBtn, mvPipelineUpBtn}, org.jdesktop.layout.GroupLayout.HORIZONTAL);

    pipelineTabLayout.setVerticalGroup(
      pipelineTabLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
      .add(pipelineTabLayout.createSequentialGroup()
        .add(jScrollPane6, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 339, Short.MAX_VALUE)
        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
        .add(pipelineTabLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
          .add(pipelineTabLayout.createSequentialGroup()
            .add(mvPipelineUpBtn, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 36, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
            .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
            .add(mvPipelineDownBtn, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 36, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
          .add(deletePipelineBtn, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 36, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
        .add(116, 116, 116))
    );

    pipelineTabLayout.linkSize(new java.awt.Component[] {deletePipelineBtn, mvPipelineDownBtn, mvPipelineUpBtn}, org.jdesktop.layout.GroupLayout.VERTICAL);

    mainTabPanel.addTab("Pipelines", null, pipelineTab, "Activate with "+KeyEvent.getModifiersExText(keyModifier)+"+1");

    libraryTab.setOpaque(false);

    jScrollPane1.setBorder(null);

    blockLibraryTree.setDragEnabled(true);
    blockLibraryTree.addTreeSelectionListener(new javax.swing.event.TreeSelectionListener() {
      public void valueChanged(javax.swing.event.TreeSelectionEvent evt) {
        blockLibraryTreeValueChanged(evt);
      }
    });
    blockLibraryTree.addKeyListener(new java.awt.event.KeyAdapter() {
      public void keyPressed(java.awt.event.KeyEvent evt) {
        blockLibraryTreeKeyPressed(evt);
      }
    });
    blockLibraryTree.addMouseListener(new java.awt.event.MouseAdapter() {
      public void mouseClicked(java.awt.event.MouseEvent evt) {
        blockLibraryTreeMouseClicked(evt);
      }
      public void mousePressed(java.awt.event.MouseEvent evt) {
        blockLibraryTreeMousePressed(evt);
      }
      public void mouseReleased(java.awt.event.MouseEvent evt) {
        blockLibraryTreeMouseReleased(evt);
      }
    });
    jScrollPane1.setViewportView(blockLibraryTree);

    BlockSearchTxt.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        BlockSearchTxtActionPerformed(evt);
      }
    });
    BlockSearchTxt.addPropertyChangeListener(new java.beans.PropertyChangeListener() {
      public void propertyChange(java.beans.PropertyChangeEvent evt) {
        BlockSearchTxtPropertyChange(evt);
      }
    });
    BlockSearchTxt.addKeyListener(new java.awt.event.KeyAdapter() {
      public void keyPressed(java.awt.event.KeyEvent evt) {
        BlockSearchTxtKeyPressed(evt);
      }
      public void keyReleased(java.awt.event.KeyEvent evt) {
        BlockSearchTxtKeyReleased(evt);
      }
      public void keyTyped(java.awt.event.KeyEvent evt) {
        BlockSearchTxtKeyTyped(evt);
      }
    });

    jLabel1.setText("search");

    librarySearchPrevious.setIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/previous.png"))); // NOI18N
    librarySearchPrevious.setToolTipText("Previous match");
    librarySearchPrevious.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/previous_ro.png"))); // NOI18N
    librarySearchPrevious.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        librarySearchPreviousActionPerformed(evt);
      }
    });

    librarySearchNext.setIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/next_small.png"))); // NOI18N
    librarySearchNext.setToolTipText("Next match");
    librarySearchNext.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/next_small_ro.png"))); // NOI18N
    librarySearchNext.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        librarySearchNextActionPerformed(evt);
      }
    });

    org.jdesktop.layout.GroupLayout libraryTabLayout = new org.jdesktop.layout.GroupLayout(libraryTab);
    libraryTab.setLayout(libraryTabLayout);
    libraryTabLayout.setHorizontalGroup(
      libraryTabLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
      .add(jScrollPane1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 197, Short.MAX_VALUE)
      .add(org.jdesktop.layout.GroupLayout.TRAILING, libraryTabLayout.createSequentialGroup()
        .addContainerGap(53, Short.MAX_VALUE)
        .add(jLabel1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 66, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
        .add(4, 4, 4)
        .add(libraryTabLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING, false)
          .add(libraryTabLayout.createSequentialGroup()
            .add(librarySearchPrevious)
            .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
            .add(librarySearchNext))
          .add(BlockSearchTxt))
        .addContainerGap())
    );
    libraryTabLayout.setVerticalGroup(
      libraryTabLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
      .add(libraryTabLayout.createSequentialGroup()
        .add(jScrollPane1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 341, Short.MAX_VALUE)
        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
        .add(libraryTabLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.CENTER)
          .add(jLabel1)
          .add(BlockSearchTxt, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
        .add(libraryTabLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
          .add(librarySearchPrevious)
          .add(librarySearchNext))
        .add(133, 133, 133))
    );

    mainTabPanel.addTab("Library", null, libraryTab, "Activate with "+KeyEvent.getModifiersExText(keyModifier)+"+2");

    shelfTab.setOpaque(false);

    jScrollPane2.setBorder(null);

    shelfTree.setDragEnabled(true);
    shelfTree.addMouseListener(new java.awt.event.MouseAdapter() {
      public void mouseClicked(java.awt.event.MouseEvent evt) {
        shelfTreeMouseClicked(evt);
      }
      public void mousePressed(java.awt.event.MouseEvent evt) {
        shelfTreeMousePressed(evt);
      }
      public void mouseReleased(java.awt.event.MouseEvent evt) {
        shelfTreeMouseReleased(evt);
      }
    });
    jScrollPane2.setViewportView(shelfTree);

    org.jdesktop.layout.GroupLayout shelfTabLayout = new org.jdesktop.layout.GroupLayout(shelfTab);
    shelfTab.setLayout(shelfTabLayout);
    shelfTabLayout.setHorizontalGroup(
      shelfTabLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
      .add(jScrollPane2, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 197, Short.MAX_VALUE)
    );
    shelfTabLayout.setVerticalGroup(
      shelfTabLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
      .add(shelfTabLayout.createSequentialGroup()
        .add(jScrollPane2, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 496, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
        .addContainerGap(43, Short.MAX_VALUE))
    );

    mainTabPanel.addTab("Shelf", null, shelfTab, "Activate with "+KeyEvent.getModifiersExText(keyModifier)+"+3");

    paramsTab.setOpaque(false);

    jSplitPane2.setBorder(null);
    jSplitPane2.setDividerLocation(120);
    jSplitPane2.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT);

    jPanel1.setOpaque(false);

    jScrollPane3.setBorder(null);
    jScrollPane3.addMouseListener(new java.awt.event.MouseAdapter() {
      public void mouseClicked(java.awt.event.MouseEvent evt) {
        jScrollPane3MouseClicked(evt);
      }
    });

    BlockPropertyTable.setModel(new javax.swing.table.DefaultTableModel(
      new Object [][] {

      },
      new String [] {
        "Parameter", "Value"
      }
    ) {
      boolean[] canEdit = new boolean [] {
        false, true
      };

      public boolean isCellEditable(int rowIndex, int columnIndex) {
        return canEdit [columnIndex];
      }
    });
    BlockPropertyTable.setAutoResizeMode(javax.swing.JTable.AUTO_RESIZE_LAST_COLUMN);
    BlockPropertyTable.setGridColor(new java.awt.Color(102, 102, 255));
    BlockPropertyTable.getTableHeader().setReorderingAllowed(false);
    jScrollPane3.setViewportView(BlockPropertyTable);

    org.jdesktop.layout.GroupLayout jPanel1Layout = new org.jdesktop.layout.GroupLayout(jPanel1);
    jPanel1.setLayout(jPanel1Layout);
    jPanel1Layout.setHorizontalGroup(
      jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
      .add(jScrollPane3, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 197, Short.MAX_VALUE)
    );
    jPanel1Layout.setVerticalGroup(
      jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
      .add(jPanel1Layout.createSequentialGroup()
        .add(jScrollPane3, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 108, Short.MAX_VALUE)
        .addContainerGap())
    );

    jSplitPane2.setLeftComponent(jPanel1);

    jPanel2.setOpaque(false);

    ParamRmvBtn.setFont(new java.awt.Font("Lucida Grande", 0, 12));
    ParamRmvBtn.setIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/subtract.png"))); // NOI18N
    ParamRmvBtn.setToolTipText("Remove parameter");
    ParamRmvBtn.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/subtract_ro.png"))); // NOI18N
    ParamRmvBtn.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        ParamRmvBtnActionPerformed(evt);
      }
    });

    ParamAddBtn.setFont(new java.awt.Font("Lucida Grande", 0, 12));
    ParamAddBtn.setIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/add.png"))); // NOI18N
    ParamAddBtn.setToolTipText("Add parameter");
    ParamAddBtn.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/add_ro.png"))); // NOI18N
    ParamAddBtn.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        ParamAddBtnActionPerformed(evt);
      }
    });

    setCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
    setCombo.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        setComboActionPerformed(evt);
      }
    });
    setCombo.addPropertyChangeListener(new java.beans.PropertyChangeListener() {
      public void propertyChange(java.beans.PropertyChangeEvent evt) {
        setComboPropertyChange(evt);
      }
    });

    ApplyBtn.setFont(new java.awt.Font("Lucida Grande", 0, 12));
    ApplyBtn.setText("Set");
    ApplyBtn.setToolTipText("Set the plist");
    ApplyBtn.setEnabled(false);
    ApplyBtn.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        ApplyBtnActionPerformed(evt);
      }
    });

    plistTable.setModel(new PlistTableModel(this, new JPlist()));
    plistTable.setMaximumSize(new java.awt.Dimension(1000, 1000));
    plistTable.setMinimumSize(new java.awt.Dimension(10, 10));
    plistTable.setSelectionMode(javax.swing.ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
    jScrollPane5.setViewportView(plistTable);
    plistTable.getColumnModel().getSelectionModel().setSelectionMode(javax.swing.ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);

    org.jdesktop.layout.GroupLayout jPanel2Layout = new org.jdesktop.layout.GroupLayout(jPanel2);
    jPanel2.setLayout(jPanel2Layout);
    jPanel2Layout.setHorizontalGroup(
      jPanel2Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
      .add(org.jdesktop.layout.GroupLayout.TRAILING, jPanel2Layout.createSequentialGroup()
        .addContainerGap()
        .add(ApplyBtn)
        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, 62, Short.MAX_VALUE)
        .add(ParamRmvBtn, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 36, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
        .add(ParamAddBtn, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 36, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
        .addContainerGap())
      .add(jPanel2Layout.createSequentialGroup()
        .addContainerGap()
        .add(setCombo, 0, 173, Short.MAX_VALUE)
        .addContainerGap())
      .add(jScrollPane5, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 197, Short.MAX_VALUE)
    );
    jPanel2Layout.setVerticalGroup(
      jPanel2Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
      .add(org.jdesktop.layout.GroupLayout.TRAILING, jPanel2Layout.createSequentialGroup()
        .addContainerGap()
        .add(setCombo, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
        .add(jScrollPane5, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 304, Short.MAX_VALUE)
        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
        .add(jPanel2Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING)
          .add(ParamAddBtn, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 36, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
          .add(ParamRmvBtn, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 36, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
          .add(ApplyBtn, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 36, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
        .addContainerGap())
    );

    jPanel2Layout.linkSize(new java.awt.Component[] {ApplyBtn, ParamAddBtn, ParamRmvBtn}, org.jdesktop.layout.GroupLayout.VERTICAL);

    jSplitPane2.setRightComponent(jPanel2);

    org.jdesktop.layout.GroupLayout paramsTabLayout = new org.jdesktop.layout.GroupLayout(paramsTab);
    paramsTab.setLayout(paramsTabLayout);
    paramsTabLayout.setHorizontalGroup(
      paramsTabLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
      .add(jSplitPane2, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 197, Short.MAX_VALUE)
    );
    paramsTabLayout.setVerticalGroup(
      paramsTabLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
      .add(paramsTabLayout.createSequentialGroup()
        .add(jSplitPane2, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 527, Short.MAX_VALUE)
        .addContainerGap())
    );

    mainTabPanel.addTab("Properties", null, paramsTab, "Activate with "+KeyEvent.getModifiersExText(keyModifier)+"+4");

    controlsTab.setOpaque(false);

    jPanel3.setOpaque(false);

    StepBackwardsBtn.setIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/rewind3.png"))); // NOI18N
    StepBackwardsBtn.setToolTipText("Step Backward");
    StepBackwardsBtn.setFocusable(false);
    StepBackwardsBtn.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
    StepBackwardsBtn.setMaximumSize(new java.awt.Dimension(32, 32));
    StepBackwardsBtn.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/rewind3_ro.png"))); // NOI18N
    StepBackwardsBtn.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
    StepBackwardsBtn.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        StepBackwardsBtnActionPerformed(evt);
      }
    });

    ResetBtn.setIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/reload3.png"))); // NOI18N
    ResetBtn.setToolTipText("Reset pipeline");
    ResetBtn.setFocusable(false);
    ResetBtn.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
    ResetBtn.setMaximumSize(new java.awt.Dimension(32, 32));
    ResetBtn.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/reload3_ro.png"))); // NOI18N
    ResetBtn.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
    ResetBtn.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        ResetBtnActionPerformed(evt);
      }
    });

    RunBtn.setIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/play3.png"))); // NOI18N
    RunBtn.setToolTipText("Run");
    RunBtn.setFocusable(false);
    RunBtn.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
    RunBtn.setMaximumSize(new java.awt.Dimension(32, 32));
    RunBtn.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/play3_ro.png"))); // NOI18N
    RunBtn.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
    RunBtn.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        RunBtnActionPerformed(evt);
      }
    });

    StepForwardBtn.setIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/fastforward3.png"))); // NOI18N
    StepForwardBtn.setToolTipText("Step Forward");
    StepForwardBtn.setFocusable(false);
    StepForwardBtn.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
    StepForwardBtn.setMaximumSize(new java.awt.Dimension(32, 32));
    StepForwardBtn.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/fastforward3_ro.png"))); // NOI18N
    StepForwardBtn.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
    StepForwardBtn.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        StepForwardBtnActionPerformed(evt);
      }
    });

    SkipForwardBtn.setIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/skipforward3.png"))); // NOI18N
    SkipForwardBtn.setToolTipText("Skip Forward");
    SkipForwardBtn.setFocusable(false);
    SkipForwardBtn.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
    SkipForwardBtn.setMaximumSize(new java.awt.Dimension(32, 32));
    SkipForwardBtn.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/skipforward3_ro.png"))); // NOI18N
    SkipForwardBtn.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
    SkipForwardBtn.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        SkipForwardBtnActionPerformed(evt);
      }
    });

    org.jdesktop.layout.GroupLayout jPanel3Layout = new org.jdesktop.layout.GroupLayout(jPanel3);
    jPanel3.setLayout(jPanel3Layout);
    jPanel3Layout.setHorizontalGroup(
      jPanel3Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
      .add(jPanel3Layout.createSequentialGroup()
        .addContainerGap()
        .add(jPanel3Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING, false)
          .add(StepBackwardsBtn, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 45, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
          .add(ResetBtn, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 45, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
        .add(7, 7, 7)
        .add(jPanel3Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING, false)
          .add(jPanel3Layout.createSequentialGroup()
            .add(StepForwardBtn, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 45, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
            .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
            .add(SkipForwardBtn, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 45, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
          .add(RunBtn, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 96, Short.MAX_VALUE))
        .add(20, 20, 20))
    );
    jPanel3Layout.setVerticalGroup(
      jPanel3Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
      .add(jPanel3Layout.createSequentialGroup()
        .addContainerGap()
        .add(jPanel3Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING)
          .add(StepForwardBtn, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 45, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
          .add(StepBackwardsBtn, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 45, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
          .add(SkipForwardBtn, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 45, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
        .add(jPanel3Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
          .add(ResetBtn, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 45, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
          .add(RunBtn, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 45, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
        .addContainerGap())
    );

    jPanel4.setOpaque(false);

    saveObjectBtn.setIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/save.png"))); // NOI18N
    saveObjectBtn.setToolTipText("<html>Save outputs of selected blocks in a cell array contained in a plist.<br><tt>plist('collection', {})<tt></html>");
    saveObjectBtn.setFocusable(false);
    saveObjectBtn.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
    saveObjectBtn.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/save_ro.png"))); // NOI18N
    saveObjectBtn.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);

    ExploreBtn.setIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/explore.png"))); // NOI18N
    ExploreBtn.setToolTipText("Explore selected object(s)");
    ExploreBtn.setFocusable(false);
    ExploreBtn.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
    ExploreBtn.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/explore_ro.png"))); // NOI18N
    ExploreBtn.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);

    HistoryBtn.setIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/history.png"))); // NOI18N
    HistoryBtn.setToolTipText("Display history of the selected object.");
    HistoryBtn.setFocusable(false);
    HistoryBtn.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
    HistoryBtn.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/history_ro.png"))); // NOI18N
    HistoryBtn.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);

    tableBtn.setIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/table.png"))); // NOI18N
    tableBtn.setToolTipText("Show data in a table");
    tableBtn.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/table_ro.png"))); // NOI18N
    tableBtn.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);

    reportBtn.setIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/report.png"))); // NOI18N
    reportBtn.setToolTipText("Show a report of the selected objects");
    reportBtn.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/report_ro.png"))); // NOI18N
    reportBtn.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);

    DisplayBtn.setIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/display.png"))); // NOI18N
    DisplayBtn.setToolTipText("Display the selected object(s) on the MATLAB terminal");
    DisplayBtn.setFocusable(false);
    DisplayBtn.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
    DisplayBtn.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/display_ro.png"))); // NOI18N
    DisplayBtn.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);

    PlotBtn.setIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/plot.png"))); // NOI18N
    PlotBtn.setToolTipText("Plot selected objects");
    PlotBtn.setFocusable(false);
    PlotBtn.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
    PlotBtn.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/plot_ro.png"))); // NOI18N
    PlotBtn.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);

    exportWorkspaceBtn.setIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/export_to_ws.png"))); // NOI18N
    exportWorkspaceBtn.setToolTipText("Store to workspace");
    exportWorkspaceBtn.setFocusable(false);
    exportWorkspaceBtn.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
    exportWorkspaceBtn.setRolloverIcon(new javax.swing.ImageIcon(getClass().getResource("/mpipeline/icons/export_to_ws_ro.png"))); // NOI18N
    exportWorkspaceBtn.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);

    org.jdesktop.layout.GroupLayout jPanel4Layout = new org.jdesktop.layout.GroupLayout(jPanel4);
    jPanel4.setLayout(jPanel4Layout);
    jPanel4Layout.setHorizontalGroup(
      jPanel4Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
      .add(jPanel4Layout.createSequentialGroup()
        .addContainerGap()
        .add(jPanel4Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
          .add(jPanel4Layout.createSequentialGroup()
            .add(saveObjectBtn, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 36, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
            .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
            .add(exportWorkspaceBtn, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 36, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
          .add(jPanel4Layout.createSequentialGroup()
            .add(ExploreBtn, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 36, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
            .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
            .add(PlotBtn, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 36, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
          .add(jPanel4Layout.createSequentialGroup()
            .add(HistoryBtn, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 36, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
            .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
            .add(DisplayBtn, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 36, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
          .add(jPanel4Layout.createSequentialGroup()
            .add(tableBtn, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 36, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
            .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
            .add(reportBtn, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 36, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)))
        .addContainerGap(107, Short.MAX_VALUE))
    );

    jPanel4Layout.linkSize(new java.awt.Component[] {DisplayBtn, ExploreBtn, HistoryBtn, PlotBtn, exportWorkspaceBtn, reportBtn, saveObjectBtn, tableBtn}, org.jdesktop.layout.GroupLayout.HORIZONTAL);

    jPanel4Layout.setVerticalGroup(
      jPanel4Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
      .add(jPanel4Layout.createSequentialGroup()
        .addContainerGap()
        .add(jPanel4Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
          .add(saveObjectBtn, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 36, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
          .add(exportWorkspaceBtn, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 36, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
        .add(jPanel4Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
          .add(PlotBtn, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 36, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
          .add(ExploreBtn, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 36, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
        .add(jPanel4Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING)
          .add(HistoryBtn, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 36, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
          .add(DisplayBtn, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 36, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
        .add(jPanel4Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING)
          .add(tableBtn, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 36, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
          .add(reportBtn, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 36, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
        .addContainerGap(org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
    );

    jPanel4Layout.linkSize(new java.awt.Component[] {DisplayBtn, ExploreBtn, HistoryBtn, PlotBtn, exportWorkspaceBtn, reportBtn, saveObjectBtn, tableBtn}, org.jdesktop.layout.GroupLayout.VERTICAL);

    jPanel6.setOpaque(false);

    vebosityCombo.setMaximumRowCount(9);
    vebosityCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "OFF", "IMPORTANT", "MNAME", "PROC1", "PROC2", "PROC3", "PROC4", "PROC5", "OMNAME", "OPROC1", "OPROC2", "OPROC3", "OPROC4", "OPROC5" }));
    vebosityCombo.setSelectedIndex(((ltpdaPreferences2 == null) ? 0 : (ltpdaPreferences2.getDisplayPrefs().getDisplayVerboseLevel()+1)));
    vebosityCombo.setToolTipText("Set the verbosity of LTPDA. Higher numbers mean more output.");
    vebosityCombo.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        vebosityComboActionPerformed(evt);
      }
    });

    jLabel2.setText("Verbosity");

    org.jdesktop.layout.GroupLayout jPanel6Layout = new org.jdesktop.layout.GroupLayout(jPanel6);
    jPanel6.setLayout(jPanel6Layout);
    jPanel6Layout.setHorizontalGroup(
      jPanel6Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
      .add(jPanel6Layout.createSequentialGroup()
        .addContainerGap()
        .add(jPanel6Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
          .add(jPanel6Layout.createSequentialGroup()
            .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, 3, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
            .add(jLabel2))
          .add(vebosityCombo, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
        .addContainerGap(81, Short.MAX_VALUE))
    );
    jPanel6Layout.setVerticalGroup(
      jPanel6Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
      .add(jPanel6Layout.createSequentialGroup()
        .addContainerGap()
        .add(jLabel2)
        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
        .add(vebosityCombo, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 27, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
        .add(218, 218, 218))
    );

    org.jdesktop.layout.GroupLayout controlsTabLayout = new org.jdesktop.layout.GroupLayout(controlsTab);
    controlsTab.setLayout(controlsTabLayout);
    controlsTabLayout.setHorizontalGroup(
      controlsTabLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
      .add(controlsTabLayout.createSequentialGroup()
        .add(jSeparator6, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 185, Short.MAX_VALUE)
        .addContainerGap())
      .add(jPanel3, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 197, Short.MAX_VALUE)
      .add(jPanel4, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
      .add(controlsTabLayout.createSequentialGroup()
        .add(jSeparator7, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 185, Short.MAX_VALUE)
        .addContainerGap())
      .add(jPanel6, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
    );
    controlsTabLayout.setVerticalGroup(
      controlsTabLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
      .add(controlsTabLayout.createSequentialGroup()
        .add(jPanel3, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
        .add(jSeparator6, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
        .add(jPanel4, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
        .add(jSeparator7, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
        .add(jPanel6, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 160, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
        .addContainerGap(37, Short.MAX_VALUE))
    );

    mainTabPanel.addTab("Controls", null, controlsTab, "Activate with "+KeyEvent.getModifiersExText(keyModifier)+"+5 or "+KeyEvent.getModifiersExText(keyModifier)+"+R");

    jSplitPane1.setLeftComponent(mainTabPanel);

    instanceIdLabel.setText("Status:");

    jLabel4.setText("Workbench ID:");

    org.jdesktop.layout.GroupLayout jPanel5Layout = new org.jdesktop.layout.GroupLayout(jPanel5);
    jPanel5.setLayout(jPanel5Layout);
    jPanel5Layout.setHorizontalGroup(
      jPanel5Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
      .add(jSplitPane1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 1084, Short.MAX_VALUE)
      .add(org.jdesktop.layout.GroupLayout.TRAILING, jPanel5Layout.createSequentialGroup()
        .addContainerGap(895, Short.MAX_VALUE)
        .add(jLabel4)
        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
        .add(instanceIdLabel, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 93, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
    );
    jPanel5Layout.setVerticalGroup(
      jPanel5Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
      .add(jPanel5Layout.createSequentialGroup()
        .add(jSplitPane1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 551, Short.MAX_VALUE)
        .addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED)
        .add(jPanel5Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
          .add(instanceIdLabel)
          .add(jLabel4))
        .add(20, 20, 20))
    );

    MainMenuFile.setText("File");
    MainMenuBar.add(MainMenuFile);

    MainMenuEdit.setText("Edit");
    MainMenuBar.add(MainMenuEdit);

    MainMenuView.setText("View");
    MainMenuBar.add(MainMenuView);

    MainMenuFormat.setText("Format");
    MainMenuBar.add(MainMenuFormat);

    MainMenuPipeline.setText("Pipeline");
    MainMenuBar.add(MainMenuPipeline);

    MainMenuTools.setText("Tools");
    MainMenuBar.add(MainMenuTools);

    MainMenuWindow.setText("Window");
    MainMenuWindow.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        MainMenuWindowActionPerformed(evt);
      }
    });
    MainMenuWindow.addMenuListener(new javax.swing.event.MenuListener() {
      public void menuSelected(javax.swing.event.MenuEvent evt) {
        MainMenuWindowMenuSelected(evt);
      }
      public void menuDeselected(javax.swing.event.MenuEvent evt) {
      }
      public void menuCanceled(javax.swing.event.MenuEvent evt) {
      }
    });
    MainMenuBar.add(MainMenuWindow);

    MainMenuHelp.setText("Help");
    MainMenuBar.add(MainMenuHelp);

    setJMenuBar(MainMenuBar);

    org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(getContentPane());
    getContentPane().setLayout(layout);
    layout.setHorizontalGroup(
      layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
      .add(MainToolbar, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 1096, Short.MAX_VALUE)
      .add(layout.createSequentialGroup()
        .add(jPanel5, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        .addContainerGap())
      .add(statusLabel, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 1096, Short.MAX_VALUE)
    );
    layout.setVerticalGroup(
      layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
      .add(layout.createSequentialGroup()
        .add(MainToolbar, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 32, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
        .add(jPanel5, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        .add(4, 4, 4)
        .add(statusLabel))
    );

    pack();
  }// </editor-fold>//GEN-END:initComponents

  /**
   * Return the LTPDA Library associated with this workbench.
   * @return
   */
  public LTPDAlibrary getLibrary() {
    return lib;
  }

  /**
   * Return a list of documents in this workbench.
   * @return
   */
  public JInternalFrame[] getDocumentList() {
    return DocumentPane.getAllFrames();
  }

  /**
   * Set the given document to the active document.
   * @param fr
   */
  public void setActiveDocument(JInternalFrame fr) {
    DocumentPane.setSelectedFrame(fr);
  }

  /**
   *
   * @param diag
   */
  public void setActiveDiagram(BlockDiagram diag) {
    diag.requestFocusInWindow();
  }

  /**
   * Create a new document in this workbench.
   * @param name
   */
  public void createNewBlockDiagram(String name) {

    if (name.length() == 0) {
      name = "New Pipeline";
    }

    name = checkDiagramName(name);

    // make a new document
    BlockDiagram newDiag = new BlockDiagram(name, this);
//        documents.put(newDiag.getTitle(), newDiag);
    documents.add(newDiag);
    DocumentPane.add(newDiag);
    newDiag.setLocation(100 * documents.size(), 100 * documents.size());
    DocumentPane.setComponentZOrder(newDiag, 0);
    newDiag.requestFocusInWindow();
    try {
      newDiag.setSelected(true);
      newDiag.maximise(true);
    } catch (PropertyVetoException ex) {
      Logger.getLogger(MainWindow.class.getName()).log(Level.SEVERE, null, ex);
    }
    setSaved(false);
  }

  /**
   * Set up the sets popup menu
   */
  public void setupSetsPopup() {
    String[] sets = {"Current Parameters"};
    setCombo.setModel(new DefaultComboBoxModel(sets));
    setCombo.setEditable(false);
  }

  /**
   * Setup the block property table
   */
  public void setupBlockPropertyTable() {

    BlockPropertyTable.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
  }

  /**
   * Setup the parameter table
   */
  public void setupParamTable() {
//    ParamTable.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);

    Utils.dmsg("Parameter table setup.");
  }

  /**
   * Get the parameter table
   * @return
   */
  public JTable getParamTable() {
    return plistTable;
  }

  /**
   * Get the name of the given document.
   * @param fr
   * @return
   */
  public String getDiagramName(
          JInternalFrame fr) {
    return fr.getTitle();
  }

  /**
   * Get the canvas of the given document.
   * @param fr
   * @return
   */
  public MCanvas getCanvas(
          JInternalFrame fr) {
    BlockDiagram diag = (BlockDiagram) fr;
    return diag.getCanvas();
  }

  /**
   * Get the active document.
   * @return
   */
  public String getActiveDiagramName() {
    BlockDiagram diag = (BlockDiagram) DocumentPane.getSelectedFrame();
    if (diag != null) {
      if (diag.isSubsystem()) {
        diag = diag.getTopLevelDiagram();
      }

      return diag.getTitle();
    } else {
      return "Untitled";
    }

  }

  /**
   * Get the active document name as a MATLAB variable
   * @return
   */
  public String getActiveDiagramNameAsVar() {
    BlockDiagram diag = (BlockDiagram) DocumentPane.getSelectedFrame();
    String varname = null;
    if (diag != null) {
      if (diag.isSubsystem()) {
        diag = diag.getTopLevelDiagram();
      }

      varname = diag.getTitle();
    } else {
      varname = "Untitled";
    }

    varname = varname.replaceAll("\\s", "_");
    varname = varname.replaceAll("-", "_");

    varname = Utils.checkName(varname);

    return instanceIdentifier + "." + varname;
  }

  /**
   *
   * @param name
   * @return
   */
  public String checkDiagramName(
          String name) {
    name = Utils.checkName(name);
    Iterator it = documents.iterator();
    while (it.hasNext()) {
      BlockDiagram b = (BlockDiagram) it.next();
      String newtitle = name;
      if (b.isSubsystem()) {
        newtitle = b.getTitle() + " / " + name;
      }

//            if (!b.getCanvas().getMyParentDiagramTitle().equals("")) {
//                newtitle = b.getCanvas().getMyParentDiagramTitle() + " / " + name;
//            }
      Utils.dmsg("Checking requested diagram title: " + newtitle + " against: " + b.getTitle());
      if (b.getTitle().equals(newtitle)) {

        String bname = b.getName();

        name =
                Utils.incrementName(bname);

        if (name.equals(bname)) {
          name += "_1";
        }

      }
    }
    return name;
  }

  /**
   * Restore a block diagram with the given name and canvas.
   * @param name
   * @param canvas
   * @return
   */
  public BlockDiagram restoreBlockDiagram(
          String name, MCanvas canvas) {


    // if this is a top-level canvas we need to check its name
    name = Utils.checkName(name);
    String newname = name;
//        if (canvas.getMyParentDiagramTitle().equals("")) {
//            // check the block diagram name
//            newname = checkDiagramName(name);
//        }

    if (!newname.equals(name)) {
      Utils.dmsg(" requested name: " + name);
      Utils.dmsg(" suggested name: " + newname);
      JOptionPane.showMessageDialog(null,
              "Pipelines must have unique names within a workbench. Rename other pipelines before loading this one.",
              "Pipeline name error",
              JOptionPane.ERROR_MESSAGE);

      return null;
    } else {



      BlockDiagram diag = new BlockDiagram(newname, canvas, this);
      documents.add(diag);
      DocumentPane.add(diag);
      diag.setLocation(100 * documents.size(), 100 * documents.size());
      DocumentPane.setComponentZOrder(diag, 0);
      this.setVisible(true);
      diag.requestFocusInWindow();
      diag.revalidate();
      diag.repaint();
      try {
        diag.setSelected(true);
        diag.maximise(true);
      } catch (PropertyVetoException ex) {
        Logger.getLogger(MainWindow.class.getName()).log(Level.SEVERE, null, ex);
      }
      setSaved(false);
      return diag;
    }

  }

  /**
   * Set the library of this workbench.
   * @param l
   */
  public void setLibrary(LTPDAlibrary l) {
    lib = l;
  }

  /**
   * Get the canvas of the active document.
   * @return
   */
  public MCanvas getActiveCanvas() {
    BlockDiagram diag = (BlockDiagram) DocumentPane.getSelectedFrame();
    if (diag != null) {
      return diag.getCanvas();
    } else {
      return new MCanvas(this);
    }

  }

  /**
   * Get all blocks on the current document.
   * @return
   */
  public ArrayList<MElementWithPorts> getAllBlocks() {
    MCanvas canvas = null;
    // get active document
    BlockDiagram diag = (BlockDiagram) DocumentPane.getSelectedFrame();
    if (diag != null) {
      // Get the canvas
      canvas = diag.getCanvas();
    }

    if (canvas != null) {
      return canvas.getAllBlocksWithPorts();
    } else {
      return new ArrayList<MElementWithPorts>();
    }

  }

  /**
   * Get all nodes on the current document.
   * @return
   */
  public ArrayList<MNode> getAllNodes() {
    MCanvas canvas = null;
    // get active document
    BlockDiagram diag = (BlockDiagram) DocumentPane.getSelectedFrame();
    if (diag != null) {
      // Get the canvas
      canvas = diag.getCanvas();
    }

    if (canvas != null) {
      return canvas.getAllNodes();
    } else {
      return new ArrayList<MNode>();
    }

  }

  /**
   * Refresh the library tree.
   */
  public void refreshLibraryTree() {
    libmodel = new LTPDALibraryModel(lib);
    blockLibraryTree.setModel(libmodel);
    blockLibraryTree.revalidate();
    blockLibraryTree.repaint();
  }

  /**
   * Set up the shelf.
   */
  private void setupShelf() {


    shelfController = new ShelfController(this, null, shelfTree, shelfFile, version);
    shelf = shelfController.loadShelf();
    shelfController.validateShelf();
    shelfTree.setSelectionRow(0);

  }

  /**
   * Set up a starting default library. Useful for testing.
   */
  private void setupLibrary() {

    LTPDAcategory cat = new LTPDAcategory("AO");
    LTPDAcategory scat = new LTPDAcategory("Constructors");
    LTPDAalgorithm a = new LTPDAalgorithm();
    a.setMname("ao");
    a.setMcategory("Constructor");
    a.setMclass("ao");
    a.setHelpTxt("% PSD makes power spectral density estimates of the time-series objects\n"
            + "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"
            + "%\n"
            + "% DESCRIPTION: PSD makes power spectral density estimates of the\n"
            + "%              time-series objects in the input analysis objects\n"
            + "%              using the Welch Overlap method. PSD is computed\n"
            + "%              using a modified version of MATLAB's welch (>> help welch).\n"
            + "%\n"
            + "% CALL:        bs = psd(a1,a2,a3,...,pl)\n"
            + "%              bs = psd(as,pl)\n"
            + "%              bs = as.psd(pl)\n"
            + "%\n"
            + "% INPUTS:      aN   - input analysis objects\n"
            + "%              as   - input analysis objects array\n"
            + "%              pl   - input parameter list\n"
            + "% \n"
            + "% OUTPUTS:     bs   - array of analysis objects, one for each input\n"
            + "%\n"
            + "% <a href=\"matlab:web(ao.getInfo('psd').tohtml, '-helpbrowser')\">Parameter Sets</a>\n"
            + "%\n"
            + "% VERSION:    $Id: MainWindow.java,v 1.151 2011/05/12 17:06:53 ingo Exp $\n"
            + "%\n"
            + "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n");
    a.setMinInputs(2);
    a.setMinOutputs(1);
    JPlist pl = new JPlist();
    pl.add("Filename", "foo.xml", "char", "The filename to read from or write to \\n and even on two lines");
    pl.add("Count", 2.0, "double", "Some parameter that represents a count.");
    JParamValue pv = new JParamValue();
    pv.addOption("ASD", "char");
    pv.addOption("PSD", "char");
    pv.addOption("AS", "char");
    pv.setValIndex(0);
    try {
      pv.setSelection(JParamValue.SINGLE);
    } catch (Exception ex) {
      Logger.getLogger(MainWindow.class.getName()).log(Level.SEVERE, null, ex);
    }
    JParam p = new JParam("SCALE", pv);
    pl.add(p);

//    pl.display();

    a.addSetPlist("From Filename", pl);

    JPlist dpl = new JPlist();
    dpl.add("Key", "val", "char", "A key/value pair");

    a.addSetPlist("Default", dpl);

    scat.addAlgorithm(a);

    LTPDAalgorithm b = new LTPDAalgorithm();
    b.setMname("save");
    b.setMcategory("Output");
    b.setMclass("ao");
    b.setHelpTxt("Help me please because I want to help you to use me in the right way.");
    b.setMinInputs(1);
    b.setMinOutputs(1);
    JPlist pl2 = new JPlist();
    pl2.add("Filename", "foo.xml", "char", "The filename to read from or write to.");
    pl2.add("Count", 2, "double", "Some parameter that represents a count.");
    b.addSetPlist("From Filename", pl2);
    scat.addAlgorithm(b);

    LTPDAalgorithm c = new LTPDAalgorithm();
    c.setMname("ssm");
    c.setMcategory("Constructor");
    c.setMclass("ssm");
    c.setMinInputs(1);
    c.setMinOutputs(1);
    JPlist pl3 = new JPlist();
    pl3.add("built-in", "", "char");
    c.addSetPlist("From Built-in", pl3);
    scat.addAlgorithm(c);


    LTPDAalgorithm d = new LTPDAalgorithm();
    d.setMname("miir");
    d.setMcategory("Constructor");
    d.setMclass("miir");
    d.setMinInputs(1);
    d.setMinOutputs(1);
    JPlist pl4 = new JPlist();
    pl4.add("type", "lowpass", "char");
    d.addSetPlist("From Standard Type", pl4);
    scat.addAlgorithm(d);
    cat.addSubCategory(scat);
    lib.addCategory(cat);
    libmodel = new LTPDALibraryModel(lib);

    blockLibraryTree.setModel(libmodel);
//    blockLibraryTree.setExpandsSelectedPaths(true);
//
//    blockLibraryTree.expandRow(0);
//
//    blockLibraryTree.setDragEnabled(true);
//    blockLibraryTree.setTransferHandler(new AlgorithmTransfer());

//    HelperWindow w = new HelperWindow();
//    w.addFunction(a);
//    w.addFunction(b);
//    w.addFunction(c);
//    w.addFunction(d);
//
//    w.setVisible(true);
  }

  /**
   * Make a new pipeline document.
   */
  public void newDocument() {
//        System.out.println("Preparing for new document: " + documents.size() + " documents");
//        Iterator dit = documents.iterator();
//        while (dit.hasNext()) {
//            BlockDiagram d = (BlockDiagram) dit.next();
//            System.out.println("  diagram: " + d.getTitle());
//        }
    // make a new document
    BlockDiagram newDiag = new BlockDiagram(documents.size() + 1, this);
    documents.add(newDiag);
    DocumentPane.add(newDiag);
    newDiag.setLocation(10 * documents.size(), 10 * documents.size());
    DocumentPane.setComponentZOrder(newDiag, 0);
    newDiag.requestFocusInWindow();
    try {
      newDiag.setSelected(true);
      newDiag.maximise(true);
    } catch (PropertyVetoException ex) {
      Logger.getLogger(MainWindow.class.getName()).log(Level.SEVERE, null, ex);
    }

//        System.out.println("  now have " + documents.size() + " documents");
//        dit = documents.iterator();
//        while (dit.hasNext()) {
//            BlockDiagram d = (BlockDiagram) dit.next();
//            System.out.println("  diagram: " + d.getTitle());
//        }

    setSaved(false);
    stateChanged("New Document");

    buildPipelineList();
    ((PipelineListTree) pipelineListTree).setActivePipeline(newDiag);

//    newDiag.setCurrent(true);
  }

  /**
   *
   * @param newDiag
   */
  public void addDocument(BlockDiagram newDiag) {

    boolean docViewExists = false;
    MCanvas nc = newDiag.getCanvas();
    Iterator it = documents.iterator();
    while (it.hasNext()) {
      BlockDiagram d = (BlockDiagram) it.next();
      MCanvas c = d.getCanvas();
      if (c.equals(nc)) {
        docViewExists = true;
      }
    }

    if (!docViewExists) {
      documents.add(newDiag);
      newDiag.setLocation(10 * documents.size(), 10 * documents.size());
      DocumentPane.add(newDiag);
      DocumentPane.setComponentZOrder(newDiag, 0);
      newDiag.setVisible(false);
    }
    buildPipelineList();
  }

  /**
   * Reset the current pipeline to initial state.
   */
  public void resetCurrentPipeline() {
    // get active document
    BlockDiagram diag = (BlockDiagram) DocumentPane.getSelectedFrame();
    if (diag != null) {
      if (diag.isSubsystem()) {
        diag = diag.getTopLevelDiagram();
      }

      Utils.msg("Resetting diagram: " + diag.getTitle());
      // Get the canvas
      MCanvas canvas = diag.getCanvas();
      // Reset all blocks to not executed
      canvas.resetAllBlocks();
    }

  }

  /**
   * Step forward in the current pipeline
   */
  public void stepForwardCurrentPipeline() {
    // get active document
    BlockDiagram diag = (BlockDiagram) DocumentPane.getSelectedFrame();
    if (diag != null) {
      if (diag.isSubsystem()) {
        diag = diag.getTopLevelDiagram();
      }
      // Get the canvas
      MCanvas canvas = diag.getCanvas();
      canvas.stepForwards();
    }

  }

  /**
   * Step backwards in the current diagram.
   */
  public void stepBackwardCurrentPipeline() {
    // get active document
    BlockDiagram diag = (BlockDiagram) DocumentPane.getSelectedFrame();
    if (diag != null) {
      if (diag.isSubsystem()) {
        diag = diag.getTopLevelDiagram();
      }
// Get the canvas

      MCanvas canvas = diag.getCanvas();
      canvas.stepBackwards();
    }

  }

  /**
   * Return a count of the blocks currently ready to execute.
   * @return
   */
  public int countReadyBlocks() {
    // get active document
    BlockDiagram diag = (BlockDiagram) DocumentPane.getSelectedFrame();
    // Get the canvas
    if (diag == null) {
      System.err.println("No selected pipeline found.");
      return 0;
    } else {
      if (diag.isSubsystem()) {
        diag = diag.getTopLevelDiagram();
      }

      MCanvas canvas = diag.getCanvas();
      return canvas.getReadyBlocks().size();
    }

  }

  /**
   *
   * @return
   */
  public ArrayList<MConstant> getAllConstants() {

    ArrayList<MConstant> constants = new ArrayList<MConstant>();
    // get active document
    JInternalFrame jif = DocumentPane.getSelectedFrame();
    if (jif != null) {
      BlockDiagram diag = (BlockDiagram) jif;
//            if (!diag.isSubsystem()) {
      // Get the canvas
      if (diag != null) {
        MCanvas canvas = diag.getCanvas();
        constants =
                canvas.getAllConstants();
      }
//            } else {
//                System.err.println("Pipeline execution can only take place on the top level pipeline.");
//            }

    }
    return constants;
  }

  /**
   * Get an array of the current ready blocks.
   * @return
   */
  public ArrayList<MElementWithPorts> getReadyBlocks() {
    ArrayList<MElementWithPorts> readyblocks = new ArrayList<MElementWithPorts>();
    // get active document
    JInternalFrame jif = DocumentPane.getSelectedFrame();
    if (jif != null) {
      BlockDiagram diag = (BlockDiagram) jif;
//            if (!diag.isSubsystem()) {
      // Get the canvas
      if (diag != null) {
        if (diag.isSubsystem()) {
          diag = diag.getTopLevelDiagram();
        }

        MCanvas canvas = diag.getCanvas();
        readyblocks = canvas.getReadyBlocks();
      }
//            } else {
//                System.err.println("Pipeline execution can only take place on the top level pipeline.");
//            }

    }
    return readyblocks;
  }

  /**
   * Return an array of the selected blocks.
   * @return
   */
  public ArrayList<MBlock> getSelectedBlocks() {
    // get active document
    BlockDiagram diag = (BlockDiagram) DocumentPane.getSelectedFrame();
    // Get the canvas
    if (diag != null) {
      MCanvas canvas = diag.getCanvas();
      return canvas.getSelectedBlocks();
    } else {
      return new ArrayList<MBlock>();
    }

  }

  /**
   * Return an array of the selected elements.
   * @return
   */
  public ArrayList<MElementSelectable> getSelectedElements() {
    ArrayList<MElementSelectable> els = new ArrayList<MElementSelectable>();

    // get active document
    BlockDiagram diag = (BlockDiagram) DocumentPane.getSelectedFrame();
    // Get the canvas
    if (diag != null) {
      MCanvas canvas = diag.getCanvas();
      els.addAll(canvas.getSelectedElements());
    }

    return els;
  }

  /**
   *
   * @return
   */
  public JButton getPlotBtn() {
    return PlotBtn;
  }

  /**
   *
   * @return
   */
  public JButton getExploreBtn() {
    return ExploreBtn;
  }

  private void showBlockLibraryContextMenu(MouseEvent evt) {
    if (evt.isPopupTrigger()) {
      // is a tree node selected?
      Object o = blockLibraryTree.getLastSelectedPathComponent();
      if (o == null) {
        //Nothing is selected.
        return;
      }

      if (o instanceof LTPDAalgorithm) {
        // pop up a context menu
        BlocktreeContextMenu.show(evt.getComponent(), evt.getX(), evt.getY());
      }

    }
  }

private void blockLibraryTreeMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_blockLibraryTreeMousePressed
  // respond to system popup menu actions
  showBlockLibraryContextMenu(evt);
}//GEN-LAST:event_blockLibraryTreeMousePressed

  /**
   * Connect the blocks with the given names at the given port numbers.
   * @param src
   * @param sp
   * @param dst
   * @param dp
   */
  public void connectBlocks(String src, int sp, String dst, int dp) {

    BlockDiagram diag = (BlockDiagram) DocumentPane.getSelectedFrame();
    if (diag != null) {
      // get canvas
      MCanvas canvas = diag.getCanvas();
      // find blocks
      MElementWithPorts srcblock = canvas.getBlock(src);
      MElementWithPorts dstblock = canvas.getBlock(dst);
      // connect these up
      canvas.connectElements(srcblock, sp - 1, dstblock, dp - 1);
      setSaved(false);
    }

  }

  /**
   * Add an input to the given block.
   * @param name
   */
  public void addBlockInput(String name) {
    BlockDiagram diag = (BlockDiagram) DocumentPane.getSelectedFrame();
    MElementWithPorts b = null;
    if (diag != null) {
      // get canvas
      MCanvas canvas = diag.getCanvas();
      // find blocks
      b = canvas.getBlock(name);
      b.addInput();
      setSaved(false);
    }

  }

  /**
   * Add an output to the given block.
   * @param name
   */
  public void addBlockOutput(String name) {
    BlockDiagram diag = (BlockDiagram) DocumentPane.getSelectedFrame();
    MElementWithPorts b = null;
    if (diag != null) {
      // get canvas
      MCanvas canvas = diag.getCanvas();
      // find blocks
      b =
              canvas.getBlock(name);
      b.addOutput();
      setSaved(false);
    }

  }

  /**
   * Get the block with the given name.
   * @param name
   * @return
   */
  public MElementWithPorts getBlockByName(
          String name) {
    BlockDiagram diag = (BlockDiagram) DocumentPane.getSelectedFrame();
    MElementWithPorts b = null;
    if (diag != null) {
      // get canvas
      MCanvas canvas = diag.getCanvas();
      // find blocks
      b =
              canvas.getBlock(name);
    }

    return b;
  }

  /**
   * Add a block with the given name and representing the given LTPDA
   * algorithm to the current document.
   * @param name
   * @param a
   * @return
   */
  public String AddBlock(
          String name, LTPDAalgorithm a) {
    BlockDiagram diag = (BlockDiagram) DocumentPane.getSelectedFrame();
    if (diag != null) {
      if (a instanceof LTPDAalgorithm) {
        // check this name against existing blocks
        MCanvas canvas = diag.getCanvas();
        Utils.dmsg("Adding to canvas: " + canvas);
        canvas.newBlock(name, a);
      }

    }
    setSaved(false);
    return name;
  }

  /**
   * Get the block selected in the tree
   * @return
   */
  public LTPDAalgorithm getBlockInMenu() {
    Object a = blockLibraryTree.getLastSelectedPathComponent();
    if (a != null) {
      return (LTPDAalgorithm) a;
    } else {
      return null;
    }

  }

  /**
   * Add a block to the current canvas.
   * @param name the name of the block
   * @param a an LTPDAalgorithm that this block represents
   * @param x place the block at this x coordinate
   * @param y place the block at this y coordinate
   * @return
   */
  public MBlock AddBlock(
          String name, LTPDAalgorithm a, int x, int y) {
    BlockDiagram diag = (BlockDiagram) DocumentPane.getSelectedFrame();
    MBlock b = null;
    if (diag != null) {
      if (a instanceof LTPDAalgorithm) {
        Utils.dmsg("Adding block");
        // check this name against existing blocks
        MCanvas canvas = diag.getCanvas();
        int dw = preferences.getMblockPreferences().getDefaultWidth();
        int dh = preferences.getMblockPreferences().getDefaultHeight();
        b = new MBlock(name, a, new Point(x, y), new Dimension(dw, dh));
        b.applyPreferences(preferences.getMblockPreferences());
        canvas.addBlock(b);
      }
    }
    setSaved(false);
    return b;
  }

private void AddBlockMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_AddBlockMenuItemActionPerformed
  // get current document
  addLibraryBlock();
}//GEN-LAST:event_AddBlockMenuItemActionPerformed

  /**
   * Add the library block to the canvas.
   */
  public void addLibraryBlock() {
    BlockDiagram diag = (BlockDiagram) DocumentPane.getSelectedFrame();
    if (diag != null) {
      TreePath[] paths = blockLibraryTree.getSelectionPaths();
      for (int kk = 0; kk < paths.length; kk++) {
        Object a = paths[kk].getLastPathComponent();

        if (a instanceof LTPDAalgorithm) {
          LTPDAalgorithm algo = (LTPDAalgorithm) a;
          MCanvas c = diag.getCanvas();
          if (c != null) {
            Point p = c.getViewportCenter();
            int dw = preferences.getMblockPreferences().getDefaultWidth();
            int dh = preferences.getMblockPreferences().getDefaultHeight();
            MBlock b = new MBlock("Unknown", new LTPDAalgorithm(algo), new Point(p.x, p.y), new Dimension(dw, dh));
            b.setDefaultPlist();
            b.getPlist().replaceKeysWithDefaultPreferences(ltpdaPreferences2);

            b.applyPreferences(preferences.getMblockPreferences());
            c.addBlock(b);
            c.autoPlace(b);
            c.postAddElementEdit(b);
            // select the new block
            c.clearSelection();
            c.selectElement(b);
            c.updatePropertiesAndParametersTables(c.getSelectedElements());
          }
        }
      }
    }
  }

private void blockLibraryTreeValueChanged(javax.swing.event.TreeSelectionEvent evt) {//GEN-FIRST:event_blockLibraryTreeValueChanged
  Object a = blockLibraryTree.getLastSelectedPathComponent();

  if (a instanceof LTPDAalgorithm) {
    LTPDAalgorithm algo = (LTPDAalgorithm) a;
//        System.out.println(algo.getHelpTxt());
    blockLibraryTree.setToolTipText(algo.getHelpTxt());
  }

}//GEN-LAST:event_blockLibraryTreeValueChanged

private void ParamRmvBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ParamRmvBtnActionPerformed
    // get selected block//GEN-LAST:event_ParamRmvBtnActionPerformed
    BlockDiagram diag = (BlockDiagram) DocumentPane.getSelectedFrame();
    MBlock b = null;
    if (diag != null) {
      // get canvas
      MCanvas canvas = diag.getCanvas();
      // find blocks
      ArrayList<MBlock> blocks = canvas.getSelectedBlocks();
      if (!blocks.isEmpty()) {
        b = blocks.get(0);
        // get selected parameter
        int[] srows = plistTable.getSelectedRows();
        int nr = srows.length;
        if (nr > 0) {
          int i0 = srows[0];
          for (int kk = 0; kk < nr; kk++) {
            String pm = (String) plistTable.getValueAt(i0, 1);
            b.getPlist().removeParam(pm);
          }
          plistTable.getSelectionModel().setSelectionInterval(srows[0] - 1, srows[0] - 1);
        }
        ((PlistTable) plistTable).setParameterList(b.getPlist());
        stateChanged("Parameter removed from list");
        plistTable.repaint();
      }
    }
  }

  /**
   * Move the requested block to the given coordinates.
   * @param bname
   * @param X
   * @param Y
   */
  public void moveBlock(String bname, int X, int Y) {

    BlockDiagram diag = (BlockDiagram) DocumentPane.getSelectedFrame();
    MElementWithPorts b = null;
    if (diag != null) {
      // get canvas
      MCanvas canvas = diag.getCanvas();
      // find blocks
      b =
              canvas.getBlock(bname);
      b.moveTo(X, Y);
      setSaved(false);

    }

  }

private void ParamAddBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ParamAddBtnActionPerformed
  // get selected block
  BlockDiagram diag = (BlockDiagram) DocumentPane.getSelectedFrame();
  MBlock b = null;
  if (diag != null) {
    // get canvas
    MCanvas canvas = diag.getCanvas();
    // find blocks
    ArrayList<MBlock> blocks = canvas.getSelectedBlocks();
    if (!blocks.isEmpty()) {
      b = blocks.get(0);

      // get name for new parameter
      SimpleInputDialog sd = new SimpleInputDialog(this, true,
              "Set Key",
              "New key",
              "NewKey", b);

      sd.setVisible(true);

      String newkey = null;
      if (!sd.wasCancelled()) {
        newkey = sd.getInput();
      }

//                String newkey = JOptionPane.showInputDialog(null,
//                    "Key", "NewKey");

      if (newkey != null) {

        b.getPlist().add(newkey, "none", "char");

        // get value for new parameter
        // select the cell and fire the edit callback
        int eRow = plistTable.getRowCount() - 1;
        plistTable.setEditingColumn(1);
        plistTable.setEditingRow(eRow);
        TableModel tm = plistTable.getModel();
//        String newvalue = tm.getParamValue(this, b, eRow, 1, "");
        Object newvalue = tm.getValueAt(eRow, 1);
        if (newvalue == null) {
          newvalue = "";
        }
        if (tm instanceof PlistTableModel) {
          PlistTableModel ptm = (PlistTableModel) tm;
          ptm.setPl(b.getPlist());
        }
//        plistTable.setModel(new PlistTableModel(b.getPlist()));
//        b.getPlist().setValueForKey(newkey, newvalue);
        plistTable.getSelectionModel().setSelectionInterval(eRow, eRow);
      }
    }
    stateChanged("Parameter added to list");
  }
  plistTable.repaint();
}//GEN-LAST:event_ParamAddBtnActionPerformed

private void setComboActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_setComboActionPerformed

  // get selected block
  BlockDiagram diag = (BlockDiagram) DocumentPane.getSelectedFrame();
  MBlock b = null;
  if (diag != null) {
    // get canvas
    MCanvas canvas = diag.getCanvas();
    // find blocks
    ArrayList<MBlock> blocks = canvas.getSelectedBlocks();
    if (!blocks.isEmpty()) {
      b = blocks.get(0);
//            b.getPlist().addParam(new Param("Unknown", "", "Char"));
      // get plists and sets from the block
//      b.getMinfo().display();
      ArrayList<String> sets = b.getMinfo().getSets();
      ArrayList<JPlist> plists = b.getMinfo().getPlists();
      // which set did the user select?
      String set = (String) setCombo.getSelectedItem();
      Utils.dmsg("Selected set: " + set);
      // find this set in the list
      int idx = sets.indexOf(set);
      JPlist pl = null;
      if (idx == -1) {
        pl = b.getPlist();
      } else {
        Utils.dmsg("Selected set: " + idx + "(" + sets.get(idx) + ")");
        pl = plists.get(idx);
      }
      // set plist
      ((PlistTable) plistTable).setParameterList(pl);

      // If we are on 'current parameters' the table should be editable
      if (idx >= 0) {
        plistTable.setEnabled(false);
        ParamAddBtn.setEnabled(false);
        ParamRmvBtn.setEnabled(false);
      } else {
        plistTable.setEnabled(true);
        ParamAddBtn.setEnabled(true);
        ParamRmvBtn.setEnabled(true);
      }

      // do we need to enable the set button
      JPlist bpl = b.getPlist();

      if (!bpl.equals(pl)) {
        ApplyBtn.setEnabled(true);
      } else {
        ApplyBtn.setEnabled(false);
      }

    }
  }
}//GEN-LAST:event_setComboActionPerformed

private void setComboPropertyChange(java.beans.PropertyChangeEvent evt) {//GEN-FIRST:event_setComboPropertyChange
}//GEN-LAST:event_setComboPropertyChange

private void ApplyBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ApplyBtnActionPerformed

  // get selected block
  BlockDiagram diag = (BlockDiagram) DocumentPane.getSelectedFrame();
  MBlock b = null;
  // get plist
  JPlist pl = ((PlistTableModel) plistTable.getModel()).getPl();
  if (diag != null) {
    // get canvas
    MCanvas canvas = diag.getCanvas();
    // find blocks
    ArrayList<MBlock> blocks = canvas.getSelectedBlocks();
    Iterator itBlock = blocks.iterator();
    while (itBlock.hasNext()) {

      JPlist plCopy = new JPlist(pl);
      plCopy.replaceKeysWithDefaultPreferences(ltpdaPreferences2);

      b = (MBlock) itBlock.next();
      b.setPlist(plCopy);

      // set the combo box to 'current parameters'
      canvas.updatePropertiesAndParametersTables(canvas.getSelectedElements());
    }

    stateChanged("Parameter list set to block(s)");
  }
  ApplyBtn.setEnabled(false);
  setSaved(false);

}//GEN-LAST:event_ApplyBtnActionPerformed

private void BlockSearchTxtPropertyChange(java.beans.PropertyChangeEvent evt) {//GEN-FIRST:event_BlockSearchTxtPropertyChange
}//GEN-LAST:event_BlockSearchTxtPropertyChange

private void BlockSearchTxtActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_BlockSearchTxtActionPerformed
//
//
//    Object result = lib.search(searchText);
//    System.out.println("Found : " + result.toString());
//    
}//GEN-LAST:event_BlockSearchTxtActionPerformed

private void formKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_formKeyPressed
}//GEN-LAST:event_formKeyPressed

  /**
   * Call this when the window is closing, for whatever reason.
   */
  private void handleWindowClosing() {

    // are you sure you want to close this window?
    int n = JOptionPane.showConfirmDialog(null,
            "Are you sure you want to close this workbench?",
            "Confirm", JOptionPane.YES_NO_OPTION);

    if (n == JOptionPane.YES_OPTION) {
      // is the workbench saved?
      if (isSaved()) {
//                this.setVisible(false);
        closeMe();
      } else {
        // save before closing?
        int sn = JOptionPane.showConfirmDialog(null,
                "Do you want to save this workbench before closing?",
                "Confirm", JOptionPane.YES_NO_OPTION);
        if (sn == JOptionPane.YES_OPTION) {
          try {
            // save this workbench
            if (saveWorkbench()) {
//                            this.setVisible(false);
              closeMe();
            }


          } catch (Exception ex) {
            Logger.getLogger(MainWindow.class.getName()).log(Level.SEVERE, null, ex);
          }
        } else {
//                    this.setVisible(false);
          closeMe();
        }

      }
    }

  }

  private void closeMe() {

    // Save workbench preferences
    writePreferences();
    // commit LTPDA preferences to disk
    ltpdaPreferences2.writeToDisk();

    // Deleting documents
    Utils.msg("Deleting documents: " + documents.size());
    int nk = documents.size();
    for (int kk = 0; kk
            < nk; kk++) {
      BlockDiagram doc = documents.get(kk);
      Utils.msg("  deleting document: " + doc.getTitle());
      Utils.msg("Disposing of main window");
      doc.dispose();
    }

    autosaveTimer.stop();
    DocumentPane.removeAll();
    documents.clear();

    if (parametersOverviewDialog != null) {
      parametersOverviewDialog.dispose();
    }
    if (console != null) {
      console.dispose();
    }

    this.dispose();
    try {
      this.finalize();
    } catch (Throwable ex) {
      Logger.getLogger(MainWindow.class.getName()).log(Level.SEVERE, null, ex);
    }
  }

private void ResetBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ResetBtnActionPerformed


  this.resetCurrentPipeline();


}//GEN-LAST:event_ResetBtnActionPerformed

private void StepForwardBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_StepForwardBtnActionPerformed
}//GEN-LAST:event_StepForwardBtnActionPerformed

private void StepBackwardsBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_StepBackwardsBtnActionPerformed
}//GEN-LAST:event_StepBackwardsBtnActionPerformed

private void RunBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_RunBtnActionPerformed
}//GEN-LAST:event_RunBtnActionPerformed

private void SkipForwardBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_SkipForwardBtnActionPerformed
}//GEN-LAST:event_SkipForwardBtnActionPerformed

private void MainMenuWindowActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_MainMenuWindowActionPerformed
}//GEN-LAST:event_MainMenuWindowActionPerformed

private void MainMenuWindowMenuSelected(javax.swing.event.MenuEvent evt) {//GEN-FIRST:event_MainMenuWindowMenuSelected
  MainMenuWindow.removeAll();
  buildWindowsMenu("none");
}//GEN-LAST:event_MainMenuWindowMenuSelected

private void BlockSearchTxtKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_BlockSearchTxtKeyPressed
//    searchLibrary(evt);
}//GEN-LAST:event_BlockSearchTxtKeyPressed

private void BlockSearchTxtKeyTyped(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_BlockSearchTxtKeyTyped
//    Utils.msg("Key typed: " + evt.toString());
//    searchLibrary(evt);
}//GEN-LAST:event_BlockSearchTxtKeyTyped

private void BlockSearchTxtKeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_BlockSearchTxtKeyReleased

  searchLibrary(evt);
}//GEN-LAST:event_BlockSearchTxtKeyReleased

  private void searchLibrary(KeyEvent evt) {
    String searchText = BlockSearchTxt.getText();
    boolean matched = false;
    if (searchText.equals("")) {
//            Utils.dmsg("search string is empty");
      blockLibraryTree.setSelectionRow(0);
      blockLibraryTree.scrollPathToVisible(blockLibraryTree.getSelectionPath());
    } else {
      if (searchText.equals(lastSearchTxt)) {
        if (evt.getKeyCode() == KeyEvent.VK_ENTER && evt.isShiftDown()) {
          int[] srow = blockLibraryTree.getSelectionRows();
          matched = listTableRows(srow[0] + 1, searchText, true);
        }
      } else {
        lastSearchTxt = searchText;
        // search the whole tree until we find a leaf that starts with this text
        matched = listTableRows(0, searchText, true);
        if (!matched) {
          blockLibraryTree.setSelectionRow(0);
          blockLibraryTree.scrollPathToVisible(blockLibraryTree.getSelectionPath());
        }
      }
    }

    if (evt.getKeyCode() == KeyEvent.VK_ENTER && !evt.isShiftDown()) {
      addLibraryBlock();
    }

  }

  private boolean listTableRows(int start, String searchText, boolean forward) {
    int nrows = blockLibraryTree.getRowCount();
    int kk = start;
    TreePath lastParent = null;
    boolean matched = false;
    if (forward) {
      while (kk < nrows) {
        blockLibraryTree.setSelectionRow(kk);
        // expand this row
        TreePath tp = blockLibraryTree.getSelectionPath();
        blockLibraryTree.expandPath(tp);
//            System.out.println("Row " + kk + " = " + tp);

        // check if this is a leaf
        Object o = tp.getPathComponent(tp.getPathCount() - 1);
        if (o instanceof LTPDAalgorithm) {
          // does it match the search string?
          LTPDAalgorithm a = (LTPDAalgorithm) o;
          if (a.getMname().toLowerCase().startsWith(searchText.toLowerCase())) {
            blockLibraryTree.scrollPathToVisible(tp);
            matched = true;
            break;
          }
        }
        nrows = blockLibraryTree.getRowCount();
        kk++;
      }

      if (kk == nrows && !matched) {
        // reset tree
        blockLibraryTree.setSelectionRow(0);
        blockLibraryTree.scrollPathToVisible(blockLibraryTree.getSelectionPath());
      }
    } else {

      while (kk >= 0) {
        blockLibraryTree.setSelectionRow(kk);
        // expand this row
        TreePath tp = blockLibraryTree.getSelectionPath();
        blockLibraryTree.expandPath(tp);
//            System.out.println("Row " + kk + " = " + tp);

        // check if this is a leaf
        Object o = tp.getPathComponent(tp.getPathCount() - 1);
        if (o instanceof LTPDAalgorithm) {
          // does it match the search string?
          LTPDAalgorithm a = (LTPDAalgorithm) o;
          if (a.getMname().toLowerCase().startsWith(searchText.toLowerCase())) {
            blockLibraryTree.scrollPathToVisible(tp);
            matched = true;
            break;
          }
        }
        nrows = blockLibraryTree.getRowCount();
        kk--;
      }

      if (kk <= 0 && !matched) {
        // reset tree
        blockLibraryTree.setSelectionRow(0);
        blockLibraryTree.scrollPathToVisible(blockLibraryTree.getSelectionPath());
      }
    }

    return matched;
  }

private void blockLibraryTreeKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_blockLibraryTreeKeyPressed

  if (evt.getKeyCode() == KeyEvent.VK_ENTER) {
    // add the selected leaf
    addLibraryBlock();

  } else if (evt.getKeyCode() == KeyEvent.VK_ESCAPE) {

    // reset library tree
    blockLibraryTree.setSelectionRow(0);
    blockLibraryTree.scrollPathToVisible(blockLibraryTree.getSelectionPath());
  }

}//GEN-LAST:event_blockLibraryTreeKeyPressed

private void formWindowClosing(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosing

  handleWindowClosing();
}//GEN-LAST:event_formWindowClosing

private void blockLibraryTreeMouseReleased(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_blockLibraryTreeMouseReleased

// respond to system popup menu actions
  showBlockLibraryContextMenu(evt);
//  if (evt.isPopupTrigger()) {
//    // is a tree node selected?
//    Object o = blockLibraryTree.getLastSelectedPathComponent();
//    if (o == null) {
//      //Nothing is selected.
//      return;
//    }
//
//    if (o instanceof LTPDAalgorithm) {
//      // pop up a context menu
//      BlocktreeContextMenu.show(evt.getComponent(), evt.getX(), evt.getY());
//    }
//
//  }
}//GEN-LAST:event_blockLibraryTreeMouseReleased

private void BlockHelpMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_BlockHelpMenuItemActionPerformed

  Object a = blockLibraryTree.getLastSelectedPathComponent();

  if (a instanceof LTPDAalgorithm) {
    LTPDAalgorithm algo = (LTPDAalgorithm) a;
//        System.out.println(algo.getHelpTxt());
    HelpDialog hd = new HelpDialog(this, false);
    hd.setText(algo.getHelpTxt());
    hd.setVisible(true);
    hd.setTitle("Help: " + algo.getMclass() + "/" + algo.getMname());
  }

}//GEN-LAST:event_BlockHelpMenuItemActionPerformed

private void blockLibraryTreeMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_blockLibraryTreeMouseClicked


  if (evt.getClickCount() == 2 && !evt.isPopupTrigger()) {
    addLibraryBlock();
  } else {
    TreePath[] paths = blockLibraryTree.getSelectionPaths();
    if (paths != null) {
      for (int kk = 0; kk < paths.length; kk++) {
        Object a = paths[kk].getLastPathComponent();
        if (a instanceof LTPDAalgorithm) {
          LTPDAalgorithm algo = (LTPDAalgorithm) a;
//        algo.display();
        }
      }
    }
  }


}//GEN-LAST:event_blockLibraryTreeMouseClicked

private void jScrollPane3MouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jScrollPane3MouseClicked

  if (evt.getClickCount() == 2) {

    Utils.msg("Double-click on table");
  }

}//GEN-LAST:event_jScrollPane3MouseClicked

private void togifTBBActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_togifTBBActionPerformed

  BlockDiagram diag = (BlockDiagram) DocumentPane.getSelectedFrame();
  if (diag != null) {

    // get a filename from the user
    String[] exts = {"jpg"};
    File out = getFileToSave(exts, "");
    if (out != null) {
      // Get the canvas
      MCanvas canvas = diag.getCanvas();
      canvas.saveComponentAsJPEG(out.getAbsolutePath());
    }
  }

}//GEN-LAST:event_togifTBBActionPerformed

private void shelfTreeMouseReleased(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_shelfTreeMouseReleased
  this.showShelfPopupMenu(evt);
}//GEN-LAST:event_shelfTreeMouseReleased

  private void showShelfPopupMenu(java.awt.event.MouseEvent evt) {

    if (evt.isPopupTrigger()) {
      // is a tree node selected?
      Object o = shelfTree.getLastSelectedPathComponent();
      final TreePath currentPath = shelfTree.getSelectionPath();

      if (o == null) {
        //Nothing is selected.
        return;
      }

      JPopupMenu contextMenu = new JPopupMenu();
      JMenuItem menuItem;
      if (o instanceof Shelf) {
        /** Rename **/
        menuItem = new JMenuItem("Rename ...");
        menuItem.addActionListener(new java.awt.event.ActionListener() {

          public void actionPerformed(java.awt.event.ActionEvent evt) {
            shelfController.renameShelf();
          }
        });

        contextMenu.add(menuItem);

        /** Add category **/
        menuItem = new JMenuItem("Add category ...");
        menuItem.addActionListener(new java.awt.event.ActionListener() {

          public void actionPerformed(java.awt.event.ActionEvent evt) {
            shelfController.addNewCategory();
            shelfTree.expandPath(currentPath);
          }
        });

        contextMenu.add(menuItem);
        contextMenu.add(new JSeparator());

        /** Export shelf **/
        menuItem = new JMenuItem("Export shelf ...");
        menuItem.addActionListener(new java.awt.event.ActionListener() {

          public void actionPerformed(java.awt.event.ActionEvent evt) {
            // TODO: Code me up -> actionPerformed for "Export shelf ..."
          }
        });
        menuItem.setEnabled(false);
        contextMenu.add(menuItem);

        /** Import shelf **/
        menuItem = new JMenuItem("Import shelf ...");
        menuItem.addActionListener(new java.awt.event.ActionListener() {

          public void actionPerformed(java.awt.event.ActionEvent evt) {
            // TODO: Code me up -> actionPerformed for "Import shelf ..."
          }
        });
        menuItem.setEnabled(false);
        contextMenu.add(menuItem);

        /** Import category **/
        menuItem = new JMenuItem("Import category...");
        menuItem.addActionListener(new java.awt.event.ActionListener() {

          public void actionPerformed(java.awt.event.ActionEvent evt) {
            shelfController.importCategory(null);
          }
        });
        contextMenu.add(menuItem);


        // show menu
        contextMenu.show(evt.getComponent(), evt.getX(), evt.getY());

      } else if (o instanceof ShelfCategory) {
        // pop up a context menu
        final ShelfCategory cat = (ShelfCategory) o;
        // add, remove, rename category

        /** Rename **/
        menuItem = new JMenuItem("Rename ...");
        menuItem.addActionListener(new java.awt.event.ActionListener() {

          public void actionPerformed(java.awt.event.ActionEvent evt) {
            shelfController.renameCategory(cat);
          }
        });
        contextMenu.add(menuItem);

        /** Add subcategory **/
        menuItem = new JMenuItem("Add subcategory ...");
        menuItem.addActionListener(new java.awt.event.ActionListener() {

          public void actionPerformed(java.awt.event.ActionEvent evt) {
            shelfController.addNewSubcategory(cat);
            shelfTree.expandPath(currentPath);
          }
        });
        contextMenu.add(menuItem);

        /** Remove subcategory **/
        menuItem = new JMenuItem("Remove subcategory");
        menuItem.addActionListener(new java.awt.event.ActionListener() {

          public void actionPerformed(java.awt.event.ActionEvent evt) {
            shelfController.removeCategory(cat);
          }
        });
        contextMenu.add(menuItem);
        contextMenu.add(new JSeparator());

        /** Export category **/
        menuItem = new JMenuItem("Export category...");
        menuItem.addActionListener(new java.awt.event.ActionListener() {

          public void actionPerformed(java.awt.event.ActionEvent evt) {
            shelfController.exportCategory(cat);
          }
        });
        contextMenu.add(menuItem);

        /** Import category **/
        menuItem = new JMenuItem("Import category...");
        menuItem.addActionListener(new java.awt.event.ActionListener() {

          public void actionPerformed(java.awt.event.ActionEvent evt) {
            shelfController.importCategory(cat);
          }
        });
        contextMenu.add(menuItem);


        contextMenu.add(new JSeparator());

        /** Add subsystem **/
        menuItem = new JMenuItem("Add selected subsystems");
        menuItem.addActionListener(new java.awt.event.ActionListener() {

          public void actionPerformed(java.awt.event.ActionEvent evt) {
            shelfController.addSelectedSubsystemToCategory(cat);
            shelfTree.expandPath(currentPath);
          }
        });
        contextMenu.add(menuItem);

        // show menu
        contextMenu.show(evt.getComponent(), evt.getX(), evt.getY());

      } else if (o instanceof MSubsystem) {
        // pop up a context menu
        final MSubsystem ss = (MSubsystem) o;
        // add, remove, rename category

        /** Remove subsystem from shelf **/
        menuItem = new JMenuItem("Remove from shelf");
        menuItem.addActionListener(new java.awt.event.ActionListener() {

          public void actionPerformed(java.awt.event.ActionEvent evt) {
            TreePath parentPath = shelfTree.getSelectionPath().getParentPath();
            Object obj = parentPath.getLastPathComponent();
            ShelfCategory cat = (ShelfCategory) obj;
            shelfController.removeSubsystemFromCategory(ss, cat);
            shelfTree.expandPath(parentPath);
          }
        });
        contextMenu.add(menuItem);

        /** Remove subcategory **/
        menuItem = new JMenuItem("Add to pipeline");
        menuItem.addActionListener(new java.awt.event.ActionListener() {

          public void actionPerformed(java.awt.event.ActionEvent evt) {
            addSubsystemToPipeline();
          }
        });
        contextMenu.add(menuItem);

        // show menu
        contextMenu.show(evt.getComponent(),
                evt.getX(), evt.getY());
      }
    }
  }

  /**
   * Add the subsystem block to the canvas.
   */
  public void addSubsystemToPipeline() {
    BlockDiagram diag = (BlockDiagram) DocumentPane.getSelectedFrame();
    if (diag != null) {
      TreePath[] paths = shelfTree.getSelectionPaths();
      for (int kk = 0; kk < paths.length; kk++) {
        Object a = paths[kk].getLastPathComponent();
        if (a instanceof MSubsystem) {
          MSubsystem ss = (MSubsystem) a;
          MCanvas c = diag.getCanvas();
          if (c != null) {
            shelfController.addSubsystemToCanvas(ss, c);
          }
        }
      }
    }
  }

  /**
   *
   * @param mSubsystem
   */
  public void addSubsystemToShelf(MSubsystem mSubsystem) {

    TreePath selectedPath = shelfTree.getSelectionPath();

    // make a copy
    MSubsystem ss = new MSubsystem(mSubsystem);
    // get selected category
    Object o = shelfTree.getLastSelectedPathComponent();
    if (o instanceof ShelfCategory) {
      ShelfCategory cat = (ShelfCategory) o;
      shelfController.addSubsystemToCategory(ss, cat);
      shelfTree.expandPath(selectedPath);
    } else if (o instanceof MSubsystem) {
      // get parent
      if (selectedPath != null) {
        TreePath parentPath = selectedPath.getParentPath();
        Object obj = parentPath.getLastPathComponent();
        ShelfCategory cat = (ShelfCategory) obj;
        shelfController.addSubsystemToCategory(ss, cat);
        shelfTree.expandPath(parentPath);
      }
    } else {
      // get the first category
//      if (shelf.getCategoryCount() > 0) {
//        ShelfCategory cat = shelf.getCategory(0);
//        shelfController.addSubsystemToCategory(ss, cat);
//      } else {
//        Utils.msg("Add a category first.");
//      }

      // rather warn the user
      if (shelf.getCategoryCount() > 0) {
        JOptionPane.showMessageDialog(this, "Please select a category first.");
      } else {
        JOptionPane.showMessageDialog(this, "Please create a category first.");
      }

    }

  }

private void shelfTreeMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_shelfTreeMousePressed

  this.showShelfPopupMenu(evt);


}//GEN-LAST:event_shelfTreeMousePressed

private void shelfTreeMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_shelfTreeMouseClicked

  if (evt.getClickCount() == 2 && !evt.isPopupTrigger()) {
    addSubsystemToPipeline();
  }

  if (evt.isPopupTrigger()) {
    this.showShelfPopupMenu(evt);
  }

}//GEN-LAST:event_shelfTreeMouseClicked

private void pipelineListTreeMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_pipelineListTreeMouseClicked


  if (evt.getClickCount() >= 2) {
    Object o = pipelineListTree.getLastSelectedPathComponent();
    if (o instanceof PipelineList) {
      final PipelineList plist = (PipelineList) o;
      final BlockDiagram diag = plist.getDiagram();
      diag.showDiagram();
      // set all others not selected
      PipelineList root = (PipelineList) pipelineListTree.getModel().getRoot();
      root.deselectAll();
      // and select this one
      plist.setSelected(true);
    }
  } else {
    this.showPipelineListPopupMenu(evt);
  }

}//GEN-LAST:event_pipelineListTreeMouseClicked

private void pipelineListTreeMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_pipelineListTreeMousePressed
  this.showPipelineListPopupMenu(evt);
}//GEN-LAST:event_pipelineListTreeMousePressed

private void pipelineListTreeMouseReleased(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_pipelineListTreeMouseReleased
  this.showPipelineListPopupMenu(evt);
}//GEN-LAST:event_pipelineListTreeMouseReleased

private void librarySearchPreviousActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_librarySearchPreviousActionPerformed

  String searchText = BlockSearchTxt.getText();
  boolean matched = false;
  int[] srow = blockLibraryTree.getSelectionRows();
  matched = listTableRows(srow[0] - 1, searchText, false);
}//GEN-LAST:event_librarySearchPreviousActionPerformed

private void librarySearchNextActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_librarySearchNextActionPerformed

  String searchText = BlockSearchTxt.getText();
  boolean matched = false;
  int[] srow = blockLibraryTree.getSelectionRows();
  matched = listTableRows(srow[0] + 1, searchText, true);
}//GEN-LAST:event_librarySearchNextActionPerformed

private void paramsOverviewBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_paramsOverviewBtnActionPerformed

  this.showParametersOverview();
}//GEN-LAST:event_paramsOverviewBtnActionPerformed

  public void showParametersOverview() {
    if (parametersOverviewDialog == null) {
      parametersOverviewDialog = new ParametersOverviewDialog(this);
    }
    parametersOverviewDialog.setVisible(true);
  }

  public void addWarning(String s) {
    if (console == null) {
      console = new ConsoleDialog(this);
    }
    console.addWarningMessage(s);
  }

  public void addMessage(String s) {
    if (console == null) {
      console = new ConsoleDialog(this);
    }
    console.addMessage(s);
  }

  public void addError(String s) {
    if (console == null) {
      console = new ConsoleDialog(this);
    }
    console.addErrorMessage(s);
  }

  public void showConsole() {
    if (console == null) {
      console = new ConsoleDialog(this);
    }
    console.setVisible(true);


//  for (int kk=0; kk<100; kk++) {
//    System.out.println("adding message " + kk);
//    addMessage("message " + kk);
//  }
  }

  private void promptAnddeletePipeline(BlockDiagram diag) {
    // are we sure we want to close?
    int n = JOptionPane.showConfirmDialog(null,
            "Are you sure you want to delete pipeline '" + diag.getName() + "'?",
            "Confirm Pipeline Delete", JOptionPane.YES_NO_OPTION);

    if (n == JOptionPane.YES_OPTION) {

      // do you want to save this pipeline before closing it?
      n = JOptionPane.showConfirmDialog(null,
              "Do you want to save this pipeline before closing it?",
              "Save '" + diag.getName() + "'", JOptionPane.YES_NO_OPTION);

      if (n == JOptionPane.YES_OPTION) {
        setActiveDiagram(diag);
        if (saveActivePipelineAs()) {
          // delete all subsystems on the canvas
          diag.deleteAllSubsystemsOnCanvas();
          // Delete this block diagram from the list
          deleteDiagram(diag);
        }
      } else {
        // delete all subsystems on the canvas
        diag.deleteAllSubsystemsOnCanvas();
        // Delete this block diagram from the list
        deleteDiagram(diag);
      }
    }
  }

private void showConsoleBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_showConsoleBtnActionPerformed

  this.showConsole();
}//GEN-LAST:event_showConsoleBtnActionPerformed

private void vebosityComboActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_vebosityComboActionPerformed

  if (ltpdaPreferences2 != null) {
    ltpdaPreferences2.getDisplayPrefs().setDisplayVerboseLevel(vebosityCombo.getSelectedIndex() - 1);
  }

}//GEN-LAST:event_vebosityComboActionPerformed

private void mvPipelineUpBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_mvPipelineUpBtnActionPerformed

  Object o = pipelineListTree.getLastSelectedPathComponent();
  if (o instanceof PipelineList) {
    PipelineList pipeList = (PipelineList) o;
    BlockDiagram selectedDiag = pipeList.getDiagram();

    // Move the pipeline only if the pipeline is not a subsystem
    if (!selectedDiag.isSubsystem()) {

      int selectedIdx = documents.indexOf(selectedDiag);

      int foundIdx = -1;
      // Get the index of a top level pipeline before this selected index
      for (int i = selectedIdx - 1; i >= 0; i--) {

        BlockDiagram diag = documents.get(i);

        // Check if the pipeline is not a subsystem
        if (!diag.isSubsystem()) {
          foundIdx = i;
          break;
        }
      }

      if (foundIdx != -1) {
        try {
          // swap the top level pipelines
          Collections.swap(documents, selectedIdx, foundIdx);
          // rebuild the pipeline list tree
          buildPipelineList();
          // set the selected path
          TreePath selectedPipePath = pipelineListTree.getNextMatch(selectedDiag.getCanvas().getName(), 0, Bias.Forward);
          pipelineListTree.setSelectionPath(selectedPipePath);
          // Activate the moved pipeline
          selectedDiag.setSelected(true);
          selectedDiag.revalidate();
          DocumentPane.revalidate();
          this.repaint();
        } catch (PropertyVetoException ex) {
          Logger.getLogger(MainWindow.class.getName()).log(Level.SEVERE, null, ex);
        }
      }

    }
  }

}//GEN-LAST:event_mvPipelineUpBtnActionPerformed

private void mvPipelineDownBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_mvPipelineDownBtnActionPerformed

  Object o = pipelineListTree.getLastSelectedPathComponent();
  if (o instanceof PipelineList) {
    PipelineList pipeList = (PipelineList) o;
    BlockDiagram selectedDiag = pipeList.getDiagram();

    // Move the pipeline only if the pipeline is not a subsystem
    if (!selectedDiag.isSubsystem()) {

      int selectedIdx = documents.indexOf(selectedDiag);

      int foundIdx = -1;
      // Get the index of a top level pipeline after this selected index
      for (int i = selectedIdx + 1; i < documents.size(); i++) {

        BlockDiagram diag = documents.get(i);

        // Check if the pipeline is not a subsystem
        if (!diag.isSubsystem()) {
          foundIdx = i;
          break;
        }
      }

      if (foundIdx != -1) {
        try {
          // swap the top level pipelines
          Collections.swap(documents, selectedIdx, foundIdx);
          // rebuild the pipeline list tree
          buildPipelineList();
          // set the selected path
          TreePath selectedPipePath = pipelineListTree.getNextMatch(selectedDiag.getCanvas().getName(), 0, Bias.Forward);
          pipelineListTree.setSelectionPath(selectedPipePath);
          // Activate the moved pipeline
          selectedDiag.setSelected(true);
          selectedDiag.revalidate();
          DocumentPane.revalidate();
          this.repaint();
        } catch (PropertyVetoException ex) {
          Logger.getLogger(MainWindow.class.getName()).log(Level.SEVERE, null, ex);
        }
      }

    }
  }

}//GEN-LAST:event_mvPipelineDownBtnActionPerformed

private void deletePipelineBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deletePipelineBtnActionPerformed

  Object o = pipelineListTree.getLastSelectedPathComponent();
  if (o instanceof PipelineList) {
    PipelineList pipeList = (PipelineList) o;
    BlockDiagram diag = pipeList.getDiagram();
    promptAnddeletePipeline(diag);
  }

}//GEN-LAST:event_deletePipelineBtnActionPerformed

  private void showPipelineListPopupMenu(java.awt.event.MouseEvent evt) {


    if (evt.isPopupTrigger()) {
      // is a tree node selected?
      Object o = pipelineListTree.getLastSelectedPathComponent();
      final TreePath currentPath = pipelineListTree.getSelectionPath();

      if (o == null) {
        //Nothing is selected.
        return;
      }


      JPopupMenu contextMenu = new JPopupMenu();
      JMenuItem menuItem;
      if (o instanceof PipelineList) {
        final PipelineList plist = (PipelineList) o;
        final BlockDiagram diag = plist.getDiagram();
        /** show **/
        menuItem = new JMenuItem("Show pipeline");
        menuItem.addActionListener(new java.awt.event.ActionListener() {

          public void actionPerformed(java.awt.event.ActionEvent evt) {
            diag.showDiagram();
          }
        });

        contextMenu.add(menuItem);
        /** Rename **/
        menuItem = new JMenuItem("Rename pipeline");
        menuItem.addActionListener(new java.awt.event.ActionListener() {

          public void actionPerformed(java.awt.event.ActionEvent evt) {
            if (diag != null) {
              MCanvas c = diag.getCanvas();
              if (c != null) {
                c.renamePipeline();
                // This is only a workaround !!!
                // Normally should we only fire that we have changed the
                // node name but this tree is quite different.
                PipelineListTreeModel mdl = (PipelineListTreeModel) pipelineListTree.getModel();
//                updatePipelineList();
                buildPipelineList();
              }
            }
          }
        });
        contextMenu.add(menuItem);
        /** Delete **/
        menuItem = new JMenuItem("Delete pipeline");
        menuItem.addActionListener(new java.awt.event.ActionListener() {

          public void actionPerformed(java.awt.event.ActionEvent evt) {
            if (diag != null) {
              promptAnddeletePipeline(diag);
            }
          }
        });
        contextMenu.add(menuItem);

        /** show subsystem **/
        if (diag != null && diag.isSubsystem()) {
          menuItem = new JMenuItem("Show subsystem");
          menuItem.addActionListener(new java.awt.event.ActionListener() {

            public void actionPerformed(java.awt.event.ActionEvent evt) {
              MCanvas c = diag.getCanvas();
              if (c != null) {
                MSubsystem ss = c.getMySubsystemView();
                MCanvas pc = ss.getParentCanvas();
                if (pc != null) {
                  BlockDiagram pd = pc.getBlockDiagram();
                  if (pd != null) {
                    pd.showDiagram();
                  }
                  pc.focusOnElement(ss);
                }
              }
            }
          });
        }
        contextMenu.add(menuItem);

        /** Set canvas info **/
        menuItem = new JMenuItem("Edit canvas info");
        menuItem.addActionListener(new java.awt.event.ActionListener() {

          public void actionPerformed(java.awt.event.ActionEvent evt) {
            if (diag != null) {
              MCanvas c = diag.getCanvas();
              if (c != null) {
                c.editCanvasInfo();
              }
            }
          }
        });
        contextMenu.add(menuItem);


      }

      // show menu
      contextMenu.show(evt.getComponent(), evt.getX(), evt.getY());

    }
  }

  public void updatePipelineList() {
    pipelineListTree.revalidate();
    pipelineListTree.repaint();
  }

  public void buildPipelineList() {


//    pipelineListPanel.removeAll();
//    pipelineListPanel.revalidate();

//    GridLayout listLayout = new GridLayout(documents.size(), 1);
//
//    pipelineListPanel.setLayout(null);

//    int bh = 20;
//    int y = 10;
//    int w = pipelineListPanel.getWidth() - 20;
//
//    // add window list
//    Iterator it = documents.iterator();
//    while (it.hasNext()) {
//      BlockDiagram diag = (BlockDiagram) it.next();
//      PipelineButton wi = new PipelineButton(diag);
//      pipelineListPanel.add(wi);
//      wi.setBounds(0, y, w, bh);
//
//      y += bh;
//
//      pipelineListPanel.setPreferredSize(new Dimension(pipelineListPanel.getWidth(), documents.size()*wi.getSize().height));
//    }
//    pipelineListPanel.revalidate();
//    pipelineListPanel.repaint();


    // build new tree
    pipelineList = new PipelineList();
    Iterator it = documents.iterator();
//    pipelineList.clear();
    while (it.hasNext()) {
      BlockDiagram diag = (BlockDiagram) it.next();
      if (!diag.isSubsystem()) {
        pipelineList.addPipeline(diag);
      }
    }

    pipelineListTreeModel = new PipelineListTreeModel(pipelineList);
    pipelineListTree.setModel(pipelineListTreeModel);

    ((PipelineListTree) pipelineListTree).setActivePipeline(this.getActiveDiagram());

  }

  /**
   * Build the windows menu
   */
  private void buildWindowsMenu(String focus) {

    String systemName = System.getProperty("os.name");

    // Define the window menu on the fly

    // add Maximise all
    JMenuItem mi = new JMenuItem("Maximise All");
    mi.addActionListener(new java.awt.event.ActionListener() {

      public void actionPerformed(java.awt.event.ActionEvent evt) {
        try {
          maximiseAllWindows();
        } catch (PropertyVetoException ex) {
          Logger.getLogger(MainWindow.class.getName()).log(Level.SEVERE, null, ex);
        }
      }
    });
    MainMenuWindow.add(mi);

    // add Maximise all
    mi = new JMenuItem("Minimise All");
    mi.addActionListener(new java.awt.event.ActionListener() {

      public void actionPerformed(java.awt.event.ActionEvent evt) {
        try {
          minimiseAllWindows();
        } catch (PropertyVetoException ex) {
          Logger.getLogger(MainWindow.class.getName()).log(Level.SEVERE, null, ex);
        }
      }
    });
    MainMenuWindow.add(mi);

    // add Maximise all
    mi = new JMenuItem("Iconize All");
    mi.addActionListener(new java.awt.event.ActionListener() {

      public void actionPerformed(java.awt.event.ActionEvent evt) {
        try {
          iconizeAllWindows();
        } catch (PropertyVetoException ex) {
          Logger.getLogger(MainWindow.class.getName()).log(Level.SEVERE, null, ex);
        }
      }
    });
    MainMenuWindow.add(mi);

    if (focus.equals("pipeline")) {
      // add Next Document
      mi = new JMenuItem("Next Pipeline");
      if (systemName.equals("Mac OS X")) {
        mi.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, InputEvent.ALT_MASK | InputEvent.SHIFT_MASK));
      } else {
        mi.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, InputEvent.ALT_MASK | InputEvent.SHIFT_MASK));
      }

      mi.addActionListener(new java.awt.event.ActionListener() {

        public void actionPerformed(java.awt.event.ActionEvent evt) {
          nextDocumentWindow();
        }
      });
      MainMenuWindow.add(mi);
      // add Previous Document
      mi = new JMenuItem("Previous Pipeline");
      if (systemName.equals("Mac OS X")) {
        mi.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, InputEvent.ALT_MASK | InputEvent.SHIFT_MASK));
      } else {
        mi.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, InputEvent.ALT_MASK | InputEvent.SHIFT_MASK));
      }

      mi.addActionListener(new java.awt.event.ActionListener() {

        public void actionPerformed(java.awt.event.ActionEvent evt) {
          previousDocumentWindow();
        }
      });
      MainMenuWindow.add(mi);
    }


    // separator
    MainMenuWindow.add(new JSeparator());

    // add window list
    Iterator it = documents.iterator();
    while (it.hasNext()) {
      final BlockDiagram diag = (BlockDiagram) it.next();
//            if (!diag.isSubsystem()){
      JMenuItem wi = new JMenuItem(diag.getTitle());
      wi.addActionListener(new java.awt.event.ActionListener() {

        public void actionPerformed(java.awt.event.ActionEvent evt) {
          try {
            diag.setIcon(false);
            diag.setVisible(true);
            diag.setSelected(true);
          } catch (PropertyVetoException ex) {
            Logger.getLogger(MainWindow.class.getName()).log(Level.SEVERE, null, ex);
          }
        }
      });
      MainMenuWindow.add(wi);
//            }
    }

    // separator
    MainMenuWindow.add(new JSeparator());

    // add window list
    it = txtdocs.iterator();
    while (it.hasNext()) {
      final MTextDocument td = (MTextDocument) it.next();
//            if (!diag.isSubsystem()){
      JMenuItem wi = new JMenuItem(td.getTitle());
      wi.addActionListener(new java.awt.event.ActionListener() {

        public void actionPerformed(java.awt.event.ActionEvent evt) {
          try {
            td.setVisible(true);
            td.setSelected(true);
          } catch (PropertyVetoException ex) {
            Logger.getLogger(MainWindow.class.getName()).log(Level.SEVERE, null, ex);
          }
        }
      });
      MainMenuWindow.add(wi);
//            }
    }
  }

  /**
   *
   * @return
   */
  public ArrayList<BlockDiagram> getDocuments() {
    return documents;
  }

  /**
   *
   * @param name
   * @return
   */
  public BlockDiagram getDiagramByName(
          String name) {
//        System.out.println("Looking for " + name);
    Iterator it = documents.iterator();
    while (it.hasNext()) {
      BlockDiagram diag = (BlockDiagram) it.next();
//            System.out.println("  checking against " + diag.getName());
      if (diag.getName().equals(name)) {
        return diag;
      }

    }

    return null;
  }

  /**
   *
   * @param title
   * @return
   */
  public BlockDiagram getDiagramByTitle(
          String title) {
//        System.out.println("Looking for " + title);
    Iterator it = documents.iterator();
    while (it.hasNext()) {
      BlockDiagram diag = (BlockDiagram) it.next();
//            System.out.println("  checking against " + diag.getTitle());
      if (diag.getTitle().equals(title)) {
        return diag;
      }

    }

    return null;
  }

  /**
   * Get previous document
   */
  private void previousDocumentWindow() {

    // first determine the current document
    BlockDiagram cd = (BlockDiagram) DocumentPane.getSelectedFrame();

    int dn = documents.indexOf(cd);
    int pd = dn - 1;
    if (pd < 0) {
      pd = documents.size() - 1;
    }

    BlockDiagram d = documents.get(pd);
    d.setVisible(true);
    try {
      d.setSelected(true);
    } catch (PropertyVetoException ex) {
      Logger.getLogger(MainWindow.class.getName()).log(Level.SEVERE, null, ex);
    }
  }

  /**
   * Get next document
   */
  private void nextDocumentWindow() {

    // first determine the current document
    BlockDiagram cd = (BlockDiagram) DocumentPane.getSelectedFrame();
    int dn = documents.indexOf(cd);
    int pd = dn + 1;
    if (pd > documents.size() - 1) {
      pd = 0;
    }

    BlockDiagram d = documents.get(pd);
    d.setVisible(true);
    try {
      d.setSelected(true);
    } catch (PropertyVetoException ex) {
      Logger.getLogger(MainWindow.class.getName()).log(Level.SEVERE, null, ex);
    }
  }

  /**
   * Maximise all documents
   */
  private void maximiseAllWindows() throws PropertyVetoException {
    Iterator it = documents.iterator();
    while (it.hasNext()) {
      BlockDiagram d = (BlockDiagram) it.next();
      if (d != null) {
        d.setIcon(false);
        d.setMaximum(true);
      }
    }
  }

  /**
   * minimise all documents
   */
  private void minimiseAllWindows() throws PropertyVetoException {
    Iterator it = documents.iterator();
    while (it.hasNext()) {
      BlockDiagram d = (BlockDiagram) it.next();
      if (d != null) {
        d.setIcon(false);
        d.setMaximum(false);
      }
    }
  }

  /**
   * Iconize all documents
   */
  private void iconizeAllWindows() throws PropertyVetoException {
    Iterator it = documents.iterator();
    while (it.hasNext()) {
      BlockDiagram d = (BlockDiagram) it.next();
      if (d != null) {
        if (d.isVisible()) {
          d.setIcon(true);
        }
      }

    }
  }

  /**
   * Set the filepath for this workbench
   * @param filepath
   * @return
   */
  public boolean setMyfilepath(String filepath) {
    File f = new File(filepath);
    String extension = Utils.getExtension(f);
    if (extension != null) {
      if (extension.equals("lwb")) {
        if (f.exists()) {
          int response = JOptionPane.showConfirmDialog(null,
                  "Overwrite existing file?", "Confirm Overwrite",
                  JOptionPane.OK_CANCEL_OPTION,
                  JOptionPane.QUESTION_MESSAGE);
          if (response == JOptionPane.CANCEL_OPTION) {
            return false;
          }

        }
        // carry on and save
        Utils.msg("Saving to: " + f.toString());
        try {
          // set title
          workbenchFilePath = f;
          setTitle(f.getName());
          setSaved(false);
        } catch (Exception ex) {
          Logger.getLogger(MainWindow.class.getName()).log(Level.SEVERE, null, ex);
        }
      } else {
        //custom title, error icon
        JOptionPane.showMessageDialog(null,
                "LTPDA Workbenches should be save with extension: " + workbenchFileExtension,
                "Filename error",
                JOptionPane.ERROR_MESSAGE);
      }

    }
    Utils.dmsg("Set filepath to " + workbenchFilePath.getAbsolutePath());
    return true;
  }

  public ArrayList<BlockDiagram> readPipelines(File filepath, Element node) {


    float fileVer = -1f;
    ArrayList<BlockDiagram> docsAdded = new ArrayList<BlockDiagram>();

    if (!node.getNodeName().equals("LTPDAworkbench")) {
      // we have an error
    }

    // get name of workbench
    NamedNodeMap wbnm = node.getAttributes();
    Node wbname = wbnm.getNamedItem("name");

    // get workbench file version
    Node versionNode = wbnm.getNamedItem("version");
    if (versionNode != null) {
      String fileVersion = versionNode.getNodeValue();
      fileVer = Float.parseFloat(fileVersion);
      if (fileVer < version) {
        JOptionPane.showMessageDialog(null,
                "The workbench file was created for an older version of the LTPDA Workbench.\n"
                + "It may not load properly so please review the resulting diagram.",
                "Warning", JOptionPane.WARNING_MESSAGE);
      }
    } else {
      JOptionPane.showMessageDialog(null,
              "The workbench file contains no version number. \nIt must be quite old and probably won't load properly.",
              "Warning", JOptionPane.WARNING_MESSAGE);
    }

    // get all children
    NodeList nl = node.getChildNodes();
    for (int ii = 0; ii < nl.getLength(); ii++) {
      Node n = nl.item(ii);
      if (n.getNodeName().equals("document")) {

        BlockDiagram d = new BlockDiagram(this, n, version, fileVer);
        System.out.println("Loaded pipeline " + d.getTitle());
//        this.postStatusMessage("Loaded pipeline " + d.getTitle());
        if (d == null) {
          // if we failed to load this diagram, then we can stop
          //... but first delete the successful loads
          int nd = docsAdded.size();
          for (int kk = 0; kk < nd; kk++) {
            BlockDiagram doc = docsAdded.get(kk);
            doc.dispose();
          }
          docsAdded.clear();
          return docsAdded;
        } else {
          docsAdded.add(d);
        }
      } // end if document node
    } // end loop over child nodes


    return docsAdded;
  }

  public void postStatusMessage(String message) {
    this.statusLabel.setText(message);
    this.statusLabel.revalidate();
    this.statusLabel.repaint();
    this.repaint();
    try {
      Thread.sleep(100); // sleep for 20 milliseconds
    } catch (InterruptedException ex) {
      Logger.getLogger(MainWindow.class.getName()).log(Level.SEVERE, null, ex);
    }
  }

  public float fileVersionFromNode(Element node) {
    float fileVer = -1f;
    NamedNodeMap wbnm = node.getAttributes();
    Node versionNode = wbnm.getNamedItem("version");
    if (versionNode != null) {
      String fileVersion = versionNode.getNodeValue();
      fileVer = Float.parseFloat(fileVersion);
    }
    return fileVer;
  }

  public void addTextDocuments(File filepath, Element node) {

    float fileVer = this.fileVersionFromNode(node);

    // get all children
    NodeList nl = node.getChildNodes();
    for (int ii = 0; ii < nl.getLength(); ii++) {
      Node n = nl.item(ii);
      if (n.getNodeName().equals("textDocument")) {
        MTextDocument mtd = new MTextDocument(this, n, version, fileVer);
        if (mtd != null) {
          txtdocs.add(mtd);
          DocumentPane.add(mtd);
          mtd.setLocation(10 * txtdocs.size(), 10 * txtdocs.size());
          DocumentPane.setComponentZOrder(mtd, 0);
          mtd.requestFocusInWindow();
          try {
            mtd.setSelected(true);
            mtd.maximise(true);
          } catch (PropertyVetoException ex) {
            Logger.getLogger(MainWindow.class.getName()).log(Level.SEVERE, null, ex);
          }

          setSaved(false);
          stateChanged("New Text Document");
        }
      }
    }
  }

  public ExecutionPlan readExecutionPlan(File filepath, Element node) {

    float fileVer = this.fileVersionFromNode(node);

    // get all children
    NodeList nl = node.getChildNodes();
    for (int ii = 0; ii < nl.getLength(); ii++) {
      Node n = nl.item(ii);
      if (n.getNodeName().equals("ExecutionPlan")) {
        ExecutionPlan ep = new ExecutionPlan(this, n, version, fileVer);
        if (ep != null) {
          return ep;
        }
      }
    }
    System.out.println("No execution plan found in workbench " + filepath);
    return new ExecutionPlan();
  }

  /**
   * Read XML document.
   * @param filepath 
   * @param node
   * @return
   * @throws PropertyVetoException
   */
  public boolean readXMLdoc(File filepath, Element node) throws PropertyVetoException {

    // set workbench title
    if (getTitle().startsWith("Untitled") && documents.size() == 0) {
//        setTitle(wbname.getNodeValue());
      setTitle(filepath.getName());
    }

    // read pipelines from XML
    ArrayList<BlockDiagram> docsAdded = this.readPipelines(filepath, node);

    // add documents for all top-level diagrams
    Iterator dit = docsAdded.iterator();
    while (dit.hasNext()) {
      BlockDiagram d = (BlockDiagram) dit.next();

      if (!d.isSubsystem()) {
        addDocument(d);
        d.setFilepath(filepath);
        d.setVisible(true);
        d.setSelected(true);
        d.maximise(true);
      }
    }

    // read execution plan
    this.execPlan = this.readExecutionPlan(filepath, node);

    // add text documents
    this.addTextDocuments(filepath, node);

    //=========== Do any consolidating we need to do
    this.consolidateBlockDiagrams(documents);


    // make sure we have the correct menu focus
    JInternalFrame frame = DocumentPane.getSelectedFrame();
    if (frame instanceof BlockDiagram) {
      this.switchMenuFocus("pipeline");
    } else if (frame instanceof MTextDocument) {
      this.switchMenuFocus("document");
    }

    return true;
  }

  public String getDisplayTitle() {
    if (this.isSaved()) {
      return this.getTitle();
    } else {
      String title = this.getTitle();
      return title.substring(0, title.length() - 1);
    }
  }

  public void consolidateBlockDiagrams(ArrayList<BlockDiagram> documents) {

    // fix-up and 'from pipeline' blocks
    Iterator it = documents.iterator();
    while (it.hasNext()) {
      BlockDiagram bd = (BlockDiagram) it.next();
      Utils.msg("Checking document: " + bd.getTitle());
      MCanvas mc = bd.getCanvas();
      ArrayList<PipelineBlock> plbs = mc.getPipelineBlocks();
      Iterator pit = plbs.iterator();
      while (pit.hasNext()) {
        PipelineBlock pb = (PipelineBlock) pit.next();
        Utils.msg("   checking pipelineblock: " + pb.getName());
        if (pb.getSrcId() != null && pb.getSourcePort() == null) {
          // look for an element on all documents with this uuid
          MElement el = findElementWithUUID(documents, pb.getSrcId());
          if (el instanceof MPort) {
            pb.setSourcePort((MPort) el);
          }
        }
      }
    }
  }

  /**
   *
   * @param id
   * @return
   */
  public MElement findElementWithUUID(ArrayList<BlockDiagram> documents, UUID id) {
    Utils.msg("Looking for UUID: " + id.toString());
    Iterator it = documents.iterator();
    while (it.hasNext()) {
      BlockDiagram bd = (BlockDiagram) it.next();
      Utils.msg("Searching document: " + bd.getName());
      MCanvas mc = bd.getCanvas();
      ArrayList<MElementWithPorts> els = mc.getAllElements();
      Iterator eit = els.iterator();
      while (eit.hasNext()) {
        MElementWithPorts el = (MElementWithPorts) eit.next();
        Utils.msg("   checking element: " + el.getName() + " / " + el.getId().toString());
        if (el.getId() == id) {
          Utils.msg("FOUND");
          return el;
        }
        // check input ports
        Utils.msg("   checking inputs...");
        Iterator pit = el.getInputs().iterator();
        while (pit.hasNext()) {
          MPort pt = (MPort) pit.next();
          Utils.msg("     checking port: " + pt.getId().toString());
          if (pt.getId() == id) {
            Utils.msg("FOUND");
            return pt;
          }
        }
        // check output ports
        Utils.msg("   checking outputs...");
        pit = el.getOutputs().iterator();
        while (pit.hasNext()) {
          MPort pt = (MPort) pit.next();
          Utils.msg("     checking port: " + pt.getId().toString());
          if (pt.getId().equals(id)) {
            Utils.msg("FOUND");
            return pt;
          }
        }
      }
    }
    return null;
  }

  /**
   * Read an XML (.LWB) file from disk.
   *
   * @param filename
   * @throws javax.xml.parsers.ParserConfigurationException
   * @throws org.xml.sax.SAXException
   * @throws java.io.IOException
   */
  public void loadFromXML(String filename) throws ParserConfigurationException, SAXException, IOException {


    if (filename.trim().startsWith("~")) {
      filename = filename.replaceFirst("~", System.getProperty("user.home"));
    }

    File f = new File(filename);
    Utils.msg("Looking for file: " + f.toString());
    if (f.exists()) {
      DocumentBuilderFactory parserFactory = DocumentBuilderFactory.newInstance();
      parserFactory.setValidating(false);
      DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
      try {
        Document doc = db.parse(f);
        Utils.msg("Read document:  " + doc.getDocumentElement().toString());
        // pass this new workbench document to the MainWindow construtor.
        if (readXMLdoc(f, doc.getDocumentElement())) {
          if (workbenchFilePath == null) {
            workbenchFilePath = f;
          }
          addRecentFile(f);

        } else {
          System.err.println("Failed to load: " + filename);
        }

      } catch (PropertyVetoException ex) {
        Logger.getLogger(MainWindow.class.getName()).log(Level.SEVERE, null, ex);
      } catch (Exception ex) {
        JOptionPane.showMessageDialog(this, "Can not load the file: " + filename, "Load Error", JOptionPane.ERROR_MESSAGE);
      }
    } else {
      JOptionPane.showMessageDialog(this, "File not found: " + filename, "Load Error", JOptionPane.ERROR_MESSAGE);
    }

  }

//  /**
//   *
//   * @return
//   */
//  public JSplitPane getMainPanel() {
//    return MainPanel;
//  }
//  /**
//   *
//   * @param MainPanel
//   */
//  public void setMainPanel(JSplitPane MainPanel) {
//    this.MainPanel = MainPanel;
//  }
  /**
   * Get the reset button
   * @return
   */
  public JButton getResetBtn() {
    return ResetBtn;
  }

  /**
   * set the reset button
   * @param ResetBtn
   */
  public void setResetBtn(JButton ResetBtn) {
    this.ResetBtn = ResetBtn;
  }

  /**
   * set the instance identifier string
   * @param instanceIdentifier
   */
  public void setInstanceIdentifier(String instanceIdentifier) {
    this.instanceIdentifier = instanceIdentifier;
    instanceIdLabel.setText(this.instanceIdentifier);
  }

  public String getInstanceIdentifier() {
    return instanceIdentifier;
  }

  /**
   * get step forward button
   * @return
   */
  public JButton getStepForwardBtn() {
    return StepForwardBtn;
  }

  /**
   * set step forward button
   * @param StepForwardBtn
   */
  public void setStepForwardBtn(JButton StepForwardBtn) {
    this.StepForwardBtn = StepForwardBtn;
  }

  /**
   * get run button
   * @return
   */
  public JButton getRunBtn() {
    return RunBtn;
  }

  /**
   * set the run button
   * @param RunBtn
   */
  public void setRunBtn(JButton RunBtn) {
    this.RunBtn = RunBtn;
  }

  /**
   * Get the step backwards button
   * @return
   */
  public JButton getStepBackwardsBtn() {
    return StepBackwardsBtn;
  }

  /**
   * Set the step backwards button
   * @param StepBackwardsBtn
   */
  public void setStepBackwardsBtn(JButton StepBackwardsBtn) {
    this.StepBackwardsBtn = StepBackwardsBtn;
  }

  /**
   * Get the skip forwards button
   * @return
   */
  public JButton getSkipForwardBtn() {
    return SkipForwardBtn;
  }

  /**
   * Set the skip forwards button
   * @param SkipForwardBtn
   */
  public void setSkipForwardBtn(JButton SkipForwardBtn) {
    this.SkipForwardBtn = SkipForwardBtn;
  }

  public void resetWorkbench() {
    while (documents.size() > 0) {
      deleteDiagram(documents.get(0));
    }
    documents.clear();
    buildPipelineList();
    workbenchFilePath = null;
    setTitle("Untitled");
    setSaved(false);
  }

  public boolean loadWorkbench() throws FileNotFoundException, ParserConfigurationException, SAXException, IOException, Exception {

    // is the workbench saved?
    if ((!saved) && ((documents.size() > 0) || (txtdocs.size() > 0))) {
      // prompt user
      int response = JOptionPane.showConfirmDialog(null,
              "Save workbench before loading the new one?", "Save Workbench",
              JOptionPane.YES_NO_CANCEL_OPTION,
              JOptionPane.QUESTION_MESSAGE);
      if (response == JOptionPane.CANCEL_OPTION) {
        return false;
      } else if (response == JOptionPane.YES_OPTION) {
        this.saveWorkbench();
      }
    }

    // reset the workbench
    resetWorkbench();

    // call loadCanvases
    loadCanvases();

    return true;
  }

  /**
   * Load canvases from XML file on disk.
   * @return
   * @throws java.io.FileNotFoundException
   * @throws javax.xml.parsers.ParserConfigurationException
   * @throws org.xml.sax.SAXException
   * @throws java.io.IOException
   */
  public boolean loadCanvases() throws FileNotFoundException, ParserConfigurationException, SAXException, IOException {

    String[] exts = {workbenchFileExtension};
    File f = getFileToLoad(exts, null);

    if (f != null) {
      String extension = Utils.getExtension(f);
      Utils.dmsg("File extension: " + extension);
      if (extension != null) {
        if (f.exists()) {
          Utils.dmsg("Loading " + f.getAbsolutePath());

          // read XML document
          loadFromXML(f.getAbsolutePath());
          lastLoadPath = new File(Utils.removeFileName(f.getAbsolutePath()));
          Utils.dmsg("Set last load path to: " + lastLoadPath.getAbsolutePath());
          return true;
        } else {
          JOptionPane.showMessageDialog(this, "File not found: " + f.getAbsolutePath(), "Load Error", JOptionPane.ERROR_MESSAGE);
        }
      }
    }
    return false;
  }

  /**
   * Set the color of a block
   * @param block
   * @param pnum
   * @param col
   */
  public void setBlockColor(String block, int pnum, String col) {

    // get this block
    MElementWithPorts b = getBlockByName(block);
    // get the output port
    MPort output = b.getOutput(pnum);
    // get the node
    MNode n = output.getNode();
    if (n != null) {
      ArrayList<MPipe> pipes = n.getPipes();
      Iterator it = pipes.iterator();
      while (it.hasNext()) {
        MPipe p = (MPipe) it.next();
        p.setColor(Color.decode(col));
      }

    }
  }

  /**
   * Save this workbench to disk in XML format (.LWB)
   * @return
   * @throws java.lang.Exception
   */
  public boolean saveWorkbench() throws Exception {

    File oldFilePath = null;
    if (workbenchFilePath != null) {
      oldFilePath = new File(workbenchFilePath.getAbsolutePath());
    }

    Utils.dmsg("My title: " + getTitle());
    Utils.dmsg("My filepath: " + workbenchFilePath);


    // if this workbench is still untitled, get a name from the user...
    if (getTitle().startsWith("Untitled") || workbenchFilePath == null) { // save as

      // get filename from user
      if (saveWorkbenchAs(true)) {
        return true;
      }

    } else { // just save
      try {
        backupFile();
        XMLUtils.serializeXML(this.toXMLdom(true, workbenchFilePath.getName()), workbenchFilePath);
        setSaved(true);
      } catch (FileNotFoundException e) {
        JOptionPane.showMessageDialog(null,
                "Error saving file: " + workbenchFilePath.getAbsolutePath(),
                "Filename error",
                JOptionPane.ERROR_MESSAGE);

        workbenchFilePath = oldFilePath;
        setSaved(false);

        return false;
      }

      return true;
    }

    return false;
  }

  public String workbenchAsXMLString() {

    String xmlout = "";
    try {
      TransformerFactory tf = TransformerFactory.newInstance();
      Transformer trans = tf.newTransformer();
      StringWriter sw = new StringWriter();
      trans.transform(new DOMSource(this.toXMLdom(true, getTitle())), new StreamResult(sw));
      xmlout = sw.toString();
    } catch (ParserConfigurationException ex) {
      Logger.getLogger(MainWindow.class.getName()).log(Level.SEVERE, null, ex);
    } catch (Exception ex) {
      Logger.getLogger(MainWindow.class.getName()).log(Level.SEVERE, null, ex);
    }

    return xmlout;
  }

  /**
   * Save this workbench to disk in XML format (.LWB)
   * @param filename
   * @return
   * @throws java.lang.Exception
   */
  public boolean saveWorkbenchAs(String filename) throws Exception {

    File oldFilePath = null;
    if (workbenchFilePath != null) {
      oldFilePath = new File(workbenchFilePath.getAbsolutePath());
    }

    workbenchFilePath = new File(filename);
    Utils.dmsg("My title: " + getTitle());
    Utils.dmsg("My filepath: " + workbenchFilePath);


    String extension = Utils.getExtension(workbenchFilePath);
    boolean shouldSave = false;
    if (extension != null) {
      if (extension.equals("lwb")) {
        shouldSave = true;
      } else {
        //custom title, error icon
        JOptionPane.showMessageDialog(null,
                "LTPDA Workbenches should be save with extension: " + workbenchFileExtension,
                "Filename error",
                JOptionPane.ERROR_MESSAGE);
      }

    } else {
      // add extension
      workbenchFilePath = new File(workbenchFilePath.getAbsoluteFile() + "." + workbenchFileExtension);
      shouldSave = true;
    }

    if (shouldSave) {
      setSaved(true);
      backupFile();

      Utils.dmsg("Saving to " + workbenchFilePath.getAbsolutePath());
      try {
        XMLUtils.serializeXML(this.toXMLdom(true, workbenchFilePath.getName()), workbenchFilePath);
        addRecentFile(workbenchFilePath);
      } catch (FileNotFoundException e) {
        JOptionPane.showMessageDialog(null,
                "Error saving file: " + workbenchFilePath.getAbsolutePath(),
                "Filename error",
                JOptionPane.ERROR_MESSAGE);


        workbenchFilePath =
                oldFilePath;
        setSaved(false);

        return false;
      }

      return true;
    } else {
      return false;
    }
  }

  /**
   *
   * @return
   */
  public boolean saveActivePipelineAs() {
    try {
      return saveWorkbenchAs(false);
    } catch (Exception ex) {
      Logger.getLogger(MainWindow.class.getName()).log(Level.SEVERE, null, ex);
    }
    return false;
  }

  /**
   * Save this workbench to disk in XML format (.LWB), prompting for a filename.
   * @param saveAll 
   * @return
   * @throws java.lang.Exception
   */
  public boolean saveWorkbenchAs(boolean saveAll) throws Exception {

    String[] exts = {workbenchFileExtension};
    String cfile = null;
    if ((workbenchFilePath != null) && (saveAll)) {
      cfile = workbenchFilePath.getName();
    } else if (!saveAll) {
      cfile = getActiveTopLevelDiagram().getCanvas().getName() + "." + workbenchFileExtension;
    }

    File f = getFileToSave(exts, cfile);
    boolean shouldSave = false;
    if (f != null) {

      String extension = Utils.getExtension(f);
      if (extension != null) {
        if (extension.equals(workbenchFileExtension)) {
          shouldSave = true;
        } else {
          //custom title, error icon
          JOptionPane.showMessageDialog(null,
                  "LTPDA Workbenches should be saved with extension: " + workbenchFileExtension,
                  "Filename error",
                  JOptionPane.ERROR_MESSAGE);
        }
      } else {
        // add extension
        f = new File(f.getAbsoluteFile() + "." + workbenchFileExtension);
        shouldSave = true;
      }
    }

    if (shouldSave) {
      // If the file exists, we may need to check if the user wants to
      // overwrite. On OS X the file chooser does this for us, but only
      // if the user adds the extension. So, if we added the extension here
      // we stil need to check, even if we are on OS X.
      if (f.exists()) {
        int response = JOptionPane.showConfirmDialog(null,
                "Overwrite existing file?", "Confirm Overwrite",
                JOptionPane.OK_CANCEL_OPTION,
                JOptionPane.QUESTION_MESSAGE);
        if (response == JOptionPane.CANCEL_OPTION) {
          return false;
        }

      }
      // carry on and save
      Utils.dmsg("Saving to: " + f.toString());
      try {


        // Make sure that 'workbenchFilePath' is set before we call backupFile()
        if (workbenchFilePath == null) {
          workbenchFilePath = new File(f.getAbsolutePath());
        }

        // make a backup first
        backupFile();

        // save to XML
        File oldFilePath = null;
        if (f != null) {
          oldFilePath = new File(f.getAbsolutePath());
        }

        try {
          XMLUtils.serializeXML(this.toXMLdom(saveAll, f.getName()), f);
          if (saveAll) {
            workbenchFilePath = oldFilePath;
            setSaved(true);
          } else {
            pipelineFilePath = oldFilePath;
            System.out.println("Set to BACKUP myFilePath: " + workbenchFilePath.toString());
          }
          addRecentFile(oldFilePath);
        } catch (FileNotFoundException e) {
          JOptionPane.showMessageDialog(null,
                  "Error saving file: " + workbenchFilePath.getAbsolutePath(),
                  "Filename error",
                  JOptionPane.ERROR_MESSAGE);

          workbenchFilePath = oldFilePath;
          setSaved(false);

          return false;
        }

        return true;
      } catch (Exception ex) {
        Logger.getLogger(MainWindow.class.getName()).log(Level.SEVERE, null, ex);
      }
    }

    return false;
  }

  private void backupFile() {
    Date now = new Date();
    Utils.dmsg("saving at " + now.toString());
    String DATE_FORMAT = "yyyyMMdd_HHmmss";
    SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);

    File myBackupFilePath = new File(workbenchFilePath.getPath() + "." + sdf.format(now));

    Utils.dmsg("backing up to " + myBackupFilePath.toString());

//        copyfile(myFilePath, myBackupFilePath);

  }

  private static void copyfile(File f1, File f2) {
    try {
//            File f1 = new File(srFile);
//            File f2 = new File(dtFile);
      InputStream in = new FileInputStream(f1);

      //For Append the file.
//      OutputStream out = new FileOutputStream(f2,true);

      //For Overwrite the file.
      OutputStream out = new FileOutputStream(f2);

      byte[] buf = new byte[1024];
      int len;
      while ((len = in.read(buf)) > 0) {
        out.write(buf, 0, len);
      }

      in.close();
      out.close();
      Utils.dmsg("File copied.");
    } catch (FileNotFoundException ex) {
      Utils.msg(ex.getMessage() + " in the specified directory.");
    } catch (IOException e) {
      Utils.msg(e.getMessage());
    }

  }

  private BlockDiagram getActiveTopLevelDiagram() {
    BlockDiagram cd = (BlockDiagram) DocumentPane.getSelectedFrame();
    if (cd != null) {
      if (cd.isSubsystem()) {
        cd = cd.getTopLevelDiagram();
      }
    }
    return cd;
  }

  /**
   * Serialize this workbench to XML.
   * @return
   * @throws javax.xml.parsers.ParserConfigurationException
   * @throws java.lang.Exception
   */
  private Document toXMLdom(boolean all, String toFileName) throws ParserConfigurationException, Exception {

    Document doc = XMLUtils.createDocument("LTPDAworkbench");
    Element root = doc.getDocumentElement();
    root.setAttribute("name", this.getTitle());
    root.setAttribute("version", "" + version);
    if (workbenchFilePath != null) {
      root.setAttribute("filepath", toFileName);
    }

    // add each document root document
    if (all) {
      setTitle(toFileName);
      root.setAttribute("name", this.getTitle());
      Iterator dit = documents.iterator();
      while (dit.hasNext()) {
        BlockDiagram diag = (BlockDiagram) dit.next();
        if (!diag.isSubsystem()) {
          diag.attachToDom(doc, root);
        }

      }

      // add execution plan
      execPlan.attachToDom(doc, root);

      // add all text docs as well
      Iterator it = txtdocs.iterator();
      while (it.hasNext()) {
        MTextDocument td = (MTextDocument) it.next();
        td.attachToDom(doc, root);
      }


    } else {
      // just the active one

      BlockDiagram cd = getActiveTopLevelDiagram();
//      cd.getCanvas().updateDiagramName(Utils.removeFileExtension(toFileName));
      if (cd != null) {
        cd.attachToDom(doc, root);
      }
    }



    return doc;
  }

  private boolean allCanvasesSaved() {
    // add each document
    Iterator dit = documents.iterator();
    while (dit.hasNext()) {
      BlockDiagram diag = (BlockDiagram) dit.next();
      MCanvas c = diag.getCanvas();
      if (!c.isWasSaved()) {
        return false;
      }

    }

    return true;
  }

  /**
   * Return an array of all blockdiagrams in the workbench.
   * @return
   */
  private ArrayList<MCanvas> getAllCanvases() {
    ArrayList<MCanvas> ccs = new ArrayList<MCanvas>();

    Iterator it = documents.iterator();
    while (it.hasNext()) {
      BlockDiagram diag = (BlockDiagram) it.next();
      ccs.add(diag.getCanvas());
    }

    return ccs;
  }

  /**
   * @param args the command line arguments
   */
  public static void main(String args[]) {
    java.awt.EventQueue.invokeLater(new Runnable() {

      public void run() {
        new MainWindow("", null).setVisible(true);
      }
    });
  }

  /**
   * Get apply button
   * @return
   */
  public JButton getApplyBtn() {
    return ApplyBtn;
  }

  /**
   * Set apply button
   * @param ApplyBtn
   */
  public void setApplyBtn(JButton ApplyBtn) {
    this.ApplyBtn = ApplyBtn;
  }

  /**
   * Get the library tree
   * @return
   */
  public JTree getBlockLibraryTree() {
    return blockLibraryTree;
  }

  /**
   * Set the library tree
   * @param aBlockLibraryTree
   */
  public void setBlockLibraryTree(JTree aBlockLibraryTree) {
    this.blockLibraryTree = aBlockLibraryTree;
  }

  /**
   * Get the block property table
   * @return
   */
  public JTable getBlockPropertyTable() {
    return BlockPropertyTable;
  }

  /**
   * Get the block search text field
   * @return
   */
  public JTextField getBlockSearchTxt() {
    return BlockSearchTxt;
  }

  /**
   *
   * @return
   */
  public JPopupMenu getBlocktreeContextMenu() {
    return BlocktreeContextMenu;
  }

  /**
   *
   * @param BlocktreeContextMenu
   */
  public void setBlocktreeContextMenu(JPopupMenu BlocktreeContextMenu) {
    this.BlocktreeContextMenu = BlocktreeContextMenu;
  }

  /**
   *
   * @return
   */
  public JDesktopPane getDocumentPane() {
    return DocumentPane;
  }

  /**
   *
   * @param DocumentPane
   */
  public void setDocumentPane(JDesktopPane DocumentPane) {
    this.DocumentPane = DocumentPane;
  }

  /**
   *
   * @return
   */
  public JMenuItem getNewMenuItem() {
    return NewMenuItem;
  }

  /**
   *
   * @param NewMenuItem
   */
  public void setNewMenuItem(JMenuItem NewMenuItem) {
    this.NewMenuItem = NewMenuItem;
  }

  /**
   *
   * @return
   */
  public JButton getParamAddBtn() {
    return ParamAddBtn;
  }

  /**
   *
   * @param ParamAddBtn
   */
  public void setParamAddBtn(JButton ParamAddBtn) {
    this.ParamAddBtn = ParamAddBtn;
  }

  /**
   *
   * @return
   */
  public JButton getParamRmvBtn() {
    return ParamRmvBtn;
  }

  /**
   *
   * @param ParamRmvBtn
   */
  public void setParamRmvBtn(JButton ParamRmvBtn) {
    this.ParamRmvBtn = ParamRmvBtn;
  }

  /**
   *
   * @return
   */
  public LTPDAlibrary getLib() {
    return lib;
  }

  /**
   *
   * @param lib
   */
  public void setLib(LTPDAlibrary lib) {
    this.lib = lib;
  }

  /**
   *
   * @return
   */
  public LTPDALibraryModel getLibmodel() {
    return libmodel;
  }

  /**
   *
   * @param libmodel
   */
  public void setLibmodel(LTPDALibraryModel libmodel) {
    this.libmodel = libmodel;
  }

  /**
   *
   * @return
   */
  public JMenuItem getExploreSelectedMenuItem() {
    return ExploreSelectedMenuItem;
  }

  /**
   *
   * @return
   */
  public JMenuItem getPlotSelectedMenuItem() {
    return PlotSelectedMenuItem;
  }

  /**
   *
   * @return
   */
  public JMenuItem getRebuildLibraryMenuItem() {
    return RebuildLibraryMenuItem;
  }

  /**
   *
   * @return
   */
  public JButton getDisplayBtn() {
    return DisplayBtn;
  }

  /**
   *
   * @return
   */
  public JMenuItem getExportToMFileMenuItem() {
    return ExportToMFileMenuItem;
  }

  public SubmissionInfo getSubmissionInfo() {
    return submissionInfo;
  }

  public void setSubmissionInfo(SubmissionInfo submissionInfo) {
    this.submissionInfo = submissionInfo;
  }

  /**
   *
   * @return
   */
  public JMenuItem getExportToTerminalMenuItem() {
    return ExportToTerminalMenuItem;
  }

  /**
   *
   * @return
   */
  public JMenuItem getImportFromMfileMenuItem() {
    return ImportFromMfileMenuItem;
  }

  /**
   *
   * @return
   */
  public JMenuItem getImportFromWorkspaceMenuItem() {
    return ImportFromWorkspaceMenuItem;
  }

  /**
   *
   * @return
   */
  public JMenuItem getLtpdaConstructorHelperMenuItem() {
    return ltpdaConstructorHelperMenuItem;
  }

  /**
   *
   * @return
   */
  public JMenuItem getLtpdaPZmodelHelperMenuItem() {
    return ltpdaPZmodelHelperMenuItem;
  }

  /**
   *
   * @return
   */
  public JMenuItem getLtpdaPreferencesMenuItem() {
    return ltpdaPreferencesMenuItem;
  }

  /**
   *
   * @return
   */
  public JMenuItem getLtpdaSignalBuilderMenuItem() {
    return ltpdaSignalBuilderMenuItem;
  }

  /**
   * 
   * @return
   */
  public JMenuItem getLtpdaSpecwinViewerMenuItem() {
    return ltpdaSpecwinViewerMenuItem;
  }

  /**
   *
   * @return
   */
  public JMenuItem getPlanRunMenuItem() {
    return planRunMenuItem;
  }

  /**
   *
   * @param planRunMenuItem
   */
  public void setPlanRunMenuItem(JMenuItem planRunMenuItem) {
    this.planRunMenuItem = planRunMenuItem;
  }

  /**
   *
   * @return
   */
  public ExecutionPlan getExecPlan() {
    return execPlan;
  }

  /**
   *
   * @param execPlan
   */
  public void setExecPlan(ExecutionPlan execPlan) {
    this.execPlan = execPlan;
  }

  /**
   *
   * @return
   */
  public JComboBox getSetCombo() {
    return setCombo;
  }

  /**
   *
   * @return
   */
  public ArrayList<String> getWindowTypes() {
    return windowTypes;
  }

  /**
   *
   * @return
   */
  public File getLastLoadPath() {
    return lastLoadPath;
  }

  /**
   *
   * @return
   */
  public File getLastSavePath() {
    return lastSavePath;
  }

  /**
   *
   * @return
   */
  public JButton getHistoryBtn() {
    return HistoryBtn;
  }

  /**
   *
   * @return
   */
  public ArrayList<LTPDAModel> getAoModels() {
    return aoModels;
  }

  /**
   *
   * @return
   */
  public ArrayList<LTPDAModel> getSsmModels() {
    return ssmModels;
  }

  /**
   *
   * @return
   */
  public JMenuItem getHelpBlockDocMenuItem() {
    return HelpBlockDocMenuItem;
  }

  /**
   *
   * @return
   */
  public JButton getExportWorkspaceBtn() {
    return exportWorkspaceBtn;
  }

  /**
   *
   * @return
   */
  public JComboBox getVebosityCombo() {
    return vebosityCombo;
  }

  /**
   *
   * @param preferences
   */
  public void setPreferences(LWBpreferences preferences) {
    this.preferences = preferences;
  }

  /**
   *
   * @return
   */
  public LWBpreferences getPreferences() {
    return preferences;
  }

  public JMenuItem getWBOpenFromObjectMenuItem() {
    return WBOpenFromObjectMenuItem;
  }

  /**
   *
   * @return
   */
  public ArrayList<LTPDAModel> getBuiltinModels() {
    return builtinModels;
  }

  /**
   *
   * @return
   */
  public Shelf getShelf() {
    return shelf;
  }

  /**
   *
   * @param shelf
   */
  public void setShelf(Shelf shelf) {
    this.shelf = shelf;
  }

  /**
   *
   * @return
   */
  public JTree getShelfTree() {
    return shelfTree;
  }

  /**
   *
   * @param ShelfTree
   */
  public void setShelfTree(JTree ShelfTree) {
    this.shelfTree = ShelfTree;
  }

  /**
   * 
   * @return
   */
  public JButton getSaveObjectBtn() {
    return saveObjectBtn;
  }

  /**
   *
   * @param cl
   * @param name
   * @param help
   * @param pl
   */
  public void addBuiltInModel(String cl, String name, String help, JPlist pl) {
    LTPDAModel mdl = new LTPDAModel(cl, name, help, pl);
    Utils.dmsg("Added built-in model: " + cl + "/" + name);
    builtinModels.add(mdl);
  }

  /**
   *
   * @param type
   * @return
   */
  public ArrayList<LTPDAModel> getBuiltinModels(String type) {

    if (type.equals("")) {
      return builtinModels;
    }

    ArrayList<LTPDAModel> mdls = new ArrayList<LTPDAModel>();
    Iterator it = builtinModels.iterator();
    while (it.hasNext()) {
      LTPDAModel mdl = (LTPDAModel) it.next();
      if (mdl.getModelClass().equals(type)) {
        mdls.add(mdl);
      }
    }
    return mdls;
  }

  public ArrayList<String> getUnitPrefixes() {
    return unitPrefixes;
  }

  public ArrayList<String> getUnits() {
    return units;
  }

  public void addUnit(String u) {
    units.add(u);
  }

  public void addPrefix(String p) {
    unitPrefixes.add(p);
  }

  public void clearUnits() {
    units.clear();
  }

  public void clearPrefixes() {
    unitPrefixes.clear();
  }

  public JButton getRepoSubmitTBB() {
    return repoSubmitTBB;
  }

  public JButton getRepoSearchTBB() {
    return repoSearchTBB;
  }

  public JButton getTableBtn() {
    return tableBtn;
  }

  public JButton getReportBtn() {
    return reportBtn;
  }

  public PreferencesDialog getPrefsDialog() {
    return prefsDialog;
  }

  public LTPDAPreferences getLtpdaPreferences2() {
    return ltpdaPreferences2;
  }

  /**
   *
   * @param setCombo
   */
  public void setSetCombo(JComboBox setCombo) {
    this.setCombo = setCombo;
  }

  /**
   *
   * @return
   */
  public boolean isExecuting() {
    return executing;
  }

  /**
   *
   * @param executing
   */
  public void setExecuting(boolean executing) {
    this.executing = executing;

    // set state of window menu
    MainMenuWindow.setEnabled(!executing);
    // set state of  pipeline list
    pipelineListTree.setEnabled(!executing);
//    Component[] children = pipelineListPanel.getComponents();
//    for (int kk = 0; kk < children.length; kk++) {
//      Component c = children[kk];
//      if (c instanceof PipelineButton) {
//        c.setEnabled(!executing);
//      }
//    }

    // set state of document panel
    DocumentPane.setEnabled(!executing);

  }

  public void createPipelinesFromXMLstring(String xmlStr) {

    try {
      // pass this new workbench document to the MainWindow construtor.
      if (xmlStr.equals("")) {
        JOptionPane.showMessageDialog(this, "The chosen object has no attached Workbench file.", "Import error", JOptionPane.ERROR_MESSAGE);
        return;
      }
      // load from XML string
      DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
      DocumentBuilder builder = factory.newDocumentBuilder();
      Document doc = builder.parse(new InputSource(new StringReader(xmlStr)));
      Utils.msg("Read document:  " + doc.getDocumentElement().toString());
      // pass this new workbench document to the MainWindow construtor.
      if (readXMLdoc(null, doc.getDocumentElement())) {
      } else {
        System.err.println("Failed to import from object.");
      }
    } catch (PropertyVetoException ex) {
      Logger.getLogger(MainWindow.class.getName()).log(Level.SEVERE, null, ex);
    } catch (SAXException ex) {
      Logger.getLogger(MainWindow.class.getName()).log(Level.SEVERE, null, ex);
    } catch (IOException ex) {
      Logger.getLogger(MainWindow.class.getName()).log(Level.SEVERE, null, ex);
    } catch (ParserConfigurationException ex) {
      Logger.getLogger(MainWindow.class.getName()).log(Level.SEVERE, null, ex);
    }

  }
  // Variables declaration - do not modify//GEN-BEGIN:variables
  private javax.swing.JMenuItem AddBlockMenuItem;
  private javax.swing.JButton ApplyBtn;
  private javax.swing.JMenuItem BlockHelpMenuItem;
  private javax.swing.JTable BlockPropertyTable;
  private javax.swing.JTextField BlockSearchTxt;
  private javax.swing.JPopupMenu BlocktreeContextMenu;
  private javax.swing.JButton DisplayBtn;
  private javax.swing.JDesktopPane DocumentPane;
  private javax.swing.JButton ExploreBtn;
  private javax.swing.JButton HistoryBtn;
  private javax.swing.JMenuBar MainMenuBar;
  private javax.swing.JMenu MainMenuEdit;
  private javax.swing.JMenu MainMenuFile;
  private javax.swing.JMenu MainMenuFormat;
  private javax.swing.JMenu MainMenuHelp;
  private javax.swing.JMenu MainMenuPipeline;
  private javax.swing.JMenu MainMenuTools;
  private javax.swing.JMenu MainMenuView;
  private javax.swing.JMenu MainMenuWindow;
  private javax.swing.JToolBar MainToolbar;
  private javax.swing.JButton ParamAddBtn;
  private javax.swing.JButton ParamRmvBtn;
  private javax.swing.JButton PlotBtn;
  private javax.swing.JButton ResetBtn;
  private javax.swing.JButton RunBtn;
  private javax.swing.JButton SkipForwardBtn;
  private javax.swing.JButton StepBackwardsBtn;
  private javax.swing.JButton StepForwardBtn;
  private javax.swing.JTree blockLibraryTree;
  private javax.swing.JPanel controlsTab;
  private javax.swing.JButton copyTBB;
  private javax.swing.JButton deletePipelineBtn;
  private javax.swing.JButton deleteSelectedTBB;
  private javax.swing.JButton downTBB;
  private javax.swing.JButton exportWorkspaceBtn;
  private javax.swing.JButton helpTBB;
  private javax.swing.JButton importTBB;
  private javax.swing.JButton infoTBB;
  private javax.swing.JLabel instanceIdLabel;
  private javax.swing.JLabel jLabel1;
  private javax.swing.JLabel jLabel2;
  private javax.swing.JLabel jLabel4;
  private javax.swing.JPanel jPanel1;
  private javax.swing.JPanel jPanel2;
  private javax.swing.JPanel jPanel3;
  private javax.swing.JPanel jPanel4;
  private javax.swing.JPanel jPanel5;
  private javax.swing.JPanel jPanel6;
  private javax.swing.JScrollPane jScrollPane1;
  private javax.swing.JScrollPane jScrollPane2;
  private javax.swing.JScrollPane jScrollPane3;
  private javax.swing.JScrollPane jScrollPane5;
  private javax.swing.JScrollPane jScrollPane6;
  private javax.swing.JToolBar.Separator jSeparator1;
  private javax.swing.JToolBar.Separator jSeparator2;
  private javax.swing.JToolBar.Separator jSeparator3;
  private javax.swing.JToolBar.Separator jSeparator4;
  private javax.swing.JToolBar.Separator jSeparator5;
  private javax.swing.JSeparator jSeparator6;
  private javax.swing.JSeparator jSeparator7;
  private javax.swing.JSplitPane jSplitPane1;
  private javax.swing.JSplitPane jSplitPane2;
  private javax.swing.JButton leftTBB;
  private javax.swing.JButton librarySearchNext;
  private javax.swing.JButton librarySearchPrevious;
  private javax.swing.JPanel libraryTab;
  private javax.swing.JTabbedPane mainTabPanel;
  private javax.swing.JButton mvPipelineDownBtn;
  private javax.swing.JButton mvPipelineUpBtn;
  private javax.swing.JButton newPipelineTBB;
  private javax.swing.JButton paramsOverviewBtn;
  private javax.swing.JPanel paramsTab;
  private javax.swing.JButton pasteTBB;
  private javax.swing.JTree pipelineListTree;
  private javax.swing.JPanel pipelineTab;
  private final javax.swing.JTable plistTable = new PlistTable(this);
  private javax.swing.JButton redoTBB;
  private javax.swing.JButton repoSearchTBB;
  private javax.swing.JButton repoSubmitTBB;
  private javax.swing.JButton reportBtn;
  private javax.swing.JButton rightTBB;
  private javax.swing.JButton saveObjectBtn;
  private javax.swing.JButton saveWorkbenchAsTBB;
  private javax.swing.JButton saveWorkbenchTBB;
  private javax.swing.JButton searchTBB;
  private javax.swing.JComboBox setCombo;
  private javax.swing.JPanel shelfTab;
  private javax.swing.JTree shelfTree;
  private javax.swing.JButton showConsoleBtn;
  private javax.swing.JLabel statusLabel;
  private javax.swing.JButton tableBtn;
  private javax.swing.JButton togifTBB;
  private javax.swing.JButton undoTBB;
  private javax.swing.JButton upTBB;
  private javax.swing.JComboBox vebosityCombo;
  private javax.swing.JButton zoomInTBB;
  private javax.swing.JButton zoomOutTBB;
  // End of variables declaration//GEN-END:variables

  public void deleteTextDocument(MTextDocument aDoc) {

    txtdocs.remove(aDoc);
    aDoc.dispose();
    DocumentPane.remove(aDoc);
    setSaved(false);

    JInternalFrame[] frames = DocumentPane.getAllFrames();
    if (frames.length > 0) {
      DocumentPane.setSelectedFrame(frames[frames.length - 1]);
    } else {
      switchMenuFocus("none");
    }

    this.repaint();
  }

  public String getContext() {
    return context;
  }

  public void switchMenuFocus(String focus) {

    if (parametersOverviewDialog == null) {
      parametersOverviewDialog = new ParametersOverviewDialog(this);
    }
    parametersOverviewDialog.reloadParameters();

    context = focus;

    if (focus.equals("document")) {

      /** File **/
      setMenuItemState(WBSavePipelineMenuItem, false);
      setMenuState(PlanMenu, false);
      /** Edit **/
      setMenuState(MainMenuEdit, true);
      setMenuItemState(DuplicateMenuItem, false);
      setMenuItemState(DeleteMenuItem, false);
      setMenuItemState(UndoMenuItem, false);
      setMenuItemState(RedoMenuItem, false);
      /** View **/
      setMenuState(MainMenuView, false);
      /** Format **/
      setMenuState(MainMenuFormat, false);
      /** Pipeline **/
      setMenuItemState(NewMenuItem, true);
      setMenuItemState(RenamePipelineMenuItem, false);
      setMenuItemState(ExportToMFileMenuItem, false);
      setMenuItemState(ExportToTerminalMenuItem, false);
      setMenuItemState(ExportToImageMenuItem, false);
      setMenuItemState(CreateSubsystemPipelineMenuItem, false);
      setMenuItemState(showQuickBlockMenuItem, false);
      setMenuItemState(editCanvasInfoMenuItem, false);
      setMenuItemState(searchCanvasMenuItem, false);
      setMenuItemState(ClosePipelineMenuItem, false);
      setMenuItemState(CloseAllPipelinesMenuItem, false);
      /** Tools **/
      setMenuItemState(PlotSelectedMenuItem, false);
      setMenuItemState(ExploreSelectedMenuItem, false);
      /** Window **/
      buildWindowsMenu("document");
      /** Help **/
      setMenuItemState(HelpBlockHelpMenuItem, false);
      setMenuItemState(HelpBlockDocMenuItem, false);

      setButtonState(newPipelineTBB, true);
      setButtonState(saveWorkbenchTBB, true);
      setButtonState(saveWorkbenchAsTBB, true);
      setButtonState(importTBB, true);
      setButtonState(copyTBB, true);
      setButtonState(pasteTBB, true);
      setButtonState(undoTBB, false);
      setButtonState(redoTBB, false);
      setButtonState(deleteSelectedTBB, false);
      setButtonState(leftTBB, false);
      setButtonState(rightTBB, false);
      setButtonState(upTBB, false);
      setButtonState(downTBB, false);
      setButtonState(zoomInTBB, false);
      setButtonState(zoomOutTBB, false);
      setButtonState(searchTBB, false);
      setButtonState(helpTBB, false);
      setButtonState(infoTBB, false);
      setButtonState(togifTBB, false);
      setButtonState(repoSubmitTBB, false);
      setButtonState(repoSearchTBB, false);
      setButtonState(paramsOverviewBtn, false);

      // deactivate library, shelf, execution buttons, parameter table buttons
      mainTabPanel.setSelectedComponent(pipelineTab);
      mainTabPanel.setEnabledAt(0, true);  // pipeline
      mainTabPanel.setEnabledAt(1, false); // library
      mainTabPanel.setEnabledAt(2, false); // shelf
      mainTabPanel.setEnabledAt(3, false); // properties
      mainTabPanel.setEnabledAt(4, false); // controls
      activatePipelineControls(false);

      // Set parameter and block property table to empty
//      PlistTableModel tm = (PlistTableModel) plistTable.getModel();
//      tm.setPl(new JPlist());
//      plistTable.setModel(new DefaultTableModel());
      setCombo.setModel(new DefaultComboBoxModel());

//      BlockPropertyTableModel bpm = new BlockPropertyTableModel(null);
      BlockPropertyTable.setModel(new DefaultTableModel());


    } else if (focus.equals("pipeline")) {


      /** File **/
      setMenuItemState(WBSavePipelineMenuItem, true);
      setMenuState(PlanMenu, true);
      /** Edit **/
      setMenuState(MainMenuEdit, true);
      setMenuItemState(DuplicateMenuItem, true);
      setMenuItemState(DeleteMenuItem, true);
      setMenuItemState(UndoMenuItem, true);
      setMenuItemState(RedoMenuItem, true);
      /** View **/
      setMenuState(MainMenuView, true);
      /** Format **/
      setMenuState(MainMenuFormat, true);
      /** Pipeline **/
      setMenuItemState(NewMenuItem, true);
      setMenuItemState(RenamePipelineMenuItem, true);
      setMenuItemState(ExportToMFileMenuItem, true);
      setMenuItemState(ExportToTerminalMenuItem, true);
      setMenuItemState(ExportToImageMenuItem, true);
      setMenuItemState(CreateSubsystemPipelineMenuItem, true);
      setMenuItemState(showQuickBlockMenuItem, true);
      setMenuItemState(editCanvasInfoMenuItem, true);
      setMenuItemState(searchCanvasMenuItem, true);
      setMenuItemState(ClosePipelineMenuItem, true);
      setMenuItemState(CloseAllPipelinesMenuItem, true);
      /** Tools **/
      setMenuItemState(PlotSelectedMenuItem, true);
      setMenuItemState(ExploreSelectedMenuItem, true);
      /** Window **/
      buildWindowsMenu("pipeline");
      /** Help **/
      setMenuItemState(HelpBlockHelpMenuItem, true);
      setMenuItemState(HelpBlockDocMenuItem, true);

      setButtonState(newPipelineTBB, true);
      setButtonState(saveWorkbenchTBB, true);
      setButtonState(saveWorkbenchAsTBB, true);
      setButtonState(importTBB, true);
      setButtonState(copyTBB, true);
      setButtonState(pasteTBB, true);
      setButtonState(undoTBB, true);
      setButtonState(redoTBB, true);
      setButtonState(deleteSelectedTBB, true);
      setButtonState(leftTBB, true);
      setButtonState(rightTBB, true);
      setButtonState(upTBB, true);
      setButtonState(downTBB, true);
      setButtonState(zoomInTBB, true);
      setButtonState(zoomOutTBB, true);
      setButtonState(searchTBB, true);
      setButtonState(helpTBB, true);
      setButtonState(infoTBB, true);
      setButtonState(togifTBB, true);
      setButtonState(repoSubmitTBB, false); // this is controlled by the selection state on the canvas
      setButtonState(repoSearchTBB, true);
      setButtonState(paramsOverviewBtn, true);

      // deactivate library, shelf, execution buttons, parameter table buttons
      mainTabPanel.setSelectedComponent(pipelineTab);
      mainTabPanel.setEnabledAt(0, true); // pipeline
      mainTabPanel.setEnabledAt(1, true); // library
      mainTabPanel.setEnabledAt(2, true); // shelf
      mainTabPanel.setEnabledAt(3, true); // properties
      mainTabPanel.setEnabledAt(4, true); // properties
      activatePipelineControls(true);

    } else {

      /** File **/
      setMenuItemState(WBSavePipelineMenuItem, false);
      setMenuState(PlanMenu, false);
      /** Edit **/
      setMenuState(MainMenuEdit, false);
      /** View **/
      setMenuState(MainMenuView, false);
      /** Format **/
      setMenuState(MainMenuFormat, false);
      /** Pipeline **/
      setMenuItemState(NewMenuItem, true);
      setMenuItemState(RenamePipelineMenuItem, false);
      setMenuItemState(ExportToMFileMenuItem, false);
      setMenuItemState(ExportToTerminalMenuItem, false);
      setMenuItemState(ExportToImageMenuItem, false);
      setMenuItemState(CreateSubsystemPipelineMenuItem, false);
      setMenuItemState(showQuickBlockMenuItem, false);
      setMenuItemState(editCanvasInfoMenuItem, false);
      setMenuItemState(searchCanvasMenuItem, false);
      setMenuItemState(ClosePipelineMenuItem, false);
      setMenuItemState(CloseAllPipelinesMenuItem, false);
      /** Tools **/
      setMenuItemState(PlotSelectedMenuItem, false);
      setMenuItemState(ExploreSelectedMenuItem, false);
      /** Window **/
      buildWindowsMenu("none");
      /** Help **/
      setMenuItemState(HelpBlockHelpMenuItem, false);
      setMenuItemState(HelpBlockDocMenuItem, false);

      setButtonState(newPipelineTBB, true);
      setButtonState(saveWorkbenchTBB, true);
      setButtonState(saveWorkbenchAsTBB, true);
      setButtonState(importTBB, true);
      setButtonState(copyTBB, false);
      setButtonState(pasteTBB, false);
      setButtonState(undoTBB, false);
      setButtonState(redoTBB, false);
      setButtonState(deleteSelectedTBB, false);
      setButtonState(leftTBB, false);
      setButtonState(rightTBB, false);
      setButtonState(upTBB, false);
      setButtonState(downTBB, false);
      setButtonState(zoomInTBB, false);
      setButtonState(zoomOutTBB, false);
      setButtonState(searchTBB, false);
      setButtonState(helpTBB, false);
      setButtonState(infoTBB, false);
      setButtonState(togifTBB, false);
      setButtonState(repoSubmitTBB, false);
      setButtonState(repoSearchTBB, false);
      setButtonState(paramsOverviewBtn, false);

      // deactivate library, shelf, execution buttons, parameter table buttons
      mainTabPanel.setSelectedComponent(pipelineTab);
      mainTabPanel.setEnabledAt(0, false); // pipeline
      mainTabPanel.setEnabledAt(1, false); // library
      mainTabPanel.setEnabledAt(2, false); // shelf
      mainTabPanel.setEnabledAt(3, false); // properties
      mainTabPanel.setEnabledAt(4, false); // properties
      activatePipelineControls(false);

    }

    activatePipelineTabButtons();

  }

  private static void setButtonState(JButton bt, boolean state) {
    bt.setEnabled(state);
  }

  private static void setMenuItemState(JMenuItem mi, boolean state) {

    Component[] submenus = mi.getComponents();
    for (int kk = 0; kk < submenus.length; kk++) {
      submenus[kk].setEnabled(state);
      submenus[kk].setVisible(state);
    }
    mi.setEnabled(state);
    mi.setVisible(state);

  }

  private static void setMenuState(JMenu m, boolean state) {

    Component[] submenus = m.getMenuComponents();
    for (int kk = 0; kk < submenus.length; kk++) {
      submenus[kk].setEnabled(state);
      submenus[kk].setVisible(state);
    }
    m.setEnabled(state);
    m.setVisible(state);
  }

  private void activatePipelineTabButtons() {

    if (documents.size() == 1) {
      mvPipelineUpBtn.setEnabled(false);
      mvPipelineDownBtn.setEnabled(false);
      deletePipelineBtn.setEnabled(true);
    } else if (documents.size() > 1) {
      mvPipelineUpBtn.setEnabled(true);
      mvPipelineDownBtn.setEnabled(true);
      deletePipelineBtn.setEnabled(true);
    } else {
      mvPipelineUpBtn.setEnabled(false);
      mvPipelineDownBtn.setEnabled(false);
      deletePipelineBtn.setEnabled(false);
    }

  }

  private void activatePipelineControls(boolean state) {
    ResetBtn.setEnabled(state);
    StepForwardBtn.setEnabled(state);
    StepBackwardsBtn.setEnabled(state);
    RunBtn.setEnabled(state);
    SkipForwardBtn.setEnabled(state);
    ExploreBtn.setEnabled(state);
    PlotBtn.setEnabled(state);
    DisplayBtn.setEnabled(state);
    HistoryBtn.setEnabled(state);
    exportWorkspaceBtn.setEnabled(state);
    saveObjectBtn.setEnabled(state);
    tableBtn.setEnabled(state);
    reportBtn.setEnabled(state);

    ParamAddBtn.setEnabled(state);
    ParamRmvBtn.setEnabled(state);
    setCombo.setEnabled(state);
  }

  public BlockDiagram getActiveDiagram() {
    if (DocumentPane.getSelectedFrame() instanceof BlockDiagram) {
      return (BlockDiagram) DocumentPane.getSelectedFrame();
    } else {
      return null;
    }
  }

  public PipelineListTree getPipelineListTree() {
    return (PipelineListTree) pipelineListTree;
  }

  public boolean popupConsoleOnExecution() {
    return preferences.getGeneralPreferences().isShowConsoleOnExecution();
  }

  public void showBlockProperties() {

    mainTabPanel.setSelectedIndex(3); // select properties tab

  }

  public void setLtpdaPreferences2(LTPDAPreferences ltpdaPreferences2) {
    this.ltpdaPreferences2 = ltpdaPreferences2;
  }
//  private static class ObserverImpl implements Observer {
//
//    MainWindow mw = null;
//
//    private ObserverImpl(MainWindow mw) {
//      this.mw = mw;
//    }
//
//    public void update(Observable o, Object arg) {
//
//      if (o instanceof LTPDAPreferences) {
//        if (arg instanceof DisplayPrefGroup) {
//          DisplayPrefGroup displayPrefs = (DisplayPrefGroup) arg;
//          if (mw != null && displayPrefs != null) {
//            mw.getVebosityCombo().setSelectedIndex(displayPrefs.getDisplayVerboseLevel() +1);
//          } else {
//            System.err.println("Mainwindow is null");
//          }
//        }
//      }
//    }
//
//  }
}