Logo Search packages:      
Sourcecode: latexdraw version File versions  Download package

DrawContainer.java

package latexDraw.ui;

import java.awt.*;
import java.awt.event.InputEvent;
import java.awt.event.MouseEvent;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.Locale;
import java.util.Vector;

import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.plugins.bmp.BMPImageWriteParam;
import javax.imageio.plugins.jpeg.JPEGImageWriteParam;
import javax.imageio.stream.ImageOutputStream;
import javax.swing.JComponent;
import javax.swing.JViewport;
import javax.swing.Scrollable;
import javax.swing.SwingConstants;

import latexDraw.figures.*;
import latexDraw.figures.properties.Arrowable;
import latexDraw.parsers.svg.SVGAttributes;
import latexDraw.parsers.svg.SVGDocument;
import latexDraw.parsers.svg.SVGElements;
import latexDraw.parsers.svg.elements.SVGMetadataElement;
import latexDraw.psTricks.DviPsColors;
import latexDraw.ui.components.MagneticGrid;
import latexDraw.ui.components.XScale;
import latexDraw.ui.dialog.ExceptionFrameDialog;
import latexDraw.util.LaTeXDrawException;
import latexDraw.util.LaTeXDrawNamespace;
import latexDraw.util.LaTeXDrawPoint2D;
import latexDraw.util.UndoRedoManager;
import net.sourceforge.jiu.codecs.CodecMode;
import net.sourceforge.jiu.codecs.PNMCodec;
import net.sourceforge.jiu.gui.awt.BufferedRGB24Image;

import org.sourceforge.jlibeps.epsgraphics.EpsGraphics2D;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 * This file is part of LaTeXDraw<br>
 * Copyright (c) 2005-2008 Arnaud BLOUIN<br>
 *<br>
 *  LaTeXDraw is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.<br>
 *<br>
 *  LaTeXDraw is distributed without any warranty; without even the 
 *  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
 *  PURPOSE.  See the GNU General Public License for more details.<br>
 *<br>
 * 01/20/06<br>
 * @author Arnaud BLOUIN<br>
 * @version 2.0.0<br>
 */
