Package jsynoptic.ui

Source Code of jsynoptic.ui.JSynopticPanels

/* ========================
* 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: JSynopticPanels.java,v 1.57 2009/02/04 13:43:50 ogor Exp $
*
* Changes
* -------
* 25-Sep-2003 : Initial public release (NB);
* 19-may-2005 : init method added to enable developpers to redefine what was
*  made in the constructor
*
*/
package jsynoptic.ui;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Frame;
import java.awt.GraphicsEnvironment;
import java.awt.Shape;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.print.PageFormat;
import java.awt.print.Pageable;
import java.awt.print.Printable;
import java.awt.print.PrinterJob;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.io.IOException;
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.TimerTask;
import java.util.Vector;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.DefaultListModel;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JEditorPane;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JSeparator;
import javax.swing.JSplitPane;
import javax.swing.JTextField;
import javax.swing.JToggleButton;
import javax.swing.JToolBar;
import javax.swing.JViewport;
import javax.swing.KeyStroke;
import javax.swing.ListSelectionModel;
import javax.swing.TransferHandler;
import javax.swing.filechooser.FileFilter;

import jsynoptic.base.Plugin;
import jsynoptic.base.Template;
import jsynoptic.builtin.Builtin;
import jsynoptic.ui.ShapesContainer.ShapesComponent;
import simtools.data.DataSource;
import simtools.data.DataSourceCollection;
import simtools.data.DataSourcePool;
import simtools.data.EmptyDataSourcePool;
import simtools.diagram.DiagramClipboard;
import simtools.diagram.DiagramClipboardListener;
import simtools.diagram.DiagramComponent;
import simtools.diagram.DiagramSelection;
import simtools.diagram.DiagramSelectionListener;
import simtools.diagram.undo.UndoHandler;
import simtools.logging.LogConfigurator;
import simtools.shapes.AbstractShape;
import simtools.ui.ActionComboBox;
import simtools.ui.AggregateFileFilter;
import simtools.ui.BasicMessageWriter;
import simtools.ui.CheckBoxList;
import simtools.ui.DesktopCardPanelListener;
import simtools.ui.MenuResourceBundle;
import simtools.ui.PrintDialog;
import simtools.ui.ReportingDialog;
import simtools.ui.ResourceFinder;
import simtools.ui.UserProperties;
import simtools.ui.UserPropertiesEditor;
import simtools.util.CurrentPathProvider;
import simtools.util.FileSerializer;

