Package jsynoptic.builtin

Source Code of jsynoptic.builtin.Builtin

/* ========================
* 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;
    }
}
TOP

Related Classes of jsynoptic.builtin.Builtin

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.