00073 public final class DrawContainer extends JComponent implements Scrollable, Printable
{
      private static final long serialVersionUID = 1L;

      /** Correspond to the figures of the drawing */
00078       private Vector<Figure> figures;
      
      /** The parent of the DrawContainer (a @see DrawPanel) */
00081       private transient DrawPanel parentPanel;
      
      /** Allow to adjust (and to see) the complete borders of the drawing.<br>
       * @see #bordersReal for more informations */
00085       private DrawBorders bordersComplete;
      
      /** Define the real borders of the drawing: <br>
       * It's different from @see bordersComplete because bordersComplete considers the thickness,
       * the double borders, ... of the figures ; whereas bordersReal just consider the coordinates
       * of the figures (Useful for the code generation, because bordersComplete is not adapted for that.
       */
00092       private DrawBorders bordersReal;
      
      /** Allow to know if the user want or not to display to borders of the drawing */
00095       private boolean drawBorders;

      /** Correspond to the @see Figure selected by the user */
00098       private Draw selected;
      
      /** Allows to know if the user want to adjust automatically the borders
       * of the drawing */
00102       private boolean autoAdjustement;
      
      /** Allows to know if the menu "selection" is selected */
00105       private boolean inSelection;
      
      /** Corresponds to the number of pixels per centimetre */
00108       private int pixelsPerCm;
      
      /** The unit used to measure the number of pixels per cm */
00111       private String unitForPixelsPerCm;

      /** Allows to know if the drawing has been modified */
00114       private boolean isModified;
      
      /** The value of the antialiasing (cf. RenderingHints.VALUE_ANTIALIAS_ON/OFF) */
00117       private transient Object antiAliasingValue;
      
      /** The value of the rendering (cf. RenderingHints.VALUE_RENDER_QUALITY/SPEED) */
00120       private transient Object renderingValue;
      
      /** The value of the colour rendering (cf. RenderingHints.VALUE_COLOR_RENDER_QUALITY/SPEED) */
00123       private transient Object colorRenderingValue;
      
      /** The value of the alpha-interpolation ( cf. RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY/SPEED */
00126       private transient Object alphaInterpolValue;
      
      /** The value by default of the anti-aliasing */
00129       public static final Object DEFAULT_ANTIALIASING_VAL = RenderingHints.VALUE_ANTIALIAS_ON;
      
      /** The value by default of the rendering */
00132       public static final Object DEFAULT_RENDERING_VAL    = RenderingHints.VALUE_RENDER_QUALITY;
      
      /** The value by default of the colour rendering */
00135       public static final Object DEFAULT_COLORRENDER_VAL  = RenderingHints.VALUE_COLOR_RENDER_QUALITY;
      
      /** The value by default of the alpha-interpolation */
00138       public static final Object DEFAULT_ALPHAINTER_VAL   = RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY;
      
      /** The value we add to the zoom when to user click on a zoom button */
00141       public static final double DEFAULT_ADD_ZOOM = 0.25;
      
      /** The number by default of pixels per cm */
00144       public static final int DEFAULT_PIXPERCM = 50;
      
      /** The zoom by default (100%) */
00147       public static final double DEFAULT_ZOOM = 1.;
      
      /** The biggest zoom we can do */
00150       public static final double MAX_ZOOM = 4.5;
      
      /** The smallest zoom we can do */
00153       public static final double MIN_ZOOM = 0.25;     
      
      /** Corresponds to a possible value of whichCodeOutput attribute. @since 2.0.0 */
00156       public static final short CODE_PSTRICKS = 0;
         
    /** Contains to figure copied or cut */
00159     protected Draw copiedFigure;
      
      /** The zoom : MIN_ZOOM<=zoom<=MAX_ZOOM */
00162       private double zoom;
      
      /** Define if the figure must be rotated. */
00165       private boolean onRotation;
      
      /** Define the code that will be generated. @since 2.0.0 */
00168       protected short whichCodeOutput;
      
      /** The grid of the panel. @since 2.0.0 */
00171       protected MagneticGrid grid;
      
      
      /**
       * The constructor by default.
       */
00177       public DrawContainer()
      {
            this(false);
      }
      
      
      
      
      /**
       * The constructor by default.
       * @param displayBorders Allow to know if the borders of the drawing.
       * must be displayed
       */
00190       public DrawContainer(boolean displayBorders)
      {
            setWhichCodeOutput(CODE_PSTRICKS);
            onRotation = false;
            zoom = DEFAULT_ZOOM;
            drawBorders = displayBorders;
            selected = new Draw(false, false);
            figures = new Vector<Figure>();
            pixelsPerCm = DEFAULT_PIXPERCM;
            inSelection = true;
            setIsModified(false);
            renderingValue      = DEFAULT_RENDERING_VAL;
            alphaInterpolValue  = DEFAULT_ALPHAINTER_VAL;
            colorRenderingValue = DEFAULT_COLORRENDER_VAL;
            antiAliasingValue   = DEFAULT_ANTIALIASING_VAL;
            setDoubleBuffered(true);
            
            grid = new MagneticGrid(getWidth(), getHeight(), pixelsPerCm, zoom);
      }
      
      
      
      
      /**
       * Allows to delete a given figure of the drawing
       * @param f The figure to remove
       */
00217       public void deleteFigure(Figure f, UndoRedoManager manager)
      {
            if(f!=null && figures.contains(f))
            {
                  if(manager!=null)
                        manager.add(UndoRedoManager.LABEL_DEL, figures.indexOf(f), f);
                  
                  figures.remove(f);
                  selected.removeFigure(f);
                  parentPanel.updateDraw(true);
            }
      }
      
      
      
      
      /**
       * Allows to set if figures must be in rotation or not
       * @param on True : the figures must be in rotation   
       */
00237       public void setOnRotation(boolean on)
      {
            onRotation = on;
            if(!selected.isEmpty())
            {
                  selected.setOnRotation(on);
                  repaint();
            }
      }
      
      
      
      
      /**
       * Allows to know if figures are in rotation or not
       * @return True : figures are in rotation
       */
00254       public boolean isOnRotation()
      {
            return onRotation;
      }
      
      
      
      /**
       * Allows to know if a a figure is selected
       * @return True if a figure is selected
       */
00265       public boolean isAFigureSelected()
      {
            return !selected.isEmpty();
      }
      
      
      
      /**
       * Allows to get the vector containing the figures
       * @return The vector containing the figures
       */
00276       public Vector<Figure> getFigures()
      {
            return figures;
      }
      
      
      
      
      /**
       * Allows to put some figures f1 behind the figure f2
       * @param f1 The drawing to put behind f2
       * @param f2 The figure to put in front of f1
       */
00289       public void putBehind(Draw f1, Figure f2)
      {
            if(f1==f2 || f1==null || f2==null || f1.isEmpty())
                  return ;
            
            try
            {
                  int i, size = f1.size();
                  int[] oldId = new int[size], id = new int[size];
                  Figure f;

                  for(i=size-1; i>=0; i--)
                  {
                        f = f1.getFigureAt(i);
                        oldId[i] = figures.indexOf(f);
                        putBehind(f, f2);
                        id[i] = figures.indexOf(f);
                  }
                  
                  UndoRedoManager manager = parentPanel.getFrameParent().getUndoManager();
                  manager.add(UndoRedoManager.LABEL_CHANGE_DISPOSITION, id, oldId, false);
                  parentPanel.getFrameParent().updateUndoRedo();
            }catch(Exception e)
            {
                  e.printStackTrace(); 
                  ExceptionFrameDialog.showExceptionDialog(e);
            }
      }
      
      
      
      
      /**
       * Allows to put the figure f1 behind the figure f2
       * @param f1 The figure to put behind f2
       * @param f2 The figure to put in front of f1
       */
00326       public void putBehind(Figure f1, Figure f2)
      {
            if(f1==f2 || f1==null || f2==null) 
                  return;
            
            try
            {
                  if(!figures.contains(f1) || !figures.contains(f2))
                        throw new IllegalArgumentException();

                  int id1 = figures.indexOf(f1), id2 = figures.indexOf(f2);
                  
                  if(id1>=id2)
                  {
                        figures.remove(f1);
                        figures.add(id2, f1);
                        
                        repaint();
                  }
                  
            }catch(Exception e)
            {
                  e.printStackTrace();
                  ExceptionFrameDialog.showExceptionDialog(e);
            }
      }
      
      
      
      /**
       * Allows to put some figures f1 in front of the figure f2
       * @param f1 The drawing to put in front of f2
       * @param f2 The figure to put behind f1
       */
00360       public void putInFrontOf(Draw f1, Figure f2)
      {
            if(f1==f2 || f1==null || f2==null || f1.isEmpty())
                  return ;
            
            try
            {
                  int i, size = f1.size();
                  int[] oldId = new int[size], id = new int[size];
                  
                  for(i=0; i<size; i++)
                        oldId[i] = figures.indexOf(f1.getFigureAt(i));
                  
                  for(i=0; i<size; i++)
                        putBehind(f2, f1.getFigureAt(i));
                  
                  for(i=0; i<size; i++)
                        id[i] = figures.indexOf(f1.getFigureAt(i));
            

                  UndoRedoManager manager = parentPanel.getFrameParent().getUndoManager();
                  manager.add(UndoRedoManager.LABEL_CHANGE_DISPOSITION, id, oldId, false);
                  parentPanel.getFrameParent().updateUndoRedo();
            }
            catch(Exception e)
            {
                  e.printStackTrace(); 
                  ExceptionFrameDialog.showExceptionDialog(e);
            }
      }
      
      
      
      
      /**
       * Allows to put the selected figure in the background
       */
00397       public void selectedInBackground()
      {
            try
            {
                  if(selected!=null && !selected.isEmpty()) 
                  {
                        int i, size = selected.size();
                        int[] oldId = new int[size], id = new int[size];
                        
                        for(i=size-1; i>=0; i--)
                        {
                              Figure f = selected.getFigureAt(i);
                              if(figures.contains(f))
                              {
                                    oldId[i] = figures.indexOf(f);
                                    figures.remove(f);
                                    figures.add(0, f);
                                    id[i] = 0;
                                    repaint();
                              }
                              else throw new LaTeXDrawException(LaTeXDrawException.INCORRECT_VALUE);
                        }
                        
                        UndoRedoManager manager = parentPanel.getFrameParent().getUndoManager();
                        manager.add(UndoRedoManager.LABEL_CHANGE_DISPOSITION, id, oldId, false);
                        parentPanel.getFrameParent().updateUndoRedo();
                  }
            }
            catch(Exception e)
            {
                  e.printStackTrace(); 
                  ExceptionFrameDialog.showExceptionDialog(e);
            }
      }
      
      
      
      /**
       * Allows to put the selected figure in the foreground
       */
00437       public void selectedInForeground()
      {
            try
            {
                  if(selected!=null && !selected.isEmpty()) 
                  {
                        int i, size = selected.size();
                        int[] oldId = new int[size], id = new int[size];
                        
                        for(i=0; i<size; i++)
                        {
                              Figure f = selected.getFigureAt(i);
                              if(figures.contains(f))
                              {
                                    oldId[i] = figures.indexOf(f);
                                    figures.remove(f);
                                    figures.add(f);
                                    repaint();
                                    id[i] = figures.indexOf(f);
                              }
                              else throw new LaTeXDrawException(LaTeXDrawException.INCORRECT_VALUE);
                              
                              UndoRedoManager manager = parentPanel.getFrameParent().getUndoManager();
                              manager.add(UndoRedoManager.LABEL_CHANGE_DISPOSITION, id, oldId, false);
                              parentPanel.getFrameParent().updateUndoRedo();
                        }
                  }
            }
            catch(Exception e)
            {
                  e.printStackTrace(); 
                  ExceptionFrameDialog.showExceptionDialog(e);
            }
      }
      
      
      
      
      /**
       * Allows to zoom in the drawing (up to 450%)
       */
00478       public void zoomIn()
      {
            if(zoom+DEFAULT_ADD_ZOOM<=MAX_ZOOM)
            {
                  zoom+=DEFAULT_ADD_ZOOM;
                  grid.setZoom(zoom);
                  updatePreferredSize();
                  repaint();
                  revalidate();
                  setIsModified(true);
            }
      }
      
      
      
      
      /**
       * Set the zoom.
       * @param z The new zoom.
       */
00498       public void setZoom(double z)
      {
            if(z<=MAX_ZOOM && z>=MIN_ZOOM)
            {
                  zoom=z;
                  grid.setZoom(z);
                  repaint();
                  updatePreferredSize();
                  revalidate();
                  setIsModified(true);
            }
      }
      
      
      
      
      /**
       * Allows to zoom out the drawing (up to 25%).
       */
00517       public void zoomOut()
      {
            if(zoom-DEFAULT_ADD_ZOOM>=MIN_ZOOM)
            {
                  zoom-=DEFAULT_ADD_ZOOM;
                  grid.setZoom(zoom);
                  repaint();
                  updatePreferredSize();
                  revalidate();
                  setIsModified(true);
            }
      }
      
      
      
      
      
      /**
       * Allows to set the zoom to default.
       */
00537       public void zoomDefault()
      {
            if(zoom!=DEFAULT_ZOOM)
            {
                  zoom = DEFAULT_ZOOM;
                  grid.setZoom(zoom);
                  repaint();
                  updatePreferredSize();
                  revalidate();
                  setIsModified(true);
            }
      }
      
      
      
      
      /**
       * Allows to get the current zoom.
       * @return The zoom.
       */
00557       public double getZoom()
      {
            return zoom;
      }
      
      
      
      /**
       * Allows to set the value of the anti-aliasing by default.
       */
00567       public void setAntiAliasByDefault()
      {
            antiAliasingValue = DEFAULT_ANTIALIASING_VAL;
      }
      

      
      /**
       * Allows to set the value of the colour rendering by default.
       */
00577       public void setRenderingcolorByDefault()
      {
            colorRenderingValue = DEFAULT_COLORRENDER_VAL;
      }
      
      
      
      /**
       * Allows to set the value of the rendering by default.
       */
00587       public void setRenderingByDefault()
      {
            renderingValue = DEFAULT_RENDERING_VAL;
      }
      
      
      
      
      /**
       * Allows to set the value of the alpha interpolation by default.
       */
00598       public void setAlphaInterByDefault()
      {
            alphaInterpolValue = DEFAULT_ALPHAINTER_VAL;
      }
      
      
      
      
      /**
       * Allows to set the value of the anti-aliasing value
       * @param useAntiAlias True : anti-aliasing must be used
       */
00610       public void setAntiAliasingValue(boolean useAntiAlias)
      {
            if(useAntiAlias)
                    antiAliasingValue = RenderingHints.VALUE_ANTIALIAS_ON;
            else  antiAliasingValue = RenderingHints.VALUE_ANTIALIAS_OFF;
      }
      
      
      
      /**
       * Allows to set the value of the colour rendering value
       * @param useRenderCol True : colour rendering must be of quality
       */
00623       public void setRenderingcolorValue(boolean useRenderCol)
      {
            if(useRenderCol)
                    colorRenderingValue = RenderingHints.VALUE_COLOR_RENDER_QUALITY;
            else  colorRenderingValue = RenderingHints.VALUE_COLOR_RENDER_SPEED;
      }
      
      
      
      /**
       * Allows to set the value of the rendering value
       * @param useRender True : rendering must be of quality
       */
00636       public void setRenderingValue(boolean useRender)
      {
            if(useRender)
                    renderingValue = RenderingHints.VALUE_RENDER_QUALITY;
            else  renderingValue = RenderingHints.VALUE_RENDER_SPEED;
      }
      
      
      
      /**
       * Allows to set the value of the anti-aliasing value
       * @param useAlphaInter True : anti-aliasing must be used
       */
00649       public void setAlphaInterValue(boolean useAlphaInter)
      {
            if(useAlphaInter)
                    alphaInterpolValue = RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY;
            else  alphaInterpolValue = RenderingHints.VALUE_ALPHA_INTERPOLATION_SPEED;
      }
      
      
      
      
      /**
       * Allows to get the anti-aliasing value
       * @return The anti-aliasing value
       */
00663       public Object getAntiAliasingValue()
      {
            return antiAliasingValue;
      }
      
      
      
      /**
       * Allows to get the alpha-interpolation value
       * @return The alpha-interpolation value
       */
00674       public Object getAlphaInterValue()
      {
            return alphaInterpolValue;
      }
      
      
      
      /**
       * Allows to get the colour rendering value
       * @return The colour rendering value
       */
00685       public Object getColorRenderValue()
      {
            return colorRenderingValue;
      }
      
      
      /**
       * Allows to get the rendering value
       * @return The rendering value
       */
00695       public Object getRenderingValue()
      {
            return renderingValue;
      }
      
      
      
      /**
       * Allows to add a figure to the vector of figures
       * @param f The figure to add
       */
00706       public void addFigure(Figure f, UndoRedoManager manager) 
      {
            if(figures.add(f))
                  setIsModified(true);
            
            if(manager!=null)
                  manager.add(UndoRedoManager.LABEL_CREATE, figures.size()-1, null);
      }

      

      /**
       * Allows to copy a drawContainer is the current drawContainer
       * @param draw The drawContainer to copy
       */
00721       public void copy(DrawContainer draw)
      {
            try
            {
                  if(figures!=null)
                        figures.clear();
                  
                  figures = draw.figures;
                  for(int i=0, size=figures.size(); i<size; i++)
                        figures.elementAt(i).setSelected(false);
                  
                  pixelsPerCm     = draw.pixelsPerCm;
                  selected        = draw.selected;
                  autoAdjustement = draw.autoAdjustement;
                  inSelection     = draw.inSelection;

                  if(draw.bordersComplete!=null)
                  {
                        bordersComplete = (DrawBorders) draw.bordersComplete.clone();
                        bordersComplete.setSelected(!draw.autoAdjustement && draw.inSelection);
                  }
                  if(draw.bordersReal!=null)
                        bordersReal = (DrawBorders)draw.bordersReal.clone();
                  
                  setZoom(draw.zoom);
                  
            }catch(Exception e)
            {
                  e.printStackTrace(); 
                  ExceptionFrameDialog.showExceptionDialog(e);
            }
      }
      
      
      
      
      public void newDrawing()
      {
            figures.clear();
            pixelsPerCm = 50;
            selected    = new Draw(false, false);
            inSelection = true;
            setIsModified(false);
            onRotation = false;
            bordersComplete = null;
            bordersReal = null;
            grid.reInitGrid();
            setZoom(DEFAULT_ZOOM);
      }
      

      
      public void defineSelected(LaTeXDrawRectangle bound, boolean isShiftOn, boolean isCtrlOn)
      {
            if(bound==null)
                  return ;
            
            Rectangle2D.Double r = (Rectangle2D.Double)bound.createShape2D();
            
            if((!isShiftOn && !isCtrlOn) || (isShiftOn && isCtrlOn))
            {
                  selected.onRelease();
                  selected = new Draw(false, false);

                        for(Figure f : figures)
                              if(f!=null && f.intersected(r))
                                    selected.addFigure(f);
            }
            else
                  if(isCtrlOn)
                  {
                        for(Figure f : figures)
                              if(f!=null && f.intersected(r) && !selected.contains(f))
                                    selected.addFigure(f);
                  
                        if(selected.size()>1)
                              selected.getFigureAt(0).setSelected(false);
                  }
                  else
                        for(Figure f : figures)
                              if(f!=null && f.intersected(r) && selected.contains(f))
                              {
                                    f.setSelected(false);
                                    selected.removeFigure(f);
                              }
            
            selected.setSelected(true);
            selected.setOnRotation(isOnRotation());
      }
      
      
      
      /**
       * Defines the borders of the drawing.
       */
00816       public void updateBorders()
      {
            int i, size = figures.size();
            Figure f;

            try
            {
                  if(size>0)
                  {
                        f = figures.firstElement();                     
                        
                        // We must define the entire borders (considering the double boundary, the thickness,...)
                        // and the real borders (consider only the real coordinates of the figures).
                        LaTeXDrawPoint2D NWpt = f.getTheNWBoundPoint();
                        LaTeXDrawPoint2D SEpt = f.getTheSEBoundPoint();
                        LaTeXDrawPoint2D NWptReal = (LaTeXDrawPoint2D)f.getTheNWRotatedPoint().clone();
                        LaTeXDrawPoint2D SEptReal = (LaTeXDrawPoint2D)f.getTheSERotatedPoint().clone();
                        
                        for(i=1; i<size; i++)
                        {
                              f = figures.elementAt(i);
                              LaTeXDrawPoint2D curNWpt = f.getTheNWBoundPoint();
                              LaTeXDrawPoint2D curSEpt = f.getTheSEBoundPoint();
                              LaTeXDrawPoint2D curNWptReal = f.getTheNWRotatedPoint();
                              LaTeXDrawPoint2D curSEptReal = f.getTheSERotatedPoint();
                              
                              if(curNWpt.x<NWpt.x) 
                                    NWpt.x = curNWpt.x;
                              if(curNWpt.y<NWpt.y) 
                                    NWpt.y = curNWpt.y;
                              if(curSEpt.x>SEpt.x) 
                                    SEpt.x = curSEpt.x;
                              if(curSEpt.y>SEpt.y) 
                                    SEpt.y = curSEpt.y;
                              
                              if(curNWptReal.x<NWptReal.x) 
                                    NWptReal.x = curNWptReal.x;
                              if(curNWptReal.y<NWptReal.y) 
                                    NWptReal.y = curNWptReal.y;
                              if(curSEptReal.x>SEptReal.x) 
                                    SEptReal.x = curSEptReal.x;
                              if(curSEptReal.y>SEptReal.y) 
                                    SEptReal.y = curSEptReal.y;
                        }
                        
                        if(bordersReal==null)
                              bordersReal = new DrawBorders(NWptReal, SEptReal, true, false, false);
                        else
                        {
                              bordersReal.setFirstPoint(NWptReal);
                              bordersReal.setLastPoint(SEptReal);
                        }
                              
                        if(bordersComplete==null)
                        { 
                              bordersComplete = new DrawBorders(NWpt, SEpt, autoAdjustement, inSelection, false);
                              boolean state = parentPanel.getFrameParent().isAutoAdjustBorders();
                              bordersComplete.setSelected(!state && inSelection);
                              autoAdjustement = state;
                        }
                        else 
                        {
                              LaTeXDrawPoint2D NW = bordersComplete.getTheNWPoint();
                              LaTeXDrawPoint2D SE = bordersComplete.getTheSEPoint();
                              
                              if(!autoAdjustement)
                              {
                                    if(NW.x>NWpt.x)
                                          if(NW.y>NWpt.y)
                                                 bordersComplete.setFirstPoint(NWpt);
                                          else bordersComplete.setFirstPoint(new LaTeXDrawPoint2D(NWpt.x, NW.y));
                                    else
                                          if(NW.y>NWpt.y)
                                                bordersComplete.setFirstPoint(new LaTeXDrawPoint2D(NW.x, NWpt.y));      
                                    if(SE.x<SEpt.x)
                                          if(SE.y<SEpt.y)
                                                bordersComplete.setLastPoint(SEpt);
                                          else bordersComplete.setLastPoint(new LaTeXDrawPoint2D(SEpt.x, SE.y));
                                    else
                                          if(SE.y<SEpt.y)
                                                bordersComplete.setLastPoint(new LaTeXDrawPoint2D(SE.x, SEpt.y));                   
                        
                              } // if(!autoAdjustement)
                              else
                              {
                                    bordersComplete.setFirstPoint(NWpt);
                                    bordersComplete.setLastPoint(SEpt);
                              }
                        } // else if(borders==null)*/
                  } // if(size>0)
                  else
                  {
                        if(bordersComplete!=null)
                        {
                              bordersComplete.setFirstPoint(0, 0);
                              bordersComplete.setLastPoint(0, 0);
                        }
                        
                        if(bordersReal!=null)
                        {
                              bordersReal.setFirstPoint(0, 0);
                              bordersReal.setLastPoint(0, 0);
                        }
                  }
            
            }catch(Exception e) { e.printStackTrace(); }
      }


      /**
       * This method allows the user to delete the selected figure
       */
00928       public void deleteSelection(UndoRedoManager manager)
      {
            if(figures!=null && !selected.isEmpty())
            {
                  int i, size = selected.size();
                  int[] id = new int[size];
                  
                  for(i=0; i<size; i++)
                        id[i] = figures.indexOf(selected.getFigureAt(i));
                        
                  for(i=0; i<size;i++)
                  {
                        Figure f = selected.getFigureAt(i);
                        figures.remove(f);
                  }

                  manager.add(UndoRedoManager.LABEL_DEL, id, selected, false);

                  selected = new Draw(false, false);
                  selected.setOnRotation(isOnRotation());
                  setIsModified(true);
            }
                  
      }

      
      

      /**
       * Allow the display or to hide the borders of the drawing
       * @param display Allow to know if the user want to display the borders
       * of the drawing
       */
00961       public void displayBorders(boolean display)
      {
            drawBorders = display;
            
            if(autoAdjustement)
                  updateBorders();
            
            if(bordersComplete!=null)
                  bordersComplete.setSelected(!autoAdjustement && inSelection);
            
            repaint();
      }

      
      
      
      /**
       * Allows to export the drawing as a eps file
       * @param file The new eps file
       */   
00981       public void exportAsEPS(File file) 
      {
            try
            {
                  if(bordersComplete==null)
                        updateBorders();
                  
                  LaTeXDrawPoint2D NW = bordersComplete.getTheNWPoint(), SE = bordersComplete.getTheSEPoint();    
                  int dec = 5;      
                  FileOutputStream finalImage = new FileOutputStream(file);
                  EpsGraphics2D g = new EpsGraphics2D("LaTeXDraw",  //$NON-NLS-1$
                              finalImage, (int)(NW.x-dec), (int)(NW.y-dec), (int)(SE.x+dec), (int)(SE.y+dec));
                  
                  selected.setSelected(false);
                  paintFigures(g, false, false);
                  g.flush();
                  g.close();
                  finalImage.close();
                  
                  selected.setSelected(true);
            }
            catch(Exception e)
            { 
                  e.printStackTrace(); 
                  ExceptionFrameDialog.showExceptionDialog(e);
            }
      }
      
      
      
      
      /**
       * Allows to export the drawing as a PPM file
       * @param file The new PPM file
       */
01016       public void exportAsPPMFile(File file)
      {
            BufferedImage bufImage = createRenderedImage();
            
            if(bufImage==null)
                  return ;
            
            try 
            {
                  PNMCodec codec = new PNMCodec();
                  codec.setFile(file.getAbsolutePath(), CodecMode.SAVE);
                  BufferedRGB24Image img = new BufferedRGB24Image(bufImage);
                  codec.setImage(img); 
                  codec.process();
                  
                  codec.close();
                  bufImage.flush();
                  
                  bufImage = null;
                  img   = null;
                  codec = null;
          }
            catch(Exception e) 
          {
                  e.printStackTrace(); 
                  ExceptionFrameDialog.showExceptionDialog(e);
          }
      }
      
      
      
      
      /**
       * Allows to export the drawing as a bmp file
       * @param file The new bmp file
       */
01052       public void exportAsBMP(File file)
      {
            RenderedImage rendImage = createRenderedImage();
            
            if(rendImage==null)
                  return ;
            
            try 
            {
                  ImageWriteParam iwparam = new BMPImageWriteParam();
                  iwparam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
                  ImageWriter iw = ImageIO.getImageWritersByFormatName("bmp").next();//$NON-NLS-1$
                  ImageOutputStream ios = ImageIO.createImageOutputStream(file);
                  iw.setOutput(ios);
                  
                  iw.write(null, new IIOImage(rendImage, null, null), iwparam);
                  iw.dispose();
                  ios.close();
          }
            catch(Exception e) 
          {
                  e.printStackTrace(); 
                  ExceptionFrameDialog.showExceptionDialog(e);
          }
      }
      
      

      
      /**
       * Allows to export the drawing as a png file
       * @param file The new png file
       */
01085       public void exportAsPNG(File file)
      {
            RenderedImage rendImage = createRenderedImage();
            
            if(rendImage==null)
                  return ;
            
            try { ImageIO.write(rendImage, "png", file); } //$NON-NLS-1$
            catch(IOException e) 
          {
                  e.printStackTrace(); 
                  ExceptionFrameDialog.showExceptionDialog(e);
          }
      }
      
      
      
      
      /**
       * Allows to export the drawing as a jpg file.
       * @param file The new jpg file.
       * @param compressionRate The compression rate of the pictures.
       */
01108       public void exportAsJPG(File file, float compressionRate)
      {
            RenderedImage rendImage = createRenderedImage();
            
            if(rendImage==null)
                  return ;
            
            try 
            {
                  ImageWriteParam iwparam = new JPEGImageWriteParam(Locale.getDefault());
                  iwparam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
                  iwparam.setCompressionQuality(compressionRate);
                  ImageWriter iw = ImageIO.getImageWritersByFormatName("jpg").next();//$NON-NLS-1$
                  ImageOutputStream ios = ImageIO.createImageOutputStream(file);
                  iw.setOutput(ios);
                  
                  iw.write(null, new IIOImage(rendImage, null, null), iwparam);
                  iw.dispose();
                  ios.close();
          }
            catch(IOException e) 
          {
                  e.printStackTrace(); 
                  ExceptionFrameDialog.showExceptionDialog(e);
          }
      }
      
      
      
      
      public BufferedImage createRenderedImage()
      {
            try 
            {// Creation of the first buffer : the drawing and the empty white space
                  if(bordersComplete==null) 
                        updateBorders();
                  
                  LaTeXDrawPoint2D NW = bordersComplete.getTheNWPoint(), SE = bordersComplete.getTheSEPoint();

                  double dec = 5.;
                  double width = Math.abs(NW.x - SE.x)+dec;
                  double height = Math.abs(NW.y - SE.y)+dec;

                  BufferedImage bufferImage = new BufferedImage(
                              (int)(SE.x+dec), (int)(SE.y+dec), BufferedImage.TYPE_INT_RGB);
                  Graphics2D graphic = bufferImage.createGraphics();
                              
                  graphic.setColor(Color.WHITE);
                  graphic.fillRect(0, 0, (int)(SE.x+dec), (int)(SE.y+dec));

                  Draw selection = getSelected();
                  isSelection(false);
                  
                  paintFigures(graphic, false, false);
                  
                  setSelected(selection);
                  
                  // To delete the empty whitespace, we do a translation to
                  // the North-West point of the drawing (dec : to avoid to cut
                  // the start of some figures, we let a few white space around
                  // the drawing.
                  AffineTransform aff = new AffineTransform();
                  aff.translate(-NW.x+dec, -NW.y+dec);
                  
                  BufferedImage bufferImage2 = new BufferedImage(
                              (int)(width+dec), (int)(height+dec), BufferedImage.TYPE_INT_RGB);
                  Graphics2D graphic2 = bufferImage2.createGraphics();
                  graphic2.setColor(Color.WHITE);
                  graphic2.fillRect(0, 0, (int)(width+dec), (int)(height+dec));
                  
                  // We add quality to the drawing
                  graphic2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
                  graphic2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
                  graphic2.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION,
                                                        RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
                  graphic2.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, 
                                                        RenderingHints.VALUE_COLOR_RENDER_QUALITY);
                  graphic2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, 
                                                        RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
                  
                  // We draw the new picture
                  graphic2.drawImage(bufferImage, aff, null);
                  
                  graphic.dispose();
                  graphic2.dispose();
                  bufferImage.flush();
                  graphic      = null;
                  graphic2     = null;
                  bufferImage  = null;
                  
                  return bufferImage2;
            }
            catch(Exception e)
            { 
                  e.printStackTrace(); 
                  ExceptionFrameDialog.showExceptionDialog(e);
                  return null;
            }
      }
      
      
      
      
      /**
       * This method allows to know if the project has been
       * modified or not
       * @return true if the project has been modified
       */
