/* ========================
* JSynoptic : a free Synoptic editor
* ========================
*
* Project Info: http://jsynoptic.sourceforge.net/index.html
*
* This program is free software; you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Foundation;
* either version 2.1 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307, USA.
*
* (C) Copyright 2001-2003, by :
* Corporate:
* Astrium SAS
* EADS CRC
* Individual:
* Nicolas Brodu
*
* $Id: Builtin.java,v 1.69 2009/02/04 11:12:09 ogor Exp $
*
* Changes
* -------
* 25-Sep-2003 : Initial public release (NB);
*
*/
package jsynoptic.builtin;
import java.awt.event.ActionEvent;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.SortedMap;
import java.util.TimeZone;
import java.util.Vector;
import java.util.logging.Logger;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.filechooser.FileFilter;
import jsynoptic.base.HelpNode;
import jsynoptic.base.Linkable;
import jsynoptic.base.Plugin;
import jsynoptic.base.Template;
import jsynoptic.data.DataSourceAnimator;
import jsynoptic.data.DataSourceAnimatorProvider;
import jsynoptic.data.DataSourceCollectionAnimator;
import jsynoptic.data.DataSourceCollectionAnimatorProvider;
import jsynoptic.ui.JSynoptic;
import jsynoptic.ui.JSynopticBatch;
import jsynoptic.ui.Run;
import jsynoptic.ui.ShapeCreator;
import jsynoptic.ui.ShapesContainer;
import simtools.data.AsciiFileDataSourceCollection;
import simtools.data.LinearSinusDataSourceProvider;
import simtools.data.DataSource;
import simtools.data.DataSourceCollection;
import simtools.data.DataSourcePool;
import simtools.data.buffer.DelayedBuffer;
import simtools.data.buffer.ResizeableBuffer;
import simtools.shapes.AbstractShape;
import simtools.shapes.CurveShape;
import simtools.shapes.PlotShape;
import simtools.shapes.ShapeListener;
import simtools.ui.ActionCheckBox;
import simtools.ui.BasicMessageWriter;
import simtools.ui.ColorMapper;
import simtools.ui.HelpBundle;
import simtools.ui.HelpFinder;
import simtools.ui.ReportingDialog;
import simtools.ui.ImageMapper;
import simtools.ui.MenuResourceBundle;
import simtools.ui.NumberField;
import simtools.ui.ResourceFinder;
import simtools.ui.TextMapper;
import simtools.ui.TimeCurveStatisticPanel;
import simtools.ui.TimePlotStatisticsDialog;
import simtools.ui.TimeStampedDataSourceInformation;
import simtools.ui.UserProperties;
import simtools.util.CurrentPathProvider;
import simtools.util.SysExec;
/**
* Default plugin, actually built in jsynoptic
*
* @author Nicolas Brodu
*
* @version 1.0 2001
*/
public class Builtin extends Plugin {
/** Resources */
public static MenuResourceBundle resources = ResourceFinder.getMenu(Builtin.class);
public static BasicMessageWriter messageWriter = ResourceFinder.getMessages(Builtin.class);
public static MenuResourceBundle.FileFilter jsynopticFilter;
public static MenuResourceBundle.FileFilter asciiFileFilter;
public static MenuResourceBundle.FileFilter shellFileFilter;
public static HelpBundle builtinHelp = HelpFinder.getMenu(Builtin.class);
/**
* A looger to dump error or warning messages in a soket, an output stream,
* a file...
*/
static Logger _logger = simtools.util.LogConfigurator.getLogger(Builtin.class.getName());
static {
jsynopticFilter = resources.getFileFilter("jsynopticFilter");
jsynopticFilter.setCanProcessDirectory(true);
asciiFileFilter = resources.getFileFilter("asciiFileFilter");
String[] executableExtensions;
if ((System.getProperty("os.name")).startsWith("Win")) {
executableExtensions = new String[2];
executableExtensions[0] = new String("exe");
executableExtensions[1] = new String("com");
} else {
executableExtensions = new String[1];
executableExtensions[0] = new String("sh");
}
shellFileFilter = resources.getFileFilter("shellFileFilter", executableExtensions);
}
protected static javax.swing.filechooser.FileFilter[] bothFilters = new javax.swing.filechooser.FileFilter[] {
jsynopticFilter,
asciiFileFilter,
shellFileFilter };
protected static javax.swing.filechooser.FileFilter[] jsynopticOnlyFilters = new javax.swing.filechooser.FileFilter[] { jsynopticFilter };
public List shapeCreators;
public final static String PLOT = resources.getString("Plot");
public final static String TIME_PLOT = resources.getString("TimePlot");
public final static String TEXT = resources.getString("Text");
public final static String TEXT_ARRAY = resources.getString("TextArray");
public final static String HISTORY = resources.getString("History");
public final static String POLYGON = resources.getString("Polygon");
public final static String ELLIPSE = resources.getString("Ellipse");
public final static String RECTANGLE = resources.getString("Rectangle");
public final static String LINES = resources.getString("Lines");
public final static String IMAGE = resources.getString("Image");
public final static String AUTOMATON = resources.getString("Automaton");
public final static String CONNECTION = resources.getString("Connection");
public final static String BAR = resources.getString("Bar");
protected static boolean hasAlreadyPutProviders = false;
public Builtin() {
if (hasAlreadyPutProviders) {
return;
}
// builtin shape creators
shapeCreators = new ArrayList();
shapeCreators.add(new ShapeCreator(this, PLOT, resources.getIcon("PlotIcon")));
shapeCreators.add(new ShapeCreator(this, TIME_PLOT));
shapeCreators.add(new ShapeCreator(this, TEXT, resources.getIcon("TextIcon")));
shapeCreators.add(new ShapeCreator(this, TEXT_ARRAY));
shapeCreators.add(new ShapeCreator(this, HISTORY));
shapeCreators.add(new ShapeCreator(this, POLYGON));
shapeCreators.add(new ShapeCreator(this, ELLIPSE, resources.getIcon("EllipseIcon")));
shapeCreators.add(new ShapeCreator(this, RECTANGLE, resources.getIcon("RectangleIcon")));
shapeCreators.add(new ShapeCreator(this, LINES));
shapeCreators.add(new ShapeCreator(this, IMAGE));
shapeCreators.add(new ShapeCreator(this, AUTOMATON));
shapeCreators.add(new ShapeCreator(this, CONNECTION));
shapeCreators.add(new ShapeCreator(this, BAR));
// Providers
DataSourcePool.global.addProvider(new LinearSinusDataSourceProvider());
DataSourcePool.global.addProvider(new DataSourceCollectionAnimatorProvider());
DataSourcePool.global.addProvider(new DataSourceAnimatorProvider());
DataSourcePool.global.addProvider(new RangeSourceProvider());
DataSourcePool.global.addProvider(new RandomSourceProvider());
DataSourcePool.global.addProvider(new AsciiProvider());
UserProperties prop = Run.getProperties();
jsynoptic.builtin.TextShape.groupTextDigits = prop.getBoolean("jsynoptic.builtin.Text.groupTextDigits",
jsynoptic.builtin.TextShape.groupTextDigits);
String imageDefaultDirectoryName = prop.getString("jsynoptic.builtin.ui.ImagePropertiesPanel.defaultDirectory",
null);
if (imageDefaultDirectoryName != null) {
jsynoptic.builtin.ui.ImagePropertiesPanel.defaultDirectory = new File(imageDefaultDirectoryName);
simtools.ui.ImageMapper.defaultDirectory = new File(imageDefaultDirectoryName);
}
/**
* take property PreferredXGraduation and PreferredYGraduation for plot
*/
jsynoptic.builtin.Plot.preferredXGraduation = prop.getInt("jsynoptic.builtin.Plot.preferredXGraduation",
jsynoptic.builtin.Plot.preferredXGraduation);
jsynoptic.builtin.Plot.preferredYGraduation = prop.getInt("jsynoptic.builtin.Plot.preferredYGraduation",
jsynoptic.builtin.Plot.preferredYGraduation);
/**
* the type of the line in the grid false : simple lines for the grid
* true : dashed lines for the grid
*/
simtools.shapes.AxisShape.preferredDashedGrid = prop.getBoolean(
"simtools.shapes.AxisShape.preferredDashedGrid", simtools.shapes.AxisShape.preferredDashedGrid);
/**
* Indicate the presence of grids for the initialization
*/
simtools.shapes.AxisShape.preferredShowGrid = prop.getBoolean("simtools.shapes.AxisShape.preferredShowGrid",
simtools.shapes.AxisShape.preferredShowGrid);
hasAlreadyPutProviders = true;
/**
* Update several reading date formats
*/
String readTimeZone = prop.getString("simtools.data.readTimeZone", null);
if (readTimeZone == null) {
prop.setString("simtools.data.readTimeZone", "GMT");
readTimeZone = prop.getString("simtools.data.readTimeZone", null);
}
TextShape.dateFormatPattern = prop.getString("simtools.data.dateFormat", TextShape.dateFormatPattern);
TextShape.shortTimeFormatPattern = prop.getString("simtools.data.shortTimeFormat", TextShape.shortTimeFormatPattern);
TextShape.longTimeFormatPattern = prop.getString("simtools.data.longTimeFormat", TextShape.longTimeFormatPattern);
if (prop.getString("simtools.data.longTimeFormat", null) != null){
TimeStampedDataSourceInformation.dateTimeFormatter = new SimpleDateFormat(prop.getString("simtools.data.longTimeFormat", null));
}
String pattern;
String newPattern;
pattern = AsciiFileDataSourceCollection.dateFormat.toPattern();
newPattern = prop.getString("simtools.data.dateFormat", null);
if (newPattern == null) {
// set property to default value
prop.setString("simtools.data.dateFormat", pattern);
} else {
// apply property value
AsciiFileDataSourceCollection.dateFormat = new SimpleDateFormat(newPattern);
}
pattern = AsciiFileDataSourceCollection.shortTimeFormat.toPattern();
newPattern = prop.getString("simtools.data.shortTimeFormat", null);
if (newPattern == null) {
// set property to default value
prop.setString("simtools.data.shortTimeFormat", pattern);
} else {
// apply property value
AsciiFileDataSourceCollection.shortTimeFormat = new SimpleDateFormat(newPattern);
}
pattern = AsciiFileDataSourceCollection.longTimeFormat.toPattern();
newPattern = prop.getString("simtools.data.longTimeFormat", null);
if (newPattern == null) {
// set property to default value
prop.setString("simtools.data.longTimeFormat", pattern);
} else {
// apply property value
AsciiFileDataSourceCollection.longTimeFormat = new SimpleDateFormat(newPattern);
}
AsciiFileDataSourceCollection.dateFormat.setTimeZone(TimeZone.getTimeZone(readTimeZone));
AsciiFileDataSourceCollection.shortTimeFormat.setTimeZone(TimeZone.getTimeZone(readTimeZone));
AsciiFileDataSourceCollection.longTimeFormat.setTimeZone(TimeZone.getTimeZone(readTimeZone));
/**
* Update several wrinting date formats
*
*/
String displayTimeZone = prop.getString("simtools.ui.displayTimeZone", null);
if (displayTimeZone == null) {
prop.setString("simtools.ui.displayTimeZone", "GMT");
displayTimeZone = prop.getString("simtools.ui.displayTimeZone", null);
}
TimeCurveStatisticPanel.dateTimeFormatter.setTimeZone(TimeZone.getTimeZone(displayTimeZone));
TimePlotStatisticsDialog.dateTimeFormatter.setTimeZone(TimeZone.getTimeZone(displayTimeZone));
TimeStampedDataSourceInformation.dateTimeFormatter.setTimeZone(TimeZone.getTimeZone(displayTimeZone));
TextShape.timeZone = displayTimeZone;
// Text properties
TextShape.DEFAULT_FIXED_FONT = prop.getBoolean("jsynoptic.builtin.TextShape.fixedFont",
TextShape.DEFAULT_FIXED_FONT);
TextShape.DEFAULT_FIXED_FRAME = prop.getBoolean("jsynoptic.builtin.TextShape.fixedFrame",
TextShape.DEFAULT_FIXED_FRAME);
TextShape.DEFAUT_CHAR_NUMBER = prop.getInt("jsynoptic.builtin.TextShape.charNumber",
TextShape.DEFAUT_CHAR_NUMBER);
TextShape.DEFAULT_TEXT_SIZE = prop.getInt("jsynoptic.builtin.TextShape.textSize", TextShape.DEFAULT_TEXT_SIZE);
TextShape.DEFAULT_TEXT_FONT = prop.getString("jsynoptic.builtin.TextShape.textFont",
TextShape.DEFAULT_TEXT_FONT);
TextShape.DEFAULT_FORMAT = prop.getInt("jsynoptic.builtin.TextShape.format", TextShape.DEFAULT_FORMAT);
TextShape.DEFAULT_DISPLAY_NAME = prop.getBoolean("jsynoptic.builtin.TextShape.displayName",
TextShape.DEFAULT_DISPLAY_NAME);
TextShape.DEFAULT_DISPLAY_VALUE = prop.getBoolean("jsynoptic.builtin.TextShape.displayValue",
TextShape.DEFAULT_DISPLAY_VALUE);
TextShape.DEFAULT_DISPLAY_UNIT = prop.getBoolean("jsynoptic.builtin.TextShape.displayUnit",
TextShape.DEFAULT_DISPLAY_UNIT);
TextShape.DEFAULT_DISPLAY_COMMENTS = prop.getBoolean("jsynoptic.builtin.TextShape.displayComments",
TextShape.DEFAULT_DISPLAY_COMMENTS);
// Plot properties
Plot.DEFAULT_DISPLAY_DATA_SOURCE_ID = prop.getBoolean("jsynoptic.builtin.Plot.displayDataSourceId",
Plot.DEFAULT_DISPLAY_DATA_SOURCE_ID);
// Curve statistic properties
CurveShape.SHOW_X_MIN = prop.getBoolean("simtools.shapes.CurveShape.showXMin", CurveShape.SHOW_X_MIN);
CurveShape.SHOW_X_MAX = prop.getBoolean("simtools.shapes.CurveShape.showXMax", CurveShape.SHOW_X_MAX);
CurveShape.SHOW_Y_MIN = prop.getBoolean("simtools.shapes.CurveShape.showYMin", CurveShape.SHOW_Y_MIN);
CurveShape.SHOW_Y_MAX = prop.getBoolean("simtools.shapes.CurveShape.showYMax", CurveShape.SHOW_Y_MAX);
CurveShape.SHOW_POINT_NUMBER = prop.getBoolean("simtools.shapes.CurveShape.showPointNumber", CurveShape.SHOW_POINT_NUMBER);
CurveShape.SHOW_MEAN = prop.getBoolean("simtools.shapes.CurveShape.showMean", CurveShape.SHOW_MEAN);
CurveShape.SHOW_DEVIATION = prop.getBoolean("simtools.shapes.CurveShape.ShowDeviation", CurveShape.SHOW_DEVIATION);
CurveShape.SHOW_INTEGRAL = prop.getBoolean("simtools.shapes.CurveShape.showIntegral", CurveShape.SHOW_INTEGRAL);
CurveShape.STATISTIC_ACCURACY = prop.getInt("simtools.shapes.CurveShape.statisticAccuracy", CurveShape.STATISTIC_ACCURACY);
}
/* (non-Javadoc)
* @see jsynoptic.base.Plugin#getShapeCreators()
*/
public List getShapeCreators(){
return shapeCreators;
}
/* (non-Javadoc)
* @see jsynoptic.base.Plugin#createShape(java.lang.String)
*/
public AbstractShape createShape(String name) {
AbstractShape res = null;
if ((name.equals(PLOT)) || (name.equals(TIME_PLOT))) {
Plot plot = null;
if (name.equals(PLOT)) {
plot = new Plot(0, 0, resources.getIntValue("defaultPlotWidth"), resources
.getIntValue("defaultPlotHeight"));
} else if (name.equals(TIME_PLOT)) {
plot = new TimePlot(0, 0, resources.getIntValue("defaultPlotWidth"), resources
.getIntValue("defaultPlotHeight"));
}
res = plot;
} else if (name.equals(TEXT)) {
res = new TextShape(resources.getString("Text"), 150, 50);
}else if (name.equals(TEXT_ARRAY)) {
res = new TextArrayShape(resources.getString("Text"), 150, 50);
} else if (name.equals(HISTORY)) {
res = new HistoryTextShape(5, 150, 50);
} else if (name.equals(POLYGON)) {
res = new PolygonShape(0, 0, 100, 100);
}else if (name.equals(ELLIPSE)) {
res = new EllipseShape(0, 0, 100, 100);
} else if (name.equals(RECTANGLE)) {
res = new RectangleShape(0, 0, 100, 50);
} else if (name.equals(LINES)) {
res = new LinesShape(0, 0, 100, 100);
} else if (name.equals(IMAGE)) {
res = new ImageShape(0, 0, 100, 100);
} else if (name.equals(AUTOMATON)) {
res = new AutomatonShape(0, 0, 5, 5, 100, 100);
} else if (name.equals(CONNECTION)) {
res = new ConnectionShape(0, 0, 50, 0);
} else if (name.equals(BAR)) {
res = new BarShape(0, 0, 400, 100);
}
return res;
}
/* (non-Javadoc)
* @see jsynoptic.base.Plugin#createShape(java.lang.String, int, int, int, int)
*/
public AbstractShape createShape(String name, int x, int y, int width, int height) {
AbstractShape res = null;
if (name.equals(TEXT)) {
// Do not fit text bounds if a width and a height is specified
res = new TextShape(resources.getString("Text"), x, y, width, height, false);
} else if (name.equals(RECTANGLE)) {
// Do not fit text bounds if a width and a height is specified
res = new RectangleShape( x, y, width, height);
} else if (name.equals(ELLIPSE)) {
// Do not fit text bounds if a width and a height is specified
res = new EllipseShape(x, y, width, height);
} else if (name.equals(PLOT)) {
// Do not fit text bounds if a width and a height is specified
res = new PlotShape(x, y, width, height);
}
return res;
}
public javax.swing.filechooser.FileFilter[] getFileFilters(int action) {
if (action == SAVE) {
return jsynopticOnlyFilters;
}
if (action == OPEN) {
return bothFilters;
}
return null;
}
protected boolean processJSynopticFile(File f, int action) {
switch (action) {
case OPEN:
int numF = 0;
if (JSynoptic.gui != null) {
numF = JSynoptic.gui.getFilePanel().getFileCount();
}
// Do not enter the loop in batch mode
for (int i = 0; i < numF; ++i) {
File fi = JSynoptic.gui.getFilePanel().getFile(i);
if (fi == null) {
continue;
}
if (fi.equals(f)) {
// Same file, select existing tab => useful for links
JSynoptic.gui.getFilePanel().selectComponent(JSynoptic.gui.getFilePanel().getComponentAt(i));
return true;
}
}
// Reach this point only the file isn't already loaded
JSynoptic.setStatus(messageWriter.print1args("loading", f.getName()));
DataSourcePool.global.clearLocalEmptySources();
try {
FileInputStream fis = new FileInputStream(f);
ObjectInputStream is = new ObjectInputStream(fis);
Object o = is.readObject();
if ((o == null) || !(o instanceof ShapesContainer)) {
throw new java.io.IOException();
}
ShapesContainer sc = (ShapesContainer) o;
String name = f.getName();
String myExt = resources.getStringValue("jsynopticFilterExtension");
if (name.endsWith(myExt)) {
name = name.substring(0, name.length() - myExt.length() - 1);
}
sc.getComponent().setName(name);
// for ascending compatibility
o = is.readObject();
if ((o != null) && (o instanceof Vector)) {
for (Iterator it = ((Vector) o).iterator(); it.hasNext();) {
Object ito = it.next();
if (!(ito instanceof ColorMapper)) {
continue;
}
if (ColorMapper.colorMappers == null) {
ColorMapper.colorMappers = new Vector();
}
if (!ColorMapper.colorMappers.contains(ito)) {
ColorMapper.colorMappers.add(ito);
}
}
}
// for ascending compatibility
o = is.readObject();
if ((o != null) && (o instanceof Vector)) {
for (Iterator it = ((Vector) o).iterator(); it.hasNext();) {
Object ito = it.next();
if (!(ito instanceof TextMapper)) {
continue;
}
if (TextMapper.textMappers == null) {
TextMapper.textMappers = new Vector();
}
if (!TextMapper.textMappers.contains(ito)) {
TextMapper.textMappers.add(ito);
}
}
}
// for ascending compatibility
o = is.readObject();
if ((o != null) && (o instanceof Vector)) {
for (Iterator it = ((Vector) o).iterator(); it.hasNext();) {
Object ito = it.next();
if (!(ito instanceof ImageMapper)) {
continue;
}
if (ImageMapper.imageMappers == null) {
ImageMapper.imageMappers = new Vector();
}
if (!ImageMapper.imageMappers.contains(ito)) {
ImageMapper.imageMappers.add(ito);
}
}
}
is.close();
fis.close(); // also closes the file
for (Iterator it = sc.iterator(); it.hasNext();) {
try {
AbstractShape abs = (AbstractShape) it.next();
abs.addListener( (ShapeListener)sc.getComponent());
if (!(abs instanceof Linkable)) {
continue;
}
Linkable l = (Linkable) abs;
// Now trying to restore absolute file
File parent = f.getParentFile();
if (parent == null) {
parent = new File("./");
}
String link = l.getLink();
if ((link != null) && (!link.equals(""))) {
File nl = new File(parent, link);
l.setLink(nl.getCanonicalPath());
}
} catch (ClassCastException cce) {
}
}
if (JSynoptic.gui != null) {
JSynoptic.gui.addContainer(sc, f);
}
if (JSynopticBatch.batch != null) {
JSynopticBatch.batch.addContainer(sc, f);
}
} catch (Exception e) {
if (JSynoptic.gui != null) {
JOptionPane.showMessageDialog(JSynoptic.gui.getOwner(), new JLabel(messageWriter.print1args(
"cannotLoadFile", f.getName())), messageWriter.print0args("loadedFileRemarks"),
JOptionPane.ERROR_MESSAGE);
}
e.printStackTrace();
if (JSynopticBatch.batch != null) {
_logger.severe(messageWriter.print1args("cannotLoadFile", f.getName()));
}
JSynoptic.setStatus(messageWriter.print1args("cannotLoadFile", f.getName()));
return false;
}
if (!DataSourcePool.global.localEmptySourcesIsEmpty()) {
if (JSynoptic.gui != null) {
JOptionPane.showMessageDialog(JSynoptic.gui.getOwner(), new ReportingDialog(messageWriter
.print1args("missingElements", f.getName()), DataSourcePool.global
.getEmptySourcesDumpColumnNames(), DataSourcePool.global.getEmptySourcesDump()),
messageWriter.print0args("loadedFileRemarks"), JOptionPane.INFORMATION_MESSAGE);
}
}
JSynoptic.setStatus(messageWriter.print1args("loadOK", f.getName()));
return true;
case SAVE:
if (JSynoptic.gui == null) {
return false;
}
JSynoptic.setStatus(messageWriter.print1args("saving", f.getName()));
try {
ShapesContainer sc = JSynoptic.gui.getActiveContainer();
if (sc == null) {
return false;
}
// Save container into specified file
saveShapeContainer(sc, f);
} catch (java.io.IOException ioe) {
ioe.printStackTrace();
JOptionPane.showMessageDialog(JSynoptic.gui.getOwner(), messageWriter.print1args("cannotSaveFile", f
.getName()), resources.getStringValue("IOError"), JOptionPane.ERROR_MESSAGE);
JSynoptic.setStatus(messageWriter.print1args("cannotSaveFile", f.getName()));
return false;
}
JSynoptic.setStatus(messageWriter.print1args("saveOK", f.getName()));
return true;
} // end switch
return false;
}
/**
* Save Shape container into a specified file.
*
* @param sc,
* the shape container
* @param f,
* the file where to save shape container contents
* @return
* @throws java.io.IOException
*/
public boolean saveShapeContainer(ShapesContainer sc, File f) throws java.io.IOException {
// Make links relative now the file is known
// Was tested under both Unix and the Windows horror
for (Iterator it = sc.iterator(); it.hasNext();) {
Object o = it.next();
if (!(o instanceof Linkable)) {
continue;
}
Linkable l = (Linkable) o;
String link = l.getLink();
if (link != null) {
File flink = new File(link);
String sf = f.getCanonicalPath();
String sl = flink.getCanonicalPath();
int i = -1, lastOK = -1;
while ((i < sl.length()) && (i < sf.length())
&& ((i == -1) || sf.substring(0, i).equals(sl.substring(0, i)))) {
lastOK = i;
i = sl.indexOf(File.separator, i + 1);
if (i == -1) {
break;
}
}
String subf = sf.substring(lastOK + 1, sf.length());
String subl = sl.substring(lastOK + 1, sl.length());
String prefix = "";
i = -1;
while (true) {
i = subf.indexOf(File.separator, i + 1);
if (i == -1) {
break;
}
prefix += "../";
}
link = prefix + subl;
link = link.replaceAll("\\\\", "/"); // regexp black magic
// incantation
// Set the relative link
l.setLink(link);
}
}
FileOutputStream fos = new FileOutputStream(f);
// ZipOutputStream zos = new ZipOutputStream(fos);
// zos.setComment(resources.getStringValue("zipComment"));
ObjectOutputStream os = new ObjectOutputStream(fos);
// os.writeObject(resources.getStringValue("fileComment"));
os.writeObject(sc);
os.writeObject(null); // for ascending compatibility
os.writeObject(null); // for ascending compatibility
os.writeObject(null); // for ascending compatibility
os.flush();
os.close();
fos.close(); // also closes the file
String name = f.getName();
String myExt = resources.getStringValue("jsynopticFilterExtension");
if (name.endsWith(myExt)) {
name = name.substring(0, name.length() - myExt.length() - 1);
}
sc.getComponent().setName(name);
// Restoring absolute links
for (Iterator it = sc.iterator(); it.hasNext();) {
try {
AbstractShape abs = (AbstractShape) it.next();
abs.addListener( (ShapeListener)sc.getComponent());
if (!(abs instanceof Linkable)) {
continue;
}
Linkable l = (Linkable) abs;
// Now trying to restore absolute file
File parent = f.getParentFile();
if (parent == null) {
parent = new File("./");
}
String link = l.getLink();
if ((link != null) && (!link.equals(""))) {
File nl = new File(parent, link);
l.setLink(nl.getCanonicalPath());
}
} catch (ClassCastException cce) {
}
}
if (JSynoptic.gui != null) {
JSynoptic.gui.getFilePanel().setFile(sc.getComponent(), f);
}
// Set diagramm modification status as not modified
sc.getComponent().setHasBeenModified(false);
return true;
}
protected ASCIIFileOptionComponent optionPanel;
protected boolean processAsciiFile(File f, int action) {
if (action != OPEN) {
return false; // but should not happen
}
try {
DataSourceCollection dsc;
if ((optionPanel != null) && optionPanel.isSubSampled()) {
dsc = new AsciiFileDataSourceCollection(f, (int) optionPanel.getSubSampleValue(), optionPanel
.getChartsetName(), f.getName().endsWith(".csv"));
} else if (optionPanel != null) {
dsc = new AsciiFileDataSourceCollection(f, optionPanel.getChartsetName(), f.getName().endsWith(".csv"));
} else {
dsc = new AsciiFileDataSourceCollection(f, f.getName().endsWith(".csv"));
}
if ((optionPanel != null) && optionPanel.isDynamic()) {
DataSourceCollectionAnimator dsca = new DataSourceCollectionAnimator(dsc);
dsca.bufferize(new DelayedBuffer(optionPanel.getBufferSize()));
dsca.setPeriod(optionPanel.getDynamicRefreshValue());
DataSourcePool.global.addDataSourceCollection(dsca);
} else {
dsc.bufferize(new ResizeableBuffer(resources.getIntValue("maxBufferSize")));
DataSourcePool.global.addDataSourceCollection(dsc);
}
} catch (Exception e) {
if (JSynoptic.gui == null) {
_logger.severe(messageWriter.print1args("cannotLoadFile", f.getName()));
} else {
JOptionPane.showMessageDialog(JSynoptic.gui.getOwner(), messageWriter.print1args("cannotLoadFile", f
.getName()), resources.getStringValue("IOError"), JOptionPane.ERROR_MESSAGE);
}
return false;
}
JSynoptic.setStatus(messageWriter.print1args("loadOK", f.getName()));
return true;
}
/**
* Execute a shell file. Shell execution is performed in another thread
*
* @param shell
* file
* @return true if shell file could be launched
*/
protected boolean processShellFile(File f) {
try {
new ExecutableFileProcess(f);
return true;
} catch (Exception e) {
}
return false;
}
public class ExecutableFileProcess implements SysExec.ErrOutWriter {
protected File executableFile;
public ExecutableFileProcess(File executableFile) throws Exception {
if (executableFile.exists()) {
this.executableFile = executableFile;
ExecutableFileProcessThread sfp = new ExecutableFileProcessThread();
sfp.start();
}
}
public void errPrintln(String line) {
_logger.severe(line);
}
public void outPrintln(String line) {
_logger.fine(line);
}
public class ExecutableFileProcessThread extends Thread {
public void run() {
SysExec executableFileExec = new SysExec(ExecutableFileProcess.this);
executableFileExec.add(ExecutableFileProcess.this.executableFile.getAbsolutePath());
int exitValue = executableFileExec.run();
ExecutableFileProcess.this.outPrintln("End of execution : " + exitValue);
}
}
}
public boolean processFile(File f, int action) {
CurrentPathProvider.currentPathProvider.setCurrentPath(f);
if (f.isDirectory()) {
return true;
}
if (jsynopticFilter.canProcess(f)) {
return processJSynopticFile(f, action);
}
if (asciiFileFilter.canProcess(f)) {
return processAsciiFile(f, action);
}
if ((shellFileFilter.canProcess(f) && (action == OPEN))) {
return processShellFile(f);
}
return false;
}
public JComponent getOptionPanelForFilter(FileFilter filter) {
_logger.fine(filter.toString());
if (filter == null) {
return optionPanel = new ASCIIFileOptionComponent();
}
if (asciiFileFilter.equals(filter)) {
return optionPanel = new ASCIIFileOptionComponent();
}
return null;
}
/*
* (non-Javadoc)
*
* @see jsynoptic.base.Plugin#about()
*/
public String about() {
return null;
}
public static class ASCIIFileOptionComponent extends JPanel {
protected NumberField nfsubsample, nfdelay, nfbuffersize;
protected ActionCheckBox cbsubsample, cbdynamic;
protected JLabel ldynamic, lsubsample, ldynamicbuffersize;
protected JComboBox cbxCharset;
public ASCIIFileOptionComponent() {
Box box = new Box(BoxLayout.Y_AXIS);
Box hbox = Box.createHorizontalBox();
hbox.add(cbsubsample = new ActionCheckBox(resources.getStringValue("asciiOptionSubSampling"), false) {
public void actionPerformed(ActionEvent e) {
nfsubsample.setEnabled(isSelected());
lsubsample.setEnabled(isSelected());
if (!isSelected()) {
nfsubsample.setValue(1);
}
}
});
hbox.add(Box.createHorizontalGlue());
box.add(hbox);
hbox = Box.createHorizontalBox();
hbox.add(lsubsample = new JLabel(resources.getStringValue("asciiOptionSubSamplingText")));
hbox.add(Box.createHorizontalGlue());
hbox.add(nfsubsample = new NumberField(1, 5));
box.add(hbox);
cbsubsample.apply();
hbox = Box.createHorizontalBox();
hbox.add(cbdynamic = new ActionCheckBox(resources.getStringValue("asciiOptionDynamic"), false) {
public void actionPerformed(ActionEvent e) {
nfdelay.setEnabled(isSelected());
ldynamic.setEnabled(isSelected());
nfbuffersize.setEnabled(isSelected());
ldynamicbuffersize.setEnabled(isSelected());
if (!isSelected()) {
nfdelay.setValue(1000);
}
if (!isSelected()) {
nfbuffersize.setValue(100);
}
}
});
hbox.add(Box.createHorizontalGlue());
box.add(hbox);
hbox = Box.createHorizontalBox();
hbox.add(ldynamic = new JLabel(resources.getStringValue("asciiOptionDynamicPeriod")));
hbox.add(Box.createHorizontalGlue());
hbox.add(nfdelay = new NumberField(1000, 5));
box.add(hbox);
hbox = Box.createHorizontalBox();
hbox.add(ldynamicbuffersize = new JLabel(resources.getStringValue("asciiOptionDynamicBufferSize")));
hbox.add(Box.createHorizontalGlue());
hbox.add(nfbuffersize = new NumberField(100, 5));
box.add(hbox);
cbdynamic.apply();
hbox = Box.createHorizontalBox();
hbox.add(new JLabel(resources.getStringValue("asciiOptionCharset")));
hbox.add(Box.createHorizontalGlue());
hbox.add(cbxCharset = new JComboBox());
cbxCharset.addItem(resources.getStringValue("asciiOptionNoCharset"));
SortedMap map = Charset.availableCharsets();
for (Iterator it = map.keySet().iterator(); it.hasNext();) {
cbxCharset.addItem(it.next());
}
// TODO: Use preferences to set a default charset if desired by user
cbxCharset.setSelectedIndex(0); // None by default
box.add(hbox);
add(box);
nfsubsample.setMaximumSize(nfsubsample.getPreferredSize());
nfdelay.setMaximumSize(nfdelay.getPreferredSize());
nfbuffersize.setMaximumSize(nfbuffersize.getPreferredSize());
}
public boolean isDynamic() {
return cbdynamic.isSelected();
}
public boolean isSubSampled() {
return cbsubsample.isSelected();
}
public long getSubSampleValue() {
return nfsubsample.getLongValue();
}
public long getDynamicRefreshValue() {
return nfdelay.getLongValue();
}
public int getBufferSize() {
return (int) nfbuffersize.getLongValue();
}
public String getChartsetName() {
int idx = cbxCharset.getSelectedIndex();
if (idx <= 0) {
return null; // none
}
return cbxCharset.getSelectedItem().toString();
}
}
protected static String[] providedSources = {
resources.getString("UniformRandom"),
resources.getString("GaussianRandom"),
resources.getString("RangeSource"),
// resources.getString("NaturalNumbers"),
/*
* "Natural numbers", "Uniform Random", "Gaussian Random", "Linear", "Sine",
* "Range",
*/
};
public Template[] getTemplates() {
Template[] res = new Template[1];
res = new Template[1];
res[0] = new PlotTemplate();
return res;
}
/*
* (non-Javadoc)
*
* @see jsynoptic.base.Plugin#getSources()
*/
public String[] getSources() {
return providedSources;
}
public DataSource createSource(String name, String instanceName) {
if (name == null) {
return null;
}
if (name.equals(resources.getString("UniformRandom"))) {
UniformRandomSource.OptionPanel panel = new UniformRandomSource.OptionPanel();
int result = JOptionPane.showConfirmDialog(JSynoptic.gui.getOwner(), panel, resources
.getString("SourceOptionPanelTitle"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
if (result == JOptionPane.OK_OPTION) {
return panel.createSource(instanceName);
}
return null;
}
if (name.equals(resources.getString("GaussianRandom"))) {
GaussianRandomSource.OptionPanel panel = new GaussianRandomSource.OptionPanel();
int result = JOptionPane.showConfirmDialog(JSynoptic.gui.getOwner(), panel, resources
.getString("SourceOptionPanelTitle"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
if (result == JOptionPane.OK_OPTION) {
return panel.createSource(instanceName);
}
return null;
}
if (name.equals(resources.getString("RangeSource"))) {
RangeSource.OptionPanel panel = new RangeSource.OptionPanel();
int result = JOptionPane.showConfirmDialog(JSynoptic.gui.getOwner(), panel, resources
.getString("SourceOptionPanelTitle"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
if (result == JOptionPane.OK_OPTION) {
return panel.createSource(instanceName);
}
return null;
}
if (name.equals(resources.getString("NaturalNumbers"))) {
return new DataSourceAnimator(new RangeSource(instanceName, 0, Long.MAX_VALUE, 1));
}
return super.createSource(name, instanceName);
}
public HelpNode getHelp(){
HelpNode rootNode = new HelpNode();
rootNode.addHelpNode(new HelpNode("Help on JSynoptic", builtinHelp.getURLValue("welcome")));
// General
HelpNode overviewNode = new HelpNode("Overview", builtinHelp.getURLValue("generalFeature"));
overviewNode.addHelpNode(new HelpNode("How to launch JSynoptic ?", builtinHelp.getURLValue("generalFeature_running")));
overviewNode.addHelpNode(new HelpNode("First steps with JSynoptic...", builtinHelp.getURLValue("generalFeature_composition")));
overviewNode.addHelpNode(new HelpNode("Extending JSynoptic with plugins", builtinHelp.getURLValue("generalFeature_extending")));
rootNode.addHelpNode(overviewNode);
//File features
HelpNode fileNode = new HelpNode("File features", builtinHelp.getURLValue("fileFeature"));
fileNode.addHelpNode(new HelpNode("Create a new sheet", builtinHelp.getURLValue("fileFeature_create")));
fileNode.addHelpNode(new HelpNode("Open files", builtinHelp.getURLValue("fileFeature_open")));
fileNode.addHelpNode(new HelpNode("Close current sheet", builtinHelp.getURLValue("fileFeature_close")));
fileNode.addHelpNode(new HelpNode("Close all sheets", builtinHelp.getURLValue("fileFeature_closeAll")));
fileNode.addHelpNode(new HelpNode("Refresh all sheets", builtinHelp.getURLValue("fileFeature_refreshAll")));
fileNode.addHelpNode(new HelpNode("Save current sheet", builtinHelp.getURLValue("fileFeature_save")));
fileNode.addHelpNode(new HelpNode("Save all", builtinHelp.getURLValue("fileFeature_save","saveAll")));
HelpNode exportNode = new HelpNode("Export sheet", builtinHelp.getURLValue("fileFeature_export"));
exportNode.addHelpNode(new HelpNode("Export into .zip archive", builtinHelp.getURLValue("exportFeature")));
fileNode.addHelpNode(exportNode);
fileNode.addHelpNode(new HelpNode("Sheet view...", builtinHelp.getURLValue("fileFeature_sheetView")));
fileNode.addHelpNode(new HelpNode("Print current sheet", builtinHelp.getURLValue("fileFeature_print")));
fileNode.addHelpNode(new HelpNode("Generate current sheet image", builtinHelp.getURLValue("fileFeature_generateImage")));
fileNode.addHelpNode(new HelpNode("Snapshot", builtinHelp.getURLValue("fileFeature_snapshot")));
fileNode.addHelpNode(new HelpNode("Display sheet information", builtinHelp.getURLValue("fileFeature_sid")));
fileNode.addHelpNode(new HelpNode("Exit from JSynoptic", builtinHelp.getURLValue("fileFeature_exit")));
rootNode.addHelpNode(fileNode);
// Editing
HelpNode efHelpNode = new HelpNode("Editing features", builtinHelp.getURLValue("editingFeature"));
efHelpNode.addHelpNode(new HelpNode("Create a shape", builtinHelp.getURLValue("editingFeature_create")));
efHelpNode.addHelpNode(new HelpNode("Select shapes", builtinHelp.getURLValue("editingFeature_select")));
efHelpNode.addHelpNode(new HelpNode("Undo, redo an action", builtinHelp.getURLValue("editingFeature_undo")));
efHelpNode.addHelpNode(new HelpNode("Cut, paste, copy or remove", builtinHelp.getURLValue("editingFeature_cut")));
efHelpNode.addHelpNode(new HelpNode("Resize selected shapes", builtinHelp.getURLValue("editingFeature_resize")));
efHelpNode.addHelpNode(new HelpNode("Move shapes", builtinHelp.getURLValue("editingFeature_move")));
efHelpNode.addHelpNode(new HelpNode("Group shapes", builtinHelp.getURLValue("editingFeature_group")));
efHelpNode.addHelpNode(new HelpNode("Order shapes", builtinHelp.getURLValue("editingFeature_order")));
efHelpNode.addHelpNode(new HelpNode("Align", builtinHelp.getURLValue("editingFeature_align")));
efHelpNode.addHelpNode(new HelpNode("Distribute", builtinHelp.getURLValue("editingFeature_distribute")));
efHelpNode.addHelpNode(new HelpNode("Display grid", builtinHelp.getURLValue("editingFeature_grid")));
efHelpNode.addHelpNode(new HelpNode("Ajust a diagram", builtinHelp.getURLValue("editingFeature_ajust")));
efHelpNode.addHelpNode(new HelpNode("Set background color", builtinHelp.getURLValue("editingFeature_backgroundColor")));
rootNode.addHelpNode(efHelpNode);
// Data sources
HelpNode dsHelpNode = new HelpNode("Data sources features", builtinHelp.getURLValue("dsGeneralFeature"));
HelpNode dsBasic = new HelpNode("Data source basic features", builtinHelp.getURLValue("dsGeneralFeature_basicFeatures"));
dsBasic.addHelpNode(new HelpNode("Data source : a structure to hold information...", builtinHelp.getURLValue("dsGeneralFeature_basicFeatures","holdInformation")));
dsBasic.addHelpNode(new HelpNode("Source tree", builtinHelp.getURLValue("dsGeneralFeature_basicFeatures","tree")));
dsBasic.addHelpNode(new HelpNode("Display data source information", builtinHelp.getURLValue("dsGeneralFeature_basicFeatures","information")));
dsBasic.addHelpNode(new HelpNode("Alias a data source", builtinHelp.getURLValue("dsGeneralFeature_basicFeatures","alias")));
dsHelpNode.addHelpNode(dsBasic);
dsHelpNode.addHelpNode(new HelpNode("Data source collection", builtinHelp.getURLValue("dsGeneralFeature_collection")));
dsHelpNode.addHelpNode(new HelpNode("Dynamic data source", builtinHelp.getURLValue("dsGeneralFeature_dynamic")));
dsHelpNode.addHelpNode(new HelpNode("Asynchronous data source", builtinHelp.getURLValue("dsGeneralFeature_asynchronous")));
HelpNode dsExpr = new HelpNode("Mathematical expression", builtinHelp.getURLValue("dsGeneralFeature_expressions"));
dsExpr.addHelpNode(new HelpNode("Create/Update a mathematical expression", builtinHelp.getURLValue("dsGeneralFeature_expressions","expWrite")));
dsExpr.addHelpNode(new HelpNode("What can be used in a such expression ?", builtinHelp.getURLValue("dsGeneralFeature_expressions","expOperators")));
dsHelpNode.addHelpNode(dsExpr);
HelpNode dsTemp = new HelpNode("Data source templates", builtinHelp.getURLValue("dsGeneralFeature_templates"));
dsTemp.addHelpNode(new HelpNode("Static or dynamic template", builtinHelp.getURLValue("dsGeneralFeature_templates","tempStatic")));
dsTemp.addHelpNode(new HelpNode("Create a range template", builtinHelp.getURLValue("dsGeneralFeature_templates","tempRange")));
HelpNode dsRandom = new HelpNode("Create a random template", builtinHelp.getURLValue("dsGeneralFeature_templates","tempRandom"));
dsTemp.addHelpNode(dsRandom);
dsRandom.addHelpNode(new HelpNode("Uniform", builtinHelp.getURLValue("dsGeneralFeature_templates","uniform")));
dsRandom.addHelpNode(new HelpNode("Gaussian", builtinHelp.getURLValue("dsGeneralFeature_templates","gaussian")));
dsHelpNode.addHelpNode(dsTemp);
//Merge of data
HelpNode dsMerge = new HelpNode("Merge of data", builtinHelp.getURLValue("mergeDataSourcesFeature"));
HelpNode dsTerm = new HelpNode("Terminology", builtinHelp.getURLValue("mergeDataSourcesFeature_terminology"));
dsMerge.addHelpNode(dsTerm);
dsTerm.addHelpNode(new HelpNode("Time formats", builtinHelp.getURLValue("mergeDataSourcesFeature_terminology_timeFormat")));
dsTerm.addHelpNode(new HelpNode("Synchronous,asynchronous data", builtinHelp.getURLValue("mergeDataSourcesFeature_terminology_asynchronousOrSynchronousData")));
HelpNode dsSyncrhMerge = new HelpNode("Synchronous,asynchronous merge", builtinHelp.getURLValue("mergeDataSourcesFeature_terminology_synchronousOrasynchronousMerge"));
dsTerm.addHelpNode(dsSyncrhMerge);
dsSyncrhMerge.addHelpNode(new HelpNode("Asynchronous merge", builtinHelp.getURLValue("mergeDataSourcesFeature_terminology_synchronousOrasynchronousMerge","asynchronousMerge")));
HelpNode dsSMerge = new HelpNode("Synchronous merge", builtinHelp.getURLValue("mergeDataSourcesFeature_terminology_synchronousOrasynchronousMerge","synchronousMerge"));
dsSyncrhMerge.addHelpNode(dsSMerge);
dsSMerge.addHelpNode(new HelpNode("0-order interpolation", builtinHelp.getURLValue("mergeDataSourcesFeature_zeroOrderInterpolation")));
dsSMerge.addHelpNode(new HelpNode("1-order interpolation", builtinHelp.getURLValue("mergeDataSourcesFeature_oneOrderInterpolation")));
HelpNode dsMergeGuide = new HelpNode("User guide for data merge", builtinHelp.getURLValue("mergeDataSourcesFeature_userGuide"));
dsMerge.addHelpNode(dsMergeGuide);
dsMergeGuide.addHelpNode(new HelpNode("1. Specify the name and the kind of merge collection", builtinHelp.getURLValue("mergeDataSourcesFeature_userGuide_collectionPage")));
dsMergeGuide.addHelpNode(new HelpNode("2. Settings related to merge collection", builtinHelp.getURLValue("mergeDataSourcesFeature_userGuide_collectionOptionPage")));
dsMergeGuide.addHelpNode(new HelpNode("3. Add a data or a collection to merge collection", builtinHelp.getURLValue("mergeDataSourcesFeature_userGuide_addDataPage")));
dsMergeGuide.addHelpNode(new HelpNode("4. Settings related to added data", builtinHelp.getURLValue("mergeDataSourcesFeature_userGuide_addDataOptionPage")));
dsMergeGuide.addHelpNode(new HelpNode("5. Terminate or add other data", builtinHelp.getURLValue("mergeDataSourcesFeature_userGuide_finishPage")));
dsHelpNode.addHelpNode(dsMerge);
rootNode.addHelpNode(dsHelpNode);
// Mapper Features
HelpNode mapperNode = new HelpNode("Mappers features", builtinHelp.getURLValue("mapper"));
mapperNode.addHelpNode(new HelpNode("Basic features about mappers", builtinHelp.getURLValue("mapper_definition")));
mapperNode.addHelpNode(new HelpNode("Create a mapper for a shape property", builtinHelp.getURLValue("mapper_create")));
mapperNode.addHelpNode(new HelpNode("Modify a mapper", builtinHelp.getURLValue("mapper_modify")));
mapperNode.addHelpNode(new HelpNode("Duplicate a mapper", builtinHelp.getURLValue("mapper_duplicate")));
mapperNode.addHelpNode(new HelpNode("Delete a mapper", builtinHelp.getURLValue("mapper_delete")));
mapperNode.addHelpNode(new HelpNode("Edit mapper properties", builtinHelp.getURLValue("mapper_edit")));
mapperNode.addHelpNode(new HelpNode("How mappers are restored when opening a synoptic file?", builtinHelp.getURLValue("mapper_restoreProcess")));
mapperNode.addHelpNode(new HelpNode("How to apply a mapper change on saved synoptics?", builtinHelp.getURLValue("mapper_applyMapperChanges")));
HelpNode mapperKindNode = new HelpNode("Available kinds of mappers", builtinHelp.getURLValue("mapper_text"));
mapperKindNode.addHelpNode(new HelpNode("Text mapper", builtinHelp.getURLValue("mapper_text")));
mapperKindNode.addHelpNode(new HelpNode("Color mapper", builtinHelp.getURLValue("mapper_color")));
mapperKindNode.addHelpNode(new HelpNode("Image mapper", builtinHelp.getURLValue("mapper_image")));
mapperNode.addHelpNode(mapperKindNode);
rootNode.addHelpNode(mapperNode);
// shapes
HelpNode shapeFeatureNode = new HelpNode("Shape features", builtinHelp.getURLValue("shapes"));
// basic shapes
HelpNode basicShapeNode = new HelpNode("Shapes features", builtinHelp.getURLValue("shapes"));
basicShapeNode.addHelpNode(new HelpNode("Available shapes", builtinHelp.getURLValue("shapes","list")));
basicShapeNode.addHelpNode(new HelpNode("Move a shape", builtinHelp.getURLValue("shapes_move")));
basicShapeNode.addHelpNode(new HelpNode("Resize a shap", builtinHelp.getURLValue("shapes_resize")));
basicShapeNode.addHelpNode(new HelpNode("Apply a rotation or a translation", builtinHelp.getURLValue("shapes_rotation")));
basicShapeNode.addHelpNode(new HelpNode("Link a shape to a file", builtinHelp.getURLValue("shapes_link")));
shapeFeatureNode.addHelpNode(basicShapeNode);
// image shapes
HelpNode imageNode = new HelpNode("Image", builtinHelp.getURLValue("image"));
imageNode.addHelpNode(new HelpNode("Set static image", builtinHelp.getURLValue("image_static")));
imageNode.addHelpNode(new HelpNode("Use image pane to create an image shape", builtinHelp.getURLValue("image_imageFrame")));
imageNode.addHelpNode(new HelpNode("Set dynamic image", builtinHelp.getURLValue("image_dynamic")));
imageNode.addHelpNode(new HelpNode("Display a frame arount imagen", builtinHelp.getURLValue("image_frame")));
imageNode.addHelpNode(new HelpNode("Fit image to shape dimension", builtinHelp.getURLValue("image_fit")));
imageNode.addHelpNode(new HelpNode("Vector-based images", builtinHelp.getURLValue("image_vectorBasedImages")));
shapeFeatureNode.addHelpNode(imageNode);
// Connection shapes
HelpNode connectionNode = new HelpNode("Connection", builtinHelp.getURLValue("connection"));
connectionNode.addHelpNode(new HelpNode("Why using connections ?", builtinHelp.getURLValue("connection_definition")));
connectionNode.addHelpNode(new HelpNode("Create a connection", builtinHelp.getURLValue("connection_create")));
connectionNode.addHelpNode(new HelpNode("Select and move connection", builtinHelp.getURLValue("connection_select")));
connectionNode.addHelpNode(new HelpNode("Connect the connection to a gate", builtinHelp.getURLValue("connection_connect")));
connectionNode.addHelpNode(new HelpNode("Set the connection stroke style", builtinHelp.getURLValue("connection_style")));
connectionNode.addHelpNode(new HelpNode("Display arrows on ends", builtinHelp.getURLValue("connection_arrow")));
shapeFeatureNode.addHelpNode(connectionNode);
// Line shapes
HelpNode lineNode = new HelpNode("Line", builtinHelp.getURLValue("line"));
lineNode.addHelpNode(new HelpNode("Set line by specifing some points coordinates", builtinHelp.getURLValue("line_coordinates")));
lineNode.addHelpNode(new HelpNode("Set line by editing its points in the editor pane", builtinHelp.getURLValue("line_editor")));
lineNode.addHelpNode(new HelpNode("Set line color, stroke and thickness", builtinHelp.getURLValue("line_color")));
lineNode.addHelpNode(new HelpNode("Convert line to polygon", builtinHelp.getURLValue("line_convert")));
shapeFeatureNode.addHelpNode(lineNode);
// Polygon shapes
HelpNode polygonNode = new HelpNode("Polygon", builtinHelp.getURLValue("polygon"));
polygonNode.addHelpNode(new HelpNode("Set a regular polygon", builtinHelp.getURLValue("polygon_regular")));
polygonNode.addHelpNode(new HelpNode("Set a polygon specifing its coordinates", builtinHelp.getURLValue("polygon_set")));
polygonNode.addHelpNode(new HelpNode("Set polygon fill color", builtinHelp.getURLValue("polygon_fill")));
polygonNode.addHelpNode(new HelpNode("Set edges stroke and thickness", builtinHelp.getURLValue("polygon_edge")));
polygonNode.addHelpNode(new HelpNode("Convert polygon to lines", builtinHelp.getURLValue("polygon_convert")));
shapeFeatureNode.addHelpNode(polygonNode);
// Rectangle shape
HelpNode rectangleNode = new HelpNode("Rectangle", builtinHelp.getURLValue("rectangle"));
rectangleNode.addHelpNode(new HelpNode("Set rectangle fill color", builtinHelp.getURLValue("rectangle_fill")));
rectangleNode.addHelpNode(new HelpNode("Display a frame around rectangle", builtinHelp.getURLValue("rectangle_frame")));
rectangleNode.addHelpNode(new HelpNode("Set a variable ratio", builtinHelp.getURLValue("rectangle_variable")));
shapeFeatureNode.addHelpNode(rectangleNode);
// Ellipse shape
HelpNode ellipseNode = new HelpNode("Ellipse", builtinHelp.getURLValue("ellipse"));
ellipseNode.addHelpNode(new HelpNode("Make a full,a pie,a chord or an open ellipse", builtinHelp.getURLValue("ellipse_type")));
ellipseNode.addHelpNode(new HelpNode("Set ellipse fill color", builtinHelp.getURLValue("ellipse_fill")));
ellipseNode.addHelpNode(new HelpNode("Display a frame around ellipse", builtinHelp.getURLValue("ellipse_frame")));
shapeFeatureNode.addHelpNode(ellipseNode);
// Text shape
HelpNode textNode = new HelpNode("Text", builtinHelp.getURLValue("text"));
textNode.addHelpNode(new HelpNode("Edit text with a constant string", builtinHelp.getURLValue("text_static")));
textNode.addHelpNode(new HelpNode("Set frame and background aspects", builtinHelp.getURLValue("text_frame")));
textNode.addHelpNode(new HelpNode("Set text display format", builtinHelp.getURLValue("text_textDisplayFormat")));
textNode.addHelpNode(new HelpNode("Set text size format", builtinHelp.getURLValue("text_textSizeFormat")));
textNode.addHelpNode(new HelpNode("Set a dynamic text", builtinHelp.getURLValue("text_dynamic")));
HelpNode formatTextNode = new HelpNode("Format a dynamic text", builtinHelp.getURLValue("text_dynamicFormat"));
formatTextNode.addHelpNode(new HelpNode("Display data source attributes", builtinHelp.getURLValue("text_dynamicFormat","displayDataSourceAttributes")));
HelpNode formatValueNode = new HelpNode("Format a data source value", builtinHelp.getURLValue("text_dynamicFormat","formatDataSource"));
formatValueNode.addHelpNode(new HelpNode("Maximum number of digits", builtinHelp.getURLValue("text_dynamicFormat","nbDigits")));
formatValueNode.addHelpNode(new HelpNode("Time Zone", builtinHelp.getURLValue("text_dynamicFormat","timeZone")));
formatValueNode.addHelpNode(new HelpNode("Text mapper", builtinHelp.getURLValue("text_dynamicFormat","textMapper")));
formatTextNode.addHelpNode(formatValueNode);
textNode.addHelpNode(formatTextNode);
// Printf
HelpNode printfNode = new HelpNode("How to use printf format ?", builtinHelp.getURLValue("printfFormat"));
printfNode.addHelpNode(new HelpNode("Printf Syntax", builtinHelp.getURLValue("printfFormat_printfSyntax")));
printfNode.addHelpNode(new HelpNode("Escape Sequences", builtinHelp.getURLValue("printfFormat_escapeSequences")));
printfNode.addHelpNode(new HelpNode("Conversion Specifications", builtinHelp.getURLValue("printfFormat_conversionSpecifications")));
printfNode.addHelpNode(new HelpNode("Flag Characters", builtinHelp.getURLValue("printfFormat_flagCharacters")));
printfNode.addHelpNode(new HelpNode("Conversion Characters", builtinHelp.getURLValue("printfFormat_conversionCharacters")));
formatValueNode.addHelpNode(printfNode);
shapeFeatureNode.addHelpNode(textNode);
// Text array shapes
HelpNode textArrayNode = new HelpNode("Text array", builtinHelp.getURLValue("textArray"));
textArrayNode.addHelpNode(new HelpNode("Add a new cell", builtinHelp.getURLValue("textArray_add")));
textArrayNode.addHelpNode(new HelpNode("Delete a cell", builtinHelp.getURLValue("textArray_delete")));
textArrayNode.addHelpNode(new HelpNode("Set cell properties", builtinHelp.getURLValue("textArray_cell")));
textArrayNode.addHelpNode(new HelpNode("Use a unique font for the whose array", builtinHelp.getURLValue("textArray_uniqueFont")));
shapeFeatureNode.addHelpNode(textArrayNode);
// History text shapes
HelpNode textHistoryNode = new HelpNode("Text history", builtinHelp.getURLValue("textHistory"));
textHistoryNode.addHelpNode(new HelpNode("Set number of past values displayed", builtinHelp.getURLValue("textHistory","number")));
shapeFeatureNode.addHelpNode(textHistoryNode);
// Automaton shapes
HelpNode automatonNode = new HelpNode("Automaton", builtinHelp.getURLValue("automaton"));
automatonNode.addHelpNode(new HelpNode("What is an automaton ?", builtinHelp.getURLValue("automaton_definition")));
automatonNode.addHelpNode(new HelpNode("Set initial number of rows and columns", builtinHelp.getURLValue("automaton_number")));
automatonNode.addHelpNode(new HelpNode("Set initial active cell position", builtinHelp.getURLValue("automaton_active")));
automatonNode.addHelpNode(new HelpNode("Set the source reference", builtinHelp.getURLValue("automaton_source")));
HelpNode assoNode = new HelpNode("Create an association", builtinHelp.getURLValue("automaton_association"));
assoNode.addHelpNode(new HelpNode("Set association expression", builtinHelp.getURLValue("automaton_association","expression")));
assoNode.addHelpNode(new HelpNode("Delete an association", builtinHelp.getURLValue("automaton_association","delete")));
assoNode.addHelpNode(new HelpNode("Change association order", builtinHelp.getURLValue("automaton_association","order")));
assoNode.addHelpNode(new HelpNode("Set association list of actions", builtinHelp.getURLValue("automaton_association","list")));
automatonNode.addHelpNode(assoNode);
HelpNode actionNode = new HelpNode("Create an action", builtinHelp.getURLValue("automaton_action"));
actionNode.addHelpNode(new HelpNode("Set association name", builtinHelp.getURLValue("automaton_action","nameAss")));
actionNode.addHelpNode(new HelpNode("Add an action", builtinHelp.getURLValue("automaton_action","addAction")));
actionNode.addHelpNode(new HelpNode("Change action order", builtinHelp.getURLValue("automaton_action","moveAction")));
actionNode.addHelpNode(new HelpNode("Delete an action", builtinHelp.getURLValue("automaton_action","deleteAction")));
automatonNode.addHelpNode(actionNode);
HelpNode actionEditNode = new HelpNode("Edit an action", builtinHelp.getURLValue("automaton_editAction"));
actionEditNode.addHelpNode(new HelpNode("Set active cell colors", builtinHelp.getURLValue("automaton_editAction","color")));
actionEditNode.addHelpNode(new HelpNode("Move active cell", builtinHelp.getURLValue("automaton_editAction","move")));
actionEditNode.addHelpNode(new HelpNode("Set active cell text", builtinHelp.getURLValue("automaton_editAction","text")));
automatonNode.addHelpNode(actionEditNode);
shapeFeatureNode.addHelpNode(automatonNode);
// Bar shapes
HelpNode barNode = new HelpNode("Bar", builtinHelp.getURLValue("bar"));
barNode.addHelpNode(new HelpNode("What is a bar ?", builtinHelp.getURLValue("bar_definition")));
barNode.addHelpNode(new HelpNode("Attach a data source to the bar", builtinHelp.getURLValue("bar_data")));
HelpNode barEditNode = new HelpNode("Configure bar axis properties", builtinHelp.getURLValue("bar_axisProperties"));
barEditNode.addHelpNode(new HelpNode("Display axis steps on the bar", builtinHelp.getURLValue("bar_axisProperties","axisGrid")));
barEditNode.addHelpNode(new HelpNode("Define axis min, max step", builtinHelp.getURLValue("bar_axisProperties","setMinMax")));
barEditNode.addHelpNode(new HelpNode("Display axis steps on the bar", builtinHelp.getURLValue("bar_axisProperties","autoscaleProperty")));
barEditNode.addHelpNode(new HelpNode("Set Autoscale", builtinHelp.getURLValue("bar_axisProperties","logarithmicScale")));
barEditNode.addHelpNode(new HelpNode("Set floating scale", builtinHelp.getURLValue("bar_axisProperties","floatingScale")));
barEditNode.addHelpNode(new HelpNode("Display axis label", builtinHelp.getURLValue("bar_axisProperties","axisLabel")));
barNode.addHelpNode(barEditNode);
shapeFeatureNode.addHelpNode(barNode);
// Plot shapes
HelpNode plotNode = new HelpNode("Plot", builtinHelp.getURLValue("plot"));
plotNode.addHelpNode(new HelpNode("Which kind of plot may I use ?", builtinHelp.getURLValue("plot_kind")));
HelpNode plotBasicNode = new HelpNode("Basic plot", builtinHelp.getURLValue("plot_basicPlot"));
HelpNode primaryXNode = new HelpNode("Set X axis", builtinHelp.getURLValue("plot_basicPlot","primaryX"));
primaryXNode.addHelpNode(new HelpNode("Set primary X source", builtinHelp.getURLValue("plot_basicPlot","primaryX")));
primaryXNode.addHelpNode(new HelpNode("Set secondary X source", builtinHelp.getURLValue("plot_basicPlot","secondaryX")));
plotBasicNode.addHelpNode(primaryXNode);
HelpNode primaryY = new HelpNode("Add a curve", builtinHelp.getURLValue("plot_basicPlot","primaryY"));
primaryY.addHelpNode(new HelpNode("Add a curve as primary Y", builtinHelp.getURLValue("plot_basicPlot","primaryY")));
primaryY.addHelpNode(new HelpNode("Add a curve as secondary Y", builtinHelp.getURLValue("plot_basicPlot","secondaryY")));
plotBasicNode.addHelpNode(primaryY);
plotBasicNode.addHelpNode(new HelpNode("Drag & drop operation", builtinHelp.getURLValue("plot_basicPlot","dragDrop")));
plotNode.addHelpNode(plotBasicNode);
HelpNode timePlotNode = new HelpNode("Time plot", builtinHelp.getURLValue("plot_timePlot"));
plotNode.addHelpNode(timePlotNode);
HelpNode asyncPlotNode = new HelpNode("Asynchronous plots", builtinHelp.getURLValue("plot_asyncPlot"));
HelpNode asyncPrimaryY = new HelpNode("Add a curve", builtinHelp.getURLValue("plot_asyncPlot","asyncPrimaryY"));
asyncPrimaryY.addHelpNode(new HelpNode("Add a curve as primary Y", builtinHelp.getURLValue("plot_asyncPlot","asyncPrimaryY")));
asyncPrimaryY.addHelpNode(new HelpNode("Add a curve as secondary Y", builtinHelp.getURLValue("plot_asyncPlot","asyncSecondaryY")));
asyncPlotNode.addHelpNode(asyncPrimaryY);
asyncPlotNode.addHelpNode(new HelpNode("Display secondary X axis", builtinHelp.getURLValue("plot_asyncPlot","displaySecX")));
plotNode.addHelpNode(asyncPlotNode);
plotNode.addHelpNode(new HelpNode("Display plot title", builtinHelp.getURLValue("plot_plotTitle")));
HelpNode curve = new HelpNode("Curve", builtinHelp.getURLValue("plot_curve"));
curve.addHelpNode(new HelpNode("Delete a curve", builtinHelp.getURLValue("plot_curve_delete")));
curve.addHelpNode(new HelpNode("Set curve color", builtinHelp.getURLValue("plot_curve_curveColor")));
curve.addHelpNode(new HelpNode("Set curve strocke", builtinHelp.getURLValue("plot_curve_curveStrocke")));
curve.addHelpNode(new HelpNode("Display curve points", builtinHelp.getURLValue("plot_curve_curvePoints")));
curve.addHelpNode(new HelpNode("Display vertical bars", builtinHelp.getURLValue("plot_curve_verticalBars")));
curve.addHelpNode(new HelpNode("Magnetise a curve and display local slope", builtinHelp.getURLValue("plot_curve_magnetise")));
curve.addHelpNode(new HelpNode("Tag a point on curve and display relative coordinates from this point", builtinHelp.getURLValue("plot_curve_tagpoint")));
plotNode.addHelpNode(curve);
HelpNode axis = new HelpNode("Axis", builtinHelp.getURLValue("plot_axis"));
axis.addHelpNode(new HelpNode("Set axis bounds", builtinHelp.getURLValue("plot_axis_axisBounds")));
axis.addHelpNode(new HelpNode("Display axis grid", builtinHelp.getURLValue("plot_axis_axisGrid")));
axis.addHelpNode(new HelpNode("Set autoscale", builtinHelp.getURLValue("plot_axis_autoscaleProperty")));
axis.addHelpNode(new HelpNode("How to define an average steps number when autoscale is performed?", builtinHelp.getURLValue("plot_axis_autoscaleProperty","averageStepsNumber")));
axis.addHelpNode(new HelpNode("Set logarithmic scale", builtinHelp.getURLValue("plot_axis_logarithmicScale")));
axis.addHelpNode(new HelpNode("Set floating scale", builtinHelp.getURLValue("plot_axis_floatingScale")));
axis.addHelpNode(new HelpNode("Display axis label", builtinHelp.getURLValue("plot_axis_axisLabel")));
plotNode.addHelpNode(axis);
HelpNode limit = new HelpNode("Limit", builtinHelp.getURLValue("plot_limit"));
limit.addHelpNode(new HelpNode("Add a limit", builtinHelp.getURLValue("plot_limit_limitAdd")));
limit.addHelpNode(new HelpNode("Delete a limit", builtinHelp.getURLValue("plot_limit_limitDelete")));
limit.addHelpNode(new HelpNode("Set limit name", builtinHelp.getURLValue("plot_limit_limitName")));
limit.addHelpNode(new HelpNode("SSet limit position", builtinHelp.getURLValue("plot_limit_limitPosition")));
limit.addHelpNode(new HelpNode("Set limit color", builtinHelp.getURLValue("plot_limit_limitColor")));
limit.addHelpNode(new HelpNode("Set limit strocke", builtinHelp.getURLValue("plot_limit_limitStrocke")));
plotNode.addHelpNode(limit);
plotNode.addHelpNode(new HelpNode("Read mouse coordinates on plot frames", builtinHelp.getURLValue("plot_mouseCoordinates")));
HelpNode browse = new HelpNode("Browse a plot", builtinHelp.getURLValue("plot_browse"));
browse.addHelpNode(new HelpNode("Fit all", builtinHelp.getURLValue("plot_browse_autoscale")));
browse.addHelpNode(new HelpNode("Autoscale Y axis", builtinHelp.getURLValue("plot_browse_autoscaleY")));
browse.addHelpNode(new HelpNode("Adjust on X axe", builtinHelp.getURLValue("plot_browse_adjustOnX")));
browse.addHelpNode(new HelpNode("Use zoom box", builtinHelp.getURLValue("plot_browse_zoomBox")));
browse.addHelpNode(new HelpNode("Zoom with mouse wheel", builtinHelp.getURLValue("plot_browse_mouseWheel")));
plotNode.addHelpNode(browse);
HelpNode curveInformation = new HelpNode("Curves information", builtinHelp.getURLValue("plot_curveInformation"));
plotNode.addHelpNode(curveInformation);
shapeFeatureNode.addHelpNode(plotNode);
rootNode.addHelpNode(shapeFeatureNode);
// Windows Features
HelpNode windowsNode = new HelpNode("Windows features", builtinHelp.getURLValue("windowsFeature"));
windowsNode.addHelpNode(new HelpNode("Zoom on a sheet", builtinHelp.getURLValue("windowsFeature_zoom")));
windowsNode.addHelpNode(new HelpNode("Close, Close All, Close Other sheets", builtinHelp.getURLValue("windowsFeature_sheetclose")));
windowsNode.addHelpNode(new HelpNode("Change sheet appearance", builtinHelp.getURLValue("windowsFeature_sheetAppearance")));
windowsNode.addHelpNode(new HelpNode("Previous, next selected sheet ", builtinHelp.getURLValue("windowsFeature_previousSelected")));
windowsNode.addHelpNode(new HelpNode("Previous, next created sheet", builtinHelp.getURLValue("windowsFeature_previousCreated")));
rootNode.addHelpNode(windowsNode);
// JSynoptic configuration
HelpNode configurationNode = new HelpNode("JSynoptic configuration", builtinHelp.getURLValue("configurationFile"));
configurationNode.addHelpNode(new HelpNode("Configuration file definition", builtinHelp.getURLValue("configurationFile_configurationFileDefinition")));
configurationNode.addHelpNode(new HelpNode("Edit configuration file", builtinHelp.getURLValue("configurationFile_editconfigurationFile")));
configurationNode.addHelpNode(new HelpNode("Global attributes", builtinHelp.getURLValue("configurationFile_globalAttributes")));
configurationNode.addHelpNode(new HelpNode("Print attributes", builtinHelp.getURLValue("configurationFile_printAttributes")));
HelpNode configuratioShapenNode = new HelpNode("Shape attributes", builtinHelp.getURLValue("configurationFile_shapeAttributes"));
configuratioShapenNode.addHelpNode(new HelpNode("Image attributes", builtinHelp.getURLValue("configurationFile_imageAttributes")));
configuratioShapenNode.addHelpNode(new HelpNode("Text attributes", builtinHelp.getURLValue("configurationFile_textAttributes")));
HelpNode plotAttributes =new HelpNode("Plot attributes", builtinHelp.getURLValue("configurationFile_plotAttributes"));
plotAttributes.addHelpNode(new HelpNode("Curve legend attributes", builtinHelp.getURLValue("configurationFile_curveLegendAttributes")));
configuratioShapenNode.addHelpNode(plotAttributes);
configurationNode.addHelpNode(configuratioShapenNode);
rootNode.addHelpNode(configurationNode);
// Miscalleneous Features
HelpNode miscHelpNode = new HelpNode("Miscalleneous features", builtinHelp.getURLValue("miscallaneousFeature"));
miscHelpNode.addHelpNode(new HelpNode("Choose language", builtinHelp.getURLValue("miscallaneousFeature_language")));
miscHelpNode.addHelpNode(new HelpNode("How to display problems occured upon JSynoptic operations?", builtinHelp.getURLValue("miscallaneousFeature_displayProblems")));
miscHelpNode.addHelpNode(new HelpNode("Choose a look for JSynoptic", builtinHelp.getURLValue("miscallaneousFeature_look")));
miscHelpNode.addHelpNode(new HelpNode("Find plugins", builtinHelp.getURLValue("miscallaneousFeature_plugins")));
miscHelpNode.addHelpNode(new HelpNode("JSynoptic command line options", builtinHelp.getURLValue("miscallaneousFeature_command")));
miscHelpNode.addHelpNode(new HelpNode("How to launch JSynoptic on no-edit mode?", builtinHelp.getURLValue("miscallaneousFeature_noEdit")));
rootNode.addHelpNode(miscHelpNode);
// UI Features
HelpNode uiHelpNode = new HelpNode("User interface features", builtinHelp.getURLValue("uiFeature"));
HelpNode menuBarNode = new HelpNode("Menu bar", builtinHelp.getURLValue("menuBar"));
menuBarNode.addHelpNode(new HelpNode("File menu", builtinHelp.getURLValue("menuBar_fileMenu")));
menuBarNode.addHelpNode(new HelpNode("Edit menu", builtinHelp.getURLValue("menuBar_editMenu")));
menuBarNode.addHelpNode(new HelpNode("Tools menu", builtinHelp.getURLValue("menuBar_toolsMenu")));
menuBarNode.addHelpNode(new HelpNode("Transformation menu", builtinHelp.getURLValue("menuBar_transformationMenu")));
menuBarNode.addHelpNode(new HelpNode("Windows menu", builtinHelp.getURLValue("menuBar_windowsMenu")));
menuBarNode.addHelpNode(new HelpNode("Help menu", builtinHelp.getURLValue("menuBar_HelpMenu")));
uiHelpNode.addHelpNode(menuBarNode);
HelpNode toolsBarNode = new HelpNode("Tools bar", builtinHelp.getURLValue("toolsBar"));
uiHelpNode.addHelpNode(toolsBarNode);
HelpNode statusBarNode = new HelpNode("Status bar", builtinHelp.getURLValue("statusBar"));
uiHelpNode.addHelpNode(statusBarNode);
HelpNode shortKeyNode = new HelpNode("Short keys bar", builtinHelp.getURLValue("shortKeys"));
uiHelpNode.addHelpNode(shortKeyNode);
uiHelpNode.addHelpNode(new HelpNode("Pop up menu", builtinHelp.getURLValue("popupMenu")));
uiHelpNode.addHelpNode(new HelpNode("Dialog box properties", builtinHelp.getURLValue("dialogBoxProperties")));
HelpNode panesNode = new HelpNode("Panes", builtinHelp.getURLValue("panes"));
panesNode.addHelpNode(new HelpNode("Editor pane", builtinHelp.getURLValue("panes_editorPane")));
panesNode.addHelpNode(new HelpNode("Source pane", builtinHelp.getURLValue("panes_sourcePane")));
panesNode.addHelpNode(new HelpNode("Shape pane", builtinHelp.getURLValue("panes_shapePane")));
panesNode.addHelpNode(new HelpNode("Image pane", builtinHelp.getURLValue("panes_imagePane")));
uiHelpNode.addHelpNode(panesNode);
HelpNode miscUINode = new HelpNode("Miscallaneaous User interface", builtinHelp.getURLValue("miscUI"));
miscUINode.addHelpNode(new HelpNode("Color chooser", builtinHelp.getURLValue("miscUI","colorChooser")));
uiHelpNode.addHelpNode(panesNode);
uiHelpNode.addHelpNode(new HelpNode("Menu bar", builtinHelp.getURLValue("menuBar")));
rootNode.addHelpNode(uiHelpNode);
return rootNode;
}
}