/**
* The default implementation of JSynopticInterface in graphic mode It provides
* the integration of a FiledDesktopCarPanel on the right side with a
* SourcePanel on the left side. The left panel gathers all the sources used to
* build synoptics i.e. shapes and data sources. This class also provides all
* the actions for synoptics editing. These actions are available thanks to a
* tool bar or a menu item.
*
* @author Nicolas Brodu
*
* @version 1.0 2001
*/
public class JSynopticPanels implements ActionListener, DesktopCardPanelListener, DiagramClipboardListener,
DiagramSelectionListener, PropertyChangeListener, JSynopticInterface {
    /** Resources */
    public static MenuResourceBundle resources = ResourceFinder.getMenu(JSynoptic.class);

    public static BasicMessageWriter messageWriter = ResourceFinder.getMessages(JSynoptic.class);

    protected UndoHandler.UndoAction undoAction;

    protected UndoHandler.RedoAction redoAction;

    protected FiledDesktopCardPanel desktopCardPanel;

    protected Panes panes;

    protected static UserProperties userProperties = Run.getProperties();

    protected static LogConfigurator logConfigurator;

    /**
     * True to display align,depth,format and group actions in the tool bar
     */
    protected static boolean USE_SELECTION_TOOL_BOXES = false;

    /**
     * If true, user is asked whether or not to save a modified sheet, when a
     * closing action has been performed on it.
     */
    protected static boolean ASK_USER_TO_SAVE_A_MODIFIED_SHEET = true;

    /**
     * Maximum number of files displayed in the open rencent file menu item
     */
    protected static int MAX_NUMBER_OF_RECENT_FILES = 10;

    protected boolean isEditable = System.getProperty("jsynoptic.noEdit", "false").equals("false");

    protected int untitledDocumentNumber;

    protected JMenu jmFile;

    protected JMenu jmWindows;

    protected JMenu jmEdit;

    protected JMenu jmHelp;

    protected Action aCut, aCopy, aPaste, aRemove, aSelectAll, aFullScreen, aGroup, aUngroup, aRegroup, aZoomIn, aZoomOut;

    protected Action aFront, aForward, aBackward, aBack;

    protected JMenu mDepth, mRotation;

    protected Action aLeft, aRight, aTop, aBottom, aVCenter, aHCenter, dHorizontally, dVertically;

    protected JMenu mAlign;

    protected JFrame aboutFrame;

    protected HelpViewer helpFrame;

    protected PrintToImage printImage;

    protected JMenuItem miNewAs;

    protected JMenuItem miOpen;

    protected JMenu miRecentFiles;

    protected JMenuItem miClose;

    protected JMenuItem miCloseAll;

    protected JMenuItem miSave;

    protected JMenuItem miSaveAs;

    protected JMenuItem miSaveAll;

    protected JMenuItem miExport;

    protected JMenuItem miSheetDisplay;

    protected JMenuItem miPrint;

    protected JMenuItem miPrintImage;

    protected JMenuItem miSnapShot;

    protected JMenuItem miRefreshAllSheets;

    protected JMenuItem miExit;

    protected JMenuItem miFindPlugins;

    protected JMenuItem miUndo;

    protected JMenuItem miRedo;

    protected JMenuItem miPreferencesPanel;

    protected JMenuItem miChooseLanguage;

    protected JMenuItem miAbout;

    protected JMenuItem miHelp;

    protected JMenuItem miSheetInformation;

    protected TemplateMenuBox bNew;

    protected JButton bOpen;

    protected JButton bSave;

    protected JButton bPrint;

    protected JButton bPrintImage;

    protected JButton bSnapShot;

    protected JButton bRefreshAllSheets;

    protected JButton bUndo;

    protected JButton bRedo;

    protected JButton bAdjust;

    protected JButton bAlign;

    protected JToggleButton tbGridDisplay;

    protected JComboBox cbxGrid;

    protected JComboBox cbxDepth;

    protected JComboBox cbxRotation;

    protected JComboBox cbxAlign;

    protected JMenu mSel;

    protected ActionComboBox cbxSelection;

    protected JSplitPane splitPane;

    protected JToolBar toolbar;
   
    protected ShapesToolBar shapeToolBar;

    protected JLabel status;

    protected JPanel footPane;

    protected TimerTask cleanStatusTask;

    protected java.util.Timer cleanStatusTimer;

    protected long statusDelay;

    protected JFileChooser openFileChooser, saveFileChooser, exportFileChooser;

    protected TemplateChooser templateChooser;

    protected javax.swing.filechooser.FileFilter currentOpenFileFilter, currentSaveFileFilter, currentExportFileFilter;

    public Vector lockedShapes; // thoses shapes are not editable

    private int fileSaveSemaphoreCounter;

    private int fileOpenSemaphoreCounter;

    private int printSemaphoreCounter;

    protected UserPropertiesEditor propEditor;

    protected final Frame owner;

    protected final Container container;

    protected Object menuBar;

    protected boolean isOpenProcessCancelled;

    protected ArrayList recentOpenedFiles;

    protected PrintDialog printerDialog;

    protected JTextField tfZoom;

    public JSynopticPanels(Vector commands, Frame owner, Container container) {
        this.owner = owner;
        this.container = container;
        untitledDocumentNumber = 0;
        fileSaveSemaphoreCounter = 0;
        fileOpenSemaphoreCounter = 0;
        printSemaphoreCounter = 0;
        openFileChooser = null;
        saveFileChooser = null;
        exportFileChooser = null;

        currentOpenFileFilter = null;
        currentSaveFileFilter = null;
        currentExportFileFilter = null;

        recentOpenedFiles = new ArrayList();
        lockedShapes = new Vector();
        aboutFrame = null;
        isOpenProcessCancelled = false;
        JSynoptic.gui = this;
        createFileChooser(Plugin.OPEN);
        createFileChooser(Plugin.SAVE);
        createFileChooser(Plugin.EXPORT);

        printerDialog = new PrintDialog(getOwner());

        setLogger();

        init(commands);

        // Create template chooser
        templateChooser = new TemplateChooser(owner);

        // Add the Transfer handler, which will handle the files Drag and drops.
        if(getOwner() instanceof JFrame){
            JSynopticFileTransfertHandler fta = new JSynopticFileTransfertHandler();
            desktopCardPanel.setTransferHandler(fta);
            ((JFrame) getOwner()).getRootPane().setTransferHandler(fta);
        }
    }

    /*
     * (non-Javadoc)
     *
     * @see jsynoptic.ui.JSynopticInterface#getOwner()
     */
    public Frame getOwner() {
        return owner;
    }

    /* (non-Javadoc)
     * @see jsynoptic.ui.JSynopticInterface#updateComponentName(jsynoptic.ui.ShapesContainer.ShapesComponent)
     */
    public void updateComponentName(ShapesComponent component) {
        getFilePanel().updateComponentName(component);
    }

    /**
     * A default implementation to be overridden
     *
     * @param percent
     */
    protected void progress(int percent) {
        System.out.println("-->" + percent);
    }

    /**
     * Build the Jsynoptic editor components
     *
     * @param commands
     *            the commands to process
     */
    protected void init(Vector commands) {
        if (isEditable) {
            // List of excluded shapes
            String excludedShapesString = userProperties.getProperty("jsynoptic.ui.JSynoptic.excludedShapes", null);
            if ((excludedShapesString != null) && (jsynoptic.ui.ShapeListModel.excludedShapes != null)) {
                String[] excludedShapes = excludedShapesString.split(",");
                for (int i = 0; i < excludedShapes.length; i++) {
                    jsynoptic.ui.ShapeListModel.excludedShapes.add(excludedShapes[i].trim());
                }
            }
            panes = new Panes(getOwner(), DataSourcePool.global);
            // Add source panel hooks
            for (int i = 0; i < Run.plugins.size(); ++i) {
                Plugin p = (Plugin) Run.plugins.get(i);
                if (p != null) {
                    try {
                        p.newSourceComponent(panes);
                    } catch (Throwable t) {
                        t.printStackTrace();
                    }
                }
            }
            panes.invalidate();
        } else {
            panes = null;
        }


        progress(65);
        desktopCardPanel = new FiledDesktopCardPanel(true);
        createActions();
        createMenu();
        createToolBar();
        progress(70);
       
       
        // Disable all buttons
        setSelectionEditEnabled(false);
        setPasteEnabled(false);
        setDiagramComponentSpecificsEnabled(false);
        setShapeToolEnabled(false);
       
        desktopCardPanel.addListener(this);

        progress(75);

        // Add desktop panel hooks
        for (int i = 0; i < Run.plugins.size(); ++i) {
            Plugin p = (Plugin) Run.plugins.get(i);
            if (p != null) {
                p.newDesktopComponent(desktopCardPanel);
            }
        }
        desktopCardPanel.invalidate();

        // Add plugins templates
        if (isEditable) {
            for (int i = 0; i < Run.plugins.size(); ++i) {
                Plugin p = (Plugin) Run.plugins.get(i);
                if (p != null) {
                    Template[] t = p.getTemplates();
                    if (t == null){
                        continue;
                    }
                    for (int j = 0; j < t.length; j++) {
                        Template.getTemplates().add(t[j]);
                    }
                }
            }

            // Get Templates configuration from user properties
            String currentTemplateName = userProperties.getProperty("jsynoptic.ui.JSynoptic.currentTemplate", null);
            if (currentTemplateName != null){
                // Get current template from current template name
                Template t = null;
                for (int i = 0; (i < Template.getTemplates().size()) && (t == null); i++) {
                    Template temp =  (Template)Template.getTemplates().get(i);
                    if ( temp.getName().equals(currentTemplateName)){
                        t = temp;
                    }
                }
                if (t != null){
                    Template.setCurrentTemplate(t);
                }
            }
        } else {
            Template.getTemplates().clear();
        }

        // Set printer dialog properties
        printerDialog.setPropertyValue( PrintDialog.NB_COPIES, new Integer(userProperties.getInt("jsynoptic.print.nbCopies", 1)) );
        printerDialog.setPropertyValue(PrintDialog.PRINT_SELECTION, new Boolean(userProperties.getBoolean("jsynoptic.print.printSelection", false)));
        printerDialog.setPropertyValue(PrintDialog.ORIENTATION, new Integer(userProperties.getInt("jsynoptic.print.orientation", PageFormat.PORTRAIT)));
        printerDialog.setPropertyValue(PrintDialog.PRINT_BACKGROUND,new Boolean(userProperties.getBoolean("jsynoptic.print.printBackground", false)));
        printerDialog.setPropertyValue(PrintDialog.SCALE_SHEET, new Boolean(userProperties.getBoolean("jsynoptic.print.scaleSheet", true)));
        printerDialog.setPropertyValue( PrintDialog.PAPER_SIZE, new Integer(userProperties.getInt("jsynoptic.print.paperSize", 0)) );

        // Set sheet display 
        int pageHeight = userProperties.getInt("jsynoptic.sheetDisplay.height", DiagramComponent.getPageHeight());
        DiagramComponent.setPageHeight(pageHeight);

        int pageWidth = userProperties.getInt("jsynoptic.sheetDisplay.width", DiagramComponent.getPageWidth());
        DiagramComponent.setPageWidth(pageWidth);

        boolean isPageNormal = userProperties.getBoolean("jsynoptic.sheetDisplay.printView", DiagramComponent.isPrintViewEnabled());
        DiagramComponent.setPageModeEnabled(isPageNormal);

        progress(80);
        layoutSourcePanelAndDesktopPanel();
        progress(85);

        createFootPane();

        progress(90);
        DiagramClipboard.create();
        DiagramClipboard.get().addListener(this);
        progress(95);
        adjustLayout();

        // pack the main frame to compute its components preferred sizes
        owner.pack();

        // load properties from user configuration file
        loadProperties();

        // Create a new sheet
        if (isEditable) {
            newComponent();
        }



        progress(100);
        if (commands.size() > 0) {
            setStatus(messageWriter.print0args("processingCommands"));
        } else {
            setStatus(messageWriter.print0args("welcomeMessage"));
        }
        container.doLayout();
       
        // Display frame
        display();
       

        // Dispose the splashscreen
        Run.splashSreen.dispose();
       
        processCommands(commands);
        setStatus(messageWriter.print0args("welcomeMessage"));
    }

    /**
     * Default implementation for status panel
     */
    protected void createFootPane() {
        footPane = new JPanel(new BorderLayout());
        footPane.add(status = new JLabel(), BorderLayout.WEST);

        Box zoomPane = new  Box(BoxLayout.X_AXIS);
        zoomPane.add(new JLabel("Z:"));
        zoomPane.add(tfZoom = new JTextField());

        // Zoom text filed
        tfZoom.setPreferredSize(new Dimension(120, 20));
        tfZoom.setMaximumSize(new Dimension(120, 20));
        tfZoom.setMinimumSize(new Dimension(120, 20));
        tfZoom.addActionListener(this);

        // Zoom tool bar               
        JToolBar  zoomToolbar = new JToolBar();
        zoomToolbar.setRollover(true);
        zoomToolbar.setFloatable(false);
        zoomToolbar.add(aZoomIn);
        zoomToolbar.add(aZoomOut);

        zoomPane.add(zoomToolbar);


        zoomPane.add(new JPanel());

        footPane.add(zoomPane, BorderLayout.EAST);


        // Force the foot Pane height to 30 px
        Dimension statusPanelDimension = footPane.getSize();
        statusPanelDimension.height = 30;
        footPane.setPreferredSize(statusPanelDimension);
        footPane.setMaximumSize(statusPanelDimension);

        container.add(BorderLayout.SOUTH, footPane);

        cleanStatusTask = null;
        cleanStatusTimer = new java.util.Timer();
        statusDelay = resources.getLongValue("statusDelayMilliSec");
    }

    /**
     * Default implementation to layout source panel and synoptic editor
     */
    protected void layoutSourcePanelAndDesktopPanel() {
        if (panes != null) {
            splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, panes, desktopCardPanel);
            container.add(BorderLayout.CENTER, splitPane);
            splitPane.setOneTouchExpandable(true);
        } else {
            splitPane = null;
            container.add(BorderLayout.CENTER, desktopCardPanel);
        }
    }

    /**
     * Default implementation for final layout tuning
     */
    protected void adjustLayout() {
        // restrict the combo box, or they take all the space!
        Dimension restr = new Dimension(bPrint.getPreferredSize().width * 5 / 2, bPrint.getPreferredSize().height);
        adjustComboBox(cbxGrid, restr);
        adjustComboBox(cbxDepth, restr);
        adjustComboBox(cbxAlign, restr);
        adjustComboBox(cbxSelection, restr);
        container.validate();
    }

    public static void adjustComboBox(JComboBox b, Dimension d) {
        if (b != null) {
            b.setPreferredSize(d);
            b.setMaximumSize(d);
            b.setMinimumSize(d);
        }
    }

    /**
     * Default implementation to display the GUI (if needed)
     */
    protected void display() {
        if (footPane != null) {
            footPane.setMinimumSize(footPane.getSize());
            footPane.setPreferredSize(footPane.getSize());
        }
    }

    protected void exit() {
        boolean canBeClosed = closeAll();
        if (canBeClosed) {
            cleanStatusTimer.cancel();
            saveProperties();
            exitPlugins();
            System.exit(0);
        }
    }

    /**
     * @return true if sheets can be closed (user has not canceled the close action)
     */
    protected boolean closeAll() {
        boolean canCloseSheets = true;

        boolean noToallOption = false;
        boolean yesToallOption = false;

        String[] buttons = {
                resources.getString("yes"),
                resources.getString("yesAll"),
                resources.getString("no"),
                resources.getString("noAll"),
                resources.getString("cancel")
        };

        for (Iterator it = desktopCardPanel.getComponentIterator(); it.hasNext() && !noToallOption && canCloseSheets;) {           
            DiagramComponent d = (DiagramComponent) it.next();
            if (JSynopticPanels.ASK_USER_TO_SAVE_A_MODIFIED_SHEET && d.hasBeenModified()) {

                if (!yesToallOption){
                    int i = JOptionPane.showOptionDialog(
                            getOwner(),
                            d.getName().substring(1) + messageWriter.print0args("savingBeforeClosingConfirmation"),
                            d.getName().substring(1),
                            JOptionPane.YES_NO_OPTION,
                            JOptionPane.QUESTION_MESSAGE,
                            null,
                            buttons,
                            buttons[0]);


                    if ( (i == JOptionPane.CLOSED_OPTION) || (i == 4) ) {
                        canCloseSheets = false;;

                    } else if (i == 0) {
                        desktopCardPanel.selectComponent(d);
                        save();

                    } else if (i == 1) {
                        yesToallOption = true;

                    else if (i == 3) {
                        noToallOption = true;
                    }
                }

                if (yesToallOption){
                    desktopCardPanel.selectComponent(d);
                    save();
                }  
            }
        }
        if(canCloseSheets){
            // clean resources
            for (Iterator it = desktopCardPanel.getComponentIterator(); it.hasNext();) {           
                DiagramComponent d = (DiagramComponent) it.next();

                // release resources
                if(d instanceof ShapesComponent){
                    ShapesContainer sc = (ShapesContainer)((ShapesComponent)d).getContainer();

                    // release all shapes
                    for(int j = 0; j< sc.size(); j++){
                        if (sc.get(j) instanceof AbstractShape){
                            ((AbstractShape) sc.get(j)).processShapeRemoving();
                        }
                    }

                    // clean shape container
                    sc.removeAllElements();
                }
            }
        }

        return canCloseSheets;
    }

    /**
     * @param d,
     *            a sheet to close
     * @return if sheet can be closed
     */
    protected boolean close(DiagramComponent d) {
        boolean ret=true;
        // User has to confirm closing action in case diagram has changed since
        // last back up
        if (JSynopticPanels.ASK_USER_TO_SAVE_A_MODIFIED_SHEET && d.hasBeenModified()) {
            int i = (JOptionPane.showConfirmDialog(getOwner(), d.getName().substring(1)
                    + messageWriter.print0args("savingBeforeClosingConfirmation")));

            if ((i == JOptionPane.CANCEL_OPTION) || (i == JOptionPane.CLOSED_OPTION))  {
                ret=false;
            }
            else if (i == JOptionPane.YES_OPTION) {
                desktopCardPanel.selectComponent(d);
                ret=save();
            }
        }
        if(ret){
            // release resources
            if(d instanceof ShapesComponent){
                ShapesContainer sc = (ShapesContainer)((ShapesComponent)d).getContainer();

                // release all shapes
                for(int j = 0; j< sc.size(); j++){
                    if (sc.get(j) instanceof AbstractShape){
                        ((AbstractShape) sc.get(j)).processShapeRemoving();
                    }
                }

                // clean shape container
                sc.removeAllElements();
            }
        }
        return ret;
    }

    public void processCommands(Vector commands) {
        if (commands == null) {
            return;
        }
        setStatus(messageWriter.print0args("processingCommands"));
        for (Iterator it = commands.iterator(); it.hasNext();) {
            processCommand((String) it.next());
        }
    }

    public void processCommand(String command) {
        if (command.startsWith("load ")) {
            File f = FileSerializer.readFromString(command.substring(5), CurrentPathProvider.currentPathProvider
                    .getCurrentPath());
            if (f.exists()) {
                Plugin p = getPluginToProcessFile(f, Plugin.OPEN, null);
                if (p == null) {
                    return;
                }
                p.processFile(f, Plugin.OPEN); // we don't display whether or
                // not file has been
                // successfullly loaded
            }
            return;
        }
        if (command.startsWith("transform ")) {
            String actionType = command.substring(10);
            if (!actionType.equals("")) {
                boolean canTransform = false;
                for (Iterator it = desktopCardPanel.getComponentIterator(); it.hasNext();) {
                    DiagramComponent d = (DiagramComponent) it.next();
                    desktopCardPanel.selectComponent(d);
                    for (int j = 0; j < Run.plugins.size(); ++j) {
                        Plugin p = (Plugin) Run.plugins.get(j);
                        canTransform |= p.processSynoptic(getActiveContainer(), actionType, true);
                    }
                }
                if (canTransform) {
                    setStatus(messageWriter.print1args("transformed", actionType));
                } else {
                    setStatus(messageWriter.print1args("cannotTransform", actionType));
                }
            }
            return;
        }
    }

    synchronized public void lockFileSave() {
        if (fileSaveSemaphoreCounter++ == 0) {
            miSave.setEnabled(false);
            bSave.setEnabled(false);
            miSaveAs.setEnabled(false);
            miSaveAll.setEnabled(false);
        }
    }

    synchronized public void unlockFileSave() {
        if (--fileSaveSemaphoreCounter == 0) {
            miSave.setEnabled(true);
            bSave.setEnabled(true);
            miSaveAs.setEnabled(true);
            miSaveAll.setEnabled(true);
        }
    }

    synchronized public boolean canSave() {
        return (fileSaveSemaphoreCounter == 0);
    }

    synchronized public void lockFileOpen() {
        if (fileOpenSemaphoreCounter++ == 0) {
            miOpen.setEnabled(false);
            miRecentFiles.setEnabled(false);
            bOpen.setEnabled(false);
        }
    }

    synchronized public void unlockFileOpen() {
        if (--fileOpenSemaphoreCounter == 0) {
            miOpen.setEnabled(true);
            miRecentFiles.setEnabled(true);
            bOpen.setEnabled(true);
        }
    }

    synchronized public boolean canOpen() {
        return (fileOpenSemaphoreCounter == 0);
    }

    synchronized public void lockPrint() {
        if (printSemaphoreCounter++ == 0) {
            miPrint.setEnabled(false);
            bPrint.setEnabled(false);
            miPrintImage.setEnabled(false);
            miSnapShot.setEnabled(false);
            bPrintImage.setEnabled(false);
            bSnapShot.setEnabled(false);
            miSheetInformation.setEnabled(false);
        }
    }

    synchronized public void unlockPrint() {
        if (--printSemaphoreCounter == 0) {
            miPrint.setEnabled(true);
            bPrint.setEnabled(true);
            miPrintImage.setEnabled(true);
            miSnapShot.setEnabled(true);
            bPrintImage.setEnabled(true);
            bSnapShot.setEnabled(true);
            miSheetInformation.setEnabled(true);
        }
    }

    synchronized public boolean canPrint() {
        return (printSemaphoreCounter == 0);
    }

    // ---------------------------------------------------------------------------
    // Logger configuration => Set logger used for JSynoptic debugging
    // ---------------------------------------------------------------------------
    protected void setLogger() {
        /*
         * Example :
         * jsynotpic.loggings.out=3009 jsynotpicloggings.logging0=FINEST
         * jsynoptic jsynotpicloggings.logging1=FINEST simtools
         */
        logConfigurator = new LogConfigurator(userProperties, "jsynoptic");
        logConfigurator.apply();
    }

    // ---------------------------------------------------------------------------
    // Properties Management => save and restore size
    // ---------------------------------------------------------------------------
    static protected String propSplit = "jsynoptic.ui.JSynoptic.split";

    static protected String propPath = "jsynoptic.ui.JSynoptic.currentPath";

    static protected int propSplitDefault = 300;

    protected void saveProperties() {
        if (panes != null) {
            panes.save(userProperties, "SOURCE");
        }
        if (splitPane != null) {
            userProperties.setInt(propSplit, splitPane.getDividerLocation());
        }
        userProperties.setString(propPath, CurrentPathProvider.currentPathProvider.getCurrentPath().getAbsolutePath());

        // Recent files
        String recentFile = "";
        for (int i = 0; i < recentOpenedFiles.size(); i++) {
            recentFile += ((File) recentOpenedFiles.get(i)).getAbsolutePath() + ";";
        }
        userProperties.setString("jsynoptic.ui.JSynoptic.recentFiles", recentFile);
        userProperties.setString("jsynoptic.ui.JSynoptic.currentTemplate", Template.getCurrentTemplate().getName());

        setStaticProperties(userProperties);

        // print properties
        userProperties.setInt("jsynoptic.print.nbCopies", ((Integer)printerDialog.getPropertyValue(PrintDialog.NB_COPIES)).intValue());
        userProperties.setBoolean("jsynoptic.print.printSelection", ((Boolean)printerDialog.getPropertyValue(PrintDialog.PRINT_SELECTION)).booleanValue());
        userProperties.setInt("jsynoptic.print.orientation", ((Integer)printerDialog.getPropertyValue(PrintDialog.ORIENTATION)).intValue());
        userProperties.setBoolean("jsynoptic.print.printBackground", ((Boolean)printerDialog.getPropertyValue(PrintDialog.PRINT_BACKGROUND)).booleanValue());
        userProperties.setBoolean("jsynoptic.print.scaleSheet", ((Boolean)printerDialog.getPropertyValue(PrintDialog.SCALE_SHEET)).booleanValue());
        userProperties.setInt("jsynoptic.print.paperSize", ((Integer)printerDialog.getPropertyValue(PrintDialog.PAPER_SIZE)).intValue());

        // sheet display properties

        userProperties.setInt("jsynoptic.sheetDisplay.height", DiagramComponent.getPageHeight());
        userProperties.setInt("jsynoptic.sheetDisplay.width", DiagramComponent.getPageWidth());
        userProperties.setBoolean("jsynoptic.sheetDisplay.printView", DiagramComponent.isPrintViewEnabled());

        //TODO orientation

        userProperties.write();    
    }

    protected void setStaticProperties(UserProperties prop) {
        prop.setInt("simtools.shapes.AbstractShape.REFRESH_PERIOD", simtools.shapes.AbstractShape.REFRESH_PERIOD);
        prop.setBoolean("simtools.shapes.AbstractShape.ANTI_ALIASING", simtools.shapes.AbstractShape.ANTI_ALIASING);
        prop.setInt("simtools.ui.DesktopCardPanel.SCROLLING_MODE", simtools.ui.DesktopCardPanel.SCROLLING_MODE);
        String fn = "";
        for (int i = 0; i < simtools.shapes.AbstractShape.FONT_NAMES.length; i++) {
            if (i != 0) {
                fn = fn + ",";
            }
            fn = fn + simtools.shapes.AbstractShape.FONT_NAMES[i];
        }
        prop.setString("simtools.shapes.AbstractShape.FONT_NAMES", fn);
    }

    protected void getStaticProperties(UserProperties prop) {
        simtools.shapes.AbstractShape.REFRESH_PERIOD = prop.getInt("simtools.shapes.AbstractShape.REFRESH_PERIOD",
                simtools.shapes.AbstractShape.REFRESH_PERIOD);
        simtools.shapes.AbstractShape.ANTI_ALIASING = prop.getBoolean("simtools.shapes.AbstractShape.ANTI_ALIASING",
                simtools.shapes.AbstractShape.ANTI_ALIASING);
        // look for font names
        String fontNames = prop.getString("simtools.shapes.AbstractShape.FONT_NAMES", null);
        if (fontNames != null) {
            String[] names = GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
            StringTokenizer st = new StringTokenizer(fontNames, ",");
            ArrayList ar = new ArrayList();
            while (st.hasMoreTokens()) {
                String t = st.nextToken();
                t = t.trim();
                boolean found = false;
                for (int i = 0; i < names.length; i++) {
                    if (names[i].equals(t)) {
                        ar.add(t);
                        found = true;
                        break;
                    }
                }
                if (!found) {
                    System.err.println("Unknown font=" + t);
                }
            }
            if (ar.size() > 0) {
                simtools.shapes.AbstractShape.FONT_NAMES = new String[ar.size()];
                for (int i = 0; i < ar.size(); i++) {
                    simtools.shapes.AbstractShape.FONT_NAMES[i] = (String) ar.get(i);
                }
            }
        }
        int mode = prop.getInt("simtools.ui.DesktopCardPanel.SCROLLING_MODE",
                simtools.ui.DesktopCardPanel.SCROLLING_MODE);
        switch (mode) {
        case JViewport.BACKINGSTORE_SCROLL_MODE:
        case JViewport.BLIT_SCROLL_MODE:
        case JViewport.SIMPLE_SCROLL_MODE:
            break;
        default:
            mode = JViewport.BLIT_SCROLL_MODE;
        break;
        }
        simtools.ui.DesktopCardPanel.SCROLLING_MODE = mode;
    }

    protected void loadProperties() {
        if (panes != null) {
            panes.load(userProperties, "SOURCE");
        }
        if (splitPane != null) {
            splitPane.setDividerLocation(userProperties.getInt(propSplit, propSplitDefault));
        }
        String currentPathProperty = userProperties.getString(propPath, null);
        if (currentPathProperty != null) {
            CurrentPathProvider.currentPathProvider.setCurrentPath(new File(currentPathProperty));
        }
        getStaticProperties(userProperties);
    }

    /**
     * Some plugins need a particular treatment during Jsynoptic closing For
     * instance when an external process was created in a plugin, it needs to be
     * destroyed
     */
    protected void exitPlugins() {
        // Add source panel hooks
        for (int i = 0; i < Run.plugins.size(); ++i) {
            Plugin p = (Plugin) Run.plugins.get(i);
            if (p != null) {
                p.exit();
            }
        }
    }

    protected void createActions() {
        aCut = new AbstractAction(resources.getStringValue("cutAction"), resources.getIcon("cutImage")) {
            public void actionPerformed(ActionEvent e) {
                DiagramComponent d = getActiveDiagram();
                if (d != null) {
                    d.executeSelectionCut();
                }
            }
        };
        aCopy = new AbstractAction(resources.getStringValue("copyAction"), resources.getIcon("copyImage")) {
            public void actionPerformed(ActionEvent e) {
                DiagramComponent d = getActiveDiagram();
                if (d != null) {
                    d.executeSelectionCopy();
                }
            }
        };
        aPaste = new AbstractAction(resources.getStringValue("pasteAction"), resources.getIcon("pasteImage")) {
            public void actionPerformed(ActionEvent e) {
                DiagramComponent d = getActiveDiagram();
                if (d != null) {
                    d.executeClipboardPaste();
                }
            }
        };
        aGroup = new AbstractAction(resources.getStringValue("groupAction"), resources.getIcon("groupImage")) {
            public void actionPerformed(ActionEvent e) {
                DiagramComponent d = getActiveDiagram();
                if ((d != null) && (d instanceof ShapesComponent)) {
                    ((ShapesComponent) d).group();
                }
            }
        };
        aUngroup = new AbstractAction(resources.getStringValue("ungroupAction"), resources.getIcon("ungroupImage")) {
            public void actionPerformed(ActionEvent e) {
                DiagramComponent d = getActiveDiagram();
                if ((d != null) && (d instanceof ShapesComponent)) {
                    ((ShapesComponent) d).unGroup();
                }
            }
        };
        aRegroup = new AbstractAction(resources.getStringValue("regroupAction"), resources.getIcon("regroupImage")) {
            public void actionPerformed(ActionEvent e) {
                DiagramComponent d = getActiveDiagram();
                if ((d != null) && (d instanceof ShapesComponent)) {
                    ((ShapesComponent) d).reGroup();
                }
            }
        };
        aRemove = new AbstractAction(resources.getStringValue("removeAction")) {
            public void actionPerformed(ActionEvent e) {
                DiagramComponent d = getActiveDiagram();
                if (d != null) {
                    d.executeSelectionDelete();
                }
            }
        };
        aSelectAll = new AbstractAction(resources.getStringValue("selectAllAction"), null) {
            public void actionPerformed(ActionEvent e) {
                DiagramComponent d = getActiveDiagram();
                if (d != null) {
                    d.executeSelectAll();
                }
            }
        };
        aSelectAll.setEnabled(isEditable);

        aFullScreen = new AbstractAction(resources.getStringValue("fullScreen")) {
            public void actionPerformed(ActionEvent e) {
                DiagramComponent d = getActiveDiagram();
                // Toggle full screen on / off
                if (d.isFullScreen()) {
                    d.setFullScreen(false);
                } else {
                    d.setFullScreen(GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice());
                }
            }
        };
        aFullScreen.putValue(Action.ACCELERATOR_KEY, resources.getKeyStroke("fullScreenShortcut"));
        aFront = new AbstractAction(resources.getStringValue("frontAction"), resources.getIcon("frontImage")) {
            public void actionPerformed(ActionEvent e) {
                DiagramComponent d = getActiveDiagram();
                if (d != null) {
                    d.getDiagramSelection().bringSelectionToFront();
                }
            }
        };
        aForward = new AbstractAction(resources.getStringValue("forwardAction"), resources.getIcon("forwardImage")) {
            public void actionPerformed(ActionEvent e) {
                DiagramComponent d = getActiveDiagram();
                if (d != null) {
                    d.getDiagramSelection().bringSelectionForward();
                }
            }
        };
        aBackward = new AbstractAction(resources.getStringValue("backwardAction"), resources.getIcon("backwardImage")) {
            public void actionPerformed(ActionEvent e) {
                DiagramComponent d = getActiveDiagram();
                if (d != null) {
                    d.getDiagramSelection().sendSelectionBackward();
                }
            }
        };
        aBack = new AbstractAction(resources.getStringValue("backAction"), resources.getIcon("backImage")) {
            public void actionPerformed(ActionEvent e) {
                DiagramComponent d = getActiveDiagram();
                if (d != null) {
                    d.getDiagramSelection().sendSelectionToBack();
                }
            }
        };
        aLeft = new AbstractAction(resources.getStringValue("leftAction"), resources.getIcon("leftImage")) {
            public void actionPerformed(ActionEvent e) {
                DiagramComponent d = getActiveDiagram();
                if (d != null) {
                    d.getDiagramSelection().alignSelectionToLeft();
                }
            }
        };
        aRight = new AbstractAction(resources.getStringValue("rightAction"), resources.getIcon("rightImage")) {
            public void actionPerformed(ActionEvent e) {
                DiagramComponent d = getActiveDiagram();
                if (d != null) {
                    d.getDiagramSelection().alignSelectionToRight();
                }
            }
        };
        aTop = new AbstractAction(resources.getStringValue("topAction"), resources.getIcon("topImage")) {
            public void actionPerformed(ActionEvent e) {
                DiagramComponent d = getActiveDiagram();
                if (d != null) {
                    d.getDiagramSelection().alignSelectionToTop();
                }
            }
        };
        aBottom = new AbstractAction(resources.getStringValue("bottomAction"), resources.getIcon("bottomImage")) {
            public void actionPerformed(ActionEvent e) {
                DiagramComponent d = getActiveDiagram();
                if (d != null) {
                    d.getDiagramSelection().alignSelectionToBottom();
                }
            }
        };
        aVCenter = new AbstractAction(resources.getStringValue("vCenterAction"), resources.getIcon("vCenterImage")) {
            public void actionPerformed(ActionEvent e) {
                DiagramComponent d = getActiveDiagram();
                if (d != null) {
                    d.getDiagramSelection().alignSelectionVCenter();
                }
            }
        };
        aHCenter = new AbstractAction(resources.getStringValue("hCenterAction"), resources.getIcon("hCenterImage")) {
            public void actionPerformed(ActionEvent e) {
                DiagramComponent d = getActiveDiagram();
                if (d != null) {
                    d.getDiagramSelection().alignSelectionHCenter();
                }
            }
        };
        dHorizontally = new AbstractAction(resources.getStringValue("dHorizontallyAction"), resources
                .getIcon("dHorizontallyImage")) {
            public void actionPerformed(ActionEvent e) {
                DiagramComponent d = getActiveDiagram();
                if (d != null) {
                    d.getDiagramSelection().distributeSelectionHorizontally();
                }
            }
        };
        dVertically = new AbstractAction(resources.getStringValue("dVerticallyAction"), resources
                .getIcon("dVerticallyImage")) {
            public void actionPerformed(ActionEvent e) {
                DiagramComponent d = getActiveDiagram();
                if (d != null) {
                    d.getDiagramSelection().distributeSelectionVertically();
                }
            }
        };

        aZoomIn = new AbstractAction(resources.getStringValue("zoomInAction"),
                resources.getIcon("zoomInImage")) {
            public void actionPerformed(ActionEvent e) {
                zoomDiagram(true);
            }
        };

        aZoomOut = new AbstractAction(resources.getStringValue("zoomOutAction"),
                resources.getIcon("zoomOutImage")) {
            public void actionPerformed(ActionEvent e) {
                zoomDiagram(false);
            }
        };
    }

    /**
     * Default implementation to create menus
     */
    protected void createMenu() {
        menuBar = new JMenuBar();
        addFileMenu(menuBar);
        addEditMenu(menuBar);
        addToolsMenu(menuBar);
        for (Iterator it = Run.plugins.iterator(); it.hasNext();) {
            Plugin p = (Plugin) it.next();
            p.setMenu(menuBar);
        }

        jmWindows = desktopCardPanel.createMenu(null);

        JMenuItem item = jmWindows.add(aZoomIn);
        KeyStroke  k = resources.getKeyStroke("zoomInShortcut");
        if (k != null) {
            item.setAccelerator(k);
        }
        item = jmWindows.add(aZoomOut);
        k = resources.getKeyStroke("zoomOutShortcut");
        if (k != null) {
            item.setAccelerator(k);
        }
        jmWindows.addSeparator();

        ((JMenuBar) menuBar).add(jmWindows);

        addHelpMenu(menuBar);
    }

    /**
     * Default implementation to create tool bar
     */
    public void createToolBar() {
        toolbar = new JToolBar();
        toolbar.setRollover(true);
        toolbar.setFloatable(false);
        addFileButtons(toolbar);
        toolbar.addSeparator();
        addEditButtons(toolbar);
        toolbar.addSeparator();

        // Shapes Tool bar
        if (isEditable){
            shapeToolBar = new ShapesToolBar();

            int addedShapeButtons = 0;
            for (int i = 0; i < Run.plugins.size(); ++i) {
                Plugin p = (Plugin) Run.plugins.get(i);
                if (p != null) {
                    List scs = p.getShapeCreators();

                    if (scs!= null){
                        for(int j=0;j<scs.size(); j++){
                            ShapeCreator sc = (ShapeCreator)scs.get(j);
                            if (sc.shapeIcon != null){  // Create a button if the shape icon is not null
                                shapeToolBar.addShapeCreatorButton(sc);
                                addedShapeButtons++;
                            }
                        }
                    }
                }
            }
            if (addedShapeButtons > 0){
                toolbar.add(shapeToolBar);
                toolbar.addSeparator();
            }
           
        } else {
            shapeToolBar = null;
        }
       
       
        toolbar.add(bUndo = resources.getBox("undo", this));
        toolbar.add(bRedo = resources.getBox("redo", this));
        updateUndoEnabled();
        toolbar.add(desktopCardPanel.createPreviousButton());
        toolbar.add(desktopCardPanel.createNextButton());
        toolbar.addSeparator();
        if (USE_SELECTION_TOOL_BOXES) {
            addDepthButtons(toolbar);
            toolbar.addSeparator();
            addAlignButtons(toolbar);
            toolbar.addSeparator();
        }
        toolbar.add(bAdjust = resources.getBox("adjust", this));
        toolbar.add(bAlign = resources.getBox("align", this));
        toolbar.addSeparator();
        tbGridDisplay = new JToggleButton(resources.getIcon("gridImage"));
        tbGridDisplay.setPreferredSize(new Dimension(22, 22));
        tbGridDisplay.addActionListener(this);
        tbGridDisplay.setToolTipText(resources.getStringValue("gridButtonTip"));
        toolbar.add(tbGridDisplay);
        cbxGrid = new JComboBox();
        cbxGrid.addItem("0");
        cbxGrid.addItem("5");
        cbxGrid.addItem("10");
        cbxGrid.addItem("20");
        cbxGrid.addItem("40");
        cbxGrid.setSelectedItem("0");
        cbxGrid.setEditable(true);
        cbxGrid.addActionListener(this);
        toolbar.add(cbxGrid);

        toolbar.addSeparator();
        for (Iterator it = Run.plugins.iterator(); it.hasNext();) {
            Plugin p = (Plugin) it.next();
            p.setToolBarItem(toolbar);
        }
    }

    /**
     * Add a file menu to a menu bar
     */
    public void addFileMenu(Object mb) {
        jmFile = resources.getMenu("file");
        jmFile.add(miNewAs = resources.getItem("newAs", this));
        miNewAs.setIcon(resources.getIcon("newImage"));
        miNewAs.setEnabled(isEditable);

        jmFile.add(miOpen = resources.getItem("open", this));
        miOpen.setIcon(resources.getIcon("openImage"));
        miRecentFiles = new JMenu(resources.getString("openRecentFiles"));
        miRecentFiles.setIcon(resources.getIcon("emptyImage"));
        jmFile.add(miRecentFiles);
        // Recent files names are added as items to the miOpenRecentFiles menu.
        String recentFilesProperty = Run.getProperties().getString("jsynoptic.ui.JSynoptic.recentFiles", null);
        if ((recentFilesProperty != null) && !recentFilesProperty.equals("")) {
            // Get a list of absolute paths
            String[] listOfRecentFiles = recentFilesProperty.trim().split(";");
            if (listOfRecentFiles != null) {
                for (int i = 0; i < ((listOfRecentFiles.length > MAX_NUMBER_OF_RECENT_FILES) ? MAX_NUMBER_OF_RECENT_FILES
                        : listOfRecentFiles.length); i++) {
                    recentOpenedFiles.add(new File(listOfRecentFiles[i]));
                }
            }
        }
        setRecentFilesMenu();
        jmFile.add(new JSeparator());
        jmFile.add(miClose = resources.getItem("close", this));
        miClose.setIcon(resources.getIcon("closeImage"));
        jmFile.add(miCloseAll = resources.getItem("closeAll", this));
        miCloseAll.setIcon(resources.getIcon("closeAllImage"));
        jmFile.add(new JSeparator());
        jmFile.add(miSave = resources.getItem("save", this));
        miSave.setIcon(resources.getIcon("saveImage"));
        jmFile.add(miSaveAs = resources.getItem("saveAs", this));
        miSaveAs.setIcon(resources.getIcon("emptyImage"));
        jmFile.add(miSaveAll = resources.getItem("saveAll", this));
        miSaveAll.setIcon(resources.getIcon("emptyImage"));
        jmFile.add(new JSeparator());


        jmFile.add(miExport = resources.getItem("export", this));
        miExport.setIcon(resources.getIcon("exportImage"));
        jmFile.add(new JSeparator());

        jmFile.add(miRefreshAllSheets = resources.getItem("refresh", this));
        miRefreshAllSheets.setIcon(resources.getIcon("refreshImage"));
        jmFile.add(new JSeparator());

        jmFile.add(miSheetDisplay = resources.getItem("sheetDisplay", this));
        miSheetDisplay.setIcon(resources.getIcon("emptyImage"));

        jmFile.add(miPrint = resources.getItem("print", this));
        miPrint.setIcon(resources.getIcon("printImage"));

        jmFile.add(miPrintImage = resources.getItem("printToImg", this));
        miPrintImage.setIcon(resources.getIcon("printToImgImage"));
        jmFile.add(miSnapShot = resources.getItem("displayImg", this));
        miSnapShot.setIcon(resources.getIcon("snapShotImage"));
        jmFile.add(new JSeparator());
        jmFile.add(miSheetInformation = resources.getItem("sheetInformation", this));
        miSheetInformation.setIcon(resources.getIcon("emptyImage"));
        jmFile.add(new JSeparator());
        jmFile.add(miExit = resources.getItem("exit", this));
        miExit.setIcon(resources.getIcon("emptyImage"));
        if (mb instanceof JMenuBar) {
            ((JMenuBar) mb).add(jmFile);
        } else if (mb instanceof JMenu) {
            ((JMenu) mb).add(jmFile);
        }
    }

    /**
     * Add an edit menu to a menu bar1999
     */
    public void addEditMenu(Object mb) {
        jmEdit = resources.getMenu("edit");
        JMenuItem item;
        KeyStroke k;
        jmEdit.add(miUndo = resources.getItem("undo", this));
        k = resources.getKeyStroke("undoShortcut");
        miUndo.setIcon(resources.getIcon("undoImage"));
        if (k != null) {
            miUndo.setAccelerator(k);
        }
        jmEdit.add(miRedo = resources.getItem("redo", this));
        k = resources.getKeyStroke("redoShortcut");
        miRedo.setIcon(resources.getIcon("redoImage"));
        if (k != null) {
            miRedo.setAccelerator(k);
        }

        jmEdit.addSeparator();

        item = jmEdit.add(aCut);
        item.setIcon(resources.getIcon("cutImage"));
        k = resources.getKeyStroke("cutShortcut");
        if (k != null) {
            item.setAccelerator(k);
        }
        item = jmEdit.add(aCopy);
        item.setIcon(resources.getIcon("copyImage"));
        k = resources.getKeyStroke("copyShortcut");
        if (k != null) {
            item.setAccelerator(k);
        }
        item = jmEdit.add(aPaste);
        item.setIcon(resources.getIcon("pasteImage"));
        k = resources.getKeyStroke("pasteShortcut");
        if (k != null) {
            item.setAccelerator(k);
        }
        item = jmEdit.add(aRemove);
        item.setIcon(resources.getIcon("removeImage"));
        k = resources.getKeyStroke("removeShortcut");
        if (k != null) {
            item.setAccelerator(k);
        }
        jmEdit.addSeparator();

        item = jmEdit.add(aSelectAll);
        item.setIcon(resources.getIcon("emptyImage"));
        k = resources.getKeyStroke("selectAllShortcut");
        if (k != null) {
            item.setAccelerator(k);
        }

        if (mb instanceof JMenuBar) {
            ((JMenuBar) mb).add(jmEdit);
        } else if (mb instanceof JMenu) {
            ((JMenu) mb).add(jmEdit);
        }
    }

    /**
     * Add file buttons to a tool bar
     */
    public void addFileButtons(JToolBar tb) {
        tb.add(bNew = new TemplateMenuBox(resources.getBox("new", null).getIcon(), this));
        bNew.setEnabled(isEditable);

        tb.add(bOpen = resources.getBox("open", this));
        tb.add(bSave = resources.getBox("save", this));
        tb.addSeparator();
        tb.add(bPrint = resources.getBox("print", this));
        tb.add(bPrintImage = resources.getBox("printToImg", this));
        tb.add(bSnapShot = resources.getBox("snapShot", this));
        tb.addSeparator();
        tb.add(bRefreshAllSheets = resources.getBox("refresh", this));
    }

    /**
     * Add edit buttons to a tool bar
     */
    public void addEditButtons(JToolBar tb) {
        JButton button;
        String text;
        button = tb.add(aCut);
        text = resources.getStringValue("cutTip");
        if (text != null) {
            button.setToolTipText(text);
        }
        button = tb.add(aCopy);
        text = resources.getStringValue("copyTip");
        if (text != null) {
            button.setToolTipText(text);
        }
        button = tb.add(aPaste);
        text = resources.getStringValue("pasteTip");
        if (text != null) {
            button.setToolTipText(text);
        }
        if (USE_SELECTION_TOOL_BOXES) {
            button = tb.add(aGroup);
            text = resources.getStringValue("groupTip");
            if (text != null) {
                button.setToolTipText(text);
            }
            button = tb.add(aUngroup);
            text = resources.getStringValue("ungroupTip");
            if (text != null) {
                button.setToolTipText(text);
            }
            button = tb.add(aRegroup);
            text = resources.getStringValue("regroupTip");
            if (text != null) {
                button.setToolTipText(text);
            }
        }
    }

    public void addDepthButtons(JToolBar tb) {
        Vector acts = new Vector();
        Vector tips = new Vector();
        acts.add(aFront);
        tips.add(resources.getStringValue("frontTip"));
        acts.add(aForward);
        tips.add(resources.getStringValue("forwardTip"));
        acts.add(aBackward);
        tips.add(resources.getStringValue("backwardTip"));
        acts.add(aBack);
        tips.add(resources.getStringValue("backTip"));
        cbxDepth = new ActionComboBox(acts, tips);
        tb.add(cbxDepth);
    }

    public void addAlignButtons(JToolBar tb) {
        Vector acts = new Vector();
        Vector tips = new Vector();
        acts.add(aLeft);
        tips.add(resources.getStringValue("leftTip"));
        acts.add(aRight);
        tips.add(resources.getStringValue("rightTip"));
        acts.add(aTop);
        tips.add(resources.getStringValue("topTip"));
        acts.add(aBottom);
        tips.add(resources.getStringValue("bottomTip"));
        acts.add(aVCenter);
        tips.add(resources.getStringValue("vCenterTip"));
        acts.add(aHCenter);
        tips.add(resources.getStringValue("hCenterTip"));
        acts.add(dHorizontally);
        tips.add(resources.getStringValue("dHorizontallyTip"));
        acts.add(dVertically);
        tips.add(resources.getStringValue("dVerticallyTip"));
        cbxAlign = new ActionComboBox(acts, tips);
        tb.add(cbxAlign);
    }

    /**
     * Add an edit menu to a popup menu
     */
    public void addEditMenu(JPopupMenu popup) {
        JMenuItem item;
        if (!USE_SELECTION_TOOL_BOXES) {
            addDepthMenu(popup);
            addAlignMenu(popup);
            popup.addSeparator();
            // Group actions
            JMenu group = new JMenu("Group");
            item = group.add(aGroup);
            item.setIcon(resources.getIcon("groupImage"));
            item = group.add(aUngroup);
            item.setIcon(resources.getIcon("ungroupImage"));
            item = group.add(aRegroup);
            item.setIcon(resources.getIcon("regroupImage"));
            popup.add(group);
            popup.addSeparator();
        }
        // Edit Action
        item = popup.add(aCut);
        item.setIcon(resources.getIcon("cutImage"));
        item = popup.add(aCopy);
        item.setIcon(resources.getIcon("copyImage"));
        item = popup.add(aPaste);
        item.setIcon(resources.getIcon("pasteImage"));
        item = popup.add(aRemove);
        item.setIcon(resources.getIcon("removeImage"))
        item = popup.add(aSelectAll);   
        item.setIcon(resources.getIcon("emptyImage"));

    }


    public void addDepthMenu(JPopupMenu popup) {
        if (mDepth != null) {
            popup.add(mDepth);
            return;
        }
        mDepth = (JMenu) popup.add(resources.getMenu("depth"));
        mDepth.add(aFront);
        mDepth.add(aForward);
        mDepth.add(aBackward);
        mDepth.add(aBack);
    }

    public void addAlignMenu(JPopupMenu popup) {
        if (mAlign != null) {
            popup.add(mAlign);
            return;
        }
        mAlign = (JMenu) popup.add(resources.getMenu("galign"));
        mAlign.add(aLeft);
        mAlign.add(aRight);
        mAlign.add(aTop);
        mAlign.add(aBottom);
        mAlign.add(aVCenter);
        mAlign.add(aHCenter);
        mAlign.addSeparator();
        mAlign.add(dHorizontally);
        mAlign.add(dVertically);
    }

    /**
     * Add a help menu to a menu bar
     */
    public void addToolsMenu(Object mb) {
        JMenu h = resources.getMenu("tools");
        h.add(miFindPlugins = resources.getItem("findPlugins", this));
        h.add(miPreferencesPanel = resources.getItem("openPreferences", this));
        h.add(miChooseLanguage = resources.getItem("chooseLanguage", this));
        // Don't show fullscreen in stable releases until it's ready to show!
        // h.add(aFullScreen); // FIXME not ready to show
        if (mb instanceof JMenuBar) {
            ((JMenuBar) mb).add(h);
        } else if (mb instanceof JMenu) {
            ((JMenu) mb).add(h);
        }
    }

    /**
     * Add a help menu to a menu bar
     */
    public void addHelpMenu(Object mb) {
        jmHelp = resources.getMenu("help");
        jmHelp.add(miHelp = resources.getItem("helpContent", this));
        miHelp.setIcon(resources.getIcon("helpContentImage"));
        jmHelp.addSeparator();
        jmHelp.add(miAbout = resources.getItem("about", this));
        miAbout.setIcon(resources.getIcon("emptyImage"));
        if (mb instanceof JMenuBar) {
            ((JMenuBar) mb).add(jmHelp);
        } else if (mb instanceof JMenu) {
            ((JMenu) mb).add(jmHelp);
        }
    }

    /*
     * (non-Javadoc)
     *
     * @see jsynoptic.ui.JSynopticInterface#canEdit()
     */
    public boolean canEdit() {
        return isEditable;
    }

    public ShapesContainer.ShapesComponent getActiveComponent() {
        return (ShapesContainer.ShapesComponent) desktopCardPanel.getSelectedComponent();
    }

    public DiagramComponent getActiveDiagram() {
        JComponent jc = desktopCardPanel.getSelectedComponent();
        if (!(jc instanceof DiagramComponent)) {
            return null;
        }
        return (DiagramComponent) jc;
    }

    public ShapesContainer getActiveContainer() {
        JComponent jc = desktopCardPanel.getSelectedComponent();
        if (!(jc instanceof ShapesContainer.ShapesComponent)) {
            return null;
        }
        return (ShapesContainer) ((ShapesContainer.ShapesComponent) jc).getContainer();
    }

    public void addComponent(ShapesContainer.ShapesComponent jc, File f) {
        desktopCardPanel.addComponent(jc, f);
        desktopCardPanel.selectComponent(jc);
    }

    public void addComponent(ShapesContainer.ShapesComponent jc) {
        addComponent(jc, null);
    }

    public void addContainer(ShapesContainer sc, File f) {
        addComponent((ShapesContainer.ShapesComponent) sc.getComponent(), f);
    }

    public void addContainer(ShapesContainer sc) {
        addContainer(sc, null);
    }

    public void setFile(JComponent jc, File f) {
        desktopCardPanel.setFile(jc, f);
    }

    public FiledDesktopCardPanel getFilePanel() {
        return desktopCardPanel;
    }

    public File getFile(JComponent jc) {
        return desktopCardPanel.getFile(jc);
    }

    public void setFile(ShapesContainer sc, File f) {
        setFile(sc.getComponent(), f);
    }

    public File getFile(ShapesContainer sc) {
        return getFile(sc.getComponent());
    }

    protected void setRecentFilesMenu() {
        miRecentFiles.removeAll();
        for (int i = 0; i < recentOpenedFiles.size(); i++) {
            AbstractAction action = new AbstractAction(((File) recentOpenedFiles.get(i)).getName()) {
                public void actionPerformed(ActionEvent e) {
                    JSynopticPanels.this.open((File) getValue((String) getValue(Action.NAME)));
                }
            };
            action.putValue(((File) recentOpenedFiles.get(i)).getName(), recentOpenedFiles.get(i));
            miRecentFiles.add(new JMenuItem(action));
        }
        miRecentFiles.setEnabled(recentOpenedFiles.size() != 0);
    }

    /**
     * Create a OPEN or SAVE FileChooser
     *
     * @param action
     *            OPEN or SAVE action.
     * @return a new FileChooser initialised with currentDirectory and all
     *         plugin filters
     */
    public void createFileChooser(int action) {
        JFileChooser fileChooser = new JFileChooser(getPath());

        if (action == Plugin.SAVE) {
            saveFileChooser = fileChooser;

        } else if (action == Plugin.OPEN){
            openFileChooser = fileChooser;

        } else if (action == Plugin.EXPORT){
            exportFileChooser = fileChooser;
        }

        javax.swing.filechooser.FileFilter firstFilter = null;
        for (int i = 0; i < Run.plugins.size(); ++i) {
            Plugin p = (Plugin) Run.plugins.get(i);
            javax.swing.filechooser.FileFilter[] fft = p.getFileFilters(action);
            if (fft == null) {
                continue;
            }
            for (int j = 0; j < fft.length; ++j) {
                fileChooser.addChoosableFileFilter(fft[j]);
                if (firstFilter == null) {
                    firstFilter = fft[j];
                }
            }
        }
        fileChooser.setAcceptAllFileFilterUsed(false); // don't want all file
        // filters in aggregate
        AggregateFileFilter agf = null;
        if (action == Plugin.OPEN) {
            agf = new AggregateFileFilter(fileChooser.getChoosableFileFilters());
            fileChooser.addChoosableFileFilter(agf);
        }
        // Add an accessory panel
        fileChooser.setAccessory(new FileChooserAccessory(action));

        fileChooser.setMultiSelectionEnabled(action == Plugin.OPEN);
        fileChooser.setAcceptAllFileFilterUsed(true);
        if (firstFilter != null) {
            fileChooser.setFileFilter(agf != null ? agf : firstFilter);
        }
    }

    protected File[] getFilesFromDialog(int action) {
        String dialogText;
        JFileChooser fileChooser;
        if (action == Plugin.SAVE) {
            dialogText = resources.getStringValue("saveDialogText");
            fileChooser = saveFileChooser;

        } else if (action == Plugin.EXPORT) {
            dialogText = resources.getStringValue("exportDialogText");
            fileChooser = exportFileChooser;

        } else {
            dialogText = resources.getStringValue("openDialogText");
            fileChooser = openFileChooser;
        }

        fileChooser.setCurrentDirectory(getPath());

        if ((fileChooser.getAccessory() != null) && (fileChooser.getAccessory() instanceof FileChooserAccessory)){
            ((FileChooserAccessory)fileChooser.getAccessory()).updateFileChooserAccessory();
        }

        int result = fileChooser.showDialog(owner, dialogText);
        if (result != JFileChooser.APPROVE_OPTION) {
            return null;
        }
        CurrentPathProvider.currentPathProvider.setCurrentPath(fileChooser.getCurrentDirectory());


        FileFilter currentFileFilter =  fileChooser.getFileFilter();
        if (currentFileFilter instanceof AggregateFileFilter) {
            currentFileFilter = ((AggregateFileFilter) currentFileFilter).getFilterForFile(getOwner(), fileChooser
                    .getSelectedFile());
            if (currentFileFilter == null) {
                return null;
            }
        }

        if (action == Plugin.SAVE) {
            currentSaveFileFilter = currentFileFilter;
        } else if (action == Plugin.EXPORT) {
            currentExportFileFilter = currentFileFilter;
        } else {
            currentOpenFileFilter = currentFileFilter;
        }


        File[] ret;
        if (fileChooser.isMultiSelectionEnabled()) {
            ret = fileChooser.getSelectedFiles();
        } else {
            ret = new File[1];
            String fileName = fileChooser.getSelectedFile().getParent() + File.separator +  fileChooser.getSelectedFile().getName();

            // Add file extention relarging the current file filter
            if ( fileChooser.getFileFilter() instanceof MenuResourceBundle.FileFilter){
                String fileFilterExtension =  ((MenuResourceBundle.FileFilter)fileChooser.getFileFilter()).getExtension();
                if (fileName.indexOf(".") != -1) {
                    String fileExtention = fileName.substring(fileName.lastIndexOf(".") + 1, fileName.length());

                    if (!fileExtention.equalsIgnoreCase(fileFilterExtension)){
                        fileName += "." + fileFilterExtension ;
                    }

                } else {
                    fileName += "." + fileFilterExtension ;
                }
            }

            ret[0] = new File(fileName)
        }
        return ret;
    }

    protected Plugin getPluginForFilter(int action, FileFilter activeFilter) {
        if (activeFilter == null) {
            return null;
        }
        for (int i = 0; i < Run.plugins.size(); ++i) {
            Plugin p = (Plugin) Run.plugins.get(i);
            FileFilter[] fft = p.getFileFilters(action);
            if (fft == null) {
                continue;
            }
            for (int j = 0; j < fft.length; j++) {
                if (activeFilter.equals(fft[j])) {
                    return p;
                }
            }
        }
        return null;
    }

    protected Plugin getPluginToProcessFile(File f, int action, FileFilter activeFilter) {

        boolean accepted;
        if (activeFilter != null) {
            if (activeFilter instanceof simtools.ui.MenuResourceBundle.FileFilter) {
                accepted = ((simtools.ui.MenuResourceBundle.FileFilter)activeFilter).canProcess(f);
            }else {
                accepted = activeFilter.accept(f);
            }

        } else {
            accepted = false;
        }


        // if the active filter accepts the file, use its plugin in priority
        // otherwise, take the first plugin (excuding the builtin) that can
        // accept the file
        Plugin acceptedPlugin = null;
        for (int i = 0; i < Run.plugins.size(); ++i) {
            Plugin p = (Plugin) Run.plugins.get(i);
            FileFilter[] fft = p.getFileFilters(action);
            if (fft == null) {
                continue;
            }
            for (int j = 0; j < fft.length; ++j) {
                if (accepted && fft[j].equals(activeFilter)) {
                    return p;
                }

                if ((acceptedPlugin == null) || (acceptedPlugin instanceof Builtin)) {

                    if (fft[j] instanceof simtools.ui.MenuResourceBundle.FileFilter) {
                        if (((simtools.ui.MenuResourceBundle.FileFilter) fft[j]).canProcess(f)) {
                            acceptedPlugin = p;
                        }

                    } else {
                        accepted = fft[j].accept(f);
                    }
                }
            }
        }
        if (acceptedPlugin == null) {
            JOptionPane.showMessageDialog(owner, messageWriter.print1args("noPluginForFile", f.getName()), resources
                    .getStringValue("unknownFileType"), JOptionPane.ERROR_MESSAGE);
            return null;
        }
        return acceptedPlugin;
    }

    public boolean open() {
        File[] f = getFilesFromDialog(Plugin.OPEN);
        boolean ret = true;
        if (f != null) {
            for (int i = 0; i < f.length; i++) {
                ret &= open(f[i]);
            }
        }
        return ret;
    }

    public boolean open(File f) {
        setIsOpenProcessCancelled(false);
        if ((f == null) || (!f.exists())) {
            return false; // cancel
        }
        Plugin p = getPluginToProcessFile(f, Plugin.OPEN, currentOpenFileFilter);
        if (p == null) {
            return false; // error displayed already
        }
        container.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
        CurrentPathProvider.currentPathProvider.setCurrentPath(f);
        boolean loadIsOk = p.processFile(f, Plugin.OPEN);
        container.setCursor(Cursor.getDefaultCursor());
        if (loadIsOk) {
            setStatus(messageWriter.print1args("fileLoadSuccessful", f.getName()));
        } else {
            setStatus(messageWriter.print1args("fileLoadFailed", f.getName()));
        }
        // Ask for replacing empty data sources with correspongin data
        if (EmptyDataSourcePool.global.emptyDataSourcesCanBeReplaced() && (JSynoptic.gui != null)) {
            int answer = JOptionPane.showConfirmDialog(owner, new ReportingDialog(messageWriter.print1args(
                    "replaceDataSourcesText", f.getName()), EmptyDataSourcePool.global.getDataSourcesToReplaceTitles(),
                    EmptyDataSourcePool.global.getDataSourcesToReplace()), messageWriter
                    .print0args("replaceDataSources"), JOptionPane.YES_NO_OPTION);
            if (answer == JOptionPane.YES_OPTION) {
                EmptyDataSourcePool.global.replaceAllDataSources();
            }
        }
        // Add file to recentOpenedFiles list
        recentOpenedFiles.remove(f);
        while (recentOpenedFiles.size() >= MAX_NUMBER_OF_RECENT_FILES) {
            recentOpenedFiles.remove(recentOpenedFiles.size() - 1);
        }
        recentOpenedFiles.add(0, f);
        setRecentFilesMenu();
        return loadIsOk;
    }


    /**
     * Setup the display all sheets regarding sheet format and sheet size
     */
    protected void setupSheetDisplay(){



        SheetDisplayDialog   sheetDisplayDialog = new SheetDisplayDialog(getOwner());

        sheetDisplayDialog.setPropertyValue(SheetDisplayDialog.PAGE_HEIGHT, new Integer(DiagramComponent.getPageHeight()));
        sheetDisplayDialog.setPropertyValue(SheetDisplayDialog.PAGE_WIDTH, new Integer(DiagramComponent.getPageWidth()));
        sheetDisplayDialog.setPropertyValue(SheetDisplayDialog.PRINT_VIEW, new Boolean(DiagramComponent.isPrintViewEnabled()));

        //TODO orientation

        sheetDisplayDialog.setVisible(true);

        if (sheetDisplayDialog.canApplyChanges()){
            DiagramComponent.setPageModeEnabled(((Boolean)sheetDisplayDialog.getPropertyValue(SheetDisplayDialog.PRINT_VIEW)).booleanValue());
            DiagramComponent.setPageHeight(((Integer)sheetDisplayDialog.getPropertyValue(SheetDisplayDialog.PAGE_HEIGHT)).intValue());
            DiagramComponent.setPageWidth(((Integer)sheetDisplayDialog.getPropertyValue(SheetDisplayDialog.PAGE_WIDTH)).intValue()) ;

            // repaint diagram components
            Iterator it = desktopCardPanel.getComponentIterator();
            while (it.hasNext()) {
                ((JComponent) it.next()).repaint();
            }
        }
    }


    /**
     * Zoom in or zoom out in current diagram
     * @param zoomIn - if true zoom in, otherwise zoom out
     */
    protected void zoomDiagram(boolean zoomIn){
        DiagramComponent d = getActiveDiagram();
        if (d != null) {
            double newZoom =  (zoomIn)? d.getZoom()*DiagramComponent.ZOOM_FACTOR :  d.getZoom()/DiagramComponent.ZOOM_FACTOR;
            d.setZoom(newZoom);
            int zoomInt = (int) (d.getZoom() * 100) ;
            tfZoom.setText(zoomInt +  "%");
        }
    }


    protected void refreshAllSheets(){
        // Wipe-off all shape resources
        Iterator it = desktopCardPanel.getComponentIterator();
        while (it.hasNext()) {
            JComponent comp = (JComponent) it.next();
            if (comp instanceof ShapesContainer.ShapesComponent) {
                ShapesContainer sheet = (ShapesContainer) ((ShapesContainer.ShapesComponent) comp).getContainer();
                for (int i = 0; i < sheet.size(); i++) {
                    Object o = sheet.get(i);
                    if (o instanceof AbstractShape) {
                        ((AbstractShape) o).wipeOff();
                    }
                }
            }
        }
        // Refresh all shapes
        it = desktopCardPanel.getComponentIterator();
        while (it.hasNext()) {
            JComponent comp = (JComponent) it.next();
            if (comp instanceof ShapesContainer.ShapesComponent) {
                ShapesContainer sheet = (ShapesContainer) ((ShapesContainer.ShapesComponent) comp).getContainer();
                for (int i = 0; i < sheet.size(); i++) {
                    Object o = sheet.get(i);
                    if (o instanceof AbstractShape) {
                        ((AbstractShape) o).refresh();
                    }
                }
            }
        }
    }

    /**
     * Print a DiagramComponent Open a print dialog to allow user to specify
     * print parameters
     *
     * @param d
     */
    protected void print(DiagramComponent d) {
        if (!canPrint()) {
            return; // In fact, should not happen at this point
        }
        if (d == null) {
            return;
        }
        if (PrintDialog.canPrint()){

            // Display selected sheet name in dialog box
            printerDialog.setPropertyValue(PrintDialog.SHEET_NAME, d.toString());
            // Display dialog box
            printerDialog.setVisible(true);

            if (!printerDialog.getResult()) {
                return;
            }

            //  Get properties from PrintDialog UI
            PrinterJob printerJob = printerDialog.getPrinterJob();
            PageFormat pageFormat = printerJob.defaultPage();
            printerJob.setJobNamed.toString() );

            d.setSelectionPrintMode( ((Boolean)printerDialog.getPropertyValue(PrintDialog.PRINT_SELECTION)).booleanValue() );
            d.setPrintBackgroundColor( ((Boolean)printerDialog.getPropertyValue(PrintDialog.PRINT_BACKGROUND)).booleanValue());
            d.setScaleSheet(((Boolean)printerDialog.getPropertyValue(PrintDialog.SCALE_SHEET)).booleanValue());
            pageFormat.setOrientation( ((Integer)printerDialog.getPropertyValue(PrintDialog.ORIENTATION)).intValue() );
            pageFormat.setPaperPrintDialog.getPaper( ((Integer)printerDialog.getPropertyValue(PrintDialog.PAPER_SIZE)).intValue() ));
            printerJob.setCopies(((Integer)printerDialog.getPropertyValue(PrintDialog.NB_COPIES)).intValue() );

            printerJob.setPageable(new PagesToPrint(d, pageFormat));

            setStatus(messageWriter.print1args("printingTo", printerJob.getPrintService().getName()));
            try {
                printerJob.print();
            } catch (Exception ex) {
                setStatus(messageWriter.print1args("printFailed", ex.getMessage()));
                ex.printStackTrace();
            }

        } else {
            JOptionPane.showMessageDialog(
                    getOwner(),
                    messageWriter.print0args("noPrinter"),
                    messageWriter.print0args("noPrinter"),
                    JOptionPane.WARNING_MESSAGE);

        }
    }


    /**
     * Represent the diagramComposent to be printed
     * @author zxpletran007
     *
     */
    protected class PagesToPrint implements Pageable{

        Printable printableDiagram;
        PageFormat pageFormat;

        public PagesToPrint(DiagramComponent printableDiagram, PageFormat pageFormat){
            this.printableDiagram = printableDiagram;
            this.pageFormat = pageFormat;
        }

        public int getNumberOfPages() {
            return 1;
        }

        public PageFormat getPageFormat(int pageIndex) throws IndexOutOfBoundsException {
            return pageFormat;
        }

        public Printable getPrintable(int pageIndex) throws IndexOutOfBoundsException {
            return printableDiagram;
        }
    }

    /**
     * Save all sheets
     *
     * @return true if all sheets can be saved, false overwise
     */
    protected boolean saveAll() {
        boolean ret = true;
        for (Iterator it = desktopCardPanel.getComponentIterator(); it.hasNext();) {
            DiagramComponent d = (DiagramComponent) it.next();
            desktopCardPanel.selectComponent(d);
            ret &= save();
        }
        return ret;
    }

    /**
     * Save current component
     *
     * @return true if component can be saved, false overwise
     */
    protected boolean save() {
        File f = desktopCardPanel.getFile(desktopCardPanel.getSelectedComponent());
        if (f == null) {
            return saveAs(); // choose a file
        }
        return saveFile(f);
    }


    /**
     * Save current component
     *
     * @return true if component can be saved, false overwise
     */
    protected boolean export() {
        File f = desktopCardPanel.getFile(desktopCardPanel.getSelectedComponent());

        boolean hasChoosen = false;
        while (!hasChoosen) {
            if (f != null){
                exportFileChooser.setSelectedFile(f);
            }
            File[] ff = getFilesFromDialog(Plugin.EXPORT);
            if (ff == null) {
                return false; // cancel
            }
            f = ff[0];

            if (f.exists()) {
                int answer = JOptionPane.showOptionDialog(getOwner(), f.getName()
                        + messageWriter.print0args("fileOverWritting"), null, JOptionPane.YES_NO_CANCEL_OPTION,
                        JOptionPane.WARNING_MESSAGE, null, null, null);
                if (answer == JOptionPane.CANCEL_OPTION) {
                    return false;
                }
                if (answer == JOptionPane.YES_OPTION) {
                    hasChoosen = true;
                }
            } else {
                hasChoosen = true;
            }
        }
        return exportFile(f);
    }

    /**
     * Choose a file and save current component. A file chooser dialog box is
     * opened to specify a file name
     *
     * @return true if file is saved and false overwise
     */
    protected boolean saveAs() {
        boolean fileIsSaved = false;

        if (desktopCardPanel.getSelectedComponent() != null) {
            File f = desktopCardPanel.getFile(desktopCardPanel.getSelectedComponent());
            if (f == null) { // get a default name
                String fileName = desktopCardPanel.getSelectedComponent().getName();
                fileName = "Doc" + fileName.charAt(fileName.length() - 1) + resources.getStringValue("defaultSaveExtension");
                f = new File(fileName);
            }
            boolean hasChoosen = false;
            while (!hasChoosen) {
                saveFileChooser.setSelectedFile(f);
                File[] ff = getFilesFromDialog(Plugin.SAVE);
                if (ff == null) {
                    return false; // cancel
                }
                f = ff[0];
                if (f.getName().indexOf(".") == -1) {
                    f = new File(f.getAbsolutePath() + resources.getStringValue("defaultSaveExtension"));
                }
                if (f.exists()) {
                    int answer = JOptionPane.showOptionDialog(getOwner(), f.getName()
                            + messageWriter.print0args("fileOverWritting"), null, JOptionPane.YES_NO_CANCEL_OPTION,
                            JOptionPane.WARNING_MESSAGE, null, null, null);
                    if (answer == JOptionPane.CANCEL_OPTION) {
                        return false;
                    }
                    if (answer == JOptionPane.YES_OPTION) {
                        hasChoosen = true;
                    }
                } else {
                    hasChoosen = true;
                }
            }
            fileIsSaved = saveFile(f);
        }

        return fileIsSaved;
    }

    protected boolean saveFile(File f) {
        if (!canSave() || (f == null)) {
            return false; // In fact, should not happen at this point
        }
        if (f.getName().indexOf(".") == -1) {
            f = new File(f.getAbsolutePath() + resources.getStringValue("defaultSaveExtension"));
        }
        Plugin p = getPluginToProcessFile(f, Plugin.SAVE, currentSaveFileFilter);
        if (p == null) {
            return false;
        }
        CurrentPathProvider.currentPathProvider.setCurrentPath(f);
        return p.processFile(f, Plugin.SAVE);
    }

    protected boolean exportFile(File f) {
        if (f == null) {
            return false; // In fact, should not happen at this point
        }
        Plugin p = getPluginToProcessFile(f, Plugin.EXPORT, currentExportFileFilter);
        if (p == null) {
            return false;
        }
        CurrentPathProvider.currentPathProvider.setCurrentPath(f);
        return p.processFile(f, Plugin.EXPORT);
    }

    /**
     * Sets the state of the cut, copy, remove... menu items and buttons
     */
    void setSelectionEditEnabled(boolean state) {
        if (state) {
            DiagramComponent d = getActiveDiagram();
            if (d != null) {
                DiagramSelection sel = d.getDiagramSelection();
                for (int i = 0; i < lockedShapes.size(); ++i) {
                    if (sel.isSelected((Shape) lockedShapes.get(i))) {
                        state = false;
                        break;
                    }
                }
            }
        }
        aCut.setEnabled(state);
        aCopy.setEnabled(state);
        aRemove.setEnabled(state);
        aFront.setEnabled(state);
        aForward.setEnabled(state);
        aBackward.setEnabled(state);
        aBack.setEnabled(state);

        DiagramComponent d = getActiveDiagram();
        boolean canAlign = false, canDistribute = false;
        if (state && (d != null) && (d.getDiagramSelection() != null)) {
            canAlign = (d.getDiagramSelection().getShapeCount() > 1);
            canDistribute = (d.getDiagramSelection().getShapeCount() > 2);
        }
        aLeft.setEnabled(canAlign);
        aRight.setEnabled(canAlign);
        aTop.setEnabled(canAlign);
        aBottom.setEnabled(canAlign);
        aVCenter.setEnabled(canAlign);
        aHCenter.setEnabled(canAlign);
        dHorizontally.setEnabled(canDistribute);
        dVertically.setEnabled(canDistribute);
        aGroup.setEnabled((d != null) && (d instanceof ShapesComponent) && ((ShapesComponent) d).canGroup());
        aUngroup.setEnabled((d != null) && (d instanceof ShapesComponent) && ((ShapesComponent) d).canUnGroup());
        aRegroup.setEnabled((d != null) && (d instanceof ShapesComponent) && ((ShapesComponent) d).canReGroup());
    }

    /**
     * Sets the state of the paste menu items and buttons
     */
    void setPasteEnabled(boolean state) {
        aPaste.setEnabled(state);
    }
   
    void setShapeToolEnabled(boolean state){
        if (shapeToolBar != null){
            shapeToolBar.setEnabled(state);
        }
    }

    /**
     * Sets the state of the menu items and buttons
     */
    void setDiagramComponentSpecificsEnabled(boolean state) {
        miPrint.setEnabled(state);
        miPrintImage.setEnabled(state);
        miSnapShot.setEnabled(state);
        bPrint.setEnabled(state);
        bSave.setEnabled(state);
        bPrintImage.setEnabled(state);
        bRefreshAllSheets.setEnabled(state);
        bSnapShot.setEnabled(state);
       
        if (bAdjust != null) {
            bAdjust.setEnabled(state);
        }
        if (tbGridDisplay != null) {
            tbGridDisplay.setEnabled(state);
        }
        if (cbxGrid != null) {
            cbxGrid.setEnabled(state);
        }
        if (tfZoom != null) {
            tfZoom.setEnabled(state);
        }
        if (bAlign != null) {
            bAlign.setEnabled(state);
        }
        if (state) {
            updateUndoEnabled();
        } else {
            bUndo.setEnabled(state);
            bRedo.setEnabled(false);
        }
    }

    //
    // DiagramSelectionListener interface
    //
    public void selectionChanged(DiagramSelection sel) {
        setSelectionEditEnabled(!sel.isEmpty() && isEditable);
    }

    //
    // DiagramClipboardListener interface
    //
    public void clipboardChanged(DiagramClipboard sel) {
        setPasteEnabled(!sel.isEmpty());
    }

    //
    // DesktopCardPanelListener interface
    //
    /*
     * (non-Javadoc)
     *
     * @see simtools.ui.DesktopCardPanelListener#componentSelected(javax.swing.JComponent)
     */
    public void componentSelected(JComponent d) {
       
        if (!(d instanceof DiagramComponent)) {
            setSelectionEditEnabled(false);
            setPasteEnabled(false);
            setShapeToolEnabled(false);
            setDiagramComponentSpecificsEnabled(false);
            updateUndoActions();
    
        } else {
            DiagramComponent dc = (DiagramComponent) d;
            DiagramSelection sel = dc.getDiagramSelection();
            sel.addListener(this);
            selectionChanged(sel);
            setDiagramComponentSpecificsEnabled(true);
            setShapeToolEnabled(true);
           
            // update grid combo box
            if (cbxGrid != null) {
                String si = String.valueOf(dc.getGrid());
                boolean found = false;
                for (int i = 0; i < cbxGrid.getItemCount(); i++) {
                    String s = (String) cbxGrid.getItemAt(i);
                    if (si.equals(s)) {
                        cbxGrid.setSelectedIndex(i);
                        found = true;
                    }
                }
                if (!found) {
                    cbxGrid.getEditor().setItem(si);
                }
            }
            // update grid display check box
            if (tbGridDisplay != null) {
                tbGridDisplay.setSelected(dc.getGridDisplay());
            }
            // update zoom combo box
            if (tfZoom != null) {
                int zoomInt = (int) (dc.getZoom() * 100.0);
                tfZoom.setText(zoomInt +  "%");
            }
           
            // update diagram component shape creator
            if (isEditable && shapeToolBar!=null){
                dc.setElementCreator(shapeToolBar.getCurrentShapeCreateCreator());
            }

           
            // undo actions
            updateUndoActions();
        }
       
    }

    /**
     *
     */
    public void newComponent() {

        // update current action in MenuBox
        bNew.setCurrentActionFromCurrentTemplate();

        // Create sheet from template
        String docTitle = messageWriter.print1args("untitledDocNum", new Integer(++untitledDocumentNumber));
        ShapesContainer sc =  Template.getCurrentTemplate().createShapeContainer(docTitle);

        // new component shall be marked as not changed
        sc.getComponent().setHasBeenModified(false);  
        if ( sc.getComponent().getName().startsWith("*")){
            sc.getComponent().setName(sc.getComponent().getName().substring(1));
            getFilePanel().updateComponentName(sc.getComponent());
        }
       
        // Update the current shape creator
        if (isEditable && shapeToolBar!=null){
            sc.getComponent().setElementCreator(shapeToolBar.getCurrentShapeCreateCreator());
        }

        // Add sheet to container
        addContainer(sc);
    }


    /**
     *
     */
    public void newComponentAs() {
        templateChooser.showDialog();
        if (templateChooser.getReturnState() == TemplateChooser.CREATE_OPTION) {
            newComponent();
        }
    }

    //
    // ActionListener interface
    //
    public void actionPerformed(ActionEvent e) {
        Object source = e.getSource();
        if (source == miExit) {
            exit();
        } else if (e.getSource() == miNewAs) {
            newComponentAs();
            return;
        } else if (e.getSource() == bNew) {
            newComponent();
            return;
        } else if ((e.getSource() == miSave) || (e.getSource() == bSave)) {
            save();
            return;
        } else if (e.getSource() == miSaveAs) {
            saveAs();
            return;
        } else if (e.getSource() == miSaveAll) {
            saveAll();
            return;
        } else if (e.getSource() == miExport) {
            export();
            return;
        } else if ((e.getSource() == miOpen) || (e.getSource() == bOpen)) {
            if (!canOpen()) {
                return; // In fact, should not happen at this point
            }
            open();
            return;
        } else if (e.getSource() == miClose) {
            JComponent jc = desktopCardPanel.getSelectedComponent();
            if (jc == null) {
                return;
            }
            desktopCardPanel.removeComponent(jc);
        } else if (e.getSource() == miCloseAll) {
            desktopCardPanel.removeAllComponents();
        } else if ((e.getSource() == bUndo) || (e.getSource() == miUndo)) {
            undoAction.actionPerformed(e);
            desktopCardPanel.getSelectedComponent().repaint();
        } else if ((e.getSource() == bRedo) || (e.getSource() == miRedo)) {
            redoAction.actionPerformed(e);
            desktopCardPanel.getSelectedComponent().repaint();
        } else if (e.getSource() == bAdjust) {
            DiagramComponent d = getActiveDiagram();
            if (d != null) {
                d.adjust();
            }
            return;
        } else if (e.getSource() == bAlign) {
            DiagramComponent d = getActiveDiagram();
            if (d != null) {
                d.align();
            }
            return;
        } else if (e.getSource() == cbxGrid) {
            DiagramComponent d = getActiveDiagram();
            if (d == null) {
                return;
            }
            int value = 0;
            try {
                value = Long.decode((String) cbxGrid.getSelectedItem()).intValue();
            } catch (Exception eg) {
                value = 0;
            }
            d.setGrid(value);
            return;
        } else if (e.getSource() == tfZoom) {
            DiagramComponent d = getActiveDiagram();
            if (d == null) {
                return;
            }
            int value = 0;
            try {
                String zoomInt =  tfZoom.getText();
                if (zoomInt.endsWith("%")) {
                    zoomInt = zoomInt.substring(0, zoomInt.length() - 1);
                }
                value = Long.decode(zoomInt).intValue();
            } catch (Exception eg) {
                value = 100;
            }

            d.setZoom((double) value / 100.0);

            int zoomInt = (int)( d.getZoom() * 100) ;
            tfZoom.setText(zoomInt +  "%");
            return;

        } else if (e.getSource() == tbGridDisplay) {
            DiagramComponent d = getActiveDiagram();
            if (d == null) {
                return;
            }
            d.setGridDisplay(tbGridDisplay.isSelected());

        } else if (source == miSheetDisplay) {
            setupSheetDisplay();

        } else if ((source == miPrint) || (source == bPrint)) {
            print(getActiveDiagram());

        } else if ((source == miPrintImage) || (source == bPrintImage)) {
            if (!canPrint()) {
                return; // In fact, should not happen at this point
            }
            DiagramComponent d = getActiveDiagram();
            if (d == null) {
                return;
            }
            if (printImage == null) {
                printImage = new PrintToImage();
            }
            try {
                printImage.print(d, this.getActiveContainer().getDiagramParameters().backgr);
            } catch (Exception ex) {
                setStatus(messageWriter.print2args("cannotExport", d.toString(), ex.getMessage()));
                ex.printStackTrace();
            }
        } else if ((source == miSnapShot) || (source == bSnapShot)) {
            if (!canPrint()) {
                return; // In fact, should not happen at this point
            }
            DiagramComponent d = getActiveDiagram();
            if (d == null) {
                return;
            }
            try {
                ImageViewer imageViewer = new ImageViewer(getOwner(), resources.getString("snapshot"));
                imageViewer.setImage(getActiveDiagram(), this.getActiveContainer().getDiagramParameters().backgr);
                imageViewer.setLocation(getOwner().getLocation());
                imageViewer.setSize(desktopCardPanel.getWidth(), desktopCardPanel.getHeight());
                imageViewer.setVisible(true);
            } catch (Exception ex) {
                setStatus(messageWriter.print1args("printFailed", ex.getMessage()));
                ex.printStackTrace();
            }
        } else if (e.getSource() == miChooseLanguage) {
            DefaultListModel listModel = new DefaultListModel();
            int nlang = resources.getIntValue("languageNumber");
            String oldcode = Run.getProperties().getString("jsynoptic.language", "");
            int sel = -1;
            for (int i = 0; i < nlang; ++i) {
                listModel.addElement(resources.getStringValue("languageName" + i));
                if (resources.getStringValue("languageCode" + i).equals(oldcode)) {
                    sel = i;
                }
            }
            JList langlist = new JList(listModel);
            langlist.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
            if (sel != -1) {
                langlist.setSelectedIndex(sel);
            }
            int result = JOptionPane.showConfirmDialog(owner, langlist, resources.getString("chooseLanguageTitle"),
                    JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
            if ((result == JOptionPane.OK_OPTION) && (langlist.getSelectedIndex() != -1)) {
                String code = resources.getStringValue("languageCode" + langlist.getSelectedIndex());
                Run.getProperties().setString("jsynoptic.language", (code != null) ? code : "");
            }
        } else if (e.getSource() == miFindPlugins) {
            setStatus(messageWriter.print0args("lookingForPlugins"));
            new LongAction() {
                protected void doAction() {
                    if (PluginLookup.addPluginPaths(true, owner)) {
                        userProperties.setString("jsynoptic.class.path", PluginLookup.getClassPath());
                        Vector plugins = PluginLookup.lookup();
                        String[] plugs = new String[plugins.size()];
                        boolean[] checked = new boolean[plugins.size()];
                        for (int k = 0; k < plugins.size(); k++) {
                            plugs[k] = (String) plugins.get(k);
                            checked[k] = true;
                        }
                        boolean[] res = CheckBoxList.openDialog(messageWriter.print0args("foundPlugins"), owner, plugs,
                                checked);
                        if (res != null) {
                            String defaultPlugins = "";
                            for (int k = 0; k < plugins.size(); k++) {
                                if (res[k]) {
                                    if (!defaultPlugins.equals("")) {
                                        defaultPlugins += ",";
                                    }
                                    defaultPlugins += plugs[k];
                                }
                            }
                            if (!defaultPlugins.equals("")) {
                                userProperties.setString("jsynoptic.plugins", defaultPlugins);
                                JOptionPane.showMessageDialog(getOwner(),
                                        messageWriter.print0args("restartForPlugins"), messageWriter
                                        .print0args("Plugins:"), JOptionPane.INFORMATION_MESSAGE);
                            }
                        }
                    }
                }
            }.start();
            return;
        } else if (e.getSource() == miPreferencesPanel) {
            // Do always create a new instance of UPE, to have new contents, and
            // not
            // duplication of properties at each dialog call.
            propEditor = new UserPropertiesEditor(owner);
            setStaticProperties(userProperties);
            if (propEditor.showAndUpdate(userProperties, true, Run.productName)) {
                getStaticProperties(userProperties);
            }
            return;
        } else if (e.getSource() == miAbout) {
            if (aboutFrame == null) {
                aboutFrame = new JFrame(messageWriter.print1args("aboutTitle", Run.productName));
                String content = messageWriter.print0args("aboutContent");
                boolean pluginLineWritten = false;
                for (Iterator it = Run.plugins.iterator(); it.hasNext();) {
                    Plugin p = (Plugin) it.next();
                    String text = p.about();
                    if (text == null) {
                        continue;
                    }
                    if (!pluginLineWritten) {
                        content += "<p>" + messageWriter.print0args("Plugins:") + "<ul>";
                        pluginLineWritten = true;
                    }
                    content += "<li>" + p.about() + "</li>";
                }
                if (pluginLineWritten) {
                    content += "</ul></p>";
                }
                JEditorPane jdp = new JEditorPane("text/html", content);
                jdp.setEditable(false);
                aboutFrame.getContentPane().setLayout(new BoxLayout(aboutFrame.getContentPane(), BoxLayout.Y_AXIS));
                // Set Header
                JPanel header = new JPanel(new BorderLayout());
                header.setBackground(Color.WHITE);
                JLabel headerLogo = new JLabel(resources.getIcon("jsynIconHightResIcon"));
                headerLogo.setBackground(Color.WHITE);
                header.add(headerLogo, BorderLayout.WEST);
                JLabel hearderTitle = new JLabel(messageWriter.print1args("aboutVersion", Run.fullProductVersion));
                hearderTitle.setFont(new Font("Dialog", Font.PLAIN, 25));
                hearderTitle.setOpaque(true);
                hearderTitle.setBackground(Color.WHITE);
                header.add(hearderTitle, BorderLayout.EAST);
                aboutFrame.getContentPane().add(header);
                aboutFrame.getContentPane().add(jdp);
                aboutFrame.pack();
                aboutFrame.doLayout();
            }
            aboutFrame.setVisible(true);
            return;
        } else if (e.getSource() == miHelp) {
            if (helpFrame == null) {
                helpFrame = new HelpViewer(getOwner(), messageWriter.print0args("helpContentTitle"));
                helpFrame.setLocation(getOwner().getLocation());
                helpFrame.setSize(getOwner().getWidth(), getOwner().getHeight());
            }
            helpFrame.setVisible(true);
            return;
        } else if (e.getSource() == miSheetInformation) {
            if (!canPrint()) {
                return; // In fact, should not happen at this point
            }
            DiagramComponent d = getActiveDiagram();
            if (d == null) {
                return;
            }
            ShapesContainer c = getActiveContainer();
            if (c == null) {
                return;
            }
            try {
                // Create the sheet information document
                HTMLSheetInformation sid = new HTMLSheetInformation(c, d);
                // View the sheet information document
                HTMLSheetInformationViewer sidViewer = new HTMLSheetInformationViewer(getOwner(), sid);
                sidViewer.setLocation(getOwner().getLocation());
                sidViewer.setSize(desktopCardPanel.getWidth(), desktopCardPanel.getHeight());
                sidViewer.setVisible(true);
            } catch (Exception ex) {
                setStatus(messageWriter.print1args("sidFailed", ex.getMessage()));
                ex.printStackTrace();
            }
            return;


        } else if ((e.getSource() == miRefreshAllSheets) || (source == bRefreshAllSheets)) {
            refreshAllSheets();

        }
    }

    public void addLongActions(long actionMask, Object target) {
        if ((actionMask & LongAction.LONG_ACTION_FILE_OPEN) != 0) {
            lockFileOpen();
        }
        if ((actionMask & LongAction.LONG_ACTION_FILE_SAVE) != 0) {
            lockFileSave();
        }
        if ((actionMask & LongAction.LONG_ACTION_PRINT) != 0) {
            lockPrint();
        }
        if ((actionMask & LongAction.LONG_ACTION_SHAPE) != 0) {
            boolean changesDone = false;
            DiagramComponent d = getActiveDiagram();
            DiagramSelection sel = (d == null) ? null : d.getDiagramSelection();
            if (target != null) {
                if (target instanceof Shape) {
                    lockedShapes.add(target);
                    if ((sel != null) && sel.isSelected((Shape) target)) {
                        changesDone = true;
                    }
                } else if (target instanceof Vector) {
                    for (Iterator it = ((Vector) target).iterator(); it.hasNext();) {
                        Object o = it.next();
                        if (o instanceof Shape) {
                            lockedShapes.add(o);
                            if ((sel != null) && sel.isSelected((Shape) o)) {
                                changesDone = true;
                            }
                        }
                    }
                } else if (target instanceof Object[]) {
                    for (int i = 0; i < ((Object[]) target).length; ++i) {
                        Object o = ((Object[]) target)[i];
                        if (o instanceof Shape) {
                            lockedShapes.add(o);
                            if ((sel != null) && sel.isSelected((Shape) o)) {
                                changesDone = true;
                            }
                        }
                    }
                }
            }
            if (changesDone) {
                selectionChanged(sel);
            }
        }
        if ((actionMask & LongAction.LONG_ACTION_SOURCE) != 0) {
            if (target != null) {
                if ((target instanceof DataSource) || (target instanceof DataSourceCollection)) {
                    panes.getSourceTree().lock(target);
                } else if (target instanceof Vector) {
                    for (Iterator it = ((Vector) target).iterator(); it.hasNext();) {
                        Object o = it.next();
                        if ((o instanceof DataSource) || (o instanceof DataSourceCollection)) {
                            panes.getSourceTree().lock(o);
                        }
                    }
                } else if (target instanceof Object[]) {
                    for (int i = 0; i < ((Object[]) target).length; ++i) {
                        Object o = ((Object[]) target)[i];
                        if ((o instanceof DataSource) || (o instanceof DataSourceCollection)) {
                            panes.getSourceTree().lock(o);
                        }
                    }
                }
            }
        }
    }

    public void removeLongActions(long actionMask, Object target) {
        if ((actionMask & LongAction.LONG_ACTION_FILE_OPEN) != 0) {
            unlockFileOpen();
        }
        if ((actionMask & LongAction.LONG_ACTION_FILE_SAVE) != 0) {
            unlockFileSave();
        }
        if ((actionMask & LongAction.LONG_ACTION_PRINT) != 0) {
            unlockPrint();
        }
        if ((actionMask & LongAction.LONG_ACTION_SHAPE) != 0) {
            boolean changesDone = false;
            DiagramComponent d = getActiveDiagram();
            DiagramSelection sel = (d == null) ? null : d.getDiagramSelection();
            if (target != null) {
                if (target instanceof Shape) {
                    lockedShapes.remove(target);
                    if ((sel != null) && sel.isSelected((Shape) target)) {
                        changesDone = true;
                    }
                } else if (target instanceof Vector) {
                    for (Iterator it = ((Vector) target).iterator(); it.hasNext();) {
                        Object o = it.next();
                        if (o instanceof Shape) {
                            lockedShapes.remove(o);
                            if ((sel != null) && sel.isSelected((Shape) o)) {
                                changesDone = true;
                            }
                        }
                    }
                } else if (target instanceof Object[]) {
                    for (int i = 0; i < ((Object[]) target).length; ++i) {
                        Object o = ((Object[]) target)[i];
                        if (o instanceof Shape) {
                            lockedShapes.remove(o);
                            if ((sel != null) && sel.isSelected((Shape) o)) {
                                changesDone = true;
                            }
                        }
                    }
                }
            }
            if (changesDone) {
                selectionChanged(sel);
            }
        }
        if ((actionMask & LongAction.LONG_ACTION_SOURCE) != 0) {
            if (target != null) {
                if ((target instanceof DataSource) || (target instanceof DataSourceCollection)) {
                    panes.getSourceTree().unlock(target);
                } else if (target instanceof Vector) {
                    for (Iterator it = ((Vector) target).iterator(); it.hasNext();) {
                        Object o = it.next();
                        if ((o instanceof DataSource) || (o instanceof DataSourceCollection)) {
                            panes.getSourceTree().unlock(o);
                        }
                    }
                } else if (target instanceof Object[]) {
                    for (int i = 0; i < ((Object[]) target).length; ++i) {
                        Object o = ((Object[]) target)[i];
                        if ((o instanceof DataSource) || (o instanceof DataSourceCollection)) {
                            panes.getSourceTree().unlock(o);
                        }
                    }
                }
            }
        }
        container.setCursor(Cursor.getDefaultCursor());
    }

    /**
     * Changes the current path
     */
    public void setPath(File f) {
        CurrentPathProvider.currentPathProvider.setCurrentPath(f);
    }

    /**
     * Gets the current path
     */
    public File getPath() {
        return CurrentPathProvider.currentPathProvider.getCurrentPath();
    }

    public JFileChooser getFileChooser() {
        return openFileChooser;
    }

    public boolean getIsOpenProcessCancelled() {
        return isOpenProcessCancelled;
    }

    public void setIsOpenProcessCancelled(boolean b) {
        isOpenProcessCancelled = b;
    }

    public SourceTree getSourceTree() {
        return panes.getSourceTree();
    }

    public AbstractList getSelectionList() {
        return panes.getSelectionList();
    }

    public AbstractList getLockedShapes() {
        return lockedShapes;
    }

    /*
     * (non-Javadoc)
     *
     * @see jsynoptic.ui.JSynopticInterface#setStatus(java.lang.String)
     */
    public void setStatus(String message) {
        if (status == null) {
            return;
        }
        if (message == null) {
            message = "";
        }
        if (cleanStatusTask != null) {
            cleanStatusTask.cancel();
        }
        status.setText(message);
        cleanStatusTask = new TimerTask() {
            public void run() {
                status.setText("");
                cleanStatusTask.cancel();
                cleanStatusTask = null;
            }
        };
        cleanStatusTimer.schedule(cleanStatusTask, statusDelay);
    }

    /**
     * Update the actions associated to the Undo/Redo buttons. Typically called
     * when the active document changes.
     */
    protected void updateUndoActions() {
        ShapesContainer.ShapesComponent sc = (ShapesContainer.ShapesComponent) desktopCardPanel.getSelectedComponent();
        if (sc != null) {
            undoAction = sc.getUndoHandler().getUndoAction();
            redoAction = sc.getUndoHandler().getRedoAction();
            // Check if this component is already in the listener list
            // for the actions; a bit dirty but it fits with the rest
            PropertyChangeListener[] listeners = undoAction.getPropertyChangeListeners();
            boolean ok = false;
            for (int i = undoAction.getPropertyChangeListeners().length; (i > 0) && !ok; i--) {
                ok = (listeners[i - 1] == this);
            }
            if (!ok) {
                undoAction.addPropertyChangeListener(this);
            }
            listeners = redoAction.getPropertyChangeListeners();
            ok = false;
            for (int i = listeners.length; (i > 0) && !ok; i--) {
                ok = (listeners[i - 1] == this);
            }
            if (!ok) {
                redoAction.addPropertyChangeListener(this);
            }
        } else {
            // No active document --> invalidate actions
            undoAction = null;
            redoAction = null;
        }
        updateUndoEnabled();
        container.repaint();
    }

    /*
     * (non-Javadoc)
     *
     * @see java.beans.PropertyChangeListener#propertyChange(java.beans.PropertyChangeEvent)
     */
    public void propertyChange(PropertyChangeEvent evt) {
        updateUndoEnabled();
    }

    protected void updateUndoEnabled() {
        if (toolbar != null) {// ensure that toolbar was created
            if ((undoAction != null) && (redoAction != null)) {
                bUndo.setEnabled(undoAction.isEnabled());
                miUndo.setEnabled(undoAction.isEnabled());
                bRedo.setEnabled(redoAction.isEnabled());
                miRedo.setEnabled(redoAction.isEnabled());
            } else {
                bUndo.setEnabled(false);
                miUndo.setEnabled(false);
                bRedo.setEnabled(false);
                miRedo.setEnabled(false);
            }
        }
    }

    protected class FileChooserAccessory extends JPanel implements PropertyChangeListener {

        protected int action;
        public FileChooserAccessory(int action) {

            this.action = action;

            if (action == Plugin.OPEN) {
                openFileChooser.addPropertyChangeListener(JFileChooser.FILE_FILTER_CHANGED_PROPERTY, this);

            } else if (action == Plugin.SAVE) {
                saveFileChooser.addPropertyChangeListener(JFileChooser.FILE_FILTER_CHANGED_PROPERTY, this);

            } else if (action == Plugin.EXPORT) {
                exportFileChooser.addPropertyChangeListener(JFileChooser.FILE_FILTER_CHANGED_PROPERTY, this);
            }
        }

        public void propertyChange(PropertyChangeEvent e) {
            // Monitor file filter selection
            if (JFileChooser.FILE_FILTER_CHANGED_PROPERTY.equals(e.getPropertyName())) {
                updateFileChooserAccessory();

            }
        }

        public void updateFileChooserAccessory(){
            removeAll();

            FileFilter filter = null;
            if (action == Plugin.OPEN) {
                filter =  openFileChooser.getFileFilter();

            } else if (action == Plugin.SAVE) {
                filter =  saveFileChooser.getFileFilter();

            } else if (action == Plugin.EXPORT) {
                filter =  exportFileChooser.getFileFilter();
            }

            Plugin p = getPluginForFilter(action, filter);
            if (p != null) {
                JComponent j = p.getOptionPanelForFilter(filter);
                if (j != null) {
                    add(j);
                    j.setVisible(true);
                }
            }
            revalidate();
        }
    }

    /**
     * This TransferHanlder check for files drag and drop. It permits to open
     * files that are draged from OS's location, such as Navigator.
     *
     * @author zxpletran007
     *
     */
    protected class JSynopticFileTransfertHandler extends TransferHandler {
        public JSynopticFileTransfertHandler() {
            super();
        }

        /*
         * (non-Javadoc)
         *
         * @see javax.swing.TransferHandler#canImport(javax.swing.JComponent,
         *      java.awt.datatransfer.DataFlavor[])
         */
        public boolean canImport(JComponent comp, DataFlavor[] transferFlavors) {
            // Check import available.
            // The result of the method.
            boolean result = false;
            // Parse the array.
            for (int i = 0; i < transferFlavors.length; i++) {
                // retrieve current element.
                DataFlavor dataFlavor = transferFlavors[i];
                // We could only import FileList flavor.
                // Which are files to be opened by Sears.
                if (dataFlavor.isFlavorJavaFileListType()) {
                    result = true;
                }
            }
            // return the result.
            return result;
        }

        /*
         * (non-Javadoc)
         *
         * @see javax.swing.TransferHandler#importData(javax.swing.JComponent,
         *      java.awt.datatransfer.Transferable)
         */
        public boolean importData(JComponent comp, Transferable t) {
            // the result of the method.
            boolean result = true;
            try {
                Object list = t.getTransferData(DataFlavor.javaFileListFlavor);
                if ((list instanceof List) && (((List) list).size() > 0)) {
                    Iterator it = ((List) list).iterator();
                    while (it.hasNext()) {
                        result &= JSynopticPanels.this.open((File) it.next());
                    }
                    return result;
                }
            } catch (UnsupportedFlavorException exception) {
                // TODO Auto-generated catch block
                exception.printStackTrace();
            } catch (IOException exception) {
                // TODO Auto-generated catch block
                exception.printStackTrace();
            }
            return false;
        }
    }

    public TemplateChooser getTemplateChooser() {
        return templateChooser;
    }

    /**
     *
     * TODO
     * @author zxpletran007
     *
     */
    public class ShapesToolBar extends JToolBar{

        ButtonGroup group = new ButtonGroup();
        List shapeButtons;
       
        /** The current selected shape creator. Null if the arrow button is selected  */
        ShapeCreator currentShapeCreator;

        public ShapesToolBar(){
            group = new ButtonGroup();
            shapeButtons = new ArrayList();
           
            currentShapeCreator = null;
            setFloatable(false);
           
            // Add arrow button
            ArrowButton ar = new ArrowButton();
            add(ar);
            group.add(ar);
            shapeButtons.add(ar);
        }

        public void addShapeCreatorButton(ShapeCreator sc){
            ShapeCreatorButton scb = new ShapeCreatorButton(sc);
            add(scb);
            group.add(scb);
            shapeButtons.add(scb);
        }

        public void setEnabled(boolean enabled){
            super.setEnabled(enabled);
            for(int i=0; i<shapeButtons.size(); i++){
               ((JComponent) shapeButtons.get(i)).setEnabled(enabled);
            }
        }
       
        public ShapeCreator getCurrentShapeCreateCreator(){
            return currentShapeCreator;
        }
       
       
        private void setCurrentShapeCreateCreator(ShapeCreator currentShapeCreator){
            this.currentShapeCreator = currentShapeCreator;
            ShapesComponent sc = getActiveComponent();
            if (sc != null){
                sc.setElementCreator(currentShapeCreator);
            }
        }

        public class ArrowButton extends JToggleButton{

            public ArrowButton(){
                super(resources.getIcon("ArrowIcon"), true);
                addActionListener(new ActionListener(){
                    public void actionPerformed(ActionEvent e) {
                        setCurrentShapeCreateCreator(null);
                    }
                });
            }
        }
       
        public class ShapeCreatorButton extends JToggleButton{

            protected ShapeCreator shapeCreator;

            public ShapeCreatorButton(ShapeCreator shapeCreator){
                this(shapeCreator, false);
            }

            public ShapeCreatorButton(ShapeCreator shapeCreator, boolean isSelected){
                super(shapeCreator.shapeIcon, isSelected);
                this.shapeCreator = shapeCreator;
                setToolTipText(shapeCreator.shape);

                addActionListener(new ActionListener(){
                    public void actionPerformed(ActionEvent e) {
                        setCurrentShapeCreateCreator(isSelected()? ShapeCreatorButton.this.shapeCreator : null);
                    }
                });
            }
        }
    }
}
TOP

Related Classes of jsynoptic.ui.JSynopticPanels

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.