01216       public boolean isModified()
      {
            return isModified;
      }
      
      
      
      
      /**
       * This method allow to set the variable "selected" to null
       * if the user doesn't want to select a figure.
       * @param is false : the user doesn't want to select a figure
       */
01229       public void isSelection(boolean is)
      {
            try
            {
                  inSelection = is;
                  
                  if(bordersComplete!=null)
                  {
                        bordersComplete.setSelected(is && !parentPanel.getFrameParent().isAutoAdjustBorders());
                        repaint();
                  }
                        
                  if(!is && !selected.isEmpty())
                  {
                        selected.setSelected(false);              
                        selected = new Draw(false, false);
                        selected.setOnRotation(isOnRotation());
                        repaint();
                  }
            }
            catch(Exception e) 
            { 
                  e.printStackTrace(); 
                  ExceptionFrameDialog.showExceptionDialog(e);
            }
      }
      
      
      
      
      public boolean onClick(Point pt, MouseEvent e)
      {
            if(pt==null)
                  return false;
            
            if(!autoAdjustement && !figures.isEmpty())
            {
                  bordersComplete.setSelected(true);
                  
                  if(drawBorders && bordersComplete.isIn(pt))
                  {
                        selected.setSelected(false);
                        selected.clear();
                        bordersComplete.onClick(pt);
                        return false;
                  }
                  bordersComplete.onDelimitorRelease();
            }
            
            boolean isIn = false;
            int size = figures.size(), i=size-1;
            
            try
            {
                  while(i>=0 && !isIn)
                        if(figures.elementAt(i).isIn(pt))
                              isIn = true;
                        else i--;
                  
                  if(e.getModifiers()==InputEvent.CTRL_MASK+InputEvent.BUTTON1_MASK)
                  {
                        if(isIn)
                        {
                              Figure f = figures.elementAt(i);
                              
                              if(!selected.contains(f))//Don't add twice the same figure.
                              {
                                    selected.addFigure(f);
                                    selected.setSelected(true);
                              }
                              return true;
                        }
                        return false;
                  }
                  
                  if(e.getModifiers()==InputEvent.SHIFT_MASK+InputEvent.BUTTON1_MASK)
                  {
                        if(isIn)
                        {
                              Figure f = figures.elementAt(i);
                              
                              if(selected.contains(f))
                              {
                                    f.setSelected(false);
                                    selected.removeFigure(f);
                                    selected.setSelected(true);
                              }
                              return true;
                        }
                        return false;
                  }
                  
                  if(isIn)
                  {
                        if(selected!=null && selected.contains(figures.elementAt(i)))
                        {
                              selected.setSelected(true);
                              selected.onClick(pt);
                              return true;
                        }
                        
                        if(selected!=null)
                              selected.setSelected(false);
                        
                        selected = new Draw(false, false);
                        selected.setOnRotation(isOnRotation());
                        selected.addFigure(figures.elementAt(i));
                        selected.setSelected(true);
                        return true;
                  }
                  
                  if(selected!=null && selected.size()>1 && selected.isIn(pt))
                  {
                        selected.setSelected(true);
                        selected.onClick(pt);
                        return true;
                  }
                  
                  if(selected!=null)
                  {
                        selected.setSelected(false);
                        selected.clear();
                  }
                  
                  selected = new Draw(false, false);
                  
                  return false;
            }
            catch(Exception ex)
            { 
                  ex.printStackTrace(); 
                  ExceptionFrameDialog.showExceptionDialog(ex);
                  return false;
            }
      }
      
      
      
      
      /**
       * Allows to set the boolean autoAdjustement
       * @param state It's new state
       */
01372       public void setAutoAdjustement(boolean state)
      {
            if(state!=autoAdjustement)
            {
                  autoAdjustement = state;
                  setIsModified(true);
            }
            
            if(bordersComplete!=null)
                  if(autoAdjustement)
                  {
                        updateBorders();
                        bordersComplete.setSelected(false);
                  }
                  else
                        bordersComplete.setSelected(inSelection);
            
            updateDraw();
      }


      
      
      /**
       * Allows to set the new selected figure
       * @param newSelected The new selected figure
       */
01399       public void setSelected(Figure newSelected)
      {
            if(!selected.isEmpty())
                  selected.setSelected(false);

            if(newSelected instanceof Draw && !((Draw)newSelected).isDrawFigures())
                  selected = (Draw) newSelected;
            else
            {
                  selected = new Draw(false,false);
                  
                  if(newSelected!=null)
                        selected.addFigure(newSelected);
            }
            
            selected.setSelected(true);
            selected.setOnRotation(isOnRotation());
      }
      
      
      
      
      /**
       * Allows to set the variable isModified
       * @param state The new state of isModified
       */
01425       public void setIsModified(boolean state)
      {
            isModified = state;
            
            if(parentPanel!=null && parentPanel.frameParent!=null)
                  parentPanel.frameParent.setTitle();
      }
      
      
      
      
      /**
       * Allows to set the parent of this container
       * @param p The new parent
       */
01440       public void setParentPanel(DrawPanel p)
      {
            parentPanel = p;
      }
      
      
      
      
      /**
       * Allows to set the number of pixels per centimetre
       * @param pPerCm The new number of pixels per centimetre
       */
01452       public void setPixelsPerCm(int pPerCm)
      {
            if(this.pixelsPerCm!=pPerCm)
            {
                  pixelsPerCm = pPerCm;
                  setIsModified(true);
                  grid.setPixelsPerCm(pPerCm);
            }
      }


      
      
      public void paintFigures(Graphics g, boolean withZoom, boolean withGrid)
      {
            if(g==null || figures==null) return;

      g.setColor(Color.WHITE);
      g.fillRect(0, 0, getWidth(), getHeight());
            Graphics2D g2 = (Graphics2D) g;
            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, antiAliasingValue);
            g2.setRenderingHint(RenderingHints.KEY_RENDERING, renderingValue);
            g2.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, alphaInterpolValue);
            g2.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, colorRenderingValue);
            
      try
      {
            if(isGridDisplayed() && withGrid)
            {
                  if(grid.getHeight()!=getHeight())
                        grid.setHeight(getHeight());
                  
                  if(grid.getWidth()!=getWidth())
                        grid.setWidth(getWidth());
                  
                  grid.paint(g2);
            }
            
                  if(withZoom)
                        g2.scale(getZoom(), getZoom());
                  
            int size = figures.size(), i;
            Figure currentFigure = parentPanel.getCurrentFigure();
            
            for(i = 0; i<size; i++)
                  figures.elementAt(i).draw(g2, antiAliasingValue, renderingValue, alphaInterpolValue, colorRenderingValue);        
            
            if(currentFigure != null)
                  currentFigure.draw(g2, antiAliasingValue, renderingValue, alphaInterpolValue, colorRenderingValue);
      }
      catch(Exception e)
      { 
            e.printStackTrace(); 
            ExceptionFrameDialog.showExceptionDialog(e);
      }
      }
      
      
      
      
      
      /**
       * Allows to display all the figures of the drawing
       */
    @Override
01517       public void paintComponent(Graphics g)
    {       
      super.paintComponents(g);
      paintFigures(g, true, true);
            
      try
      {
            Graphics2D g2 = (Graphics2D) g;
            int size = figures.size();
            
            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, antiAliasingValue);
            g2.setRenderingHint(RenderingHints.KEY_RENDERING, renderingValue);
            g2.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, alphaInterpolValue);
            g2.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, colorRenderingValue);
            
            if(parentPanel.getBordersSelection()!=null)
                  parentPanel.getBordersSelection().draw(g2, antiAliasingValue, renderingValue, alphaInterpolValue, colorRenderingValue);
            
            if(selected!=null && !selected.isEmpty())
                  selected.draw(g2, antiAliasingValue, renderingValue, alphaInterpolValue, colorRenderingValue);

            if(drawBorders && size>0)
            { 
                  if(bordersComplete==null)
                        updateBorders();
                  
                  bordersComplete.draw(g2, antiAliasingValue, renderingValue, alphaInterpolValue, colorRenderingValue);
            }
      }
      catch(Exception e) { e.printStackTrace(); }
      
      g.dispose();
    }
    
    
    
    
    /**
       * Allows to access to the borders (the axes) of the drawing;<br>
       * see bordersReal for more informations.
       * @return The complete borders of the drawing
       */
01559       public DrawBorders getCompleteBorders()
      {
            return bordersComplete;
      }

      
      
      
    /**
       * Allows to access to the real borders of the drawing;<br>
       * see bordersReal for more informations.
       * @return The real borders of the drawing
       */
01572       public DrawBorders getRealBorders()
      {
            return bordersReal;
      }

      
      
      
      /**
     * Allows to get the pstricks code of the drawing.
     * @return the pstricks code.
     */
01584       public String getPSTricksCode()
    {
      int i, size = figures.size();
      String code = ""; //$NON-NLS-1$
      
      try
      {
            for(i=0; i<size; i++)
            {
                  Figure f = figures.elementAt(i);
                  code += f.getCodePSTricks(bordersReal, pixelsPerCm) + "\n"; //$NON-NLS-1$
            }
      }
      catch(Exception e)
      { 
            e.printStackTrace(); 
            ExceptionFrameDialog.showExceptionDialog(e);
      }
            
      return DviPsColors.getUserColoursCode(code) + code;
    }
    
    
    
    
    
    /**
       * Allows to get the number of figures
       * @return The number of figures
       */
01614       public int getNbFigures()
      {
            if(figures==null) return 0;
            return figures.size();
      }


      
      
      /**
       * Allows to get the number of pixels per centimetre
       * @return The number of pixels per centimetre
       */
01627       public int getPixelsPerCm() 
      {
            return pixelsPerCm;
      }

      
      

      /**
       * Allows to get the selected figure (if there is a one)
       * @return The selected figures or null
       */
01639       public Draw getSelected()
      {
            return selected;
      }


      
      
      /**
       * Allows to get the most top right point of the drawing (North-East point).
       * see bordersReal for more informations.
       * @return The top right point of the drawing
       * @throws Exception 
       */   
01653       public LaTeXDrawPoint2D getTheCompleteNEPoint() throws Exception
      {
            if(bordersComplete==null)
                  updateBorders();
            
            return bordersComplete.getTheNEPoint();
      }


      
      
      /**
       * Allows to get the real top right point of the drawing (North-East point).
       * see bordersReal for more informations.
       * @return The top right point of the drawing
       * @throws Exception 
       */   
01670       public LaTeXDrawPoint2D getTheRealNEPoint() throws Exception
      {
            if(bordersReal==null)
                  updateBorders();
            
            return bordersReal.getTheNEPoint();
      }
      
      
      
      
      /**
       * Allows to get the most bottom left point of the drawing (South-West point).
       * see bordersReal for more informations.
       * @return The bottom left point of the drawing
       * @throws Exception 
       */
01687       public LaTeXDrawPoint2D getTheCompleteSWPoint() throws Exception
      {
            if(bordersComplete==null)
                  updateBorders();
            
            return bordersComplete.getTheSWPoint();
      }


      
      
      /**
       * Allows to get the real bottom left point of the drawing (South-West point).
       * see bordersReal for more informations.
       * @return The bottom left point of the drawing
       * @throws Exception 
       */
01704       public LaTeXDrawPoint2D getTheRealSWPoint() throws Exception
      {
            if(bordersReal==null)
                  updateBorders();
            
            return bordersReal.getTheSWPoint();
      }
      
      
      
      
      
      /**
       * Allows to update the drawing
       */
01719       public void updateDraw()
      {     
            updateBorders();  
            updatePreferredSize();
            repaint();
            revalidate();     
      }
      
      
      
      
      /**
     * Allows to update the dimensions of the drawing (needed for
     * the scrollers)
     */
01734       public void updatePreferredSize()
      { 
                  if(bordersComplete==null)
                        setPreferredSize(new Dimension(0, 0));
                  else
                  {
                        try
                        {
                              setPreferredSize(new Dimension(
                                                 (int) ((bordersComplete.getTheSEPoint().x+10)*zoom), 
                                                 (int) ((bordersComplete.getTheSEPoint().y+10)*zoom)));
                        }
                        catch(Exception e) 
                        { 
                              e.printStackTrace(); 
                              ExceptionFrameDialog.showExceptionDialog(e);
                        }
                  }
      }
      

      
      
      /**
       * Allows to print the drawing
       */
01760       public int print(Graphics g, PageFormat pformat, int pageIndex) throws PrinterException 
      {
            if (pageIndex >= 1) return Printable.NO_SUCH_PAGE;
            
            Graphics2D g2 = (Graphics2D)g;
            
            if(bordersComplete==null)
                  updateBorders();
            
            try
            { 
                  LaTeXDrawPoint2D SE = bordersComplete.getTheSEPoint(); 
                  
                  g2.translate(pformat.getImageableX(), pformat.getImageableY());
                  g2.translate(pformat.getImageableWidth()/2, pformat.getImageableHeight()/2);
                  
                  // Id the drawing is to big for the page, we resize the drawing
                  double scale = Math.min( pformat.getImageableWidth()/SE.x, pformat.getImageableHeight()/SE.y);
                  
                   if(scale<1.0) // We resize the drawing
                         g2.scale(scale, scale);
                   
                  g2.translate(-SE.x/2.0, -SE.y/2.0);
                  g2.dispose();
                  paintFigures(g2, false, false);
            }
            catch(Exception e) 
            { 
                  e.printStackTrace(); 
                  ExceptionFrameDialog.showExceptionDialog(e);
            }
            
            return Printable.PAGE_EXISTS;
      }

      
      
      public Dimension getPreferredScrollableViewportSize()
      {     return new Dimension(-100, 100);  }
      

      
      public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) 
      {
        return (orientation == SwingConstants.VERTICAL) ? visibleRect.height : visibleRect.width;
      }
      
      
      
      public boolean getScrollableTracksViewportHeight()
      {
            return getParent() instanceof JViewport ? ((JViewport)getParent()).getHeight() > getPreferredSize().height : false;
      }
      

      public boolean getScrollableTracksViewportWidth()
      {
            return getParent() instanceof JViewport ? ((JViewport)getParent()).getWidth() > getPreferredSize().width : false;
      }
      

      
      public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction)  
      {
            return 4;
      }




      /**
       * Allows to copy the selected figure
       */
01833       public void copy() 
      {
            try
            {
                  if(!selected.isEmpty())
                  {
                        copiedFigure = (Draw) selected.clone();
                        parentPanel.getFrameParent().setMenuPaste(true);
                  }
            }
            catch(Exception e)
            {
                  e.printStackTrace(); 
                  ExceptionFrameDialog.showExceptionDialog(e);
            }
      }




      /**
       * Allows to paste a copied or a cut figure
       */
01856       public void paste()
      {
            try
            {
                  if(copiedFigure!=null)
                  {
                        int i, size =  copiedFigure.size();
                        double gap = parentPanel.isGridMagnetic() ? grid.getMagneticGridGap() : 10;
                        selected.setSelected(false);
                        selected.clear();
                        
                        for(i=0; i<size;i++)
                              copiedFigure.getFigureAt(i).shift(gap, gap);
                        
                        Draw f = (Draw) copiedFigure.clone();                       
                        
                        for(i=0; i<size; i++)
                              addFigure(copiedFigure.getFigureAt(i), parentPanel.getFrameParent().getUndoManager());
                        
                        copiedFigure.updateBorders();
                        setSelected(copiedFigure);
                        copiedFigure.setSelected(true);
                        parentPanel.getFrameParent().setSelection(true);
                        parentPanel.getFrameParent().setExportAsMenu(!figures.isEmpty());
                        copiedFigure = f;
                        
                  }
                  else
                        parentPanel.getFrameParent().setMenuPaste(false);
            }
            catch(Exception e)
            {
                  e.printStackTrace();
                  ExceptionFrameDialog.showExceptionDialog(e);
            }
      }




      /**
       * Allows to cut the selected figure
       */
01899       public void cut() 
      {
            try
            {
                  if(selected!=null && !selected.isEmpty())
                  {           
                        copiedFigure = (Draw) selected.clone();
                        Draw cloneUndo = (Draw) selected.clone();
                        int[] id = new int[selected.size()];
                        
                        for(int i=0, size=selected.size(); i<size; i++)
                        {
                              id[i] = figures.indexOf(selected.getFigureAt(i));
                              if(id[i]<0)
                                    throw new IndexOutOfBoundsException();
                        }

                        parentPanel.getFrameParent().getUndoManager().add(UndoRedoManager.LABEL_DEL, id, cloneUndo, false);
                        parentPanel.getFrameParent().updateUndoRedo();
                        
                        for(int i=0; i<selected.size();)
                              deleteFigure(selected.getFigureAt(i), null);
                        
                        parentPanel.getFrameParent().setMenuCopy(false);
                        parentPanel.getFrameParent().setSelection(false);
                        parentPanel.getFrameParent().setMenuPaste(true);
                        parentPanel.getFrameParent().setExportAsMenu(!figures.isEmpty());
                        selected.clear();
                        parentPanel.updateDraw(true);
                        setIsModified(true);
                  }
            }
            catch(Exception e)
            {
                  e.printStackTrace();
                  ExceptionFrameDialog.showExceptionDialog(e);
            }
      }
      
      
      
      
      @SuppressWarnings("unchecked") 
      private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException
      {
            if(LaTeXDrawFrame.getVersionOfFile().compareTo("1.6")>=0)//$NON-NLS-1$
            {
                  int nbFigures = ois.readInt(), i;
                  figures = new Vector<Figure>();
                  for(i=0; i<nbFigures; i++)
                        try
                        {
                              Figure f = (Figure)ois.readObject();
                              figures.add(f);
                        }
                        catch(Exception e)
                        {  
                              System.out.println("A figure cannot be read !"); //$NON-NLS-1$ 
                        }
            }
            else
            try { figures = (Vector<Figure>) ois.readObject(); }
            catch(Exception e)
            { 
                  System.out.println("A figure cannot be read !"); //$NON-NLS-1$ 
            }
            
            bordersComplete = (DrawBorders) ois.readObject();
            drawBorders = ois.readBoolean();
            autoAdjustement = ois.readBoolean();
            inSelection = ois.readBoolean();
            pixelsPerCm = ois.readInt();
            zoom = ois.readDouble();
            onRotation = ois.readBoolean();
            
            if(LaTeXDrawFrame.getVersionOfFile().compareTo("1.5")>=0)//$NON-NLS-1$
            {
                  unitForPixelsPerCm = (String)ois.readObject();
                  bordersReal = (DrawBorders)ois.readObject();
                  
                  boolean is18 = LaTeXDrawFrame.getVersionOfFile().compareTo("1.8")>=0;//$NON-NLS-1$
                  boolean is17 = LaTeXDrawFrame.getVersionOfFile().compareTo("1.7")>=0;//$NON-NLS-1$
                  
                  for(Figure f : figures)// We have to update the value which were not is pixels in the former releases.
                  {
                        if(is17)
                              f.setShadowSize(f.getShadowSize()*pixelsPerCm);
                        
                        if(is18)
                              f.setHatchingSep(f.getHatchingSep()*pixelsPerCm);
                        
                        if(f instanceof Arrowable)
                        {
                              ArrowHead ah1 = ((Arrowable)f).getArrowHead1();
                              ArrowHead ah2 = ((Arrowable)f).getArrowHead2();
                              
                              if(ah1!=null)
                              {
                                    ah1.setFigure(f);
                                    ah1.setDotSizeDim(ah1.getDotSizeDim()*pixelsPerCm);
                                    ah1.setTBarSizeDim(ah1.getTBarSizeDim()*pixelsPerCm);
                                    ah1.setArrowSizeDim(ah1.getArrowSizeDim()*pixelsPerCm);
                              }
                              
                              if(ah2!=null)
                              {
                                    ah2.setFigure(f);
                                    ah2.setDotSizeDim(ah2.getDotSizeDim()*pixelsPerCm);
                                    ah2.setTBarSizeDim(ah2.getTBarSizeDim()*pixelsPerCm);
                                    ah2.setArrowSizeDim(ah2.getArrowSizeDim()*pixelsPerCm);
                              }
                        }
                        
                        if(f instanceof Axe)
                              ((Axe)f).setTicksSize(((Axe)f).getTicksSize()*pixelsPerCm);
                        
                        if(f instanceof Grid)
                        {
                              ((Grid)f).setGridWidth(((Grid)f).getGridWidth()*pixelsPerCm);
                              ((Grid)f).setSubGridWidth(((Grid)f).getSubGridWidth()*pixelsPerCm);
                        }
                  }
            }
            else
            {
                  unitForPixelsPerCm = XScale.DEFAULT_UNIT;
                  updateBorders();
            }
            
            grid = new MagneticGrid(getWidth(), getHeight(), pixelsPerCm, zoom);
            isModified = false;
            copiedFigure = null;    
            selected = new Draw(false, false);  
            setZoom(zoom);
            setPixelsPerCm(pixelsPerCm);
      }




      /**
       * Allows to join the selected figures
       * @param undoManager The undo/redo manager
       */
02043       public void joinSelection(UndoRedoManager undoManager)
      {
            try
            {
                  if(selected!=null && !selected.isEmpty())
                  {
                        int size = selected.size(), i, min;
                        
                        if(size<2)
                              return ;
                        
                        int[] id = new int[size];
                        Draw d = (Draw)selected.clone();
                        
                        for(i=0; i<size; i++)
                        {
                              id[i] = figures.indexOf(selected.getFigureAt(i));
                              figures.remove(id[i]);
                        }
                        
                        min = id[0];
                        i = 1;
                        
                        while(i<size)
                        {
                              if(id[i]<min)
                                    min = id[i];
                              i++;
                        }
                        
                        if(undoManager!=null)
                              undoManager.add(UndoRedoManager.LABEL_JOIN, id, null, false);
                              
                        d.setDrawFigures(true);
                        d.setSelected(false);
                        d.changeMeter();
                        figures.add(min, d);
                        selected.clear();
                        setSelected(d);
                  }
            }
            catch(Exception e)
            {
                  e.printStackTrace();
                  ExceptionFrameDialog.showExceptionDialog(e);
            }
      }




      /**
       * Allows to join the figures of the selected drawing
       * @param undoManager The undo/redo manager
       */
02098       public void separateSelection(UndoRedoManager undoManager)
      {
            try
            {
                  if(selected!=null && !selected.isEmpty())
                  {
                        Draw d = (Draw)selected.getFigureAt(0);
                        int i, size = d.size(), index = figures.indexOf(d);               
                        
                        if(undoManager!=null)
                              undoManager.add(UndoRedoManager.LABEL_SEPARATE, index, d.clone());
                        
                        deleteFigure(d, null);
                        selected.clear();
                        Figure f;
                        for(i=size-1; i>=0; i--)
                        {
                              f = d.getFigureAt(i);
                              figures.add(index, f);
                              selected.addFigure(f, 0);
                        }
      
                        selected.updateBorders();
                        selected.setSelected(true);
                  }
            }
            catch(Exception e)
            {
                  e.printStackTrace();
                  ExceptionFrameDialog.showExceptionDialog(e);
            }
      }

      

      
      /**
       * Creates a thumbnail from the given selection in the given file.
       * @param templateFile The file of the future thumbnail.
       * @param selection The drawing the export.
       * @return True if the creation is successful
       * @since 1.9.2
       */
02141       public boolean createTemplateThumbnail(File templateFile, Draw selection)
      {
            try
            {
                  BufferedImage bufferImage;
                  LaTeXDrawPoint2D SE = selection.getTheSEBoundPoint();
                  LaTeXDrawPoint2D NW = selection.getTheNWBoundPoint();
                  double dec=8;
                  double width = Math.abs(SE.x-NW.x)+2*dec, height = Math.abs(SE.y-NW.y)+2*dec, maxSize = 20;
            
                  bufferImage = new BufferedImage((int)width, (int)height, BufferedImage.TYPE_INT_RGB);
                  
                  Graphics2D graphic = bufferImage.createGraphics();
                  double scale = Math.min(maxSize/width,maxSize/height);
                  graphic.setColor(Color.WHITE);
                  graphic.fillRect(0, 0, (int)width, (int)height);      
                  graphic.scale(scale, scale);
                  graphic.translate(-NW.x+dec, -NW.y+dec);
                  
                  boolean formerIsSelected            = selection.isSelected();
                  boolean formerMustDrawFigures       = selection.isDrawFigures();
                  
                  selection.setSelected(false);
                  selection.setDrawFigures(true);
                  selection.draw(graphic, antiAliasingValue, renderingValue, alphaInterpolValue, colorRenderingValue);
                  selection.setDrawFigures(formerMustDrawFigures);
                  selection.setSelected(formerIsSelected);              
                  
                  AffineTransform aff = new AffineTransform();
                  aff.translate(0, 0);
                  
                  BufferedImage bufferImage2 = new BufferedImage((int)maxSize, (int)maxSize, BufferedImage.TYPE_INT_ARGB);
                  
                  Graphics2D graphic2 = bufferImage2.createGraphics();
                  graphic2.setColor(Color.WHITE);
                  graphic2.fillRect(0, 0, (int)maxSize, (int)maxSize);
                  graphic2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
                  graphic2.setRenderingHint(RenderingHints.KEY_RENDERING,RenderingHints.VALUE_RENDER_QUALITY);
                  graphic2.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION,
                                                        RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
                  graphic2.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING,RenderingHints.VALUE_COLOR_RENDER_QUALITY);
                  graphic2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
                  
                  // We draw the template
                  graphic2.drawImage(bufferImage, aff, null);
      
                  // We create the png file with the second picture
                  ImageWriteParam iwparam = new JPEGImageWriteParam(Locale.getDefault());
                  iwparam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
                  iwparam.setCompressionQuality(1);
                  ImageWriter iw = ImageIO.getImageWritersByFormatName("png").next();//$NON-NLS-1$
                  ImageOutputStream ios = ImageIO.createImageOutputStream(templateFile);
                  iw.setOutput(ios);
                  
                  iw.write(null, new IIOImage(bufferImage2, null, null), iwparam);
                  
                  iw.dispose();
                  ios.close();
                  graphic.dispose();
                  graphic2.dispose();
                  bufferImage.flush();
                  bufferImage2.flush();
                  ios                = null;
                  iw                 = null;
                  graphic      = null;
                  graphic2     = null;
                  bufferImage  = null;
                  bufferImage2 = null;
                  
                  return true;
            }
            catch(Exception e) { return false; }
      }
      


      /**
       * @return Returns the unitForPixelsPerCm.
       */
02220       public String getUnitForPixelsPerCm()
      {
            return unitForPixelsPerCm;
      }




      /**
       * @param unitForPixelsPerCm The unitForPixelsPerCm to set.
       */
02231       public void setUnitForPixelsPerCm(String unitForPixelsPerCm)
      {
            if(unitForPixelsPerCm!=null && !unitForPixelsPerCm.equals(this.unitForPixelsPerCm))
            {
                  this.unitForPixelsPerCm = unitForPixelsPerCm;
                  
                  if(!grid.isPersonalGrid())
                        if(isUnitInCm())
                              grid.setType(MagneticGrid.TYPE_CM);
                        else
                              grid.setType(MagneticGrid.TYPE_INCH);
            }
      }

      

      
      /**
       * Allows to insert a picture into the drawing
       * @param undoManager The undo/redo manager
       * @param path The path of the picture
       * @return True is the picture is inserted
       */
02254       public boolean insertPicture(UndoRedoManager undoManager, String path)
      {
            try
            {
                  addFigure(new Picture(true, new LaTeXDrawPoint2D(50,50), path), undoManager);
                  return true;
            }
            catch(Exception e) { return false; }
      }



      /**
       * @return the isGridDisplay
       */
02269       public boolean isGridDisplayed()
      {
            return grid.isGridDisplayed();
      }




      @Override
      public void setSize(int x, int y)
      {
            super.setSize(x, y);
      }
      
      
      
      /**
       * @return True is the unit of length is the centimetre.
       */
02288       public boolean isUnitInCm()
      {
            return unitForPixelsPerCm.equals(XScale.LABEL_CM);
      }




      /**
       * @return the personalGridGap.
       */
02299       public int getPersonalGridGap()
      {
            return grid.getPersoInterval();
      }




      /**
       * @param personalGridGap the personalGridGap to set.
       * @throws IllegalArgumentException If lesser than 2.
       */
02311       public void setPersonalGridGap(int personalGridGap)
      {
            grid.setPersoInterval(personalGridGap);
            repaint();
      }



      /**
       * @return True if a classic grid is displayed.
       */
02322       public boolean isClassicGridDrawn()
      {
            return !grid.isPersonalGrid();
      }



      /**
       * @param isClassicGridDrawn the isClassicGridDrawn to set.
       */
02332       public void setClassicGridDrawn(boolean isClassicGridDrawn)
      {
            grid.setType(isClassicGridDrawn ? isUnitInCm() ? MagneticGrid.TYPE_CM : MagneticGrid.TYPE_INCH : MagneticGrid.TYPE_PERSONAL);
      }

      

      /**
       * Rotate the selected figures with a defined angle.
       * @param angle The angle of rotation in radian.
       */
02343       public void rotateSelection(double angle)
      {
            if(selected!=null && !selected.isEmpty())
            {
                  try
                  {
                        Draw clone = (Draw)selected.clone();
                        int[] id = new int[selected.size()];
                        
                        for(int i=0, size=selected.size(); i<size; i++)
                        {
                              id[i] = figures.indexOf(selected.getFigureAt(i));
                              if(id[i]<0)
                                    throw new IndexOutOfBoundsException();
                        }
                        
                        UndoRedoManager manager = parentPanel.getFrameParent().getUndoManager();
                        manager.add(UndoRedoManager.LABEL_TRANSFORM, id, clone, false);
                        parentPanel.getFrameParent().updateUndoRedo();
                  }
                  catch(Exception e)
                  {
                        e.printStackTrace();
                        ExceptionFrameDialog.showExceptionDialog(e);
                  }
                  
                  selected.rotate(selected.getGravityCenter(), angle);
                  
                  if(parentPanel.isGridMagnetic())
                        parentPanel.updateSelectionToGrid();
                  
                  parentPanel.updateDraw(true);
                  parentPanel.setIsModified(true);
            }
      }




      /**
       * Return horizontally the selected figures.
       */
02385       public void mirrorHorizontal()
      {
            try
            {
                  if(selected!=null && !selected.isEmpty()) 
                  {
                        Draw clone = (Draw)selected.clone();
                        int[] id = new int[selected.size()];
                        
                        for(int i=0, size=selected.size(); i<size; i++)
                        {
                              id[i] = figures.indexOf(selected.getFigureAt(i));
                              if(id[i]<0)
                                    throw new IndexOutOfBoundsException();
                        }
                        
                        UndoRedoManager manager = parentPanel.getFrameParent().getUndoManager();
                        manager.add(UndoRedoManager.LABEL_TRANSFORM, id, clone, false);
                        parentPanel.getFrameParent().updateUndoRedo();
                        selected.mirrorHorizontal(selected.getGravityCenter());
                  }
            }
            catch(Exception e)
            {
                  e.printStackTrace();
                  ExceptionFrameDialog.showExceptionDialog(e);
            }
            
            parentPanel.updateDraw(true);
            parentPanel.setIsModified(true);
      }



      /**
       * Return vertically the selected figures.
       */
02422       public void mirrorVertical()
      {
            try
            {
                  if(selected!=null && !selected.isEmpty()) 
                  {
                        Draw clone = (Draw)selected.clone();
                        int[] id = new int[selected.size()];
                        
                        for(int i=0, size=selected.size(); i<size; i++)
                        {
                              id[i] = figures.indexOf(selected.getFigureAt(i));
                              if(id[i]<0)
                                    throw new IndexOutOfBoundsException();
                        }
                        
                        UndoRedoManager manager = parentPanel.getFrameParent().getUndoManager();
                        manager.add(UndoRedoManager.LABEL_TRANSFORM, id, clone, false);
                        parentPanel.getFrameParent().updateUndoRedo();
                        selected.mirrorVertical(selected.getGravityCenter());
                  }
            }catch(Exception e)
            {
                  e.printStackTrace();
                  ExceptionFrameDialog.showExceptionDialog(e);
            }
            
            parentPanel.updateDraw(true);
            parentPanel.setIsModified(true);
      }




      /**
       * @return the autoAdjustement.
       * @since 1.8
       */
02460       public boolean isAutoAdjustement()
      {
            return autoAdjustement;
      }



      /**
       * Select all the figures of the current drawing.
       * @since 1.9
       */
02471       public void selectAll()
      {
            if(figures.isEmpty())
                  return ;
            
            Draw selection = new Draw(false, false);
            
            for(Figure f : figures)
                  if(f!=null)
                        selection.addFigure(f);
            
            selection.setSelected(true);
            setSelected(selection);
            parentPanel.updateDraw(false);
      }
      
      
      
      
      /**
       * Recentre all the figures.
       */
02493       public void recenterFigures()
      {
            if(figures==null) return ;
            double xMin=Double.MAX_VALUE, yMin = Double.MAX_VALUE;
            double dec = 20;
            
            for(Figure f : figures)
                  if(f!=null)
                  {
                        LaTeXDrawPoint2D NW = f.getTheNWBoundPoint();
                        if(NW.x<xMin) xMin = NW.x;
                        if(NW.y<yMin) yMin = NW.y;
                  }
            
            if(xMin>=dec && yMin>=dec) return ; // Already centred
            
            double shiftX = 0, shiftY = 0;
            
            if(xMin<dec)
            {
                  shiftX = Math.abs(xMin)+dec;
                  if(yMin<dec)
                        shiftY = Math.abs(yMin)+dec;
            }
            else shiftY = Math.abs(yMin)+dec;
            
            for(Figure f : figures)
                  if(f!=null)
                        f.shift(shiftX, shiftY);
            
            if(selected!=null)
                  selected.updateBorders();
            
            if(((float)shiftX)!=0f || ((float)shiftY)!=0f)
                  setIsModified(true);
      }


      
      /**
       * Select the first figure if no or several figures are selected; select the next figure if a single
       * figure is selected.
       * @since 1.9
       */
02537       public void selectNextFigure()
      {
            if(figures.isEmpty())
                  return ;
            
            int id = 0;
            Figure f2;
            
            if(selected==null)
                  selected = new Draw(false, false);
            
            if(selected.size()>1)
                  selected.clear();
            
            
            if(selected.size()==1)
            {
                  Figure f1 = selected.getFigureAt(0);
                  id = figures.indexOf(f1);
                  
                  if(id==-1)
                        return ;
                  
                  if(id==figures.size()-1)
                        id = 0;
                  else 
                        id++;
                  
                  selected.removeFigure(f1);

                  f1.setSelected(false);
            }
            
            f2 = figures.elementAt(id);
            selected.addFigure(f2);
            selected.setSelected(true);
            repaint();
            parentPanel.frameParent.setSelection(true);
      }




      /**
       * @return the whichCodeOutput.
       * @since 2.0.0
       */
02584       public short getWhichCodeOutput()
      {
            return whichCodeOutput;
      }




      /**
       * @param whichCodeOutput the whichCodeOutput to set.
       * @exception IllegalArgumentException If the given code is not valid.
       * @since 2.0.0
       */
02597       public void setWhichCodeOutput(short whichCodeOutput)
      {
            if(whichCodeOutput!= CODE_PSTRICKS)
                  throw new IllegalArgumentException(String.valueOf(whichCodeOutput));
            
            this.whichCodeOutput = whichCodeOutput;
      }
      
      
      
      
      /**
       * @return The code of the drawing in the language specified by the attribute whichCodeOutput.
       * @since 2.0.0
       */
02612       public String getCode()
      {
            switch(whichCodeOutput)
            {
                  case CODE_PSTRICKS:
                        return getPSTricksCode();
                        
                  default:
                        throw new IllegalArgumentException(String.valueOf(whichCodeOutput));
            }
      }
      
      
      
      
      /**
       * Define an Element containing the XML attributes of a LaTeXDraw DrawContainer.
       * @param document The XML document.
       * @param meta The meta data to complete.
       * @throws IllegalArgumentException If meta or document is null.
       * @since 2.0.0
       */
02634       public void getXMLMetadata(SVGDocument document, Element meta)
      {
            if(document==null || meta==null)
                  throw new IllegalArgumentException();
            
        Element elt = document.createElement(LaTeXDrawNamespace.LATEXDRAW_NAMESPACE+':'+LaTeXDrawNamespace.XML_DRAW_BORDERS);

        elt.appendChild(document.createTextNode(String.valueOf(drawBorders)));
        meta.appendChild(elt);
        
        elt = document.createElement(LaTeXDrawNamespace.LATEXDRAW_NAMESPACE+':'+LaTeXDrawNamespace.XML_AUTO_ADJUST);
        elt.appendChild(document.createTextNode(String.valueOf(isAutoAdjustement())));
        meta.appendChild(elt);
        
        if(!isAutoAdjustement() && bordersComplete!=null)
        {// We have to save the dimension of the borders.
            LaTeXDrawPoint2D pt = bordersComplete.getTheNWPoint();
            
            elt = document.createElement(LaTeXDrawNamespace.LATEXDRAW_NAMESPACE+':'+LaTeXDrawNamespace.XML_BORDER);
            elt.setAttribute(SVGAttributes.SVG_X,        String.valueOf(pt.x));
            elt.setAttribute(SVGAttributes.SVG_Y,        String.valueOf(pt.y));
            elt.setAttribute(SVGAttributes.SVG_HEIGHT, String.valueOf(bordersComplete.getHeight()));
            elt.setAttribute(SVGAttributes.SVG_WIDTH,  String.valueOf(bordersComplete.getWidth()));
            meta.appendChild(elt);
        }
        
        elt = document.createElement(LaTeXDrawNamespace.LATEXDRAW_NAMESPACE+':'+LaTeXDrawNamespace.XML_PPC);
        elt.appendChild(document.createTextNode(String.valueOf(getPixelsPerCm())));
        meta.appendChild(elt);
        
        elt = document.createElement(LaTeXDrawNamespace.LATEXDRAW_NAMESPACE+':'+LaTeXDrawNamespace.XML_ZOOM);
        elt.appendChild(document.createTextNode(String.valueOf(getZoom())));
        meta.appendChild(elt);
        
        elt = document.createElement(LaTeXDrawNamespace.LATEXDRAW_NAMESPACE+':'+LaTeXDrawNamespace.XML_UNIT);
        elt.appendChild(document.createTextNode(getUnitForPixelsPerCm()));
        meta.appendChild(elt);
        
        elt = document.createElement(LaTeXDrawNamespace.LATEXDRAW_NAMESPACE+':'+LaTeXDrawNamespace.XML_CLASSIC_GRID);
        elt.appendChild(document.createTextNode(String.valueOf(isClassicGridDrawn())));
        meta.appendChild(elt);
        
        elt = document.createElement(LaTeXDrawNamespace.LATEXDRAW_NAMESPACE+':'+LaTeXDrawNamespace.XML_GRID_GAP);
        elt.appendChild(document.createTextNode(String.valueOf(getPersonalGridGap())));
        meta.appendChild(elt);
        
        elt = document.createElement(LaTeXDrawNamespace.LATEXDRAW_NAMESPACE+':'+LaTeXDrawNamespace.XML_CODE);
        elt.appendChild(document.createTextNode(String.valueOf(getWhichCodeOutput())));
        meta.appendChild(elt);
        
        elt = document.createElement(LaTeXDrawNamespace.LATEXDRAW_NAMESPACE+':'+LaTeXDrawNamespace.XML_DISPLAY_GRID);
        elt.appendChild(document.createTextNode(String.valueOf(isGridDisplayed())));
        meta.appendChild(elt);
      }
      
      


      /**
       * @return The code of the selected figures.
       * @since 2.0.0
       */
02696       public String getCodeSelection()
      {
            if(selected==null || selected.isEmpty())
                  return null;
            
            String code = "";//$NON-NLS-1$
            String lineSep = System.getProperty("line.separator");//$NON-NLS-1$
            
            switch(getWhichCodeOutput())
            {
                  case CODE_PSTRICKS:
                        for(Figure f : selected.getFigures())
                              code += f.getCodePSTricks(bordersReal, pixelsPerCm) + lineSep;
                        
                        code = DviPsColors.getUserColoursCode(code) + code; 
                        break;
                        
                  default:
                        return null;
            }
            
            return code;
      }
      
      

      public void open(ObjectInputStream ois) throws IOException, ClassNotFoundException
      {
            readObject(ois);
      }


      
      /**
       * Align the selected figures.
       * @param alignCode The type of the alignment:
       * <ul>
       * <li>0: Align the selected figures to the figure on the left</li>
       * <li>1: Align the selected figures to the figure on the right</li>
       * <li>2: Align the selected figures to the figure on the top</li>
       * <li>3: Align the selected figures to the figure on the bottom</li>
       * <li>4: Align vertically the selected figures to the figure in the middle</li>
       * <li>5: Align horizontally the selected figures to the figure in the middle</li>
       * </ul>
       * @since 2.0.0
       */
02742       public void align(int alignCode)
      {
            if(selected==null || selected.size()<2)
                  return ;
            
            try
            {
                  int[] id = new int[selected.size()];
                  int i, size;
                  Draw clone = (Draw)selected.clone();
                  UndoRedoManager manager = parentPanel.getFrameParent().getUndoManager();
                  
                  for(i=0, size=selected.size(); i<size; i++)
                  {
                        id[i] = figures.indexOf(selected.getFigureAt(i));
                        
                        if(id[i]<0)
                              throw new IndexOutOfBoundsException();
                  }
                  
                  switch(alignCode)
                  {
                        case 0:
                              selected.alignLeft();
                              break;
                              
                        case 1:
                              selected.alignRight();
                              break;
                              
                        case 2:
                              selected.alignTop();
                              break;
                              
                        case 3:
                              selected.alignBottom();
                              break;
                              
                        case 4:
                              selected.alignMiddleVertically();
                              break;
                              
                        case 5:
                              selected.alignMiddleHorizontally();
                              break;
                              
                        default:
                              throw new IllegalArgumentException("Invalid alignment code: " + alignCode); //$NON-NLS-1$
                  }
                  
                  manager.add(UndoRedoManager.LABEL_ALIGN, id, clone, false);
                  parentPanel.getFrameParent().updateUndoRedo();
                  parentPanel.setIsModified(true);
            }
            catch(CloneNotSupportedException e) { e.printStackTrace(); }
      }
      
      

      /**
       * Distributes the selected figures.
       * @param distribCode The type of distribution:
       * <ul>
       * <li>0: distributes vertically at equal distance between the bottom sides of the selected figures</li>
       * <li>1: distributes vertically at equal distance between the middle of the selected figures</li>
       * <li>2: distributes vertically at equal distance between the top sides of the selected figures</li>
       * <li>3: distributes horizontally at equal distance between the selected figures</li>
       * <li>4: distributes vertically at equal distance between the left sides of the selected figures</li>
       * <li>5: distributes vertically at equal distance between the middle of the selected figures</li>
       * <li>6: distributes vertically at equal distance between the right sides of the selected figures</li>
       * <li>7: distributes vertically at equal distance between the selected figures</li>
       * </ul>
       * @since 2.0.0
       */
02816       public void distribute(int distribCode)
      {
            if(selected==null || selected.size()<2)
                  return ;
            
            try
            {
                  int[] id = new int[selected.size()];
                  int i, size;
                  Draw clone = (Draw)selected.clone();
                  UndoRedoManager manager = parentPanel.getFrameParent().getUndoManager();
                  
                  for(i=0, size=selected.size(); i<size; i++)
                  {
                        id[i] = figures.indexOf(selected.getFigureAt(i));
                        
                        if(id[i]<0)
                              throw new IndexOutOfBoundsException();
                  }
                  
                  switch(distribCode)
                  {
                        case 0:
                              selected.distributeVertBottom();
                              break;
                              
                        case 1:
                              selected.distributeVertMiddle();
                              break;
                              
                        case 2: 
                              selected.distributeVertTop();
                              break;
                              
                        case 3:
                              selected.distributeVertEqual();
                              break;
                              
                        case 4:
                              selected.distributeHorizLeft();
                              break;
                              
                        case 5:
                              selected.distributeHorizMiddle();
                              break;
                              
                        case 6:
                              selected.distributeHorizRight();
                              break;
                              
                        case 7:
                              selected.distributeHorizEqual();
                              break;
                              
                        default:
                              throw new IllegalArgumentException("Invalid distribution code: " + distribCode); //$NON-NLS-1$
                  }
                  
                  manager.add(UndoRedoManager.LABEL_DISTRIB, id, clone, false);
                  parentPanel.getFrameParent().updateUndoRedo();
                  parentPanel.setIsModified(true);
            }
            catch(CloneNotSupportedException e) { e.printStackTrace(); }
      }
      
      

      /**
       * Sets the latexdraw parameters from the <code>metadata</code> SVG tag.
       * @param meta The tag source of the parameters.
       * @since 2.0.0
       */
02888       public void setXMLMetadata(SVGMetadataElement meta)
      {
            if(meta==null)
                  return ;
            
            Node n;
            String name;
            int i = 0, size;
            boolean displayGrid = false;
            NodeList nl = meta.getElementsByTagNameNS(LaTeXDrawNamespace.LATEXDRAW_NAMESPACE_URI, SVGElements.SVG_METADATA);
            
            if(nl==null || nl.getLength()==0)
                  return;
            
            nl = nl.item(0).getChildNodes();
            
            for(i=0, size=nl.getLength(); i<size; i++)//analysis of the parameters. 
            {
                  n = nl.item(i);
                  
                  if(n!=null && LaTeXDrawNamespace.LATEXDRAW_NAMESPACE_URI.equals(n.getNamespaceURI()))
                  {
                        name = n.getNodeName();
                        
                        try
                        {
                              if(name.endsWith(LaTeXDrawNamespace.XML_AUTO_ADJUST))
                              {
                                    boolean is = Boolean.valueOf(n.getTextContent()).booleanValue();
                                    
                                    if(bordersComplete==null)
                                          bordersComplete = new DrawBorders(false);
                                    
                                    setAutoAdjustement(is);
                                    parentPanel.getFrameParent().getLMenuBar().getAutoAdjustBorders().setSelected(is);
                              }
                              else if(name.endsWith(LaTeXDrawNamespace.XML_BORDER))
                              {
                                    NamedNodeMap nnm = n.getAttributes();
                                    double x = Double.valueOf(nnm.getNamedItem(SVGAttributes.SVG_X).getNodeValue()).doubleValue();
                                    double y = Double.valueOf(nnm.getNamedItem(SVGAttributes.SVG_Y).getNodeValue()).doubleValue();
                                    double w = Double.valueOf(nnm.getNamedItem(SVGAttributes.SVG_WIDTH).getNodeValue()).doubleValue();
                                    double h = Double.valueOf(nnm.getNamedItem(SVGAttributes.SVG_HEIGHT).getNodeValue()).doubleValue();
                                    
                                    if(bordersComplete==null)
                                          bordersComplete = new DrawBorders(false);
                                    
                                    bordersComplete.setFirstPoint(x, y);
                                    bordersComplete.setLastPoint(x+w, y+h);
                              }
                              else if(name.endsWith(LaTeXDrawNamespace.XML_PPC))
                                    setPixelsPerCm(Double.valueOf(n.getTextContent()).intValue());
                              else if(name.endsWith(LaTeXDrawNamespace.XML_ZOOM))
                                    setZoom(Double.valueOf(n.getTextContent()).doubleValue());
                              else if(name.endsWith(LaTeXDrawNamespace.XML_UNIT))
                                    setUnitForPixelsPerCm(n.getTextContent());
                              else if(name.endsWith(LaTeXDrawNamespace.XML_CLASSIC_GRID))
                                    setClassicGridDrawn(Boolean.valueOf(n.getTextContent()).booleanValue());
                              else if(name.endsWith(LaTeXDrawNamespace.XML_GRID_GAP))
                                    setPersonalGridGap(Double.valueOf(n.getTextContent()).intValue());
                              else if(name.endsWith(LaTeXDrawNamespace.XML_CODE))
                                    setWhichCodeOutput(Double.valueOf(n.getTextContent()).shortValue());
                              else if(name.endsWith(LaTeXDrawNamespace.XML_DISPLAY_GRID))
                                    displayGrid = Boolean.valueOf(n.getTextContent()).booleanValue();
                              else if(name.endsWith(LaTeXDrawNamespace.XML_DRAW_BORDERS))
                                    setDrawBorders(Boolean.valueOf(n.getTextContent()).booleanValue());
                        }
                        catch(Exception e) { System.out.println(name + ": invalid value."); } //$NON-NLS-1$
                  }
            }
            
            setGridDisplayed(displayGrid);
            parentPanel.setXMLMetadata(nl);
            parentPanel.frameParent.setXMLMetadata(nl);
            parentPanel.codePanel.setXMLMetadata(nl);
      }

      
      
      /**
       * Sets if the grid must be displayed and updates the menu.
       * @param displayed
       * @since 2.0.0
       */
02972       public void setGridDisplayed(boolean displayed)
      {
            grid.setGridDisplayed(displayed);
            parentPanel.frameParent.menuBar.setGridDisplayed(displayed, isClassicGridDrawn());
      }

      
      /**
       * @return the grid
       * @since 2.0.0
       */
02983       public MagneticGrid getGrid()
      {
            return grid;
      }


      /**
       * @return the parentPanel.
       * @since 2.0.0
       */
02993       public DrawPanel getParentPanel()
      {
            return parentPanel;
      }



      /**
       * @return the drawBorders.
       * @since 2.0.0
       */
03004       public boolean isDrawBorders()
      {
            return drawBorders;
      }



      /**
       * @param drawBorders the drawBorders to set.
       * @since 2.0.0
       */
03015       public void setDrawBorders(boolean drawBorders)
      {
            this.drawBorders = drawBorders;
      }
}

Generated by  Doxygen 1.6.0   Back to index