/*
 * JReportFrame.java
 *
 * iReport  --  Visual designer for generating JasperReports Documents
 *  Copyright (C) 2002-2003  Giulio Toffoli gt@businesslogic.it
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 *  Giulio Toffoli
 *  Via T.Aspetti, 233
 *  35100 Padova ITALY
 *  gt@businesslogic.it
 *
 * Created on 12 febbraio 2003, 21.51
 *
 * Updated 13 July 2004, Robert Lamping,
 * - added: getNextElementKey(String keyElement)
 * - updated: paste(): Copied elements will get a modified key value based on previous
 *  prefix + "-"  + <next highest number for that prefix>.
 * -updated: jPanelReportMouseReleased
 *   new elements get the same treatment.
 *   new elements now get there own specific name
 
 
 */

package it.businesslogic.ireport.gui;
import it.businesslogic.ireport.gui.event.*;
import it.businesslogic.ireport.undo.*;
import it.businesslogic.ireport.util.*;
import it.businesslogic.ireport.*;
import java.awt.geom.*;
import java.awt.image.*;
import java.util.*;
import java.io.*;
import java.awt.*;
import java.awt.image.*;
import javax.swing.*;
/**
 *
 * @author  Administrator
 */
public class JReportFrame extends JMDIFrame {
    
    static int id = 0;
    static java.awt.Cursor hsplit = null;
    //private Graphics2D offscreen = null;
    //private Graphics2D offscreenDoc = null;
    //private BufferedImage offscreenImage = null;
    //private BufferedImage offscreenImageDoc = null;
    private int offscreenWidth = 0;
    private Dimension offscreenDimension = null;
    private boolean isDocDirty = true;
    
    private MainFrame mf = null;
    private BufferedImage[] shadowsImages = null;
    
    /** This point rappresent coords of left top corner of the popup menu.... */
    private java.awt.Point popup_opened_at = null;
    
    /** true if the the user is trnsforming a new element....*/
    private boolean transforming = false;
    
    /** We are dragging a band ?  */
    boolean band_dragging=false;
    /** We have started to drag a band from here */
    int band_dragging_origin=0;
    /** We are dragging this band... */
    Band band_dragging_band=null;
    /** State for XOR operation in band dragging... */
    boolean first_draw_band=true;
    boolean firstXORDraw = false ; //= false;   // why not true?
    boolean firstXORDrawTransforming = false;
    
    /**
     * This flag is true if we are selecting elements drawing a rectangle...
     */
    private boolean drag_selection_mode = false;
    /**
     * The origin of the selection rectangle...
     */
    private java.awt.Point drag_selection_origin = null;
    /**
     * The end of the selection rectangle...
     */
    private java.awt.Point drag_selection_end = null;
    /**
     * The flag is used to handle XOR operation on rectangle selection
     */
    private boolean first_draw_selection_rect = true;
    
    /**
     * Stroke to use when draw selection rectangle
     */
    private java.awt.Stroke selectionStroke = null;
    
    // Menus...
    private javax.swing.JMenu jMenuAlign;
    private javax.swing.JMenuItem jMenuItemAlignLeft;
    private javax.swing.JMenuItem jMenuItemAlignRight;
    private javax.swing.JMenuItem jMenuItemAlignTop;
    private javax.swing.JMenuItem jMenuItemAlignBottom;
    private javax.swing.JSeparator jSeparator19;
    private javax.swing.JMenuItem jMenuItemAlignVerticalAxis;
    private javax.swing.JMenuItem jMenuItemAlignHorizontalAxis ;
    private javax.swing.JSeparator jSeparator20;
    private javax.swing.JMenuItem jMenuItemAlignToBandTop;
    private javax.swing.JMenuItem jMenuItemAlignToBandBottom;
    private javax.swing.JMenu jMenuSize;
    private javax.swing.JMenuItem jMenuItemSameWidth;
    private javax.swing.JMenuItem jMenuItemSameWidthMax;
    private javax.swing.JMenuItem jMenuItemSameWidthMin;
    private javax.swing.JSeparator jSeparator17;
    private javax.swing.JMenuItem jMenuItemSameHeight;
    private javax.swing.JMenuItem jMenuItemSameHeightMax;
    private javax.swing.JMenuItem jMenuItemSameHeightMin;
    private javax.swing.JSeparator jSeparator18;
    private javax.swing.JMenuItem jMenuItemSameSize;
    private javax.swing.JMenu jMenuPosition;
    private javax.swing.JMenuItem jMenuItemCenterH;
    private javax.swing.JMenuItem jMenuItemCenterV;
    private javax.swing.JMenuItem jMenuItemCenterInBand;
    private javax.swing.JMenuItem jMenuItemCenterBackground;
    private javax.swing.JMenuItem jMenuItemJoinLeft;
    private javax.swing.JMenuItem jMenuItemJoinRight;
    private javax.swing.JSeparator jSeparator5;
    private javax.swing.JMenuItem jMenuHSpacing;
    private javax.swing.JMenuItem jMenuItemHSMakeEqual;
    private javax.swing.JMenuItem jMenuItemHSIncrease;
    private javax.swing.JMenuItem jMenuItemHSDecrease;
    private javax.swing.JMenuItem jMenuItemHSRemove;
    private javax.swing.JMenuItem jMenuVSpacing;
    private javax.swing.JMenuItem jMenuItemVSMakeEqual;
    private javax.swing.JMenuItem jMenuItemVSIncrease;
    private javax.swing.JMenuItem jMenuItemVSDecrease;
    private javax.swing.JMenuItem jMenuItemVSRemove;
    private javax.swing.JSeparator jSeparator8;
    private javax.swing.JMenuItem jMenuItemBringToFront;
    private javax.swing.JMenuItem jMenuItemSendToBack;
    private javax.swing.JPopupMenu jPopupMenuElementMS;
    private javax.swing.JMenuItem jMenuItemOrganize;
    private javax.swing.JMenuItem jMenuItemRightMargin;
    private javax.swing.JMenuItem jMenuItemLeftMargin;
    
    
    
    /*
     *  This variable is used to say if the resistence moving an element with mouse was
     *  exceeded
     */
    boolean resistenceExceeded = false;
    
    Point newObjectOrigin = null;
    
    boolean trasforming = false;
    int transformation_type= -1;
    Point transformation_origin=null;
    Point transformation_origin_end=null;
    Point transformation_undo_delta=null;
    
    /** Creates new form JReportFrame */
    public JReportFrame(Report report) {
        initComponents();
        jPanelReportContainer.setIgnoreRepaint(true);
        addFormatItemsToMenu(jPopupMenuElement);
        this.windowID = id++;
        
        selectionStroke = new java.awt.BasicStroke(
        (float)(2f),
        java.awt.BasicStroke.CAP_BUTT,
        java.awt.BasicStroke.JOIN_BEVEL,
        0f,
        new float[]{5f, 3f},
        0f
        );
        this.setPreferredSize(new Dimension(350,400));
        this.setNormalSize(new Dimension(350,400));
        if (hsplit == null) {
            hsplit = Cursor.getPredefinedCursor(Cursor.N_RESIZE_CURSOR);
        }
        this.jPanelReport.setJrf(this);
        this.report = report;
        
        this.newObjectType = ReportElementType.NONE;
        this.report=report;
        this.report.setReportFrame(this);
        this.setTitle(this.report.getName()+" "+this.report.getWidth()+"x"+this.report.getDesignHeight()+" ["+Misc.nvl(this.report.getFilename(),"unnamed")+"]");
        //System.out.println(this.getTitle());
        
        undoOperations = new Vector();
        clipboardObjects = new  Vector();
        selectedElements = new Vector();
        transformation_undo_delta = new Point(0,0);
        
        zoomFactor = 1.0;
        gridSize = 10;
        transformationMinSize =5;
        
        undoIndex = -1;
        
        // Init images...
        shadowsImages = new BufferedImage[5];
        
        shadowsImages[0] = Misc.loadBufferedImageFromResources(this,"it/businesslogic/ireport/icons/layout/sh_ur.gif");
        shadowsImages[1] = Misc.loadBufferedImageFromResources(this,"it/businesslogic/ireport/icons/layout/sh_r.gif");
        shadowsImages[2] = Misc.loadBufferedImageFromResources(this,"it/businesslogic/ireport/icons/layout/sh_lr.gif");
        shadowsImages[3] = Misc.loadBufferedImageFromResources(this,"it/businesslogic/ireport/icons/layout/sh_d.gif");
        shadowsImages[4] = Misc.loadBufferedImageFromResources(this,"it/businesslogic/ireport/icons/layout/sh_dl.gif");
        
        /*
        try {
            cursorplus = new Cursor(ResourceManager.getResource( getClass(), "cursorplus.cur"));
            cursorminus = new Cursor( ResourceManager.getResource(getClass(), "cursorminus.cur"));
        } catch (Exception ex)
        {}
         
        if (cursorplus == null )
        {
                if (com.ms.wfc.io.File.exists(com.ms.wfc.io.File.combine(  getProgramDir(), "com\\businesslogic\\ireport\\ui\\cursorplus.cur")))
                cursorplus = new Cursor(com.ms.wfc.io.File.combine(  getProgramDir(), "com\\businesslogic\\ireport\\ui\\cursorplus.cur"));
        }
         
        if (cursorminus == null )
        {
                if (com.ms.wfc.io.File.exists(com.ms.wfc.io.File.combine(  getProgramDir(), "com\\businesslogic\\ireport\\ui\\cursorminus.cur")))
                        cursorminus = new Cursor( com.ms.wfc.io.File.combine(  getProgramDir(), "com\\businesslogic\\ireport\\ui\\cursorminus.cur"));
        }
         
        if (cursorplus == null)
                cursorplus = Cursor.CROSS;
        if (cursorminus == null)
                cursorminus = Cursor.CROSS;
         */
        /*
        Enumeration enum = report.getElements().elements();
        Brush br = new Brush(imageList2.getBitmap(0));
        while (enum.hasMoreElements())
        {
                ReportElement re = (ReportElement)enum.nextElement();
                re.hached = br;
         
                if (re instanceof SubReportElement)
                {
                        ((SubReportElement)re).img = this.imageList4.getImage(0);
                }
                else if (re instanceof  ImageReportElement )
                {
         
                        ((ImageReportElement)re).defimg  = imageList3.getBitmap(0);
                }
                }
         */
        
        //offscreen.setBackground(new Color(128,128,128));
        setBackground(new Color(128,128,128));
        //Screen screen = Screen.getPrimary();
        offscreenDimension = Toolkit.getDefaultToolkit().getScreenSize();
        //offscreenImage = new java.awt.image.BufferedImage(offscreenDimension.width, offscreenDimension.height, java.awt.image.BufferedImage.TYPE_4BYTE_ABGR_PRE);
        //offscreenImageDoc  = new java.awt.image.BufferedImage(offscreenDimension.width, offscreenDimension.height, java.awt.image.BufferedImage.TYPE_4BYTE_ABGR_PRE);
        //offscreen = GraphicsEnvironment.getLocalGraphicsEnvironment().createGraphics(offscreenImage);
        
        //offscreen.setBackground(new Color(128,128,128));
        //offscreen.clearRect(0,0, offscreenDimension.width, offscreenDimension.height);
        //offscreen.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
        //offscreen.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
        //offscreen.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_DISABLE);
        
        //offscreenDoc = GraphicsEnvironment.getLocalGraphicsEnvironment().createGraphics(offscreenImageDoc);
        //offscreenDoc.setBackground(new Color(128,128,128));
        //offscreenDoc.clearRect(0,0, offscreenDimension.width, offscreenDimension.height);
        //offscreenDoc.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
        //offscreenDoc.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
        //offscreenDoc.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_DISABLE);
        //offscreen.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        
        //redrawAll(offscreen,new Rectangle(0,0,report.getWidth(),report.getHeight()), 0);
        
        //redrawAll( offscreen,new Rectangle(0,0,report.getWidth(),report.getHeight()), 0);
        
        this.jHorizontalScrollBar.setValue(0);
        this.jVerticalScrollBar.setValue(0);
        
        
        
        
    }
    
    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    private void initComponents() {//GEN-BEGIN:initComponents
        jPopupMenuBand = new javax.swing.JPopupMenu();
        jMenuItemPasteOnBand = new javax.swing.JMenuItem();
        jSeparator2 = new javax.swing.JSeparator();
        jMenuItemBandProperties = new javax.swing.JMenuItem();
        jPopupMenuElement = new javax.swing.JPopupMenu();
        jMenuItemElementProperties = new javax.swing.JMenuItem();
        jSeparator1 = new javax.swing.JSeparator();
        jMenuItemCut = new javax.swing.JMenuItem();
        jMenuItemCopy = new javax.swing.JMenuItem();
        jMenuItemPaste = new javax.swing.JMenuItem();
        jMenuItemDelete = new javax.swing.JMenuItem();
        jSeparator3 = new javax.swing.JSeparator();
        jMenuItemCopyStyle = new javax.swing.JMenuItem();
        jMenuItemPasteStyle = new javax.swing.JMenuItem();
        jMenuItemTransformStaticText = new javax.swing.JMenuItem();
        jMenuItemPattern = new javax.swing.JMenuItem();
        jSeparator4 = new javax.swing.JSeparator();
        jPanelSuperContainer = new javax.swing.JPanel();
        jPanelReportContainer = new javax.swing.JPanel();
        jPanelVRule = new javax.swing.JPanel();
        jPanelHContainerRule = new javax.swing.JPanel();
        jPanelCorner = new javax.swing.JPanel();
        jHorizontalRule = new it.businesslogic.ireport.gui.JRulePanel();
        jPanelReport = new it.businesslogic.ireport.gui.JReportPanel();
        jVerticalScrollBar = new javax.swing.JScrollBar();
        jPanelHScroll = new javax.swing.JPanel();
        jHorizontalScrollBar = new javax.swing.JScrollBar();
        jPanel1 = new javax.swing.JPanel();
        
        jMenuItemPasteOnBand.setFont(new java.awt.Font("Dialog", 0, 11));
        jMenuItemPasteOnBand.setIcon(new javax.swing.ImageIcon(""));
        jMenuItemPasteOnBand.setText("Paste here...");
        jMenuItemPasteOnBand.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItemPasteOnBandActionPerformed(evt);
            }
        });
        jMenuItemPasteOnBand.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                jMenuItemPasteOnBandMouseClicked(evt);
            }
        });
        
        jPopupMenuBand.add(jMenuItemPasteOnBand);
        
        jPopupMenuBand.add(jSeparator2);
        
        jMenuItemBandProperties.setFont(new java.awt.Font("Dialog", 0, 11));
        jMenuItemBandProperties.setIcon(new javax.swing.ImageIcon(""));
        jMenuItemBandProperties.setText("Band properties");
        jMenuItemBandProperties.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItemBandPropertiesActionPerformed(evt);
            }
        });
        
        jPopupMenuBand.add(jMenuItemBandProperties);
        
        jMenuItemElementProperties.setFont(new java.awt.Font("Dialog", 0, 11));
        jMenuItemElementProperties.setText("Properties");
        jMenuItemElementProperties.setIcon(new javax.swing.ImageIcon(""));
        jMenuItemElementProperties.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItemElementPropertiesActionPerformed(evt);
            }
        });
        jMenuItemElementProperties.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                jMenuItemElementPropertiesMouseClicked(evt);
            }
        });
        
        jPopupMenuElement.add(jMenuItemElementProperties);
        
        jPopupMenuElement.add(jSeparator1);
        
        jMenuItemCut.setFont(new java.awt.Font("Dialog", 0, 11));
        jMenuItemCut.setIcon(new javax.swing.ImageIcon(getClass().getResource("/it/businesslogic/ireport/icons/menu/cut.gif")));
        jMenuItemCut.setText("Cut");
        jMenuItemCut.setEnabled(false);
        jMenuItemCut.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItemCutActionPerformed(evt);
            }
        });
        
        jPopupMenuElement.add(jMenuItemCut);
        
        jMenuItemCopy.setFont(new java.awt.Font("Dialog", 0, 11));
        jMenuItemCopy.setIcon(new javax.swing.ImageIcon(getClass().getResource("/it/businesslogic/ireport/icons/menu/copy.gif")));
        jMenuItemCopy.setText("Copy");
        jMenuItemCopy.setEnabled(false);
        jMenuItemCopy.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItemCopyActionPerformed(evt);
            }
        });
        
        jPopupMenuElement.add(jMenuItemCopy);
        
        jMenuItemPaste.setFont(new java.awt.Font("Dialog", 0, 11));
        jMenuItemPaste.setText("Paste");
        jMenuItemPaste.setIcon(new javax.swing.ImageIcon(getClass().getResource("/it/businesslogic/ireport/icons/menu/paste.gif")));
        jMenuItemPaste.setEnabled(false);
        jMenuItemPaste.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItemPasteActionPerformed(evt);
            }
        });
        
        jPopupMenuElement.add(jMenuItemPaste);
        
        jMenuItemDelete.setFont(new java.awt.Font("Dialog", 0, 11));
        jMenuItemDelete.setText("Delete");
        jMenuItemDelete.setIcon(new javax.swing.ImageIcon(getClass().getResource("/it/businesslogic/ireport/icons/menu/delete.gif")));
        jMenuItemDelete.setEnabled(false);
        jMenuItemDelete.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItemDeleteActionPerformed(evt);
            }
        });
        
        jPopupMenuElement.add(jMenuItemDelete);
        
        jPopupMenuElement.add(jSeparator3);
        
        jMenuItemCopyStyle.setFont(new java.awt.Font("Dialog", 0, 11));
        jMenuItemCopyStyle.setLabel("Copy style");
        jMenuItemCopyStyle.setEnabled(false);
        jMenuItemCopyStyle.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItemCopyStyleActionPerformed(evt);
            }
        });
        
        jPopupMenuElement.add(jMenuItemCopyStyle);
        
        jMenuItemPasteStyle.setFont(new java.awt.Font("Dialog", 0, 11));
        jMenuItemPasteStyle.setLabel("Paste style");
        jMenuItemPasteStyle.setEnabled(false);
        jMenuItemPasteStyle.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItemPasteStyleActionPerformed(evt);
            }
        });
        
        jPopupMenuElement.add(jMenuItemPasteStyle);
        
        jMenuItemTransformStaticText.setFont(new java.awt.Font("Dialog", 0, 11));
        jMenuItemTransformStaticText.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_F3, 0));
        jMenuItemTransformStaticText.setLabel("Transform in Textfield");
        jMenuItemTransformStaticText.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItemTransformStaticTextActionPerformed(evt);
            }
        });
        
        jPopupMenuElement.add(jMenuItemTransformStaticText);
        
        jMenuItemPattern.setFont(new java.awt.Font("Dialog", 0, 11));
        jMenuItemPattern.setText("Field pattern");
        jMenuItemPattern.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItemPatternActionPerformed(evt);
            }
        });
        
        jPopupMenuElement.add(jMenuItemPattern);
        
        jPopupMenuElement.add(jSeparator4);
        
        
        try {
            setSelected(true);
        } catch (java.beans.PropertyVetoException e1) {
            e1.printStackTrace();
        }
        addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyPressed(java.awt.event.KeyEvent evt) {
                formKeyPressed(evt);
            }
        });
        
        jPanelSuperContainer.setLayout(new java.awt.BorderLayout());
        
        jPanelReportContainer.setLayout(new java.awt.BorderLayout());
        
        jPanelVRule.setLayout(null);
        
        jPanelVRule.setBackground(new java.awt.Color(255, 255, 255));
        jPanelVRule.setMaximumSize(new java.awt.Dimension(16, 32000));
        jPanelVRule.setMinimumSize(new java.awt.Dimension(16, 16));
        jPanelVRule.setPreferredSize(new java.awt.Dimension(16, 32767));
        jPanelReportContainer.add(jPanelVRule, java.awt.BorderLayout.WEST);
        
        jPanelHContainerRule.setLayout(new java.awt.BorderLayout());
        
        jPanelHContainerRule.setBackground(new java.awt.Color(255, 255, 255));
        jPanelHContainerRule.setMaximumSize(new java.awt.Dimension(32767, 16));
        jPanelHContainerRule.setMinimumSize(new java.awt.Dimension(16, 16));
        jPanelHContainerRule.setPreferredSize(new java.awt.Dimension(32767, 16));
        jPanelCorner.setLayout(null);
        
        jPanelCorner.setBorder(new javax.swing.border.BevelBorder(javax.swing.border.BevelBorder.RAISED));
        jPanelCorner.setMaximumSize(new java.awt.Dimension(16, 16));
        jPanelCorner.setMinimumSize(new java.awt.Dimension(16, 16));
        jPanelCorner.setPreferredSize(new java.awt.Dimension(16, 16));
        jPanelHContainerRule.add(jPanelCorner, java.awt.BorderLayout.WEST);
        
        jPanelHContainerRule.add(jHorizontalRule, java.awt.BorderLayout.CENTER);
        
        jPanelReportContainer.add(jPanelHContainerRule, java.awt.BorderLayout.NORTH);
        
        jPanelReport.addAncestorListener(new javax.swing.event.AncestorListener() {
            public void ancestorMoved(javax.swing.event.AncestorEvent evt) {
            }
            public void ancestorAdded(javax.swing.event.AncestorEvent evt) {
                jPanelReportAncestorAdded(evt);
            }
            public void ancestorRemoved(javax.swing.event.AncestorEvent evt) {
            }
        });
        jPanelReport.addComponentListener(new java.awt.event.ComponentAdapter() {
            public void componentResized(java.awt.event.ComponentEvent evt) {
                jPanelReportComponentResized(evt);
            }
        });
        jPanelReport.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyPressed(java.awt.event.KeyEvent evt) {
                jPanelReportKeyPressed(evt);
            }
        });
        jPanelReport.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mousePressed(java.awt.event.MouseEvent evt) {
                jPanelReportMousePressed(evt);
            }
            public void mouseReleased(java.awt.event.MouseEvent evt) {
                jPanelReportMouseReleased(evt);
            }
        });
        jPanelReport.addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {
            public void mouseDragged(java.awt.event.MouseEvent evt) {
                jPanelReportMouseDragged(evt);
            }
            public void mouseMoved(java.awt.event.MouseEvent evt) {
                jPanelReportMouseMoved(evt);
            }
        });
        
        jPanelReportContainer.add(jPanelReport, java.awt.BorderLayout.CENTER);
        
        jPanelSuperContainer.add(jPanelReportContainer, java.awt.BorderLayout.CENTER);
        
        jVerticalScrollBar.setMaximum(0);
        jVerticalScrollBar.addAdjustmentListener(new java.awt.event.AdjustmentListener() {
            public void adjustmentValueChanged(java.awt.event.AdjustmentEvent evt) {
                jVerticalScrollBarAdjustmentValueChanged(evt);
            }
        });
        jVerticalScrollBar.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyPressed(java.awt.event.KeyEvent evt) {
                jVerticalScrollBarKeyPressed(evt);
            }
        });
        jVerticalScrollBar.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseReleased(java.awt.event.MouseEvent evt) {
                jVerticalScrollBarMouseReleased(evt);
            }
        });
        
        jPanelSuperContainer.add(jVerticalScrollBar, java.awt.BorderLayout.EAST);
        
        jPanelHScroll.setLayout(new java.awt.BorderLayout());
        
        jHorizontalScrollBar.setMaximum(0);
        jHorizontalScrollBar.setOrientation(javax.swing.JScrollBar.HORIZONTAL);
        jHorizontalScrollBar.addAdjustmentListener(new java.awt.event.AdjustmentListener() {
            public void adjustmentValueChanged(java.awt.event.AdjustmentEvent evt) {
                jHorizontalScrollBarAdjustmentValueChanged(evt);
            }
        });
        
        jPanelHScroll.add(jHorizontalScrollBar, java.awt.BorderLayout.CENTER);
        
        jPanel1.setMaximumSize(new java.awt.Dimension(17, 17));
        jPanel1.setMinimumSize(new java.awt.Dimension(17, 17));
        jPanel1.setPreferredSize(new java.awt.Dimension(17, 17));
        jPanelHScroll.add(jPanel1, java.awt.BorderLayout.EAST);
        
        jPanelSuperContainer.add(jPanelHScroll, java.awt.BorderLayout.SOUTH);
        
        getContentPane().add(jPanelSuperContainer, java.awt.BorderLayout.CENTER);
        
        pack();
    }//GEN-END:initComponents
    
    private void jMenuItemPatternActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemPatternActionPerformed
        
        String pattern = "";
        FieldPatternDialog pd = new FieldPatternDialog( MainFrame.getMainInstance() ,true);
        pd.show();
        if (pd.getDialogResult() == javax.swing.JOptionPane.OK_OPTION ) {
            
            
            Enumeration selectedElementEnum = getSelectedElements().elements();
            
            while (selectedElementEnum.hasMoreElements()) {
                ReportElement re = (ReportElement)selectedElementEnum.nextElement();
                if (re instanceof TextFieldReportElement) {
                    ((TextFieldReportElement)re).setPattern( pd.getPattern() );
                }
            }
        }
        
        
    }//GEN-LAST:event_jMenuItemPatternActionPerformed
    
    private void jMenuItemPasteStyleActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemPasteStyleActionPerformed
        
        pasteStyle();
        
    }//GEN-LAST:event_jMenuItemPasteStyleActionPerformed
    
    private void jMenuItemCopyStyleActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemCopyStyleActionPerformed
        
        copyStyle();
        
    }//GEN-LAST:event_jMenuItemCopyStyleActionPerformed
    
    private void jMenuItemTransformStaticTextActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemTransformStaticTextActionPerformed
        transformStaticInTextFields();
    }//GEN-LAST:event_jMenuItemTransformStaticTextActionPerformed
    
    private void jMenuItemDeleteActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemDeleteActionPerformed
        deleteSelectedElements();
    }//GEN-LAST:event_jMenuItemDeleteActionPerformed
    
    private void jMenuItemPasteActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemPasteActionPerformed
        paste();
    }//GEN-LAST:event_jMenuItemPasteActionPerformed
    
    private void jMenuItemCopyActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemCopyActionPerformed
        copy();
    }//GEN-LAST:event_jMenuItemCopyActionPerformed
    
    private void jMenuItemCutActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemCutActionPerformed
        cut();
    }//GEN-LAST:event_jMenuItemCutActionPerformed
    
    private void jMenuItemBandPropertiesActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemBandPropertiesActionPerformed
        
        if ( popup_opened_at != null ) {
            
            // We must find the right band...
            int y = getLogicalDim( popup_opened_at.y - 10 + jVerticalScrollBar.getValue() ) + 10;
            Band myBand = getReport().getBandByPosition( y );
            
            if ( myBand != null ) {
                getMainFrame().jMenuItemBandsActionPerformed( evt );
                getMainFrame().getBandsDialog().setSelectedBand( myBand.getName() );
            }
            
        }
    }//GEN-LAST:event_jMenuItemBandPropertiesActionPerformed
    
    private void addFormatItemsToMenu(javax.swing.JComponent m){
        
        jMenuAlign = new javax.swing.JMenu();
        jMenuAlign.setText(it.businesslogic.ireport.util.I18n.getString("align", "Align..."));
        jMenuAlign.setFont(new java.awt.Font("Dialog", 0, 11));
        jMenuItemAlignLeft = new javax.swing.JMenuItem();
        jMenuItemAlignLeft.setFont(new java.awt.Font("Dialog", 0, 11));
        jMenuItemAlignLeft.setIcon(new javax.swing.ImageIcon(getClass().getResource("/it/businesslogic/ireport/icons/menu/elem_align_left.gif")));
        jMenuItemAlignLeft.setText(it.businesslogic.ireport.util.I18n.getString("alignLeft", "Align left"));
        jMenuItemAlignLeft.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                getMainFrame().jMenuItemAlignLeftActionPerformed(evt);
            }
        });
        
        jMenuAlign.add(jMenuItemAlignLeft);
        
        jMenuItemAlignRight = new javax.swing.JMenuItem();
        jMenuItemAlignRight.setFont(new java.awt.Font("Dialog", 0, 11));
        jMenuItemAlignRight.setIcon(new javax.swing.ImageIcon(getClass().getResource("/it/businesslogic/ireport/icons/menu/elem_align_right.gif")));
        jMenuItemAlignRight.setText(it.businesslogic.ireport.util.I18n.getString("alignRight", "Align right"));
        jMenuItemAlignRight.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                getMainFrame().jMenuItemAlignRightActionPerformed(evt);
            }
        });
        
        jMenuAlign.add(jMenuItemAlignRight);
        
        jMenuItemAlignTop = new javax.swing.JMenuItem();
        jMenuItemAlignTop.setFont(new java.awt.Font("Dialog", 0, 11));
        jMenuItemAlignTop.setIcon(new javax.swing.ImageIcon(getClass().getResource("/it/businesslogic/ireport/icons/menu/elem_align_top.gif")));
        jMenuItemAlignTop.setText(it.businesslogic.ireport.util.I18n.getString("alignTop", "Align top"));
        jMenuItemAlignTop.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                getMainFrame().jMenuItemAlignTopActionPerformed(evt);
            }
        });
        
        jMenuAlign.add(jMenuItemAlignTop);
        
        jMenuItemAlignBottom = new javax.swing.JMenuItem();
        jMenuItemAlignBottom.setFont(new java.awt.Font("Dialog", 0, 11));
        jMenuItemAlignBottom.setIcon(new javax.swing.ImageIcon(getClass().getResource("/it/businesslogic/ireport/icons/menu/elem_align_bottom.gif")));
        jMenuItemAlignBottom.setText(it.businesslogic.ireport.util.I18n.getString("alignBottom", "Align bottom"));
        jMenuItemAlignBottom.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                getMainFrame().jMenuItemAlignBottomActionPerformed(evt);
            }
        });
        
        jMenuAlign.add(jMenuItemAlignBottom);
        
        jSeparator19 = new javax.swing.JSeparator();
        jMenuAlign.add(jSeparator19);
        
        jMenuItemAlignVerticalAxis = new javax.swing.JMenuItem();
        jMenuItemAlignVerticalAxis.setFont(new java.awt.Font("Dialog", 0, 11));
        jMenuItemAlignVerticalAxis.setIcon(new javax.swing.ImageIcon(getClass().getResource("/it/businesslogic/ireport/icons/menu/elem_center_axis.gif")));
        jMenuItemAlignVerticalAxis.setText(it.businesslogic.ireport.util.I18n.getString("alignVerticalAxis", "Align vertical axis"));
        jMenuItemAlignVerticalAxis.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                getMainFrame().jMenuItemAlignVerticalAxisActionPerformed(evt);
            }
        });
        
        jMenuAlign.add(jMenuItemAlignVerticalAxis);
        
        jMenuItemAlignHorizontalAxis = new javax.swing.JMenuItem();
        jMenuItemAlignHorizontalAxis.setFont(new java.awt.Font("Dialog", 0, 11));
        jMenuItemAlignHorizontalAxis.setIcon(new javax.swing.ImageIcon(getClass().getResource("/it/businesslogic/ireport/icons/menu/elem_vcenter_axis.gif")));
        jMenuItemAlignHorizontalAxis.setText(it.businesslogic.ireport.util.I18n.getString("alignHorizontalAxis", "Align horizontal axis"));
        jMenuItemAlignHorizontalAxis.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                getMainFrame().jMenuItemAlignHorizontalAxisActionPerformed(evt);
            }
        });
        
        jMenuAlign.add(jMenuItemAlignHorizontalAxis);
        
        jSeparator20 = new javax.swing.JSeparator();
        jMenuAlign.add(jSeparator20);
        
        jMenuItemAlignToBandTop = new javax.swing.JMenuItem();
        jMenuItemAlignToBandTop.setFont(new java.awt.Font("Dialog", 0, 11));
        jMenuItemAlignToBandTop.setText(it.businesslogic.ireport.util.I18n.getString("alignToBandTop", "Align to band top"));
        jMenuItemAlignToBandTop.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                getMainFrame().jMenuItemAlignToBandTopActionPerformed(evt);
            }
        });
        
        jMenuAlign.add(jMenuItemAlignToBandTop);
        
        jMenuItemAlignToBandBottom = new javax.swing.JMenuItem();
        jMenuItemAlignToBandBottom.setFont(new java.awt.Font("Dialog", 0, 11));
        jMenuItemAlignToBandBottom.setText(it.businesslogic.ireport.util.I18n.getString("alignToBandBottom", "Align to band bottom"));
        jMenuItemAlignToBandBottom.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                getMainFrame().jMenuItemAlignToBandBottomActionPerformed(evt);
            }
        });
        
        jMenuAlign.add(jMenuItemAlignToBandBottom);
        
        m.add(jMenuAlign);
        
        jMenuSize = new javax.swing.JMenu();
        jMenuSize.setText(it.businesslogic.ireport.util.I18n.getString("size", "Size..."));
        jMenuSize.setFont(new java.awt.Font("Dialog", 0, 11));
        jMenuItemSameWidth = new javax.swing.JMenuItem();
        jMenuItemSameWidth.setFont(new java.awt.Font("Dialog", 0, 11));
        jMenuItemSameWidth.setIcon(new javax.swing.ImageIcon(getClass().getResource("/it/businesslogic/ireport/icons/menu/elem_same_hsize.gif")));
        jMenuItemSameWidth.setText(it.businesslogic.ireport.util.I18n.getString("sameWidth", "Same width"));
        jMenuItemSameWidth.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                getMainFrame().jMenuItemSameWidthActionPerformed(evt);
            }
        });
        
        jMenuSize.add(jMenuItemSameWidth);
        
        jMenuItemSameWidthMax = new javax.swing.JMenuItem();
        jMenuItemSameWidthMax.setFont(new java.awt.Font("Dialog", 0, 11));
        jMenuItemSameWidthMax.setIcon(new javax.swing.ImageIcon(getClass().getResource("/it/businesslogic/ireport/icons/menu/elem_same_hsize_plus.gif")));
        jMenuItemSameWidthMax.setText(it.businesslogic.ireport.util.I18n.getString("sameWidthMax", "Same width (max)"));
        jMenuItemSameWidthMax.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                getMainFrame().jMenuItemSameWidthMaxActionPerformed(evt);
            }
        });
        
        jMenuSize.add(jMenuItemSameWidthMax);
        
        jMenuItemSameWidthMin = new javax.swing.JMenuItem();
        jMenuItemSameWidthMin.setFont(new java.awt.Font("Dialog", 0, 11));
        jMenuItemSameWidthMin.setIcon(new javax.swing.ImageIcon(getClass().getResource("/it/businesslogic/ireport/icons/menu/elem_same_hsize_min.gif")));
        jMenuItemSameWidthMin.setText(it.businesslogic.ireport.util.I18n.getString("sameWidthMin", "Same width (min)"));
        jMenuItemSameWidthMin.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                getMainFrame().jMenuItemSameWidthMinActionPerformed(evt);
            }
        });
        
        jMenuSize.add(jMenuItemSameWidthMin);
        
        jSeparator17 = new javax.swing.JSeparator();
        jMenuSize.add(jSeparator17);
        
        jMenuItemSameHeight = new javax.swing.JMenuItem();
        jMenuItemSameHeight.setFont(new java.awt.Font("Dialog", 0, 11));
        jMenuItemSameHeight.setIcon(new javax.swing.ImageIcon(getClass().getResource("/it/businesslogic/ireport/icons/menu/elem_same_vsize.gif")));
        jMenuItemSameHeight.setText(it.businesslogic.ireport.util.I18n.getString("sameHeight", "Same height"));
        jMenuItemSameHeight.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                getMainFrame().jMenuItemSameHeightActionPerformed(evt);
            }
        });
        
        jMenuSize.add(jMenuItemSameHeight);
        
        jMenuItemSameHeightMin = new javax.swing.JMenuItem();
        jMenuItemSameHeightMin.setFont(new java.awt.Font("Dialog", 0, 11));
        jMenuItemSameHeightMin.setIcon(new javax.swing.ImageIcon(getClass().getResource("/it/businesslogic/ireport/icons/menu/elem_same_vsize_min.gif")));
        jMenuItemSameHeightMin.setText(it.businesslogic.ireport.util.I18n.getString("sameHeightMin", "Same height (min)"));
        jMenuItemSameHeightMin.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                getMainFrame().jMenuItemSameHeightMinActionPerformed(evt);
            }
        });
        
        jMenuSize.add(jMenuItemSameHeightMin);
        
        jMenuItemSameHeightMax = new javax.swing.JMenuItem();
        jMenuItemSameHeightMax.setFont(new java.awt.Font("Dialog", 0, 11));
        jMenuItemSameHeightMax.setIcon(new javax.swing.ImageIcon(getClass().getResource("/it/businesslogic/ireport/icons/menu/elem_same_vsize_plus.gif")));
        jMenuItemSameHeightMax.setText(it.businesslogic.ireport.util.I18n.getString("sameHeightMax", "Same height (max)"));
        jMenuItemSameHeightMax.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                getMainFrame().jMenuItemSameHeightMaxActionPerformed(evt);
            }
        });
        
        jMenuSize.add(jMenuItemSameHeightMax);
        
        jSeparator18 = new javax.swing.JSeparator();
        jMenuSize.add(jSeparator18);
        
        jMenuItemSameSize = new javax.swing.JMenuItem();
        jMenuItemSameSize.setFont(new java.awt.Font("Dialog", 0, 11));
        jMenuItemSameSize.setIcon(new javax.swing.ImageIcon(getClass().getResource("/it/businesslogic/ireport/icons/menu/elem_same_size.gif")));
        jMenuItemSameSize.setText(it.businesslogic.ireport.util.I18n.getString("sameSize", "Same size"));
        jMenuItemSameSize.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                getMainFrame().jMenuItemSameSizeActionPerformed(evt);
            }
        });
        
        jMenuSize.add(jMenuItemSameSize);
        
        m.add(jMenuSize);
        
        jMenuPosition = new javax.swing.JMenu();
        jMenuPosition.setText(it.businesslogic.ireport.util.I18n.getString("position", "Position..."));
        jMenuPosition.setFont(new java.awt.Font("Dialog", 0, 11));
        jMenuItemCenterH = new javax.swing.JMenuItem();
        jMenuItemCenterH.setFont(new java.awt.Font("Dialog", 0, 11));
        jMenuItemCenterH.setIcon(new javax.swing.ImageIcon(getClass().getResource("/it/businesslogic/ireport/icons/menu/elem_hcenter.gif")));
        jMenuItemCenterH.setText(it.businesslogic.ireport.util.I18n.getString("centerHorizontallyBandBased", "Center horizontally (band based)"));
        jMenuItemCenterH.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                getMainFrame().jMenuItemCenterHActionPerformed(evt);
            }
        });
        
        jMenuPosition.add(jMenuItemCenterH);
        
        jMenuItemCenterV = new javax.swing.JMenuItem();
        jMenuItemCenterV.setFont(new java.awt.Font("Dialog", 0, 11));
        jMenuItemCenterV.setIcon(new javax.swing.ImageIcon(getClass().getResource("/it/businesslogic/ireport/icons/menu/elem_vcenter.gif")));
        jMenuItemCenterV.setText(it.businesslogic.ireport.util.I18n.getString("centerVerticallyBandBased", "Center vertically (band based)"));
        jMenuItemCenterV.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                getMainFrame().jMenuItemCenterVActionPerformed(evt);
            }
        });
        
        jMenuPosition.add(jMenuItemCenterV);
        
        jMenuItemCenterInBand = new javax.swing.JMenuItem();
        jMenuItemCenterInBand.setFont(new java.awt.Font("Dialog", 0, 11));
        jMenuItemCenterInBand.setIcon(new javax.swing.ImageIcon(getClass().getResource("/it/businesslogic/ireport/icons/menu/elem_ccenter.gif")));
        jMenuItemCenterInBand.setText(it.businesslogic.ireport.util.I18n.getString("centerInBand", "Center in band"));
        jMenuItemCenterInBand.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                getMainFrame().jMenuItemCenterInBandActionPerformed(evt);
            }
        });
        
        jMenuPosition.add(jMenuItemCenterInBand);
        
        jMenuItemCenterBackground = new javax.swing.JMenuItem();
        jMenuItemCenterBackground.setFont(new java.awt.Font("Dialog", 0, 11));
        jMenuItemCenterBackground.setIcon(new javax.swing.ImageIcon(getClass().getResource("/it/businesslogic/ireport/icons/menu/elem_bcenter.gif")));
        jMenuItemCenterBackground.setText(it.businesslogic.ireport.util.I18n.getString("centerInBackground", "Center in background"));
        jMenuItemCenterBackground.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                getMainFrame().jMenuItemCenterBackgroundActionPerformed(evt);
            }
        });
        
        jMenuPosition.add(jMenuItemCenterBackground);
        
        jMenuItemJoinLeft = new javax.swing.JMenuItem();
        jMenuItemJoinLeft.setFont(new java.awt.Font("Dialog", 0, 11));
        jMenuItemJoinLeft.setText(it.businesslogic.ireport.util.I18n.getString("joinSidesLeft", "Join sides left"));
        jMenuItemJoinLeft.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                getMainFrame().jMenuItemJoinLeftActionPerformed(evt);
            }
        });
        
        jMenuPosition.add(jMenuItemJoinLeft);
        
        jMenuItemJoinRight = new javax.swing.JMenuItem();
        jMenuItemJoinRight.setFont(new java.awt.Font("Dialog", 0, 11));
        jMenuItemJoinRight.setText(it.businesslogic.ireport.util.I18n.getString("joinSidesRight", "Join sides right"));
        jMenuItemJoinRight.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                getMainFrame().jMenuItemJoinRightActionPerformed(evt);
            }
        });
        
        jMenuPosition.add(jMenuItemJoinRight);
        
        jMenuItemLeftMargin = new javax.swing.JMenuItem();
        jMenuItemLeftMargin.setFont(new java.awt.Font("Dialog", 0, 11));
        jMenuItemLeftMargin.setText("Join left page margin");
        jMenuItemLeftMargin.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_HOME, java.awt.event.InputEvent.SHIFT_MASK | java.awt.event.InputEvent.CTRL_MASK));
        jMenuItemLeftMargin.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                getMainFrame().jMenuItemLeftMarginActionPerformed(evt);
            }
        });
        
        jMenuPosition.add(jMenuItemLeftMargin);
        
        jMenuItemRightMargin = new javax.swing.JMenuItem();
        jMenuItemRightMargin.setFont(new java.awt.Font("Dialog", 0, 11));
        jMenuItemRightMargin.setText("Join right page margin");
        jMenuItemRightMargin.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_END, java.awt.event.InputEvent.SHIFT_MASK | java.awt.event.InputEvent.CTRL_MASK));
        jMenuItemRightMargin.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                getMainFrame().jMenuItemRightMarginActionPerformed(evt);
            }
        });
        
        jMenuPosition.add(jMenuItemRightMargin);
        
        m.add(jMenuPosition);
        
        jSeparator5 = new javax.swing.JSeparator();
        m.add(jSeparator5);
        
        jMenuHSpacing = new javax.swing.JMenuItem();
        jMenuHSpacing.setText(it.businesslogic.ireport.util.I18n.getString("horizontalSpacing", "Horizontal spacing..."));
        jMenuHSpacing.setFont(new java.awt.Font("Dialog", 0, 11));
        jMenuItemHSMakeEqual = new javax.swing.JMenuItem();
        jMenuItemHSMakeEqual.setFont(new java.awt.Font("Dialog", 0, 11));
        jMenuItemHSMakeEqual.setText(it.businesslogic.ireport.util.I18n.getString("makeEqual", "Make equal"));
        jMenuItemHSMakeEqual.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                getMainFrame().jMenuItemHSMakeEqualActionPerformed(evt);
            }
        });
        
        jMenuHSpacing.add(jMenuItemHSMakeEqual);
        
        jMenuItemHSIncrease = new javax.swing.JMenuItem();
        jMenuItemHSIncrease.setFont(new java.awt.Font("Dialog", 0, 11));
        jMenuItemHSIncrease.setText(it.businesslogic.ireport.util.I18n.getString("increase", "Increase"));
        jMenuItemHSIncrease.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                getMainFrame().jMenuItemHSIncreaseActionPerformed(evt);
            }
        });
        
        jMenuHSpacing.add(jMenuItemHSIncrease);
        
        jMenuItemHSDecrease = new javax.swing.JMenuItem();
        jMenuItemHSDecrease.setFont(new java.awt.Font("Dialog", 0, 11));
        jMenuItemHSDecrease.setText(it.businesslogic.ireport.util.I18n.getString("decrease", "Decrease"));
        jMenuItemHSDecrease.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                getMainFrame().jMenuItemHSDecreaseActionPerformed(evt);
            }
        });
        
        jMenuHSpacing.add(jMenuItemHSDecrease);
        
        jMenuItemHSRemove = new javax.swing.JMenuItem();
        jMenuItemHSRemove.setFont(new java.awt.Font("Dialog", 0, 11));
        jMenuItemHSRemove.setText(it.businesslogic.ireport.util.I18n.getString("remove", "Remove"));
        jMenuItemHSRemove.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                getMainFrame().jMenuItemHSRemoveActionPerformed(evt);
            }
        });
        
        jMenuHSpacing.add(jMenuItemHSRemove);
        
        m.add(jMenuHSpacing);
        
        jMenuVSpacing = new javax.swing.JMenuItem();
        jMenuVSpacing.setText(it.businesslogic.ireport.util.I18n.getString("verticalSpacing", "Vertical spacing"));
        jMenuVSpacing.setFont(new java.awt.Font("Dialog", 0, 11));
        jMenuItemVSMakeEqual = new javax.swing.JMenuItem();
        jMenuItemVSMakeEqual.setFont(new java.awt.Font("Dialog", 0, 11));
        jMenuItemVSMakeEqual.setText(it.businesslogic.ireport.util.I18n.getString("makeEqual", "Make equal"));
        jMenuItemVSMakeEqual.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                getMainFrame().jMenuItemVSMakeEqualActionPerformed(evt);
            }
        });
        
        jMenuVSpacing.add(jMenuItemVSMakeEqual);
        
        jMenuItemVSIncrease = new javax.swing.JMenuItem();
        jMenuItemVSIncrease.setFont(new java.awt.Font("Dialog", 0, 11));
        jMenuItemVSIncrease.setText(it.businesslogic.ireport.util.I18n.getString("increase", "Increase"));
        jMenuItemVSIncrease.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                getMainFrame().jMenuItemVSIncreaseActionPerformed(evt);
            }
        });
        
        jMenuVSpacing.add(jMenuItemVSIncrease);
        
        jMenuItemVSDecrease = new javax.swing.JMenuItem();
        jMenuItemVSDecrease.setFont(new java.awt.Font("Dialog", 0, 11));
        jMenuItemVSDecrease.setText(it.businesslogic.ireport.util.I18n.getString("decrease", "Decrease"));
        jMenuItemVSDecrease.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                getMainFrame().jMenuItemVSDecreaseActionPerformed(evt);
            }
        });
        
        jMenuVSpacing.add(jMenuItemVSDecrease);
        
        jMenuItemVSRemove = new javax.swing.JMenuItem();
        jMenuItemVSRemove.setFont(new java.awt.Font("Dialog", 0, 11));
        jMenuItemVSRemove.setText(it.businesslogic.ireport.util.I18n.getString("remove", "Remove"));
        jMenuItemVSRemove.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                getMainFrame().jMenuItemVSRemoveActionPerformed(evt);
            }
        });
        
        jMenuVSpacing.add(jMenuItemVSRemove);
        
        m.add(jMenuVSpacing);
        
        jSeparator8 = new javax.swing.JSeparator();
        m.add(jSeparator8);
        
        jMenuItemOrganize = new javax.swing.JMenuItem();
        jMenuItemOrganize.setFont(new java.awt.Font("Dialog", 0, 11));
        jMenuItemOrganize.setText("Organize as a table");
        jMenuItemOrganize.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_O, java.awt.event.InputEvent.SHIFT_MASK | java.awt.event.InputEvent.CTRL_MASK));
        jMenuItemOrganize.setIcon(new javax.swing.ImageIcon(""));
        jMenuItemOrganize.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                getMainFrame().jMenuItemOrganizeActionPerformed(evt);
            }
        });
        
        m.add(jMenuItemOrganize);
        
        jMenuItemBringToFront = new javax.swing.JMenuItem();
        jMenuItemBringToFront.setFont(new java.awt.Font("Dialog", 0, 11));
        jMenuItemBringToFront.setIcon(new javax.swing.ImageIcon(getClass().getResource("/it/businesslogic/ireport/icons/menu/sendtofront.gif")));
        jMenuItemBringToFront.setText(it.businesslogic.ireport.util.I18n.getString("bringToFront", "Bring to front"));
        jMenuItemBringToFront.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                getMainFrame().jMenuItemBringToFrontActionPerformed(evt);
            }
        });
        
        m.add(jMenuItemBringToFront);
        
        jMenuItemSendToBack = new javax.swing.JMenuItem();
        jMenuItemSendToBack.setFont(new java.awt.Font("Dialog", 0, 11));
        jMenuItemSendToBack.setIcon(new javax.swing.ImageIcon(getClass().getResource("/it/businesslogic/ireport/icons/menu/sendtoback.gif")));
        jMenuItemSendToBack.setText(it.businesslogic.ireport.util.I18n.getString("sendToBack", "Send to back"));
        jMenuItemSendToBack.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                getMainFrame().jMenuItemSendToBackActionPerformed(evt);
            }
        });
        
        m.add(jMenuItemSendToBack);
        
    }
    private void jMenuItemElementPropertiesActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemElementPropertiesActionPerformed
        openElementPropertiesDialog();
    }//GEN-LAST:event_jMenuItemElementPropertiesActionPerformed
    
    private void jMenuItemPasteOnBandActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemPasteOnBandActionPerformed
        
        if (this.popup_opened_at != null) {
            pasteHere( popup_opened_at );
        }
    }//GEN-LAST:event_jMenuItemPasteOnBandActionPerformed
    
    private void jMenuItemPasteOnBandMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jMenuItemPasteOnBandMouseClicked
        
    }//GEN-LAST:event_jMenuItemPasteOnBandMouseClicked
    
    private void jMenuItemElementPropertiesMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jMenuItemElementPropertiesMouseClicked
        
    }//GEN-LAST:event_jMenuItemElementPropertiesMouseClicked
    
    private void jVerticalScrollBarKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_jVerticalScrollBarKeyPressed
        
    }//GEN-LAST:event_jVerticalScrollBarKeyPressed
    
    private void formKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_formKeyPressed
        
    }//GEN-LAST:event_formKeyPressed
    
    private void jPanelReportKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_jPanelReportKeyPressed
        
        /*
        mf.logOnConsole(evt.getKeyCode() + " "+
        (((evt.getModifiers() & evt.CTRL_MASK) != 0 ) ? "CTL " : "") +
        (((evt.getModifiers() & evt.ALT_MASK) != 0 ) ? "ALT " : "") +
        (((evt.getModifiers() & evt.SHIFT_MASK) != 0 ) ? "SHIFT " : "") + "\n");
         */
        /*
        if (( evt.getModifiers() & evt.CTRL_MASK) != 0 &&
            evt.getKeyCode() == java.awt.event.KeyEvent.VK_Z )
        {
          .undo();
          return;
        }
         
        if (( evt.getModifiers() & evt.CTRL_MASK ) != 0 &&
            evt.getKeyCode() == java.awt.event.KeyEvent.VK_Y)
        {
          mf.redo();
          return;
        }
         */
        
        // Standard speed:
        int x=1, y=1;
        
        // Increase the speed of movement if the Shift key is pressed
        if (( evt.getModifiers() & evt.SHIFT_MASK ) != 0) {
            x = 10;
            y = 10;
        }
        
        
        //if ((evt.getModifiers() & evt.ALT_MASK) != 0)
        //    System.out.println("Tasto:"+evt.getKeyCode());
        if (evt.getKeyCode() == java.awt.event.KeyEvent.VK_DELETE) {
            this.deleteSelectedElements();
            return;
        }
        /* Begin code Robert Lamping, 12 July 2004 */
        /* Short cut keys for quick alignment */
        else  if ( (( evt.getModifiers() & evt.SHIFT_MASK) != 0) &&
        (( evt.getModifiers() & evt.CTRL_MASK) != 0) ) {
            
            /* all key presses when SHIFT/CTRL are both pressed */
            
            /* Short cuts for alignments */
            switch ( evt.getKeyCode()) {
                case java.awt.event.KeyEvent.VK_UP:
                    /* align top */
                    makeOperation( OperationType.ALIGN_TOP);
                    break;
                case java.awt.event.KeyEvent.VK_DOWN:
                    /* align bottom */
                    makeOperation( OperationType.ALIGN_BOTTOM);
                    break;
                case java.awt.event.KeyEvent.VK_LEFT:
                    /* align left */
                    //makeOperation( OperationType.ALIGN_LEFT);
                    break;
                case java.awt.event.KeyEvent.VK_RIGHT:
                    /* align right */
                    makeOperation( OperationType.ALIGN_RIGHT);
                    break;
                case java.awt.event.KeyEvent.VK_PAGE_UP:
                    /* align against band top */
                    makeOperation( OperationType.ALIGN_TOP_TO_BAND);
                    break;
                case java.awt.event.KeyEvent.VK_PAGE_DOWN:
                    /* align against band bottom */
                    makeOperation( OperationType.ALIGN_BOTTOM_TO_BAND);
                    break;
                case java.awt.event.KeyEvent.VK_HOME:
                    /* align against left margin */
                    makeOperation( OperationType.ALIGN_TO_LEFT_MARGIN);
                    break;
                case java.awt.event.KeyEvent.VK_END:
                    /* align against right margin */
                    makeOperation( OperationType.ALIGN_TO_RIGHT_MARGIN);
                    break;
                case java.awt.event.KeyEvent.VK_L:
                    /* join left */
                    makeOperation( OperationType.JOIN_LEFT);
                    break;
                case java.awt.event.KeyEvent.VK_R:
                    /* join right */
                    makeOperation( OperationType.JOIN_RIGHT);
                    break;
                case java.awt.event.KeyEvent.VK_O:
                    /* organize as a table, with spacing inbetwween */
                    makeOperation( OperationType.ORGANIZE_AS_A_TABLE);
                    break;
            }
            
        }
        /* End code Robert Lamping, 12 July 2004 */
        
        else if (evt.getKeyCode() == java.awt.event.KeyEvent.VK_UP) {
            y *= -1;
            x = 0;
            
            // Remove selected elements...
            // Up of x...
            Vector changed_elements = new Vector(); 
            for (Iterator i = selectedElements.iterator(); i.hasNext(); ) {
                ReportElement element = (ReportElement) i.next();
                element.trasform(new Point(x,y), TransformationType.TRANSFORMATION_MOVE);
                element.adjustBand();
                changed_elements.add(element);
            }
            fireReportListenerReportElementsChanged(new ReportElementChangedEvent(this, changed_elements , ReportElementChangedEvent.CHANGED));
            
            this.getMainFrame().getElementPropertiesDialog().updateSelection();
            jPanelReport.repaint();
        }
        else if (evt.getKeyCode() == java.awt.event.KeyEvent.VK_LEFT) {
            x *= -1;
            y = 0;
            
            // Up of x...
            Vector changed_elements = new Vector(); 
            for (Iterator i = selectedElements.iterator(); i.hasNext(); ) {
                ReportElement element = (ReportElement) i.next();
                element.trasform(new Point(x,y), TransformationType.TRANSFORMATION_MOVE);
                element.adjustBand();
                changed_elements.add(element);
            }
            fireReportListenerReportElementsChanged(new ReportElementChangedEvent(this, changed_elements , ReportElementChangedEvent.CHANGED));
            this.getMainFrame().getElementPropertiesDialog().updateSelection();
            jPanelReport.repaint();
        }
        else if (evt.getKeyCode() == java.awt.event.KeyEvent.VK_RIGHT) {
            y=0;
            // Remove selected elements...
            // Up of x...
            Vector changed_elements = new Vector(); 
            for (Iterator i = selectedElements.iterator(); i.hasNext(); ) {
                ReportElement element = (ReportElement) i.next();
                element.trasform(new Point(x,y), TransformationType.TRANSFORMATION_MOVE);
                element.adjustBand();
                changed_elements.add(element);
            }
            fireReportListenerReportElementsChanged(new ReportElementChangedEvent(this, changed_elements , ReportElementChangedEvent.CHANGED));
            this.getMainFrame().getElementPropertiesDialog().updateSelection();
            
            jPanelReport.repaint();
        }
        else if (evt.getKeyCode() == java.awt.event.KeyEvent.VK_DOWN) {
            x = 0;
            // Remove selected elements...
            // Up of x...
            Vector changed_elements = new Vector(); 
            for (Iterator i = selectedElements.iterator(); i.hasNext(); ) {
                ReportElement element = (ReportElement) i.next();
                element.trasform(new Point(x,y), TransformationType.TRANSFORMATION_MOVE);
                element.adjustBand();
                changed_elements.add(element);
            }
            fireReportListenerReportElementsChanged(new ReportElementChangedEvent(this, changed_elements , ReportElementChangedEvent.CHANGED));
            this.getMainFrame().getElementPropertiesDialog().updateSelection();
            jPanelReport.repaint();
        }
        else if (evt.getKeyCode() == java.awt.event.KeyEvent.VK_F2) {
            // Edit static Text
            
            DeleteElementsOperation undoOp = new DeleteElementsOperation(this);
            for (Iterator i = selectedElements.iterator(); i.hasNext(); ) {
                ReportElement re = (ReportElement) i.next();
                if(re instanceof TextReportElement){
                    String te = ((TextReportElement)re).getText();
                    String result = javax.swing.JOptionPane.showInputDialog(this, "Please enter new Value", te);
                    if(result != null && !result.equals("")){
                        ((TextReportElement)re).setText(result);
                        undoOp.addElement(  re, getReport().getElements().indexOf(re));
                        fireReportListenerReportElementsChanged(new ReportElementChangedEvent(this, re , ReportElementChangedEvent.CHANGED));
                    }
                }
            }
            this.addUndoOperation(undoOp);
            this.getMainFrame().getElementPropertiesDialog().updateSelection();
            jPanelReport.repaint();
        }
        else if (evt.getKeyCode() == java.awt.event.KeyEvent.VK_F3) {
            
            transformStaticInTextFields();
            this.getMainFrame().getElementPropertiesDialog().updateSelection();
        }
        /* Begin code by Robert Lamping, 12 july 2004 */
        /* Copy and paste via CTRL/INS and SHIFT insert */
        else if ( (( evt.getModifiers() & evt.CTRL_MASK) != 0 ) && evt.getKeyCode() == java.awt.event.KeyEvent.VK_INSERT) {
            copy();
        } else if ( (( evt.getModifiers() & evt.SHIFT_MASK) != 0) && evt.getKeyCode() == java.awt.event.KeyEvent.VK_INSERT) {
            paste();
        }
        /* End code Robert Lamping, 12 July 2004 */
        
        
    }//GEN-LAST:event_jPanelReportKeyPressed
    
    private void jPanelReportMouseReleased(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jPanelReportMouseReleased
        
        if (drag_selection_mode && evt.getButton() == evt.BUTTON1) {
            
            Graphics2D gg = (Graphics2D)jPanelReport.getGraphics();
            gg.setXORMode(Color.GREEN);
            
            Stroke s = gg.getStroke();
            gg.setStroke(selectionStroke);
            
            if (!first_draw_selection_rect) {
                gg.drawRect((int)Math.min( drag_selection_origin.x, drag_selection_end.x),
                (int)Math.min( drag_selection_origin.y, drag_selection_end.y),
                (int)Math.abs( drag_selection_origin.x - drag_selection_end.x),
                (int)Math.abs( drag_selection_origin.y - drag_selection_end.y));
            }
            
            gg.setPaintMode();
            if (s != null) {
                gg.setStroke(s);
            }
            drag_selection_mode = false;
            first_draw_selection_rect = true;
            
            if (( evt.getModifiers() & evt.SHIFT_MASK ) == 0){
                setSelectedElement(null);
            }
            
            int delta_w = evt.getX()- drag_selection_origin.x;
            int delta_h = evt.getY()- drag_selection_origin.y;
            int delta_x = (delta_w < 0) ? delta_w: 0;
            int delta_y = (delta_h < 0) ? delta_h : 0;
            
            if (jHorizontalScrollBar == null ||
            jVerticalScrollBar == null  ||
            drag_selection_origin == null ||
            drag_selection_end == null) {
                return;
            }
            
            int originX = getLogicalDim(  Math.min( drag_selection_origin.x-10+jHorizontalScrollBar.getValue(),
            drag_selection_end.x-10+jHorizontalScrollBar.getValue()))+10;
            int originY = getLogicalDim(  Math.min( drag_selection_origin.y-10+jVerticalScrollBar.getValue(),
            drag_selection_end.y-10+jVerticalScrollBar.getValue()))+10;
            int width  =  getLogicalDim(  Math.abs( delta_w ) );
            int height =  getLogicalDim(  Math.abs( delta_h ) );
            
            // We need logical coordinates...
            java.awt.Rectangle rect = new java.awt.Rectangle( originX, originY, width, height );
            boolean selection_changed = false;
            for (Iterator i = getReport().getElements().iterator(); i.hasNext(); ) {
                ReportElement re = (ReportElement) i.next();
                if ( re.intersects( rect ) ) {
                    if (!selection_changed) selection_changed = true;
                    addSelectedElement(re,false);
                }
            }
            if (selection_changed)
            {
                fireSelectionChangedEvent();
            }   
            
        }
        else if (band_dragging && evt.getButton() == evt.BUTTON1 ) {
            
            band_dragging = false;
            jPanelReport.setCursor( Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
            
            // _________ BEGIN DRAGGING REAL TIME CODE ___________________
            // Work with logical dimensions...
            int delta = getLogicalDim( evt.getY()-band_dragging_origin );
            if (delta != 0) {
                BandDraggedOperation undoOp = new BandDraggedOperation(this,band_dragging_band);
                // Search for min_height that don't cover elements in this band...
                int min_height = 0;
                
                int band_h = report.getBandYLocation(band_dragging_band) +10;
                
                if (delta < -(  band_dragging_band.getHeight()-min_height) ) {
                    delta= -(band_dragging_band.getHeight()-min_height);
                }
                //brainjava/wade
                /******
                 *I commented out the next line because we need to be able to create bands which can make the design
                 *size larger than the reports "page" size.  The page/paper size is just that.  The size of a print/page.
                 *this should not be dictating how large a band can be.  Bands can be set to start a new page.  By not
                 *allowing the users to resize their bands as they need to we limit them.  Crystal reports allows this, and
                 *this is some of their best functionality.
                 * gt - this is not permitted by jasperreports.
                 ******/
                int designHeight = report.getDesignHeightNoBG();
                if (report.isIsTitleNewPage()) {
                    designHeight -= report.getBandByName("title").getHeight();
                }
                
                if (report.isIsSummaryNewPage()) {
                    designHeight -= report.getBandByName("summary").getHeight();
                }
                
                if (!band_dragging_band.getName().equals("background")  &&
                !( band_dragging_band.getName().equals("title") && report.isIsTitleNewPage()) &&
                !( band_dragging_band.getName().equals("summary") && report.isIsSummaryNewPage()) &&
                designHeight+delta > report.getHeight()) {
                    delta = report.getHeight() - designHeight;
                }
                
                if (band_dragging_band.getHeight()+ delta > (report.getHeight() - report.getTopMargin() - report.getBottomMargin())) {
                    delta = (report.getHeight() - report.getTopMargin() - report.getBottomMargin()) - band_dragging_band.getHeight();
                }
                
                // Redraw all under the min height...
                band_dragging_band.setHeight( band_dragging_band.getHeight() + delta );
                
                this.jPanelReportComponentResized( new java.awt.event.ComponentEvent( jPanelReport, 0 ));
                
                //this.label1.setText("DRagged: "+band_dragging_band.name +" "+delta);
                int edge_y = Math.min(report.getBandYLocation(band_dragging_band)+band_dragging_band.getHeight(),
                report.getBandYLocation(band_dragging_band)+band_dragging_band.getHeight()-delta);
                
                //e = report.getElements().elements();
                
                undoOp.setBandDelta(delta);
                
                // Adjust all elements positions...
                //
                
                for (Iterator i = report.getElements().iterator(); i.hasNext(); ) {
                    ReportElement re = (ReportElement) i.next();
                    if (re.position.y >= edge_y+10) {
                        // I should add the distance form the base of resized band, and my element...
                        Rectangle oldBounds = new Rectangle( re.getPosition().x, re.getPosition().y, re.getWidth(), re.getHeight());
                        
                        int space_before_band = band_h - re.position.y - re.height;
                        if (band_h <= report.getBandYLocation(re.band) +10){
                            space_before_band = 0;
                        }
                        re.setPosition(new Point(re.position.x,re.position.y+delta));
                        //this.updateElement(re,new Rectangle(re.position.x-5,re.position.y-5-delta,re.width+10, re.height+10+delta));
                        Rectangle newBounds = new Rectangle( re.getPosition().x, re.getPosition().y, re.getWidth(), re.getHeight());
                        undoOp.addElement(re, oldBounds, newBounds );
                    }
                }
                addUndoOperation(undoOp);
            }
                        /*
                        getLogicalDim(panel9.getWidth()),getLogicalDim(panel9.getHeight()));
                        Rectangle rect = panel9.getDisplayRect(); //new Rectangle(0,0,report.getPagesize().x, report.getDesignHeight());
                         
                        // drag down all elements under this band...
                        redrawAll(offscreenbm.getGraphics(),rect,0);
                        Rectangle clipRect = panel9.getDisplayRect();      //new Rectangle(rect);
                        //clipRect.offset(-HScrollBar1.getValue(),-VScrollBar1.getValue());
                        //panel9.createGraphics().drawRect(clipRect,RasterOp.BLACK);
                        panel9.createGraphics().drawImage( offscreenbm,rect, clipRect ,false);
                         */
            this.getMainFrame().getJTreeDocument().updateUI();
            
            jPanelReport.repaint();
            // _________ STOP DRAGGING REAL TIME CODE ___________________
                        /* TODO
                        if (selectedElements.size()>0)
                        {
                                MainForm mf = (MainForm)this.getMDIParent();
                                if (mf != null)
                                {
                                        if (mf.isPropertiesOpened())
                                        {
                                                mf.initReportForm();
                                                mf.ep.setEelement(this,getSelectedElements());
                                                mf.ep.show();
                                        }
                                }
                        }
                         TODO */
        }
        
        if (newObjectType != ReportElementType.NONE) {
            // The second point was clicked
            
            firstXORDraw = true;

            // Find the band to associate to the new element...
            
            int delta_w = gridMultiple(evt.getX()-newObjectOrigin.x);
            int delta_h = gridMultiple(evt.getY()-newObjectOrigin.y);
            int delta_x = (delta_w < 0) ? delta_w : 0;
            int delta_y = (delta_h < 0) ? delta_h : 0;
            
            int originX = getLogicalDim( Math.min(newObjectOrigin.x-10+jHorizontalScrollBar.getValue(),
            newObjectOrigin.x+delta_x-10+jHorizontalScrollBar.getValue()))+10;
            int originY = getLogicalDim( Math.min(newObjectOrigin.y-10+jVerticalScrollBar.getValue(),
            newObjectOrigin.y+delta_y-10+jVerticalScrollBar.getValue()))+10;
            int width = getLogicalDim( Math.abs(delta_w) );
            int height = getLogicalDim( Math.abs(delta_h) );

                        
            if (newObjectType == ReportElementType.LINE_ELEMENT) {
                /* When shift button is pressed too, then there will be no align ment on the grid */
                if ( ( evt.getModifiers() & evt.SHIFT_MASK)  != 0) {
                    Point straight = straighten( delta_w, delta_h);
                    delta_w = straight.x;
                    delta_h = straight.y;
                }
            }
            
            Band bname = getReport().getBandByPosition( originY );
            
            ReportElement re = ReportElementFactory.create( newObjectType, originX, originY, getLogicalDim(delta_w), getLogicalDim(delta_h));
            
            /* Begin Code Robert Lamping, 13 july 2004 */
            // Element does not know about other elements, the frame does, so here we reset the key.
            // barcode becomes barcode-1, or higher depending on what the highest sub number is.
            // Same for graphcs image, or whatever initial name
            re.setKey( getNextElementKey( re.getKey()) ) ;
            
            /* End Code Robert Lamping, 13 july 2004 */
            
            re.setBand( bname );
            
            boolean ok = true;
            
            if ( newObjectType == ReportElementType.CHART_ELEMENT  )
            {
                /* Check if we have all to create the chart element... */
                if (this.getReport().getScriptletHandling() != Report.SCRIPTLET_IREPORT_INTERNAL_HANDLING )
                {
                    
                    if (JOptionPane.showConfirmDialog(this.getMainFrame(),
                it.businesslogic.ireport.util.I18n.getString( "usingSeries",
                "To use the charts and series, you must leave iReport to handle the scriptlet class code internally.\n"+
                "You can set how handle scriptlet in report properties form.\n\nDo you want activate this option now?"),
                    "Chart element", JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.INFORMATION_MESSAGE) != JOptionPane.OK_OPTION) {
                        ok = false;
                        getReportPanel().repaint();
                    }
                
                    this.getReport().setScriptletHandling( Report.SCRIPTLET_IREPORT_INTERNAL_HANDLING );
                }
                
                it.businesslogic.ireport.chart.gui.IReportChartDialog icd = new it.businesslogic.ireport.chart.gui.IReportChartDialog(this.getMainFrame(),true);
                icd.setJReportFrame( this );
                ChartReportElement cre = (ChartReportElement)re ;
                icd.setProperties(cre.getProps());
                icd.show();     
                if (icd.getDialogResult() == javax.swing.JOptionPane.OK_OPTION)
                {
                    // Integrate properties...
                    Properties props = icd.getProperties();
                    Iterator keys = props.keySet().iterator();
                    while (keys.hasNext())
                    {
                        String key = ""+keys.next();
                        String val = props.getProperty(key);
                        cre.getProps().setProperty(key, val);

                    }

                    cre.updateChartImage();
                }
                else
                {
                    ok = false;
                }
                
            }
             
            if (ok)
            {
                fireReportListenerReportElementsChanged(new ReportElementChangedEvent(this, re , ReportElementChangedEvent.ADDED));
            
                addUndoOperation( new  InsertElementOperation( this, re ) );

                report.getElements().addElement(re);
                            /*
                            if (selectedElements.size() > 0)
                            {
                                    ReportElement oldselected = (ReportElement)selectedElements.firstElement();
                                    Rectangle rect = new Rectangle(oldselected.position.x-5,oldselected.position.y-5,oldselected.width+10, oldselected.height+10);
                                    setSelectedElement(null);
                                    redrawAll(offscreen ,rect,5);
                                    Rectangle clipRect = new Rectangle(getZoomedDim(oldselected.position.x-10)-5+10-jHorizontalScrollBar.getValue(),
                                                                                                               getZoomedDim(oldselected.position.y-10)-5+10-jVerticalScrollBar.getValue(),
                                                                                                               getZoomedDim(oldselected.width)+10,
                                                                                                               getZoomedDim(oldselected.height)+10);
                                    clipRect.translate(-jHorizontalScrollBar.getValue(),-jVerticalScrollBar.getValue());

                                    //panel9.createGraphics().drawImage( offscreenbm,clipRect, clipRect ,false);
                                    jPanelReport.getGraphics().drawImage( offscreenImage ,
                                                                          clipRect.x ,clipRect.y, clipRect.width,clipRect.height,
                                                                          clipRect.x ,clipRect.y, clipRect.width,clipRect.height,
                                                                          (ImageObserver)this);
                            }
                             */
                setSelectedElement(re);
            }
            newObjectOrigin = null;
            // Add undo operation...
            //UndoOperation uo = new UndoOperation(UndoOperationType.UNDO_INSERT);
            //uo.params.addElement(new Integer(1));
            //ReportElement clone = re.cloneMe();
            
            //uo.params.addElement(clone);
            //addUndoOperation(uo);
            //repaint();
            
            newObjectType = ReportElementType.NONE;
            
            jPanelReport.setCursor( Cursor.getDefaultCursor());
            getMainFrame().setActiveTool(0);
            
            
        }
        
        if (trasforming) {
            trasforming = false;
            
            jPanelReport.setCursor( Cursor.getDefaultCursor());
            
            if (transformation_type != TransformationType.TRANSFORMATION_MOVE || resistenceExceeded == true) {
                Point p = new Point(transformation_origin_end);
                p.x = getLogicalDim(p.x);
                p.y = getLogicalDim(p.y);
                p.x -= getLogicalDim(transformation_origin.x);
                p.y -= getLogicalDim(transformation_origin.y);
                
                Enumeration e = getSelectedElements().elements();
                TransformElementsOperation undoOp = new TransformElementsOperation(this);
                Vector changed_elements = new Vector();
                while (e.hasMoreElements()) {
                    ReportElement re = (ReportElement)e.nextElement();
                    
                    Rectangle oldBounds = new Rectangle( re.getPosition().x, re.getPosition().y, re.getWidth(), re.getHeight());
                    re.trasform(p, transformation_type);
                    Band oldBand = re.getBand();
                    re.adjustBand();
                    Band newBand = re.getBand();
                    Rectangle newBounds = new Rectangle( re.getPosition().x, re.getPosition().y, re.getWidth(), re.getHeight());
                    undoOp.addElement(re, oldBounds, newBounds,oldBand,newBand);
                    
                    addUndoOperation(undoOp);
                    changed_elements.add( re );
                    
                }
                if (changed_elements.size() > 0)
                {
                    fireReportListenerReportElementsChanged(new ReportElementChangedEvent(this, changed_elements , ReportElementChangedEvent.CHANGED));
                }
                
                jPanelReport.repaint();
            }
            
                /*
                        if (p.x!=0 || p.y != 0)
                        {
                                UndoOperation uo = new UndoOperation(UndoOperationType.UNDO_TRANSFORMATION);
                                uo.params.addElement(p);
                                uo.params.addElement(new Integer( transformation_type ) );
                                Enumeration enum = selectedElements.elements();
                                while (enum.hasMoreElements())
                                {
                                                uo.params.addElement(enum.nextElement());
                                }
                                addUndoOperation(uo);
                        }
                 */
            transformation_undo_delta = new Point(0,0);
            transformation_type = TransformationType.TRANSFORMATION_NONE;
                /*
                        MainForm mf = (MainForm)this.getMDIParent();
                        if (mf != null)
                        {
                                if (mf.isPropertiesOpened())
                                {
                                        mf.initReportForm();
                                        mf.ep.setEelement(this,getSelectedElements());
                                        mf.ep.show();
                                }
                        }
                 */
            getMainFrame().getElementPropertiesDialog().updateSelection();
        }
        
    }//GEN-LAST:event_jPanelReportMouseReleased
    
    
    /**
     * Single Click
     * - Left button: ...
     * //TODO
     * - Right button: ...
     * //TODO
     *
     * Double click
     * - On a band split: If no elements are selected, then a double click on a band split tries to
     *   reduce the bandheight to the enclosing rectangle around the elements in the band above the split.
     *   Elements in the top marging are not taken into account.
     * - Otherwise
     * @param evt
     */
    private void jPanelReportMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jPanelReportMousePressed
        
        jPanelReport.requestFocus();
        if (evt.getButton() == evt.BUTTON1 && evt.getClickCount() < 2) {
            
            if (newObjectType != ReportElementType.NONE) {
                firstXORDraw = false;
                newObjectOrigin = new Point(snapToGridOrizzontally(evt.getX()),snapToGridVertically(evt.getY()));
                mouse.x = newObjectOrigin.x;
                mouse.y = newObjectOrigin.y;
                return;
            }
            
            // Begin code Robert Lamping, 18 July 2004
            // Zoom in interactively with SHIFT/CTRL + LEFT mouse button
            if ( (( evt.getModifiers() & evt.SHIFT_MASK) != 0) &&
            (( evt.getModifiers() & evt.CTRL_MASK)  != 0) ) {
                // multiply zoomfactor by 2 and zoom in with current mouse position as center!
                //Point center = new Point(
                Point clickPoint = this.realPoint( evt.getX(), evt.getY() );
                setZoomFactor( getZoomFactor() * 2 );
                getMainFrame().setComboBoxZoomFactor( getZoomFactor() * 100 );
                centerSelectedElements( clickPoint );  // if not present use clickPoint
                return;
            }
            // End code Robert Lamping, 18 July 2004
            
            
            if (selectedElements.size() > 0 && (( evt.getModifiers() & evt.SHIFT_MASK ) == 0)) {
                // We are transformation mode?
                if (transformation_type >=0) {
                    trasforming = true;
                    firstXORDrawTransforming = true;
                    transformation_origin = new Point(evt.getX(),evt.getY());
                    transformation_undo_delta = new Point(0,0);
                    transformation_origin_end = new Point(evt.getX(),evt.getY());
                    return;
                }
            }
            
            if (jPanelReport.getCursor() == hsplit) {
                
                first_draw_band=true;
                int bl = evt.getY() + jVerticalScrollBar.getValue();
                int y=report.getTopMargin();
                boolean found=false;
                Band band=null;
                
                if (( evt.getModifiers() & evt.SHIFT_MASK ) != 0) {
                    //label1.setText("Inverse search");
                    y = report.getDesignHeight()-report.getBottomMargin();
                    for (int b =report.getBands().size()-1; b>=0; --b) {
                        band = (Band)report.getBands().elementAt(b);
                        if (bl>getZoomedDim(y)+10-3 && bl < getZoomedDim(y)+10+3) {
                            break;
                        }
                        y -= band.getHeight();
                    }
                }
                else {
                    for (Iterator i = getReport().getBands().iterator(); i.hasNext(); ) {
                        band = (Band) i.next();
                        y += band.getHeight();
                        if (bl>getZoomedDim(y)+10-3 && bl < getZoomedDim(y)+10+3) {
                            break;
                        }
                    }
                }
                if (band != null) {
                    band_dragging = true;
                    band_dragging_origin = evt.getY();
                    band_dragging_band = band;
                    
                    //this.label1.setText(band_dragging_band.name +  " band height: " +(band_dragging_band.height));
                    return;
                }
            }
            for (int i=report.getElements().size()-1; i>=0; --i) {
                
                ReportElement re = (ReportElement)report.getElements().elementAt(i);
                if (re.intersects(new Point(getLogicalDim(evt.getX()+jHorizontalScrollBar.getValue()-10)+10,
                getLogicalDim(evt.getY()+jVerticalScrollBar.getValue()-10)+10))) {
                    if (selectedElements.size()>0 && re == ((ReportElement)selectedElements.firstElement())) return;
                    // 1.<Cancel old corona...
                    
                    if (selectedElements.size() > 0 &&  (( evt.getModifiers() & evt.SHIFT_MASK ) == 0)) {
                        setSelectedElement(null);
                    }
                    
                    if ((( evt.getModifiers() & evt.SHIFT_MASK ) == 0) || selectedElements.size()==0) {
                        //getSelectedElements().removeAllElements();
                        setSelectedElement(re);
                        jPanelReport.repaint();
                    }
                    else if (( evt.getModifiers() & evt.SHIFT_MASK ) != 0) {
                        if (getSelectedElements().contains(re)) {
                            getSelectedElements().remove(re);
                            jPanelReport.repaint();
                        }
                        else {
                            addSelectedElement(re);
                        }
                    }
                    else {
                        setSelectedElement(re);
                    }
                    trasforming = true;
                    firstXORDrawTransforming = true;
                    transformation_origin = new Point(evt.getX(),evt.getY());
                    transformation_origin_end = new Point(evt.getX(),evt.getY());
                    
                    if (getMainFrame().isEMMActive())
                        transformation_type = TransformationType.TRANSFORMATION_NONE;
                    else
                        transformation_type = TransformationType.TRANSFORMATION_MOVE;
                    
                    jPanelReport.setCursor(Cursor.getPredefinedCursor( Cursor.MOVE_CURSOR ));
                    return;
                    
                }
            }
            getMainFrame().getElementPropertiesDialog().updateSelection();
                        
            /*
            if (selectedElements.size()>0 && (( evt.getModifiers() & evt.SHIFT_MASK ) == 0))
            {
                ReportElement myre = (ReportElement)selectedElements.firstElement();
                if (myre != null)
                {
                        Rectangle rect = new Rectangle(myre.position.x-5,myre.position.y-5,myre.width+10, myre.height+10);
                        setSelectedElement(null);
                }
            }
             */
            
            if (( evt.getModifiers() & evt.SHIFT_MASK ) == 0 && getSelectedElements().size() > 0)
                setSelectedElement(null);
            
            // We can enter in drag selection mode...
            drag_selection_mode = true;
            first_draw_selection_rect = true;
            drag_selection_origin = new Point(evt.getX(),evt.getY());
        }
        else if (evt.getButton() == evt.BUTTON3) {
            
            // Begin code Robert Lamping, 18 July 2004
            // Zoom out interactively with SHIFT/CTRL = RIGHT mouse button
            if ( (( evt.getModifiers() & evt.SHIFT_MASK) != 0) &&
            (( evt.getModifiers() & evt.CTRL_MASK)  != 0) ) {
                // divide zoomfactor by 2 and zoom in with current mouse position as center!
                //Point center = new Point(
                Point clickPoint = this.realPoint( evt.getX(), evt.getY() );
                setZoomFactor( getZoomFactor() / 2 );
                getMainFrame().setComboBoxZoomFactor( getZoomFactor() * 100 );
                centerSelectedElements( clickPoint );  // if not present use clickPoint
                return;
            }
            // End code Robert Lamping, 18 July 2004
            
            popup_opened_at = evt.getPoint();
            boolean found = false;
            //1. We must see if we are over an object...
            for (int i=report.getElements().size()-1; i>=0; --i) {
                ReportElement re = (ReportElement)report.getElements().elementAt(i);
                if (re.intersects(new Point(getLogicalDim(evt.getX()+jHorizontalScrollBar.getValue()-10)+10,getLogicalDim(evt.getY()+jVerticalScrollBar.getValue()-10)+10))) {
                    
                    if ( this.getSelectedElements().size() <= 1 )
                        setSelectedElement(re);
                    //                    if ( this.getSelectedElements().size() > 0 && (( evt.getModifiers() & evt.SHIFT_MASK ) != 0))
                    //                    {
                    //                        addSelectedElement(re);
                    //                    }
                    //                    else
                    //                        setSelectedElement(re);
                    
                    found = true;
                    break;
                }
            }
            
            if (getSelectedElements().size() > 0) {
                this.jMenuItemCopy.setEnabled(true);
                this.jMenuItemCut.setEnabled(true);
                this.jMenuItemDelete.setEnabled(true);
                this.jMenuItemCopyStyle.setEnabled(true);
            }
            else {
                this.jMenuItemCopy.setEnabled(false);
                this.jMenuItemCut.setEnabled(false);
                this.jMenuItemDelete.setEnabled(false);
                this.jMenuItemCopyStyle.setEnabled(false);
            }
            
            
            if (getMainFrame().getStyleClipboard() != null) {
                this.jMenuItemPasteStyle.setEnabled(true);
            }
            else {
                this.jMenuItemPasteStyle.setEnabled(false);
            }
            
            if (getMainFrame().getClipBoard().size() > 0) {
                this.jMenuItemPaste.setEnabled(true);
            }
            else {
                this.jMenuItemPaste.setEnabled(false);
            }
            
            Enumeration selectedElementEnum = getSelectedElements().elements();
            boolean allTextFields = true;
            while (selectedElementEnum.hasMoreElements()) {
                ReportElement re = (ReportElement)selectedElementEnum.nextElement();
                if (!(re instanceof TextFieldReportElement)) {
                    allTextFields = false;
                    break;
                }
            }
            jMenuItemPattern.setEnabled( allTextFields );
            
            if(found){
                // we have find an element, open the contextual menu over it...
                
                if ( this.getSelectedElements().size() == 1 ){
                    //Show Popup with menu for one element
                    jMenuHSpacing.setEnabled(false);
                    jMenuVSpacing.setEnabled(false);
                    jPopupMenuElement.show(jPanelReport,evt.getX(),evt.getY());
                    
                    return;
                }
                if ( this.getSelectedElements().size() > 1 ){
                    //Show Popup with special menu for more elements
                    jMenuHSpacing.setEnabled(true);
                    jMenuVSpacing.setEnabled(true);
                    jPopupMenuElement.show(jPanelReport,evt.getX(),evt.getY());
                    return;
                }
                
                
            }
            // Looking for the band....
            jPopupMenuBand.show(this,evt.getX(),evt.getY());
            return;
        }
        else if (evt.getButton() ==  evt.BUTTON1 && evt.getClickCount() == 2) {
            
            // Begin code Robert Lamping, 18 July 2004
            // --------------------------------------------------------------------------------
            // ZOOM IN
            // --------------------------------------------------------------------------------
            if ( (( evt.getModifiers() & evt.SHIFT_MASK) != 0) &&
            (( evt.getModifiers() & evt.CTRL_MASK)  != 0) ) {
                Point clickPoint = this.realPoint( evt.getX(), evt.getY() );
                setZoomFactor( getZoomFactor() * 2 );
                getMainFrame().setComboBoxZoomFactor( getZoomFactor() * 100 );
                centerSelectedElements( clickPoint);  // if not present use clickPoint
                return;
            }
            // End code Robert Lamping, 18 July 2004
            
            
            // Begin code Robert Lamping, 24 July 2004
            // --------------------------------------------------------------------------------
            // Double click on band: move band split to lowest element in band if any.
            // Otherwise no action.
            // --------------------------------------------------------------------------------
            
            if (getSelectedElements().size() == 0) {
                
                // If there are any elements in the band just above the band limit,
                // then set the band height to the maximum Y position of the elements.
                // THis way the band just encloses the elements.
                
                // TEST: Create square in detail band. Square must be smaller than band
                // double click on lower detail band split.
                // Expected result: band height aligns under element bottom.
                
                // We must find the right band split
                
                Band band = null;
                int y = report.getTopMargin();
                int clicked_y = evt.getY() + jVerticalScrollBar.getValue();
                int proximity = 3 ;
                
                for (Iterator i = getReport().getBands().iterator(); i.hasNext(); ) {
                    band = (Band) i.next();
                    y += band.getHeight();
                    if ( clicked_y > getZoomedDim(y) + 10 - proximity && clicked_y < getZoomedDim(y) + 10 + proximity) {
                        break;
                    }
                }
                
                if ( band != null ) {
                    int bandHeight = band.getHeight();
                    shrinkBand( band );
                    if ( bandHeight != band.getHeight() ) {
                        jPanelReport.repaint();
                        return;
                    }
                }
                
            } else {
                // double clicked within a selected element
                // check if you clicked on South
                // in case of a text element, this will reset the height to fontsize() + 2
                
                //logOnConsole( "Try to check whether you clicked on south\n");
                //traverse all selectedelement and check whether you clicked on south.
                // if so then adjust the element height to textheight + 2
                int clicked_x = evt.getX() + jHorizontalScrollBar.getValue();
                int clicked_y = evt.getY() + jVerticalScrollBar.getValue();
                int proximity = 4 ;
                ReportElement clickedRe = null;
                Rectangle clickedRect = new Rectangle( clicked_x - proximity, clicked_y - proximity, 2* proximity, 2* proximity);
                //logOnConsole( "Clickpoint: " + clicked_x + " " + clicked_y + "\n");
                
                for (Iterator i = report.getElements().iterator(); i.hasNext(); ) {
                    ReportElement re = (ReportElement) i.next();
                    Point south = new Point( getZoomedDim(re.getPosition().x  + (int) (0.5 * re.getWidth()  ) ) -10 ,
                    getZoomedDim( re.getPosition().y  +             re.getHeight()  ) -10 );
                    
                    //logOnConsole( "South: " + south.x + " " + south.y + "\n");
                    
                    if ( clickedRect.contains( south ) ) {
                        clickedRe = re;
                        break ;
                    }
                }
                
                if ( clickedRe != null && getMainFrame().getProperties().getProperty("EnableTextResizeClick","true").equals("true") ) {
                    //logOnConsole( "South clicked of " + clickedRe.getKey() + " \n");
                    if (clickedRe instanceof TextReportElement ) {
                        TransformElementsOperation undoOp = new TransformElementsOperation(this);
                        TextReportElement tre = (TextReportElement) clickedRe;
                        
                        Rectangle oldBounds = clickedRe.getBounds();
                        tre.setHeight( tre.getFontSize() + 2 );
                        
                        Rectangle newBounds = clickedRe.getBounds();
                        
                        // add a task to the undo operation.
                        undoOp.addElement(clickedRe, oldBounds, newBounds );
                        
                        // Pass the undo tasks to the undo cluster.
                        addUndoOperation(undoOp);
                        
                        // repaint the screen
                        jPanelReport.repaint();
                        return;
                    }
                }
            }
            
            // End code Robert Lamping, 24 July 2004
            
            // otherwise try to open
            openElementPropertiesDialog();
        }
    }//GEN-LAST:event_jPanelReportMousePressed
    
    private void jHorizontalScrollBarAdjustmentValueChanged(java.awt.event.AdjustmentEvent evt) {//GEN-FIRST:event_jHorizontalScrollBarAdjustmentValueChanged
        isDocDirty = true;
        //logOnConsole( "jHorizontalScrollBar.getValue() : "  + jHorizontalScrollBar.getValue() + "\n" );
        jPanelReport.repaint();
    }//GEN-LAST:event_jHorizontalScrollBarAdjustmentValueChanged
    
    private void jPanelReportComponentResized(java.awt.event.ComponentEvent evt) {//GEN-FIRST:event_jPanelReportComponentResized
        if (jPanelReport.getWidth() >= (getZoomedDim( report.getWidth())+19)) {
            jHorizontalScrollBar.setMaximum(report.getWidth());
            jHorizontalScrollBar.setVisibleAmount( jHorizontalScrollBar.getMaximum());
            jHorizontalScrollBar.setValue(0);
            ////VScrollBar1_scroll(VScrollBar1, new ScrollEvent( ScrollEventType.ENDSCROLL,0));
        }
        else {
            jHorizontalScrollBar.setMaximum((getZoomedDim( report.getWidth()) +19));
            this.jHorizontalScrollBar.setVisibleAmount(jPanelReport.getWidth());
            this.jHorizontalScrollBar.setBlockIncrement( this.jHorizontalScrollBar.getVisibleAmount() );
        }
        
        if (jPanelReport.getHeight() >= getZoomedDim(report.getDesignHeight())+19) {
            jVerticalScrollBar.setMaximum(report.getDesignHeight());
            jVerticalScrollBar.setVisibleAmount( jVerticalScrollBar.getMaximum());
            jVerticalScrollBar.setValue(0);
            //VScrollBar1_scroll(VScrollBar1, new ScrollEvent( ScrollEventType.ENDSCROLL,0));
        }
        else {
            jVerticalScrollBar.setMaximum(getZoomedDim( report.getDesignHeight())+19);
            this.jVerticalScrollBar.setVisibleAmount(jPanelReport.getHeight());
            this.jVerticalScrollBar.setBlockIncrement( this.jVerticalScrollBar.getVisibleAmount() );
        }
        // getMainFrame().updateFitToPage(this);  deactivated by Robert
        
        //jPanelReport.repaint();
    }//GEN-LAST:event_jPanelReportComponentResized
    
    private void jVerticalScrollBarMouseReleased(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jVerticalScrollBarMouseReleased
        
    }//GEN-LAST:event_jVerticalScrollBarMouseReleased
    
    private void jVerticalScrollBarAdjustmentValueChanged(java.awt.event.AdjustmentEvent evt) {//GEN-FIRST:event_jVerticalScrollBarAdjustmentValueChanged
       
        isDocDirty = true;
        jPanelReport.repaint();
    }//GEN-LAST:event_jVerticalScrollBarAdjustmentValueChanged
    
    private void jPanelReportMouseDragged(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jPanelReportMouseDragged

        this.jHorizontalRule.setCursorPosition(evt.getX());
        if (mouse == null) {
            mouse = new Point();
        }
        
        if (drag_selection_mode == true) {
            Graphics2D gg = (Graphics2D)jPanelReport.getGraphics();
            gg.setXORMode(Color.GREEN);
            Stroke s = gg.getStroke();
            gg.setStroke(selectionStroke);
            if (!first_draw_selection_rect) {
                gg.drawRect((int)Math.min( drag_selection_origin.x, drag_selection_end.x),
                (int)Math.min( drag_selection_origin.y, drag_selection_end.y),
                (int)Math.abs( drag_selection_origin.x - drag_selection_end.x),
                (int)Math.abs( drag_selection_origin.y - drag_selection_end.y));
            }
            
            drag_selection_end = new java.awt.Point(evt.getX(), evt.getY());
            // Draw the new rectangle...
            gg.drawRect((int)Math.min( drag_selection_origin.x, drag_selection_end.x),
            (int)Math.min( drag_selection_origin.y, drag_selection_end.y),
            (int)Math.abs( drag_selection_origin.x - drag_selection_end.x),
            (int)Math.abs( drag_selection_origin.y - drag_selection_end.y));
            gg.setPaintMode();
            first_draw_selection_rect = false;
            if (s != null) gg.setStroke(s);
        }

        if (newObjectType == ReportElementType.NONE && !transforming) {
            // Is the mouse over a band line ?...
            if (band_dragging) {
                //  2. delta = Max altezza banda precedente e position delta
                int delta = getLogicalDim( evt.getY() - band_dragging_origin );
                //this.label1.setText(band_dragging_band.name +  " band height: " +(band_dragging_band.height));
                if (delta != 0) {
                    
                    // Vediamo se e' possibile andare piu' su...
                    // Non possiamo andare piu' su della banda prima...
                    //	1. Cerchiamo la banda precedente...
                    
                    int min_logical_base = report.getTopMargin()+10;
                    int base_position=0;// = Math.max(min_logical_base, getReport().getBandYLocation(band_dragging_band) +delta);
                    base_position = getZoomedDim(report.getBandYLocation(band_dragging_band))+10- jVerticalScrollBar.getValue();
                    Graphics gg = jPanelReport.getGraphics();
                    gg.setXORMode(Color.WHITE);
                    if (!first_draw_band) {
                        gg.drawLine( 0,Math.max(mouse.y,base_position),jPanelReport.getWidth(),Math.max(mouse.y,base_position) );
                        
                    }
                    gg.drawLine(0,Math.max(evt.getY(),base_position),jPanelReport.getWidth(),Math.max(evt.getY(),base_position) );
                    gg.setPaintMode();
                    first_draw_band = false;
                    //this.label1.setText(band_dragging_band.name +  " band height: " +(band_dragging_band.height + delta));
                }
            }
        }
        
        if (newObjectType != ReportElementType.NONE && newObjectOrigin!= null) {
            
            /* In the process of defing the second point. */
            
            Graphics gg = jPanelReport.getGraphics();
            gg.setXORMode(Color.WHITE);
            int delta_x = 0;
            int delta_y = 0;
            
            if (newObjectType != ReportElementType.LINE_ELEMENT && !firstXORDraw) {
                delta_x = mouse.x- newObjectOrigin.x;
                delta_y = mouse.y-newObjectOrigin.y;
                
                delta_x = (delta_x <0) ? delta_x : 0;
                delta_y = (delta_y<0) ? delta_y : 0;
            }
            
            
            int delta_w = 0;
            int delta_h = 0;
            if (!firstXORDraw) {
                delta_w = gridMultiple(mouse.x-newObjectOrigin.x);
                delta_h = gridMultiple(mouse.y-newObjectOrigin.y);
                delta_x = (delta_w<0) ? delta_w: 0;
                delta_y = (delta_h<0) ? delta_h : 0;
            }
            
            if (newObjectType == ReportElementType.LINE_ELEMENT) {
                
/*                if ( ( evt.getModifiers() & evt.SHIFT_MASK)  != 0) {
                  if (( delta_w + delta_h ) > 0 ) {
                      double cos =  Math.PI * delta_w /  Math.sqrt(  (delta_w* delta_w) + (delta_h*delta_h) );
                      logOnConsole( "Cosinus: " + cos + "\n");
                      
                      if ( Math.abs( cos ) >  Math.abs( Math.cos(0.25 * Math.PI ) ) ) { 
                          delta_h = 0 ; 
                      }
                  }
                }
*/
                /* overwrite the other one, so that it disappears */
                if ( ( evt.getModifiers() & evt.SHIFT_MASK)  != 0) {
                    Point straight = straighten( delta_w, delta_h);
                    delta_w = straight.x;
                    delta_h = straight.y;
                }

                
                if (!firstXORDraw) {
                    gg.drawLine( newObjectOrigin.x, newObjectOrigin.y, newObjectOrigin.x+delta_w,newObjectOrigin.y+delta_h);
                }
                
                delta_w = gridMultiple(evt.getX()-newObjectOrigin.x);
                delta_h = gridMultiple(evt.getY()-newObjectOrigin.y);

                if ( ( evt.getModifiers() & evt.SHIFT_MASK)  != 0) {
                    Point straight = straighten( delta_w, delta_h);
                    delta_w = straight.x;
                    delta_h = straight.y;
                }

/*                if ( ( evt.getModifiers() & evt.SHIFT_MASK)  != 0) {
                  if (( delta_w + delta_h ) > 0 ) {
                      double cos =  Math.PI * delta_w /  Math.sqrt(  (delta_w* delta_w) + (delta_h*delta_h) );
                      logOnConsole( "Cosinus: " + cos + "\n");
                      
                      if ( Math.abs( cos ) >  Math.abs( Math.cos(0.25 * Math.PI ) ) ) { 
                          delta_h = 0 ; 
                      }
                  }
                }
*/
                gg.drawLine( newObjectOrigin.x, newObjectOrigin.y, newObjectOrigin.x+delta_w,newObjectOrigin.y+delta_h);
                mouse.x = newObjectOrigin.x+delta_w;
                mouse.y = newObjectOrigin.x+delta_y;
                
            }
            else if (newObjectType == ReportElementType.ELLIPSE_ELEMENT) {
                if (!firstXORDraw)  gg.drawOval( newObjectOrigin.x+delta_x, snapToGridVertically(newObjectOrigin.y+delta_y), Math.abs(delta_w), Math.abs(delta_h));
                
                delta_w = gridMultiple(evt.getX()-newObjectOrigin.x);
                delta_h = gridMultiple(evt.getY()-newObjectOrigin.y);
                delta_x = (delta_w<0) ? delta_w: 0;
                delta_y = (delta_h<0) ? delta_h : 0;
                gg.drawOval( newObjectOrigin.x+delta_x, snapToGridVertically(newObjectOrigin.y+delta_y), Math.abs(delta_w), Math.abs(delta_h));
            }
            else if (newObjectType == ReportElementType.ROUND_RECTANGLE_ELEMENT) {
                if (!firstXORDraw) {
                    gg.drawRoundRect( newObjectOrigin.x+delta_x, snapToGridVertically(newObjectOrigin.y+delta_y), Math.abs(delta_w), Math.abs(delta_h),20,20);
                }
                delta_w = gridMultiple(evt.getX()-newObjectOrigin.x);
                delta_h = gridMultiple(evt.getY()-newObjectOrigin.y);
                delta_x = (delta_w<0) ? delta_w: 0;
                delta_y = (delta_h<0) ? delta_h : 0;
                //gg.drawRect( snapToGridOrizzontally(newObjectOrigin.x+w_delta_x), snapToGridVertically(newObjectOrigin.y+delta_y), gridMultiple(Math.abs(evt.getX()-newObjectOrigin.x)), gridMultiple(Math.abs(evt.getY()-newObjectOrigin.y)));
                gg.drawRoundRect( newObjectOrigin.x+delta_x, snapToGridVertically(newObjectOrigin.y+delta_y), Math.abs(delta_w), Math.abs(delta_h),20,20);
            }
            else {
                if (!firstXORDraw) {
                    gg.drawRect( newObjectOrigin.x+delta_x, snapToGridVertically(newObjectOrigin.y+delta_y), Math.abs(delta_w), Math.abs(delta_h));
                }
                delta_w = gridMultiple(evt.getX()-newObjectOrigin.x);
                delta_h = gridMultiple(evt.getY()-newObjectOrigin.y);
                delta_x = (delta_w<0) ? delta_w: 0;
                delta_y = (delta_h<0) ? delta_h : 0;
                //gg.drawRect( snapToGridOrizzontally(newObjectOrigin.x+w_delta_x), snapToGridVertically(newObjectOrigin.y+delta_y), gridMultiple(Math.abs(evt.getX()-newObjectOrigin.x)), gridMultiple(Math.abs(evt.getY()-newObjectOrigin.y)));
                gg.drawRect( newObjectOrigin.x+delta_x, snapToGridVertically(newObjectOrigin.y+delta_y), Math.abs(delta_w), Math.abs(delta_h));
                //gg.drawRect( newObjectOrigin.x+delta_x, newObjectOrigin.y+delta_y, Math.abs(delta_from_origin), Math.abs(evt.getY()-newObjectOrigin.y));
            }
            
            firstXORDraw = false;
            gg.setPaintMode();
            
            //mouse.x = mouse.x + delta_from_origin;
            //mouse.y = evt.getY();
            //return;
        }
        if (selectedElements.size() >0 && newObjectType == ReportElementType.NONE && transformation_origin_end != null) {
            int new_transformation_origin_end_x = transformation_origin_end.x;
            int new_transformation_origin_end_y = transformation_origin_end.y;
            
            if (transformation_type >=0 && trasforming) {
                Graphics gg = jPanelReport.getGraphics();
                gg.setXORMode(Color.WHITE);
                if (!firstXORDrawTransforming) {
                    // redraw old rectangles...
                    // transformation_origin
                    // transformation_origin_end
                    // Pain a rectangle....
                    
                    // if no modifications is needed, return...
                    
                    if (this.isSnapToGrid()) {
                        if (Math.abs( transformation_origin_end.x - evt.getX())%(getGridSize()*getZoomFactor())  == 0)
                            new_transformation_origin_end_x = evt.getX();
                        if (Math.abs( transformation_origin_end.y - evt.getY() )%(getGridSize()*getZoomFactor())  == 0)
                            new_transformation_origin_end_y = evt.getY();
                        
                        if (new_transformation_origin_end_x == transformation_origin_end.x &&
                        new_transformation_origin_end_y == transformation_origin_end.y) {
                            return;
                        }
                    }
                    else {
                        new_transformation_origin_end_x = evt.getX();
                        new_transformation_origin_end_y = evt.getY();
                    }
                    
                    Enumeration e = getSelectedElements().elements();
                    while (e.hasMoreElements()) {
                        ReportElement re = (ReportElement)e.nextElement();
                        Rectangle bounds = new Rectangle(getZoomedDim(re.getPosition().x-10)+10,
                        getZoomedDim(re.getPosition().y-10)+10,
                        getZoomedDim(re.getWidth()),
                        getZoomedDim(re.getHeight()));
                        // Scale rectangle...
                        if (transformation_type == TransformationType.TRANSFORMATION_MOVE) {
                            // First of all we must see if the resistence was Exceeded...
                            if (resistenceExceeded) {
                                // Change location...
                                bounds.translate(  transformation_origin_end.x-transformation_origin.x,
                                transformation_origin_end.y-transformation_origin.y);
                                gg.drawRect(bounds.x-jHorizontalScrollBar.getValue(), bounds.y-jVerticalScrollBar.getValue(),bounds.width, bounds.height );
                            }
                        }
                        else if (transformation_type == TransformationType.TRANSFORMATION_RESIZE_SE ||
                        transformation_type == TransformationType.TRANSFORMATION_RESIZE_S ||
                        transformation_type == TransformationType.TRANSFORMATION_RESIZE_E) {
                            // Change location...
                            int x_delta = ( transformation_type == TransformationType.TRANSFORMATION_RESIZE_SE || transformation_type == TransformationType.TRANSFORMATION_RESIZE_E) ? transformation_origin_end.x-transformation_origin.x : 0;
                            int y_delta = ( transformation_type == TransformationType.TRANSFORMATION_RESIZE_SE || transformation_type == TransformationType.TRANSFORMATION_RESIZE_S) ? transformation_origin_end.y-transformation_origin.y : 0;
                            bounds.setSize( Math.max(0, bounds.width + x_delta),
                            Math.max(0, bounds.height + y_delta));
                            gg.drawRect(bounds.x-jHorizontalScrollBar.getValue(), bounds.y-jVerticalScrollBar.getValue(),bounds.width, bounds.height );
                        }
                        else if (transformation_type == TransformationType.TRANSFORMATION_RESIZE_NW ||
                        transformation_type == TransformationType.TRANSFORMATION_RESIZE_N  ||
                        transformation_type == TransformationType.TRANSFORMATION_RESIZE_W) {
                            // Change location...
                            int x_delta = ( transformation_type == TransformationType.TRANSFORMATION_RESIZE_NW || transformation_type == TransformationType.TRANSFORMATION_RESIZE_W) ? transformation_origin_end.x-transformation_origin.x : 0;
                            int y_delta = ( transformation_type == TransformationType.TRANSFORMATION_RESIZE_NW || transformation_type == TransformationType.TRANSFORMATION_RESIZE_N) ? transformation_origin_end.y-transformation_origin.y : 0;
                            int height_grow = Math.min( y_delta,bounds.height);
                            int width_grow = Math.min( x_delta,bounds.width);
                            bounds.translate(width_grow,height_grow);
                            bounds.setSize( bounds.width - width_grow, bounds.height - height_grow);
                            gg.drawRect(bounds.x-jHorizontalScrollBar.getValue(), bounds.y-jVerticalScrollBar.getValue(),bounds.width, bounds.height );
                        }
                        else if (transformation_type == TransformationType.TRANSFORMATION_RESIZE_NE) {
                            // Change location...
                            int x_delta = Math.max(-bounds.width,(transformation_origin_end.x-transformation_origin.x));
                            int y_delta = Math.min(bounds.height,  (transformation_origin_end.y-transformation_origin.y) );
                            bounds.y += y_delta;
                            bounds.height -= y_delta;
                            bounds.width += x_delta;
                            gg.drawRect(bounds.x-jHorizontalScrollBar.getValue(), bounds.y-jVerticalScrollBar.getValue(),bounds.width, bounds.height );
                        }
                        else if (transformation_type == TransformationType.TRANSFORMATION_RESIZE_SW) {
                            // Change location...
                            int x_delta = Math.min(bounds.width,  (transformation_origin_end.x-transformation_origin.x) );
                            int y_delta = Math.max(-bounds.height,(transformation_origin_end.y-transformation_origin.y));
                            bounds.x += x_delta;
                            bounds.width -= x_delta;
                            bounds.height += y_delta;
                            gg.drawRect(bounds.x-jHorizontalScrollBar.getValue(), bounds.y-jVerticalScrollBar.getValue(),bounds.width, bounds.height );
                        }
                    }
                }
                
                    /*
                    if (Math.abs( transformation_origin_end.x - evt.getX())%(getGridSize()*getZoomFactor())  == 0)
                        transformation_origin_end.x = evt.getX();
                    if (Math.abs( transformation_origin_end.y - evt.getY() )%(getGridSize()*getZoomFactor())  == 0)
                        transformation_origin_end.y = evt.getY();
                     */
                transformation_origin_end.x = new_transformation_origin_end_x;
                transformation_origin_end.y = new_transformation_origin_end_y;
                
                Enumeration e = getSelectedElements().elements();
                while (e.hasMoreElements()) {
                    ReportElement re = (ReportElement)e.nextElement();
                    Rectangle bounds = new Rectangle(getZoomedDim(re.getPosition().x-10)+10-jHorizontalScrollBar.getValue(),
                    getZoomedDim(re.getPosition().y-10)+10-jVerticalScrollBar.getValue(),
                    getZoomedDim(re.getWidth()),
                    getZoomedDim(re.getHeight()));
                    // Scale rectangle...
                    if (transformation_type == TransformationType.TRANSFORMATION_MOVE) {
                        // Change location...
                        if (Math.abs(transformation_origin_end.x-transformation_origin.x) >5 ||
                        Math.abs(transformation_origin_end.y-transformation_origin.y) >5)
                            resistenceExceeded = true;
                        if (resistenceExceeded) {
                            // Search the closest x,y that match a grid intersection...
                            
                            int pex = gridMultiple( transformation_origin_end.x-10 )+10;
                            int pey = gridMultiple( transformation_origin_end.y-10 )+10;
                            int pox = gridMultiple( transformation_origin.x-10 )+10;
                            int poy = gridMultiple( transformation_origin.y-10 )+10;
                            
                            //System.out.println("x: "+transformation_origin_end + " y:" + transformation_origin_end.y);
                            
                            //this.getGraphics().drawOval( grid_multiple_x, grid_multiple_y, 5,5);
                            
                            bounds.translate( transformation_origin_end.x-transformation_origin.x,
                            transformation_origin_end.y-transformation_origin.y);
                            gg.drawRect(bounds.x, bounds.y,bounds.width, bounds.height );
                        }
                    }
                    else if (transformation_type == TransformationType.TRANSFORMATION_RESIZE_SE ||
                    transformation_type == TransformationType.TRANSFORMATION_RESIZE_S ||
                    transformation_type == TransformationType.TRANSFORMATION_RESIZE_E) {
                        // Change location...
                        int x_delta = ( transformation_type == TransformationType.TRANSFORMATION_RESIZE_SE || transformation_type == TransformationType.TRANSFORMATION_RESIZE_E) ? transformation_origin_end.x-transformation_origin.x : 0;
                        int y_delta = ( transformation_type == TransformationType.TRANSFORMATION_RESIZE_SE || transformation_type == TransformationType.TRANSFORMATION_RESIZE_S) ? transformation_origin_end.y-transformation_origin.y : 0;
                        bounds.setSize( Math.max(0, bounds.width + x_delta),
                        Math.max(0, bounds.height + y_delta));
                        gg.drawRect(bounds.x, bounds.y,bounds.width, bounds.height );
                    }
                    else if (transformation_type == TransformationType.TRANSFORMATION_RESIZE_NW ||
                    transformation_type == TransformationType.TRANSFORMATION_RESIZE_N  ||
                    transformation_type == TransformationType.TRANSFORMATION_RESIZE_W) {
                        // Change location...
                        int x_delta = ( transformation_type == TransformationType.TRANSFORMATION_RESIZE_NW || transformation_type == TransformationType.TRANSFORMATION_RESIZE_W) ? transformation_origin_end.x-transformation_origin.x : 0;
                        int y_delta = ( transformation_type == TransformationType.TRANSFORMATION_RESIZE_NW || transformation_type == TransformationType.TRANSFORMATION_RESIZE_N) ? transformation_origin_end.y-transformation_origin.y : 0;
                        int height_grow = Math.min( y_delta,bounds.height);
                        int width_grow = Math.min( x_delta,bounds.width);
                        bounds.translate(width_grow,height_grow);
                        bounds.setSize( bounds.width - width_grow, bounds.height - height_grow);
                        gg.drawRect(bounds.x, bounds.y,bounds.width, bounds.height );
                    }
                    else if (transformation_type == TransformationType.TRANSFORMATION_RESIZE_NE) {
                        // Change location...
                        int x_delta = Math.max(-bounds.width,(transformation_origin_end.x-transformation_origin.x));
                        int y_delta = Math.min(bounds.height, (transformation_origin_end.y-transformation_origin.y) );
                        bounds.y += y_delta;
                        bounds.height -= y_delta;
                        bounds.width += x_delta;
                        gg.drawRect(bounds.x, bounds.y,bounds.width, bounds.height );
                    }
                    else if (transformation_type == TransformationType.TRANSFORMATION_RESIZE_SW) {
                        // Change location...
                        int x_delta = Math.min(bounds.width, (transformation_origin_end.x-transformation_origin.x) );
                        int y_delta = Math.max(-bounds.height , (transformation_origin_end.y-transformation_origin.y));
                        bounds.x += x_delta;
                        bounds.width -= x_delta;
                        bounds.height += y_delta;
                        gg.drawRect(bounds.x, bounds.y,bounds.width, bounds.height );
                    }
                }
                
                firstXORDrawTransforming = false;
                gg.setPaintMode();
                // Calculate new rectangle...
                
                
                    /*
                        boolean makerefreshAll = false;
                        if (selectedElements.size() > 0)  makerefreshAll=true;
                        //transformation_origin = new Point(e.x+HScrollBar1.getValue(),e.y+VScrollBar1.getValue());
                        // Calcoliamo il delta
                        Point p = new Point();
                        Enumeration enum = selectedElements.elements();
                     
                        p.x = getLogicalDim( evt.getX()  - transformation_origin.x );
                        p.y = getLogicalDim( evt.getY()  - transformation_origin.y );
                     
                     
                        // Search for minimum delta admitted
                        Point real_delta = new Point(0,0);
                        int kkk=0;
                        while ((p.x!=0 || p.y!=0) && enum.hasMoreElements())
                        {
                                ReportElement selectedRe = (ReportElement)enum.nextElement();
                                Point dt = selectedRe.trasformTest(p, transformation_type);
                                if (kkk==0)
                                        real_delta = dt;
                                else
                                {
                                        real_delta.x = Math.min(dt.x,real_delta.x);
                                        real_delta.y = Math.min(dt.y,real_delta.y);
                                }
                        }
                     
                        transformation_undo_delta.x += real_delta.x;
                        transformation_undo_delta.y += real_delta.y;
                     
                        enum = selectedElements.elements();
                        int maxx = ((ReportElement)selectedElements.firstElement()).position.x+((ReportElement)selectedElements.firstElement()).width;
                     
                        while ((real_delta.x!=0 || real_delta.y!=0) && enum.hasMoreElements())
                        {
                                ReportElement selectedRe = (ReportElement)enum.nextElement();
                                // Redraw interessed area...
                                Rectangle rect = new Rectangle(Math.min( selectedRe.position.x-5 ,selectedRe.position.x+p.x-5),
                                                                                           Math.min(selectedRe.position.y-5,selectedRe.position.y+p.y-5),
                                                                                           selectedRe.width + Math.abs(p.x)+10,selectedRe.height + Math.abs(p.y)+10);
                     
                     
                                if (selectedRe.position.x >= maxx && ( (evt.getModifiers() & evt.CTRL_MASK) != 0 ) && transformation_type == TransformationType.TRANSFORMATION_RESIZE_E)
                                {
                                    selectedRe.trasform(real_delta, TransformationType.TRANSFORMATION_RESIZE_W);
                                }
                                else
                                    selectedRe.trasform(real_delta, transformation_type);
                     
                                if (!makerefreshAll)
                                {
                                        redrawAll(offscreen , rect,5);
                                                // Get Real dimensions...
                                        Rectangle clipRect = new Rectangle(getZoomedDim(rect.x-10+5)-5+10,
                                                                                                           getZoomedDim(rect.y-10+5)-5+10,
                                                                                                           getZoomedDim(rect.width-10)+10,
                                                                                                           getZoomedDim(rect.height-10)+10);
                                                clipRect.translate(-jHorizontalScrollBar.getValue(),-jVerticalScrollBar.getValue());
                                                jPanelReport.getGraphics().drawImage( offscreenImage ,
                                                                      clipRect.x ,clipRect.y, clipRect.width,clipRect.height,
                                                                      clipRect.x ,clipRect.y, clipRect.width,clipRect.height,
                                                                      (ImageObserver)this);
                                        }
                                }
                                if (makerefreshAll) jPanelReport.repaint();
                                if (p.x != 0) transformation_origin.x = evt.getX();
                                if (p.y != 0) transformation_origin.y = evt.getY();
                     */
            }
            
        }
        mouse.x = evt.getX();
        mouse.y = evt.getY();
        
    }//GEN-LAST:event_jPanelReportMouseDragged
    
    private void jPanelReportMouseMoved(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jPanelReportMouseMoved
        this.jHorizontalRule.setCursorPosition(evt.getX());
        if (mouse == null) mouse = new Point();
        if (newObjectType == ReportElementType.NONE && !transforming) {
            // Is the mouse over a band line ?...
            int bl =  evt.getY() + jVerticalScrollBar.getValue();
            Enumeration e = report.getBands().elements();
            int y= report.getTopMargin();
            boolean found=false;
            while (!found && e.hasMoreElements()) {
                Band band = (Band)e.nextElement();
                y += band.getHeight();
                if (bl>getZoomedDim(y)+10-3 && bl < getZoomedDim(y)+3+10) {
                    jPanelReport.setCursor( hsplit);
                    //this.label1.setText("Drag "+band.name);
                    found = true;
                }
            }
            if (!found && jPanelReport.getCursor() == hsplit) {
                jPanelReport.setCursor( Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
            }
        }
        
        if (selectedElements.size() >0 && newObjectType == ReportElementType.NONE) {
            // We are trasformation mode?
            {
                // Vediamo se siamo sopra la figura...
                Enumeration e = selectedElements.elements();
                boolean found = false;
                boolean sizeall = false;
                while (!found && e.hasMoreElements() ) {
                    
                    ReportElement selectedRe = (ReportElement)e.nextElement();
                    Rectangle grip = new Rectangle(getZoomedDim(selectedRe.position.x-10)-5+10, getZoomedDim(selectedRe.position.y-10)-5+10,
                    getZoomedDim(selectedRe.width)+10,getZoomedDim(selectedRe.height)+10);
                    Rectangle cursor = new Rectangle(evt.getX()+jHorizontalScrollBar.getValue(),
                    evt.getY()+jVerticalScrollBar.getValue(),
                    1,1);
                    
                    if (cursor.intersects(grip)) {
                        sizeall = true;
                        // Vediamo se interseca una grip...
                        grip.width  = 5;
                        grip.height = 5;
                        
                        if (cursor.intersects(grip)) {
                            jPanelReport.setCursor(Cursor.getPredefinedCursor( Cursor.NW_RESIZE_CURSOR ));
                            found =true;
                            transformation_type = TransformationType.TRANSFORMATION_RESIZE_NW;
                        }
                        
                        if (!found) {
                            grip.x = getZoomedDim(selectedRe.position.x-10+selectedRe.width)+10;
                            grip.y = getZoomedDim(selectedRe.position.y-10)+10-5;
                            grip.width  = 5;
                            grip.height = 5;
                            if (cursor.intersects(grip)) {
                                jPanelReport.setCursor(Cursor.getPredefinedCursor( Cursor.NE_RESIZE_CURSOR ));
                                found =true;
                                transformation_type = TransformationType.TRANSFORMATION_RESIZE_NE;
                            }
                        }
                        
                        if (!found) {
                            grip.x = getZoomedDim(selectedRe.position.x-10)+10-5;
                            grip.y = getZoomedDim(selectedRe.position.y+(selectedRe.height/2)-10)+10-2;
                            grip.width  = 5;
                            grip.height = 5;
                            if (cursor.intersects(grip)) {
                                jPanelReport.setCursor(Cursor.getPredefinedCursor( Cursor.W_RESIZE_CURSOR));
                                found =true;
                                transformation_type = TransformationType.TRANSFORMATION_RESIZE_W;
                            }
                        }
                        
                        if (!found) {
                            grip.x = getZoomedDim(selectedRe.position.x-10)+10-5;
                            grip.y = getZoomedDim(selectedRe.position.y-10+selectedRe.height)+10;
                            grip.width  = 5;
                            grip.height = 5;
                            if (cursor.intersects(grip)) {
                                jPanelReport.setCursor(Cursor.getPredefinedCursor( Cursor.SW_RESIZE_CURSOR));
                                found =true;
                                transformation_type = TransformationType.TRANSFORMATION_RESIZE_SW;
                            }
                        }
                        
                        if (!found) {
                            grip.x = getZoomedDim(selectedRe.position.x+(selectedRe.width/2)-10)+10-2;
                            grip.y = getZoomedDim(selectedRe.position.y-10)+10-5;
                            grip.width  = 5;
                            grip.height = 5;
                            if (cursor.intersects(grip)) {
                                jPanelReport.setCursor(Cursor.getPredefinedCursor( Cursor.N_RESIZE_CURSOR));
                                found =true;
                                transformation_type = TransformationType.TRANSFORMATION_RESIZE_N;
                            }
                        }
                        
                        if (!found) {
                            grip.x = getZoomedDim(selectedRe.position.x+(selectedRe.width/2)-10)+10-2;
                            grip.y = getZoomedDim(selectedRe.position.y+selectedRe.height-10)+10;
                            grip.width  = 5;
                            grip.height = 5;
                            if (cursor.intersects(grip)) {
                                jPanelReport.setCursor(Cursor.getPredefinedCursor( Cursor.S_RESIZE_CURSOR));
                                found =true;
                                transformation_type = TransformationType.TRANSFORMATION_RESIZE_S;
                            }
                        }
                        
                        if (!found) {
                            grip.x = getZoomedDim(selectedRe.position.x+selectedRe.width-10)+10;
                            grip.y = getZoomedDim(selectedRe.position.y+selectedRe.height-10)+10;
                            grip.width  = 5;
                            grip.height = 5;
                            if (cursor.intersects(grip)) {
                                jPanelReport.setCursor(Cursor.getPredefinedCursor( Cursor.SE_RESIZE_CURSOR));
                                found =true;
                                transformation_type = TransformationType.TRANSFORMATION_RESIZE_SE;
                            }
                        }
                        
                        if (!found) {
                            grip.x = getZoomedDim(selectedRe.position.x+selectedRe.width-10)+10;
                            grip.y = getZoomedDim(selectedRe.position.y+(selectedRe.height/2)-10)+10-2;
                            grip.width  = 5;
                            grip.height = 5;
                            if (cursor.intersects(grip)) {
                                jPanelReport.setCursor(Cursor.getPredefinedCursor( Cursor.E_RESIZE_CURSOR));
                                found =true;
                                transformation_type = TransformationType.TRANSFORMATION_RESIZE_E;
                            }
                        }
                        
                        if (!found) {
                            jPanelReport.setCursor(Cursor.getPredefinedCursor( Cursor.MOVE_CURSOR));
                            
                            if (getMainFrame().isEMMActive())
                                transformation_type = TransformationType.TRANSFORMATION_NONE;
                            else {
                                transformation_type = TransformationType.TRANSFORMATION_MOVE;
                                resistenceExceeded = false;
                            }
                        }
                    }
                }
                if (!sizeall) {
                    jPanelReport.setCursor(Cursor.getDefaultCursor());
                    transformation_type = TransformationType.TRANSFORMATION_NONE;
                }
            }
        }
        
        mouse.x = evt.getX();
        mouse.y = evt.getY();
    }//GEN-LAST:event_jPanelReportMouseMoved
    
    private void jPanelReportAncestorAdded(javax.swing.event.AncestorEvent evt) {//GEN-FIRST:event_jPanelReportAncestorAdded
        // Add your handling code here:
    }//GEN-LAST:event_jPanelReportAncestorAdded
    
    /** Getter for property report.
     * @return Value of property report.
     *
     */
    public it.businesslogic.ireport.Report getReport() {
        return report;
    }
    
    
    /** Getter for property selectedElements.
     * @return Value of property selectedElements.
     *
     */
    public java.util.Vector getSelectedElements() {
        return selectedElements;
    }
    
    /** Setter for property selectedElements.
     * @param selectedElements New value of property selectedElements.
     *
     */
    public void setSelectedElements(java.util.Vector selectedElements) {
        this.selectedElements = selectedElements;
    }
    
    /** Getter for property clipboardObjects.
     * @return Value of property clipboardObjects.
     *
     */
    public java.util.Vector getClipboardObjects() {
        return clipboardObjects;
    }
    
    /** Setter for property clipboardObjects.
     * @param clipboardObjects New value of property clipboardObjects.
     *
     */
    public void setClipboardObjects(java.util.Vector clipboardObjects) {
        this.clipboardObjects = clipboardObjects;
    }
    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private it.businesslogic.ireport.gui.JRulePanel jHorizontalRule;
    private javax.swing.JScrollBar jHorizontalScrollBar;
    private javax.swing.JMenuItem jMenuItemBandProperties;
    private javax.swing.JMenuItem jMenuItemCopy;
    private javax.swing.JMenuItem jMenuItemCopyStyle;
    private javax.swing.JMenuItem jMenuItemCut;
    private javax.swing.JMenuItem jMenuItemDelete;
    private javax.swing.JMenuItem jMenuItemElementProperties;
    private javax.swing.JMenuItem jMenuItemPaste;
    private javax.swing.JMenuItem jMenuItemPasteOnBand;
    private javax.swing.JMenuItem jMenuItemPasteStyle;
    private javax.swing.JMenuItem jMenuItemPattern;
    private javax.swing.JMenuItem jMenuItemTransformStaticText;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanelCorner;
    private javax.swing.JPanel jPanelHContainerRule;
    private javax.swing.JPanel jPanelHScroll;
    private it.businesslogic.ireport.gui.JReportPanel jPanelReport;
    private javax.swing.JPanel jPanelReportContainer;
    private javax.swing.JPanel jPanelSuperContainer;
    private javax.swing.JPanel jPanelVRule;
    private javax.swing.JPopupMenu jPopupMenuBand;
    private javax.swing.JPopupMenu jPopupMenuElement;
    private javax.swing.JSeparator jSeparator1;
    private javax.swing.JSeparator jSeparator2;
    private javax.swing.JSeparator jSeparator3;
    private javax.swing.JSeparator jSeparator4;
    private javax.swing.JScrollBar jVerticalScrollBar;
    // End of variables declaration//GEN-END:variables
    
    private Report report;
    
    private int undoIndex = -1;
    private Vector undoOperations;
    private Vector clipboardObjects;
    private Vector selectedElements;
    
    /**
     *  Zoom factor used in this frame...
     */
    private double zoomFactor;
    
    /**
     *  Actual mouse position...
     */
    private Point mouse = null;
    
    private boolean lensMode;
    
    private int newObjectType;
    
    private boolean showGrid;
    
    private int gridSize;
    
    private int transformationMinSize;
    
    private boolean snapToGrid;
    
    private int windowID;
    
    /** Utility field used by event firing mechanism. */
    private javax.swing.event.EventListenerList listenerList =  null;
    
    public JReportPanel getReportPanel() {
        return this.jPanelReport;
    }
    public void drawVoidDoc(Graphics2D g) {
        // Paint the background.
        g.setColor(new Color(128, 128, 128));
        // Fill a very large rectangle. Clipping will only paint what is
        //   necessary.
        g.fillRect(0, 0, 100000, 100000);
        
        // Due to optimize document drawing, we use a cache. Redraw void doc only if it+
        // is dirty...
        /*
        if (!isDocDirty)
        {
            return;
        }
         */
        
        //g.clearRect(0,0,offscreenImageDoc.getWidth(), offscreenImageDoc.getHeight());
        int horizontal_scroll = jHorizontalScrollBar.getValue();
        int vertical_scroll = jVerticalScrollBar.getValue();
        int zoomed_width = getZoomedDim(report.getWidth());
        int design_height = report.getDesignHeight();
        int zoomed_height = getZoomedDim(design_height);
        
        
        g.setColor(Color.WHITE);
        g.fillRect( 10- horizontal_scroll,10-vertical_scroll,zoomed_width , zoomed_height);
        g.setColor(Color.BLACK);
        g.drawRect( 9-horizontal_scroll, 9-vertical_scroll, zoomed_width,zoomed_height );
        
        // Paint shadow corner top-right
        g.setPaint( new TexturePaint( shadowsImages[0], new Rectangle2D.Double( zoomed_width+10-horizontal_scroll,9-vertical_scroll,9,9)));
        g.fillRect(zoomed_width+10-horizontal_scroll,9-vertical_scroll,9,9);
        
        // Paint shadow corner top-right
        g.setPaint( new TexturePaint( shadowsImages[1], new Rectangle2D.Double( zoomed_width+10-horizontal_scroll,18-vertical_scroll,9,9)));
        g.fillRect( zoomed_width+10-horizontal_scroll,18-vertical_scroll, 9,zoomed_height-8);
        
        g.setPaint(new TexturePaint( shadowsImages[2], new Rectangle2D.Double( zoomed_width+10-horizontal_scroll,zoomed_height+10-vertical_scroll,9,9)));
        g.fillRect( zoomed_width+10-horizontal_scroll,zoomed_height+10-vertical_scroll,9,9);
        
        g.setPaint(new TexturePaint( shadowsImages[3], new Rectangle2D.Double( 9-horizontal_scroll,zoomed_height+10-vertical_scroll, zoomed_width+2,9)));
        g.fillRect(  9-horizontal_scroll,zoomed_height+10-vertical_scroll, zoomed_width+1,9);
        
        g.setPaint(new TexturePaint( shadowsImages[4], new Rectangle2D.Double( 9-horizontal_scroll,zoomed_height+10-vertical_scroll,9,9)));
        g.fillRect(   9-horizontal_scroll,zoomed_height+10-vertical_scroll,9,9);
        
        // Draw grid...
        
        g.setColor(new Color(230,230,230));
        if (this.isShowGrid()) {
            
            Stroke defaultStroke = g.getStroke();
            //g.setStroke(new BasicStroke(1, BasicStroke.CAP_BUTT,
            //                     BasicStroke.JOIN_MITER, 1,
            //                     dashPattern, 0));
            float[] fArray = {2f,2f};
            BasicStroke m_Dashed3 = new BasicStroke(1, BasicStroke.CAP_SQUARE,
            BasicStroke.JOIN_BEVEL, 1.0f, fArray, 0.0f);
            g.setStroke(m_Dashed3);
            
            int zoomed_grid_size = getZoomedDim(this.gridSize);
            int grid_left = 10+ zoomed_grid_size - horizontal_scroll;
            int line_top = 10-vertical_scroll+1;
            int line_bottom = getZoomedDim(design_height)+10-vertical_scroll-2;

            if (zoomed_grid_size>2) {
                int i=1;
                grid_left = 10 - horizontal_scroll + getZoomedDim(i*this.gridSize);

                while (grid_left < zoomed_width+10-horizontal_scroll) {
                    g.drawLine(grid_left, line_top, grid_left, line_bottom);
                    i++;
                    grid_left = 10 - horizontal_scroll + getZoomedDim(i*this.gridSize);
                }
            }
            
            int grid_top = 10 - vertical_scroll;
            int line_left = 10-horizontal_scroll+1;
            int line_right = zoomed_width+10-horizontal_scroll-1;
            if (zoomed_grid_size>2) {
                int i=1;
                grid_top = 10 - vertical_scroll + getZoomedDim(i*this.gridSize);
                while (grid_top < line_bottom ) {
                    g.drawLine(line_left,grid_top,line_right,grid_top);
                    i++;
                    grid_top = 10 - vertical_scroll + getZoomedDim(i*this.gridSize);
                }
            }
            
            g.setStroke(defaultStroke);
        }
        
        
        
        // Draw document structure lines...
        g.setColor(new Color(170,170,255));
        // LEFT MARGINE LINE
        g.drawLine( getZoomedDim(report.getLeftMargin())+10-horizontal_scroll,
        10-vertical_scroll,
        getZoomedDim(report.getLeftMargin())+10-horizontal_scroll,
        zoomed_height+10-vertical_scroll-2);
        
        // RIGHT MARGIN LINE
        g.drawLine(getZoomedDim(report.getWidth()- report.getRightMargin())+10-horizontal_scroll,
        10-vertical_scroll,
        getZoomedDim(report.getWidth()-report.getRightMargin())+10-horizontal_scroll,
        zoomed_height+10-vertical_scroll-2);
        
        g.drawLine( 10-horizontal_scroll,
        getZoomedDim(report.getTopMargin())+10-vertical_scroll,
        zoomed_width+10-horizontal_scroll-2,
        getZoomedDim(report.getTopMargin())+10-vertical_scroll);
        
        g.drawLine( 10-horizontal_scroll,
        getZoomedDim(design_height-report.getBottomMargin())+10-vertical_scroll,
        zoomed_width+10-horizontal_scroll-2,
        getZoomedDim(design_height- report.getBottomMargin())+10-vertical_scroll);
        
        int y=report.getTopMargin();
        
        Band page_header=null;
        Band page_footer=null;
        
        Enumeration e = report.getBands().elements();
        while (e.hasMoreElements()) {
            g.setColor(new Color(170,170,170));
            Band band = (Band)e.nextElement();
            y += band.getHeight();
            g.drawLine( 10-horizontal_scroll,
            getZoomedDim(y)+10-vertical_scroll,
            zoomed_width+10-horizontal_scroll-2,
            getZoomedDim(y)+10-vertical_scroll);
            
            g.setFont( new Font( "Arial", Font.PLAIN, getZoomedDim(20)));
            // We must center the text..
            int txt_width = g.getFontMetrics().stringWidth(band.getName())/2;
            int txt_height = g.getFontMetrics().getHeight()/2;
            txt_height -= g.getFontMetrics().getMaxDescent();
            g.setColor(new Color(220,220,255));
                /*
                g.setClip(getZoomedDim(report.getLeftMargin())+10-horizontal_scroll,
                          getZoomedDim(y-band.getHeight())+10-vertical_scroll,
                          getZoomedDim(report.getWidth()),
                          getZoomedDim(band.getHeight()));
                 */
            //Rectangle orgClipBounds = g.getClipBounds();
            
            Java2DUtil.setClip(g,
            getZoomedDim(report.getLeftMargin())+10-horizontal_scroll,
            getZoomedDim(y-band.getHeight())+10-vertical_scroll,
            getZoomedDim(report.getWidth()),
            getZoomedDim(band.getHeight()));
               /*
                g.setClip(getZoomedDim(report.getLeftMargin())+10-horizontal_scroll,
                          getZoomedDim(y-band.getHeight())+10-vertical_scroll,
                          getZoomedDim(report.getWidth()),
                          getZoomedDim(band.getHeight()));
                */
            
            g.drawString( band.getName(),
            getZoomedDim(report.getWidth()/2)+10-horizontal_scroll - txt_width,
            getZoomedDim(y)+10-vertical_scroll +  txt_height - getZoomedDim(band.getHeight()/2) ); //, zoomed_width, getZoomedDim(band.getHeight()
            //g.drawLine(0, getZoomedDim(y)+10-vertical_scroll -  txt_height - getZoomedDim(band.getHeight()/2),  700,getZoomedDim(y)+10-vertical_scroll -  txt_height - getZoomedDim(band.getHeight()/2));
            //g.drawLine(0, getZoomedDim(y)+10-vertical_scroll +  txt_height - getZoomedDim(band.getHeight()/2),  700,getZoomedDim(y)+10-vertical_scroll +  txt_height - getZoomedDim(band.getHeight()/2));
            
            /* g.setClip(null); */
            
            //g.setClip(orgClipBounds);
            Java2DUtil.resetClip(g);
            
            if (band.getName().equals("pageHeader")) page_header = band;
            if (band.getName().equals("pageFooter")) page_footer = band;
        }
        
        // PAint columns...
        int y1 = report.getBandYLocation(report.getBandByName("columnHeader") );
        int y2 = report.getBandYLocation(page_footer);
        
        for (int i=0; i< report.getColumnCount()-1; ++i) {
            int x = 10+getZoomedDim(report.getLeftMargin()+report.getColumnWidth() + i*(report.getColumnWidth()+report.getColumnSpacing()));
            //if (i !=0 ) {
            //}
            if (x<10+zoomed_width)
                g.drawLine( x-horizontal_scroll, getZoomedDim(y1)+10-vertical_scroll,
                x-horizontal_scroll, getZoomedDim(y2)+10-vertical_scroll);
            x = 10 + getZoomedDim(report.getLeftMargin() + report.getColumnWidth()+report.getColumnSpacing() + i *(report.getColumnWidth()+report.getColumnSpacing()));
            
            if (x<10+zoomed_width)
                g.drawLine( x-horizontal_scroll, getZoomedDim(y1)+10-vertical_scroll,
                x-horizontal_scroll, getZoomedDim(y2)+10-vertical_scroll);
        }
         /*
                g.setPen(new Pen(new Color(170,170,255)));
                g.drawLine( 10,getZoomedDim(report.topMargin)+10, getZoomedDim(report.getPagesize().x)+10, getZoomedDim(report.topMargin)+10);
                g.drawLine( 10,getZoomedDim(report.getDesignHeight())- getZoomedDim(report.topMargin)+10,  getZoomedDim(report.getPagesize().x)+10,getZoomedDim(report.getDesignHeight())- getZoomedDim(report.topMargin)+10);
          */
        //	g.setPen(new Pen(Color.BLACK ));
        
        isDocDirty = false;
    }
    
    public int getReversedZoomedDim(int dim) {
        if (zoomFactor == 1.0) return dim;
        return (int)((double)dim/zoomFactor);
    }
    
    public int getZoomedDim(int dim) {
        if (zoomFactor == 1.0) return dim;
        //if (((double)dim*(double)zoom_factor)<0.5) return 1;
        // Truncate, don't round!!
        return (int)((double)dim*zoomFactor);
        //return (int)Math.ceil((double)dim*zoom_factor);
    }
    
    public int getLogicalDim(int dim) {
        if (zoomFactor == 1.0) return dim;
        //if (Math.abs(  ((double)dim/(double)zoom_factor)) < 1 &&
        //	Math.abs(  ((double)dim/(double)zoom_factor)) > 0) return 1;
        // Truncate, don't round!!
        return (int)((double)dim/zoomFactor);
        //return (int)Math.ceil((double)dim/zoom_factor);
    }
    
    /** Getter for property zoomFactor.
     * @return Value of property zoomFactor.
     *
     */
    public double getZoomFactor() {
        return zoomFactor;
    }
    
    /** Setter for property zoomFactor.
     * @param zoomFactor New value of property zoomFactor.
     *
     */
    public void setZoomFactor(double zoomFactor) {
        if (this.zoomFactor != zoomFactor) {
            this.zoomFactor = zoomFactor;
            this.jPanelReportComponentResized( new java.awt.event.ComponentEvent( jPanelReport,0));
            isDocDirty = true;
            this.getReportPanel().repaint();
        }
    }
    
    public void paintReportPanel(Graphics g) {
                /*
                redrawAll(offscreen ,null, 0);
                g.drawImage( offscreenImage , 0,0, offscreenImage.getWidth(), offscreenImage.getHeight(), (ImageObserver)this);
                 */
        Graphics2D g2 = (Graphics2D) g;
        
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
        RenderingHints.VALUE_ANTIALIAS_OFF);
        g2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL,
        RenderingHints.VALUE_STROKE_PURE);
        g2.setRenderingHint(RenderingHints.KEY_DITHERING,
        RenderingHints.VALUE_DITHER_DISABLE);
        
        //long start = System.currentTimeMillis();
        //int number = 1;
        //System.out.println("redrawAll: (clip=" + g2.getClipRect() + ")");
        //for(int i=0; i<number; i++)
        //{
        redrawAll(g2, g2.getClipRect(), 0);
        //}
        //long stop = System.currentTimeMillis();
        //System.out.println(number + " paints took " + ((stop - start) / 1000.0) + " seconds");
    }
    
    
    private void redrawAll(Graphics2D g, Rectangle clipRect, int margin) {
        //g.clearRect(0,0,offscreenImage.getWidth(), offscreenImage.getHeight());
        //System.out.println("redraw all "+clipRect);
        if (clipRect ==null) {
            clipRect = new Rectangle(0,0,this.getReport().getWidth(),this.getReport().getDesignHeight());
        }
        
        //clipRect.x += jHorizontalScrollBar.getValue();
        //clipRect.y += jVerticalScrollBar.getValue();
        //g.setClip(clipRect);
        
        g.clearRect(0,0, (int) clipRect.getWidth(),  (int) clipRect.getHeight());
/*
                                 = new Rectangle( getZoomedDim2(clipRect.x-10 - margin)+ margin +10 + jHorizontalScrollBar.getValue(),
                                        getZoomedDim2(clipRect.y-10 - margin)+ margin +10 + jVerticalScrollBar.getValue(),
                                        getZoomedDim2(clipRect.width-2*margin)+2*margin,
                                        getZoomedDim2(clipRect.height-2*margin)+2*margin);
 */
        Rectangle realRect = new Rectangle(
        getReversedZoomedDim(clipRect.x-10-margin+jHorizontalScrollBar.getValue())+ margin +10,
        getReversedZoomedDim(clipRect.y-10-margin+jVerticalScrollBar.getValue())+ margin +10,
        getReversedZoomedDim(clipRect.width-2*margin)+2*margin,
        getReversedZoomedDim(clipRect.height-2*margin)+2*margin);
        
                /*
realRect = new Rectangle(
  getZoomedDim2(clipRect.x + jHorizontalScrollBar.getValue()) + margin,
  getZoomedDim2(clipRect.y + jVerticalScrollBar.getValue()) + margin,
  getZoomedDim2(clipRect.width),
  getZoomedDim2(clipRect.height));
                 */
        
        //g.setPaint(Color.CYAN);
        //g.fillRect( 0 ,0,offscreenWidth ,offscreenDimension.height);
        //
        // 1. Draw the void document...
        //g.setClip( realRect );
        drawVoidDoc(g);
        
/*
                                g.drawImage( offscreenImageDoc , clipRect.x,clipRect.y, clipRect.x + clipRect.width, clipRect.y + clipRect.height,
                                                                 clipRect.x,clipRect.y, clipRect.x + clipRect.width, clipRect.y + clipRect.height, (ImageObserver)this);
 */
        //                              g.drawImage( offscreenImageDoc , 0,0, offscreenImageDoc.getWidth(), offscreenImageDoc.getHeight(), (ImageObserver)this);
        //g.setClip( realRect );
        // 2. Draw all Reportelements...
        Enumeration e = report.getElements().elements();
        while (e.hasMoreElements()) {
            ReportElement re = (ReportElement)e.nextElement();
            if (re.intersects(realRect))
                re.drawObject(g, getZoomFactor(), jHorizontalScrollBar.getValue(), jVerticalScrollBar.getValue());
        }
        
        // If there's a selected element, draw a corona
        if (selectedElements.size()>0) {
            //clipRect.x -=5;
            //clipRect.y -=5;
            //clipRect.width  +=10;
            //clipRect.height +=10;
            e = selectedElements.elements();
            boolean master=true;
            while (e.hasMoreElements()) {
                ReportElement re = (ReportElement)e.nextElement();
                if (re.intersects(realRect))
                    re.drawCorona( g,getZoomFactor(), jHorizontalScrollBar.getValue(), jVerticalScrollBar.getValue(), master);
                master = false;
            }
        }
        
        //g.setPaint(Color.CYAN);
        //g.fillRect(realRect.x, realRect.y, realRect.width-2, realRect.height-2);
        
    }
    
    public MainFrame getMainFrame() {
        if (mf != null) return mf;
        // Retrieve parent while != MainFrame
        Container parent = this.getDesktopPane().getParent();
        while (parent != null && !(parent instanceof MainFrame)) {
            parent = parent.getParent();
        }
        if (parent != null) {
            mf = (MainFrame)parent;
            return mf;
        }
        else
            return null;
    }
    
    /** Getter for property lensMode.
     * @return Value of property lensMode.
     *
     */
    public boolean isLensMode() {
        return lensMode;
    }
    
    /** Setter for property lensMode.
     * @param lensMode New value of property lensMode.
     *
     */
    public void setLensMode(boolean lensMode) {
        //
        if (this.lensMode == lensMode) return;
        if (lensMode == true)
            jPanelReport.setCursor( java.awt.Cursor.getDefaultCursor());
        else {
            //if (getShiftState())
            //if (this.is
            //		panel9.setCursor(cursorminus );
            //	else
            //		panel9.setCursor(cursorplus);
        }
        this.lensMode = lensMode;
    }
    
    /** Getter for property newObjectType.
     * @return Value of property newObjectType.
     *
     */
    public int getNewObjectType() {
        return newObjectType;
    }
    
    /** Setter for property newObjectType.
     * @param newObjectType New value of property newObjectType.
     *
     */
    public void setNewObjectType(int newObjectType) {
        
        
        if (this.newObjectType == newObjectType) return;
        
        if (newObjectType == ReportElementType.NONE) {
                /*
                if (!first_draw2) panel9.createGraphics().drawLines(new Point[]{new Point(ne.x, ne.y),new Point(mouse.x, ne.y),new Point(mouse.x, mouse.y),new Point(ne.x, mouse.y),new Point(ne.x, ne.y)},RasterOp.SOURCE.xorWith(RasterOp.TARGET));
                first_draw2 = true;
                panel9.setCursor(Cursor.DEFAULT);
                ne = null;
                 */
            jPanelReport.setCursor( java.awt.Cursor.getDefaultCursor());
        }
        else {
            jPanelReport.setCursor( java.awt.Cursor.getPredefinedCursor(java.awt.Cursor.CROSSHAIR_CURSOR));
        }
        this.newObjectType = newObjectType;
    }
    
    
    
    public void setSelectedElement(ReportElement el, boolean fireEvent) {
        // Cancello le corone attorno a tutti gli elementi selezionati...
        boolean makerefreshAll = false;
        //if (selectedElements.size() > 0)
        makerefreshAll=true;
        getSelectedElements().removeAllElements();
       // getMainFrame().getElementPropertiesDialog().updateSelection();
                    /*
                while (selectedElements.size() > 0)
                {
                     
                     
                        ReportElement re = (ReportElement)selectedElements.elementAt(0);
                        selectedElements.removeElementAt(0);
                     
                        if (makerefreshAll) continue;
                     
                        Rectangle rect = new Rectangle(re.position.x-5,re.position.y-5,re.width+10, re.height+10);
                     
                        redrawAll(offscreen ,rect,5);
                        Rectangle clipRect = new Rectangle(getZoomedDim(re.position.x-10)-5+10-jHorizontalScrollBar.getValue(),
                                                                                           getZoomedDim(re.position.y-10)-5+10-jVerticalScrollBar.getValue(),
                                                                                           getZoomedDim(re.width)+10,
                                                                                           getZoomedDim(re.height)+10);
                        jPanelReport.getGraphics().drawImage( offscreenImage ,
                                                                      clipRect.x ,clipRect.y, clipRect.width,clipRect.height,
                                                                      clipRect.x ,clipRect.y, clipRect.width,clipRect.height,
                                                                      (ImageObserver)this);
                     
                }
                     */
        
        if (el != null) {
            Rectangle rect = new Rectangle(el.position.x-5,el.position.y-5,el.width+10, el.height+10);
            selectedElements.addElement(el);
            
            getMainFrame().setCutCopyEnabled(true);
                        /*
                        if (!makerefreshAll)
                        {
                                redrawAll(offscreen ,rect,5);
                                Rectangle clipRect = new Rectangle(getZoomedDim(el.position.x-10)-5+10-jHorizontalScrollBar.getValue(),
                                                                                           getZoomedDim(el.position.y-10)-5+10-jVerticalScrollBar.getValue(),
                                                                                           getZoomedDim(el.width)+10,
                                                                                           getZoomedDim(el.height)+10);
                         
                                jPanelReport.getGraphics().drawImage( offscreenImage ,
                                                                      clipRect.x ,clipRect.y, clipRect.width,clipRect.height,
                                                                      clipRect.x ,clipRect.y, clipRect.width,clipRect.height,
                                                                      (ImageObserver)this);
                        }
                         */
        }
        else {
            getMainFrame().setCutCopyEnabled(false);
        }
        if (makerefreshAll) {
            jPanelReport.repaint();
        }
        
               /*
                MainForm mf = (MainForm)this.getMDIParent();
                if (mf != null)
                {
                        if (mf.isPropertiesOpened())
                        {
                                        mf.initReportForm();
                                        mf.ep.setEelement(this,getSelectedElements());
                                        mf.ep.show();
                        }
                }
                */
        
        if (fireEvent)
        {
            ReportElementsSelectionEvent rece = new ReportElementsSelectionEvent(this, this.getSelectedElements()) ;
        
            this.fireReportListenerReportElementsSelectionChanged(rece );
            getMainFrame().getElementPropertiesDialog().updateSelection();
        }
    }
    
    public void setSelectedElement(ReportElement el) {
        setSelectedElement(el, true);
    }
    
    public void fireSelectionChangedEvent()
    {
        ReportElementsSelectionEvent rece = new ReportElementsSelectionEvent(this, this.getSelectedElements()) ;
        
        this.fireReportListenerReportElementsSelectionChanged(rece );
        getMainFrame().getElementPropertiesDialog().updateSelection();
    }
    
    public void addSelectedElement(ReportElement el)
    {
        addSelectedElement(el, true);
    }
     
    public void addSelectedElement(ReportElement el, boolean fireEvent) {
        if (selectedElements.contains(el)) return;
        //label1.setText("ADDED");
        // Faccio una corona non selected attorno al nuovo elemento...
        Rectangle rect = new Rectangle(el.position.x-5,el.position.y-5,el.width+10, el.height+10);
        selectedElements.addElement(el);
                /*
                redrawAll(offscreen ,rect,5);
                Rectangle clipRect = new Rectangle(getZoomedDim(el.position.x-10)-5+10-jHorizontalScrollBar.getValue(),
                                                                        getZoomedDim(el.position.y-10)-5+10-jVerticalScrollBar.getValue(),
                                                                        getZoomedDim(el.width)+10,
                                                                        getZoomedDim(el.height)+10);
                jPanelReport.getGraphics().drawImage( offscreenImage ,
                                                                      clipRect.x ,clipRect.y, clipRect.width,clipRect.height,
                                                                      clipRect.x ,clipRect.y, clipRect.width,clipRect.height,
                                                                      (ImageObserver)this);
                 */
        jPanelReport.repaint();
        
        if (fireEvent)
        {
            fireSelectionChangedEvent();
        }

        getMainFrame().setCutCopyEnabled(true);
    }
    
    /** Getter for property jPanelReport.
     * @return Value of property jPanelReport.
     *
     */
    public it.businesslogic.ireport.gui.JReportPanel getJPanelReport() {
        return jPanelReport;
    }
    
    /** Setter for property jPanelReport.
     * @param jPanelReport New value of property jPanelReport.
     *
     */
    public void setJPanelReport(it.businesslogic.ireport.gui.JReportPanel jPanelReport) {
        this.jPanelReport = jPanelReport;
    }
    
    /** Getter for property showGrid.
     * @return Value of property showGrid.
     *
     */
    public boolean isShowGrid() {
        return showGrid;
    }
    
    /** Setter for property showGrid.
     * @param showGrid New value of property showGrid.
     *
     */
    public void setShowGrid(boolean showGrid) {
        
        if (this.showGrid == showGrid) return;
        
        this.showGrid = showGrid;
        isDocDirty = true;
        jPanelReport.repaint();
    }
    
    /** Getter for property gridSize.
     * @return Value of property gridSize.
     *
     */
    public int getGridSize() {
        return gridSize;
    }
    
    /** Setter for property gridSize.
     * @param gridSize New value of property gridSize.
     *
     */
    public void setGridSize(int gridSize) {
        this.gridSize = gridSize;
    }
    
    /** Getter for property transformationMinSize.
     * @return Value of property transformationMinSize.
     *
     */
    public int getTransformationMinSize() {
        return transformationMinSize;
    }
    
    /** Setter for property transformationMinSize.
     * @param transformationMinSize New value of property transformationMinSize.
     *
     */
    public void setTransformationMinSize(int transformationMinSize) {
        this.transformationMinSize = transformationMinSize;
    }
    
    public int snapToGridVertically(int scaledYPoint) {
        if (!isSnapToGrid()) return scaledYPoint;
        
        int vertical_scroll = jVerticalScrollBar.getValue();
        int zoomed_grid_size = getZoomedDim(this.gridSize);
        int grid_top = 10+ zoomed_grid_size - vertical_scroll;
        int design_height = report.getDesignHeight();
        int line_bottom = getZoomedDim(design_height)+10-vertical_scroll-2;
        
        if (zoomed_grid_size>2) {
            int i=1;
            while (grid_top < line_bottom ) {
                if ( Math.abs(grid_top - scaledYPoint) <= zoomed_grid_size/2) {
                    return grid_top;
                }
                i++;
                grid_top = 10 - vertical_scroll + getZoomedDim(i*this.gridSize);
            }
        }
        return scaledYPoint;
    }
    
    public int snapToGridOrizzontally(int scaledXPoint) {
        if (!isSnapToGrid()) return scaledXPoint;
        // get closest horizontal grid to the
        // get closest vetical grid to the
        int horizontal_scroll = jHorizontalScrollBar.getValue();
        //int vertical_scroll = jVerticalScrollBar.getValue();
        int zoomed_width = getZoomedDim(report.getWidth());
        //int design_height = report.getDesignHeight();
        //int zoomed_height = getZoomedDim(design_height);
        int zoomed_grid_size = getZoomedDim(this.gridSize);
        int grid_left = 10+ zoomed_grid_size - horizontal_scroll;
        
        //int line_bottom = getZoomedDim(design_height)+10-vertical_scroll-2;
        if (zoomed_grid_size>2) {
            int i=1;
            while (grid_left < zoomed_width+10-horizontal_scroll) {
                if ( Math.abs(grid_left - scaledXPoint) <= zoomed_grid_size/2) {
                    return grid_left;
                }
                i++;
                grid_left =  10 - horizontal_scroll + getZoomedDim(i*this.gridSize);
            }
        }
        return scaledXPoint;
    }
    
    public int gridMultiple( int zoomedDim) {
        if (!isSnapToGrid()) {
            return zoomedDim;
        }
                
        int zoomedGridSize = getZoomedDim(this.gridSize);
        double val = Math.abs(zoomedDim);
        if ( zoomedGridSize > 1.0 ) {
          val =  Math.floor( ( val +  (0.5 * zoomedGridSize)) / zoomedGridSize ) * zoomedGridSize;
        }
        
        return (int) ( (zoomedDim >= 0) ? val : -val );
    }
    
    // no need for gridMultipleMinues
    /*
    public int gridMultipleMinus( int zoomedDim) {
        // Round ++...
        if (!isSnapToGrid()) {
            return zoomedDim;
        }
        
        int zoomed_grid_size = getZoomedDim(this.gridSize);
        int val = Math.abs(zoomedDim);
        if (val%zoomed_grid_size == 0) {
            return zoomedDim;
        }
        if( val%zoomed_grid_size <= zoomed_grid_size/2) {
            while ( val%zoomed_grid_size != 0) {
                val--;
            }
        }
        else {
            while ( val%zoomed_grid_size != 0) {
                val++;
            }
        }
        return (zoomedDim >= 0) ? val : -val;
    }
    */
    
    
    /** Getter for property snapToGrid.
     * @return Value of property snapToGrid.
     *
     */
    public boolean isSnapToGrid() {
        return snapToGrid;
    }
    
    /** Setter for property snapToGrid.
     * @param snapToGrid New value of property snapToGrid.
     *
     */
    public void setSnapToGrid(boolean snapToGrid) {
        this.snapToGrid = snapToGrid;
    }
    
    /** Getter for property isDocDirty.
     * @return Value of property isDocDirty.
     *
     */
    public boolean isIsDocDirty() {
        return isDocDirty;
    }
    
    /** Setter for property isDocDirty.
     * @param isDocDirty New value of property isDocDirty.
     *
     */
    public void setIsDocDirty(boolean isDocDirty) {
        this.isDocDirty = isDocDirty;
    }
    
    public void checkSelection(boolean repaint) {
        boolean needRepaint = false;
        for (int i=0; i< getSelectedElements().size(); ++i) {
            // Delete all objects that don't exists..
            ReportElement selected = (ReportElement)getSelectedElements().get(i);
            if (!this.getReport().getElements().contains(selected)) {
                getSelectedElements().removeElementAt(i);
                i--;
                needRepaint = true;
            }
        }
        if (repaint && needRepaint) {
            jPanelReport.repaint();
        }
    }
    
    /** Getter for property windowID.
     * @return Value of property windowID.
     *
     */
    public int getWindowID() {
        return windowID;
    }
    
    /** Setter for property windowID.
     * @param windowID New value of property windowID.
     *
     */
    public void setWindowID(int windowID) {
        this.windowID = windowID;
    }
    
    /** Registers ReportListener to receive events.
     * @param listener The listener to register.
     *
     */
    public synchronized void addReportListener(it.businesslogic.ireport.gui.event.ReportListener listener) {
        if (listenerList == null ) {
            listenerList = new javax.swing.event.EventListenerList();
        }
        listenerList.add(it.businesslogic.ireport.gui.event.ReportListener.class, listener);
    }
    
    /** Removes ReportListener from the list of listeners.
     * @param listener The listener to remove.
     *
     */
    synchronized void removeReportListener(it.businesslogic.ireport.gui.event.ReportListener listener) {
        listenerList.remove(it.businesslogic.ireport.gui.event.ReportListener.class, listener);
    }
    
    /** Notifies all registered listeners about the event.
     *
     * @param event The event to be fired
     *
     */
    public void fireReportListenerReportElementsSelectionChanged(it.businesslogic.ireport.gui.event.ReportElementsSelectionEvent event) {
        if (listenerList == null) return;
        Object[] listeners = listenerList.getListenerList();
        for (int i = listeners.length-2; i>=0; i-=2) {
            if (listeners[i]==it.businesslogic.ireport.gui.event.ReportListener.class) {
                ((it.businesslogic.ireport.gui.event.ReportListener)listeners[i+1]).reportElementsSelectionChanged(event);
            }
        }
    }
    
    /** Notifies all registered listeners about the event.
     *
     * @param event The event to be fired
     *
     */
    public void fireReportListenerReportElementsChanged(it.businesslogic.ireport.gui.event.ReportElementChangedEvent event) {
        if (listenerList == null) return;
        Object[] listeners = listenerList.getListenerList();
        for (int i = listeners.length-2; i>=0; i-=2) {
            if (listeners[i]==it.businesslogic.ireport.gui.event.ReportListener.class) {
                ((it.businesslogic.ireport.gui.event.ReportListener)listeners[i+1]).reportElementsChanged(event);
            }
        }
    }
    
    /** Notifies all registered listeners about the event.
     *
     * @param event The event to be fired
     *
     */
    public void fireReportListenerReportBandChanged(it.businesslogic.ireport.gui.event.ReportBandChangedEvent event) {
        if (listenerList == null) return;
        Object[] listeners = listenerList.getListenerList();
        for (int i = listeners.length-2; i>=0; i-=2) {
            if (listeners[i]==it.businesslogic.ireport.gui.event.ReportListener.class) {
                ((it.businesslogic.ireport.gui.event.ReportListener)listeners[i+1]).reportBandChanged(event);
            }
        }
    }
    
    
        /* Return the operation that must be invoked on undo
         * Return null if no undo operation is available
         */
    public UndoOperation getUndoOperation() {
        if (this.undoOperations.size() > 0 && undoIndex >= 0)
            return (UndoOperation)this.undoOperations.elementAt(undoIndex);
        return null;
    }
    
        /* This call "consume" the undo operation and update
         * internally the poiter of the undo list...
         */
    public void undo() {
        if (getUndoOperation() != null) {
            getUndoOperation().undo();
            this.undoIndex--;
            
            this.getReport().decrementDirty();
            getMainFrame().updateOpenedDocumentsList();
        }
    }
    
        /* This call "consume" the redo operation and update
         * internally the poiter of the undo list...
         */
    public void redo() {
        if (getRedoOperation() != null) {
            getRedoOperation().redo();
            this.undoIndex++;
            
            this.getReport().incrementDirty();
            getMainFrame().updateOpenedDocumentsList();
        }
    }
    
        /* Return the redo operation that must be invoked on redo
         * Return null if no redo operation is available
         */
    public UndoOperation getRedoOperation() {
        if (this.undoOperations.size() > undoIndex+1)
            return (UndoOperation)this.undoOperations.elementAt(undoIndex+1);
        return null;
    }
    
    public void addUndoOperation(UndoOperation undo) {
        // Remove all operations from the index...
        while (this.undoOperations.size() > undoIndex+1) {
            this.undoOperations.removeElementAt( undoIndex+1 );
        }
        undoOperations.addElement(undo);
        undoIndex++;
        
        try {
            getMainFrame().updateOpenedDocumentsList();
        } catch (Exception ex) {
            System.out.println( "[1]" + ex);
            ex.printStackTrace();
        }
        try {
            getMainFrame().updateUndoMenu(this);
        } catch (Exception ex) {
            System.out.println( "[2]" + ex);
            ex.printStackTrace();
        }
    }
    
    public void deleteSelectedElements() {
        // Remove selected elements...
        Enumeration e = selectedElements.elements();
        
        DeleteElementsOperation undoOp = new DeleteElementsOperation(this);
        Vector deletedElements = new Vector();
        
        while (e.hasMoreElements()) {
            ReportElement re = (ReportElement) e.nextElement();
            undoOp.addElement(  re, getReport().getElements().indexOf(re));
            getReport().getElements().remove( re );
            deletedElements.add(re);
            //fireReportListenerReportElementsChanged(new ReportElementChangedEvent(this, re , ReportElementChangedEvent.REMOVED));
        }
        
        fireReportListenerReportElementsChanged(new ReportElementChangedEvent(this, deletedElements,  ReportElementChangedEvent.REMOVED ));
        this.setSelectedElement(null);
        this.addUndoOperation(undoOp);
        //selectedElements.removeAllElements();
        
        jPanelReport.repaint();
    }
    
    public void cut() {
        Vector copiedElements = new Vector();
        Enumeration e = this.getSelectedElements().elements();
        while (e.hasMoreElements()) {
            ReportElement er = (ReportElement)e.nextElement();
            copiedElements.add(er.cloneMe());
        }
        
        
        if (copiedElements.size() > 0) {
            getMainFrame().setClipBoardContent(copiedElements);
        }
        
        // Remove selected elements...
        this.deleteSelectedElements();
        
        getMainFrame().updateCutAndPasteMenu(this);
        
    }
    
    public void copy() {
        Vector copiedElements = new Vector();
        Enumeration e = this.getSelectedElements().elements();
        while (e.hasMoreElements()) {
            ReportElement er = (ReportElement)e.nextElement();
            copiedElements.add(er.cloneMe());
        }
        if (copiedElements.size() > 0) {
            getMainFrame().setClipBoardContent(copiedElements);
        }
        
        getMainFrame().updateCutAndPasteMenu(this);
        
    }
    
    public void paste() {
        // Add elements...
        
        Enumeration e = getMainFrame().getClipBoard().elements();
        setSelectedElement(null);
        Vector addedElements = new Vector();
        while (e.hasMoreElements()) {
            ReportElement re = ((ReportElement)e.nextElement()).cloneMe();
            
            // Begin code by Robert Lamping, 12 July 2004
            // if element key begins with "element-" then adjust the key to express the correct number
            // The code is at least better than the current.
            // It goes wrong when items are deleted. It should look for the highest code used. But that can be done later
            re.setKey( getNextElementKey( re.getKey() ) ) ;
            // End code by Robert Lamping, 10 July 2004
            
            String bandName = re.getBand().getName();
            re.setBand( getReport().getBandByName( bandName ) );
            java.awt.Point p = re.getPosition();
            re.setPosition(new java.awt.Point(p.x+this.getGridSize(),p.y+this.getGridSize()));
            // We must find the right band to paste into...
            //re.setBand( bname );
            //fireReportListenerReportElementsChanged(new ReportElementChangedEvent(this, re , ReportElementChangedEvent.ADDED));
            addUndoOperation( new  InsertElementOperation(this, re) );
            report.getElements().addElement(re);
            addedElements.add(re);
            addSelectedElement(re,false);
        }
        fireReportListenerReportElementsChanged(new ReportElementChangedEvent(this, addedElements , ReportElementChangedEvent.ADDED));
        fireSelectionChangedEvent();
        
        getMainFrame().updateCutAndPasteMenu(this);
        
    }
    
    public void pasteHere(Point p) {
        // Add elements...
        int y = getLogicalDim( p.y-10+jVerticalScrollBar.getValue())+10;
        Enumeration e = getMainFrame().getClipBoard().elements();
        setSelectedElement(null);
        while (e.hasMoreElements()) {
            ReportElement re = ((ReportElement)e.nextElement()).cloneMe();
            
            String bandName = re.getBand().getName();
            Band b =  getReport().getBandByName( bandName );
            re.setBand( b );
            int ylocation = getReport().getBandYLocation( b );
            
            Band myBand = null;
            
            Enumeration enum_bands = getReport().getBands().elements();
            while (enum_bands.hasMoreElements()) {
                Band bb = (Band)enum_bands.nextElement();
                if (report.getBandYLocation(bb)+10 <= y) {
                    myBand = bb;
                }
            }
            
            if (myBand == null) return;
            
            int ylocation2 = getReport().getBandYLocation( myBand );
            
            Point location = re.getPosition();
            location.y += ylocation2 - ylocation;
            re.setPosition(location);
            re.updateBounds();
            re.setBand( myBand );
            
            // We must find the right band to paste into...
            //re.setBand( bname );
            //fireReportListenerReportElementsChanged(new ReportElementChangedEvent(this, re , ReportElementChangedEvent.ADDED));
            addUndoOperation( new  InsertElementOperation(this, re) );
            report.getElements().addElement(re);
            addSelectedElement(re, false);
        }
        fireSelectionChangedEvent();
        
        getMainFrame().updateCutAndPasteMenu(this);
        
    }
    
    public void openElementPropertiesDialog(){
        // If there is at least an element selected, open the properties window...
        MainFrame mainFrame = getMainFrame();
        
        if (getSelectedElements().size() > 0) {
            if (!mainFrame.getElementPropertiesDialog().isVisible()) {
                mainFrame.getElementPropertiesDialog().updateSelection();
                mainFrame.getElementPropertiesDialog().setVisible(true);
            }
        }
        jPanelReport.requestFocus();
    }
    
    public void  updateTitle() {
        this.setTitle(this.report.getName()+" "+this.report.getWidth()+"x"+this.report.getDesignHeight()+" ["+Misc.nvl(this.report.getFilename(),"unnamed")+"]");
    }
    
    /**
     *
     */
    public void bringToFront() {
        Enumeration e = this.getSelectedElements().elements();
        
        ChangeEmentsOrderOperation undoOp = new ChangeEmentsOrderOperation(this);
        
        while  (e.hasMoreElements()) {
            ReportElement element = (ReportElement)e.nextElement();
            
            int oldPosition = getReport().getElements().indexOf(element);
            getReport().getElements().remove(element);
            getReport().getElements().addElement(element);
            int newPosition = getReport().getElements().indexOf(element);
            undoOp.addElement(element,oldPosition, newPosition);
        }
        
        if (undoOp.getElements().size() > 0) {
            addUndoOperation(undoOp);
        }
        getReportPanel().repaint();
        // We must update the tree... the order i changed...
        /* TODO */
    }
    
    public void sendToBack() {
        Enumeration e = this.getSelectedElements().elements();
        
        ChangeEmentsOrderOperation undoOp = new ChangeEmentsOrderOperation(this);
        
        while  (e.hasMoreElements()) {
            ReportElement element = (ReportElement)e.nextElement();
            
            int oldPosition = getReport().getElements().indexOf(element);
            getReport().getElements().remove(element);
            getReport().getElements().insertElementAt(element, 0);
            int newPosition = 0;
            undoOp.addElement(element,oldPosition, newPosition);
        }
        
        if (undoOp.getElements().size() > 0) {
            addUndoOperation(undoOp);
        }
        getReportPanel().repaint();
        // We must update the tree... the order i changed...
        /* TODO */
    }
    
    public void makeOperation(int operationType) {
        if (getSelectedElements().isEmpty()) return;
        
        Enumeration e = getSelectedElements().elements();
        ReportElement re = null;
        FormatElementsOperation undoOp = new FormatElementsOperation(this, operationType);
        
        switch (operationType) {
            case OperationType.ALIGN_LEFT:
                int left= ((ReportElement)getSelectedElements().firstElement()).getPosition().x;
                
                while (e.hasMoreElements()){
                    re = (ReportElement)e.nextElement();
                    Rectangle oldBounds = new Rectangle( re.getPosition().x, re.getPosition().y, re.getWidth(), re.getHeight());
                    re.setPosition(new Point(left, re.getPosition().y));
                    re.updateBounds();
                    Rectangle newBounds = new Rectangle( re.getPosition().x, re.getPosition().y, re.getWidth(), re.getHeight());
                    undoOp.addElement(re, oldBounds, newBounds );
                }
                break;
            case OperationType.ALIGN_RIGHT:
                int right= ((ReportElement)getSelectedElements().firstElement()).getPosition().x+((ReportElement)getSelectedElements().firstElement()).getWidth();
                while (e.hasMoreElements()){
                    re = (ReportElement)e.nextElement();
                    Rectangle oldBounds = new Rectangle( re.getPosition().x, re.getPosition().y, re.getWidth(), re.getHeight());
                    re.setPosition(new Point(right-re.getWidth(), re.getPosition().y));
                    re.updateBounds();
                    Rectangle newBounds = new Rectangle( re.getPosition().x, re.getPosition().y, re.getWidth(), re.getHeight());
                    undoOp.addElement(re, oldBounds, newBounds );
                }
                break;
            case OperationType.ALIGN_TOP:
                int top= ((ReportElement)getSelectedElements().firstElement()).getPosition().y;
                while (e.hasMoreElements()){
                    re = (ReportElement)e.nextElement();
                    Rectangle oldBounds = new Rectangle( re.getPosition().x, re.getPosition().y, re.getWidth(), re.getHeight());
                    re.setPosition(new Point(re.getPosition().x, top));
                    re.updateBounds();
                    Rectangle newBounds = new Rectangle( re.getPosition().x, re.getPosition().y, re.getWidth(), re.getHeight());
                    undoOp.addElement(re, oldBounds, newBounds );
                }
                break;
            case OperationType.ALIGN_BOTTOM:
                int bottom= ((ReportElement)getSelectedElements().firstElement()).getPosition().y+((ReportElement)getSelectedElements().firstElement()).height;
                while (e.hasMoreElements()){
                    re = (ReportElement)e.nextElement();
                    Rectangle oldBounds = new Rectangle( re.getPosition().x, re.getPosition().y, re.getWidth(), re.getHeight());
                    re.setPosition(new Point(re.getPosition().x, bottom-re.height));
                    re.updateBounds();
                    Rectangle newBounds = new Rectangle( re.getPosition().x, re.getPosition().y, re.getWidth(), re.getHeight());
                    undoOp.addElement(re, oldBounds, newBounds );
                }
                break;
            case OperationType.ALIGN_HORIZONTAL_AXIS:
                re = (ReportElement)getSelectedElements().firstElement();
                int center = re.getPosition().y + (re.getHeight()/2);
                while (e.hasMoreElements()){
                    re = (ReportElement)e.nextElement();
                    Rectangle oldBounds = new Rectangle( re.getPosition().x, re.getPosition().y, re.getWidth(), re.getHeight());
                    re.setPosition(new Point(re.getPosition().x, center-(re.getHeight()/2) ));
                    re.updateBounds();
                    Rectangle newBounds = new Rectangle( re.getPosition().x, re.getPosition().y, re.getWidth(), re.getHeight());
                    undoOp.addElement(re, oldBounds, newBounds );
                }
                break;
            case OperationType.ALIGN_VERTICAL_AXIS:
                re = (ReportElement)getSelectedElements().firstElement();
                center = re.getPosition().x + (re.getWidth()/2);
                while (e.hasMoreElements()){
                    re = (ReportElement)e.nextElement();
                    Rectangle oldBounds = new Rectangle( re.getPosition().x, re.getPosition().y, re.getWidth(), re.getHeight());
                    re.setPosition(new Point(center-(re.getWidth()/2), re.getPosition().y));
                    re.updateBounds();
                    Rectangle newBounds = new Rectangle( re.getPosition().x, re.getPosition().y, re.getWidth(), re.getHeight());
                    undoOp.addElement(re, oldBounds, newBounds );
                }
                break;
            case OperationType.ALIGN_CENTER_HORIZONTALLY:
            case OperationType.CENTER_IN_BAND_H:
                re = (ReportElement)getSelectedElements().firstElement();
                
                while (e.hasMoreElements()){
                    re = (ReportElement)e.nextElement();
                    center = 10+this.getReport().getWidth()/2;
                    Rectangle oldBounds = new Rectangle( re.getPosition().x, re.getPosition().y, re.getWidth(), re.getHeight());
                    re.setPosition(new Point(center-(re.getWidth()/2), re.getPosition().y));
                    re.updateBounds();
                    Rectangle newBounds = new Rectangle( re.getPosition().x, re.getPosition().y, re.getWidth(), re.getHeight());
                    undoOp.addElement(re, oldBounds, newBounds );
                }
                break;
            case OperationType.ALIGN_CENTER_VERTICALLY:
            case OperationType.CENTER_IN_BAND_V:
                re = (ReportElement)getSelectedElements().firstElement();
                while (e.hasMoreElements()){
                    re = (ReportElement)e.nextElement();
                    center = this.report.getBandYLocation(re.getBand())+10+re.getBand().getHeight()/2;
                    Rectangle oldBounds = new Rectangle( re.getPosition().x, re.getPosition().y, re.getWidth(), re.getHeight());
                    re.setPosition(new Point(re.getPosition().x, center-(re.getHeight()/2)));
                    re.updateBounds();
                    Rectangle newBounds = new Rectangle( re.getPosition().x, re.getPosition().y, re.getWidth(), re.getHeight());
                    undoOp.addElement(re, oldBounds, newBounds );
                }
                break;
            case OperationType.ALIGN_CENTER:
            case OperationType.CENTER_IN_BAND:
                re = (ReportElement)getSelectedElements().firstElement();
                int centerx = 10+this.getReport().getWidth()/2;
                int centery = this.report.getBandYLocation(re.getBand())+10+re.getBand().getHeight()/2;
                while (e.hasMoreElements()){
                    re = (ReportElement)e.nextElement();
                    Rectangle oldBounds = new Rectangle( re.getPosition().x, re.getPosition().y, re.getWidth(), re.getHeight());
                    re.setPosition(new Point(centerx-(re.getWidth()/2), this.report.getBandYLocation(re.getBand())+10+re.getBand().getHeight()/2-(re.getHeight()/2)));
                    re.updateBounds();
                    Rectangle newBounds = new Rectangle( re.getPosition().x, re.getPosition().y, re.getWidth(), re.getHeight());
                    undoOp.addElement(re, oldBounds, newBounds );
                }
                break;
            case OperationType.SAME_WIDTH:
                re = (ReportElement)getSelectedElements().firstElement();
                int width = re.getWidth();
                while (e.hasMoreElements()){
                    re = (ReportElement)e.nextElement();
                    Rectangle oldBounds = new Rectangle( re.getPosition().x, re.getPosition().y, re.getWidth(), re.getHeight());
                    re.trasform(new Point(width-re.getWidth(),0), TransformationType.TRANSFORMATION_RESIZE_SE);
                    re.updateBounds();
                    Rectangle newBounds = new Rectangle( re.getPosition().x, re.getPosition().y, re.getWidth(), re.getHeight());
                    undoOp.addElement(re, oldBounds, newBounds );
                }
                break;
            case OperationType.SAME_WIDTH_MAX:
                re = (ReportElement)getSelectedElements().firstElement();
                // Looking for the max with...
                Enumeration enum2 = getSelectedElements().elements();
                width = re.getWidth();
                while (enum2.hasMoreElements()) {
                    re = (ReportElement)enum2.nextElement();
                    if (width <= re.getWidth()) width =re.getWidth();
                }
                while (e.hasMoreElements()){
                    re = (ReportElement)e.nextElement();
                    Rectangle oldBounds = new Rectangle( re.getPosition().x, re.getPosition().y, re.getWidth(), re.getHeight());
                    re.trasform(new Point(width-re.getWidth(),0), TransformationType.TRANSFORMATION_RESIZE_SE);
                    re.updateBounds();
                    Rectangle newBounds = new Rectangle( re.getPosition().x, re.getPosition().y, re.getWidth(), re.getHeight());
                    undoOp.addElement(re, oldBounds, newBounds );
                }
                break;
            case OperationType.SAME_WIDTH_MIN:
                re = (ReportElement)getSelectedElements().firstElement();
                // Looking for the max with...
                enum2 = getSelectedElements().elements();
                width = re.getWidth();
                while (enum2.hasMoreElements()) {
                    re = (ReportElement)enum2.nextElement();
                    if (width > re.getWidth()) width =re.getWidth();
                }
                while (e.hasMoreElements()){
                    re = (ReportElement)e.nextElement();
                    Rectangle oldBounds = new Rectangle( re.getPosition().x, re.getPosition().y, re.getWidth(), re.getHeight());
                    re.trasform(new Point(width-re.getWidth(),0), TransformationType.TRANSFORMATION_RESIZE_SE);
                    re.updateBounds();
                    Rectangle newBounds = new Rectangle( re.getPosition().x, re.getPosition().y, re.getWidth(), re.getHeight());
                    undoOp.addElement(re, oldBounds, newBounds );
                }
                break;
            case OperationType.SAME_HEIGHT:
                re = (ReportElement)getSelectedElements().firstElement();
                int height = re.height;
                while (e.hasMoreElements()){
                    re = (ReportElement)e.nextElement();
                    Rectangle oldBounds = new Rectangle( re.getPosition().x, re.getPosition().y, re.getWidth(), re.getHeight());
                    re.trasform(new Point(0,height-re.height), TransformationType.TRANSFORMATION_RESIZE_SE);
                    re.updateBounds();
                    Rectangle newBounds = new Rectangle( re.getPosition().x, re.getPosition().y, re.getWidth(), re.getHeight());
                    undoOp.addElement(re, oldBounds, newBounds );
                }
                break;
            case OperationType.SAME_HEIGHT_MAX:
                re = (ReportElement)getSelectedElements().firstElement();
                height = re.getHeight();
                enum2 = getSelectedElements().elements();
                while (enum2.hasMoreElements()) {
                    re = (ReportElement)enum2.nextElement();
                    if (height <= re.getHeight()) height =re.getHeight();
                }
                while (e.hasMoreElements()){
                    re = (ReportElement)e.nextElement();
                    Rectangle oldBounds = new Rectangle( re.getPosition().x, re.getPosition().y, re.getWidth(), re.getHeight());
                    re.trasform(new Point(0,height-re.height), TransformationType.TRANSFORMATION_RESIZE_SE);
                    re.updateBounds();
                    Rectangle newBounds = new Rectangle( re.getPosition().x, re.getPosition().y, re.getWidth(), re.getHeight());
                    undoOp.addElement(re, oldBounds, newBounds );
                }
                break;
            case OperationType.SAME_HEIGHT_MIN:
                re = (ReportElement)getSelectedElements().firstElement();
                height = re.getHeight();
                enum2 = getSelectedElements().elements();
                while (enum2.hasMoreElements()) {
                    re = (ReportElement)enum2.nextElement();
                    if (height > re.getHeight()) height =re.getHeight();
                }
                while (e.hasMoreElements()){
                    re = (ReportElement)e.nextElement();
                    Rectangle oldBounds = new Rectangle( re.getPosition().x, re.getPosition().y, re.getWidth(), re.getHeight());
                    re.trasform(new Point(0,height-re.height), TransformationType.TRANSFORMATION_RESIZE_SE);
                    re.updateBounds();
                    Rectangle newBounds = new Rectangle( re.getPosition().x, re.getPosition().y, re.getWidth(), re.getHeight());
                    undoOp.addElement(re, oldBounds, newBounds );
                }
                break;
            case OperationType.SAME_SIZE:
                re = (ReportElement)getSelectedElements().firstElement();
                height = re.height;
                width = re.getWidth();
                while (e.hasMoreElements()){
                    re = (ReportElement)e.nextElement();
                    Rectangle oldBounds = new Rectangle( re.getPosition().x, re.getPosition().y, re.getWidth(), re.getHeight());
                    re.trasform(new Point(width-re.getWidth(),height-re.height), TransformationType.TRANSFORMATION_RESIZE_SE);
                    re.updateBounds();
                    Rectangle newBounds = new Rectangle( re.getPosition().x, re.getPosition().y, re.getWidth(), re.getHeight());
                    undoOp.addElement(re, oldBounds, newBounds );
                }
                break;
            case OperationType.ALIGN_TOP_TO_BAND:
                while (e.hasMoreElements()){
                    re = (ReportElement)e.nextElement();
                    Rectangle oldBounds = new Rectangle( re.getPosition().x, re.getPosition().y, re.getWidth(), re.getHeight());
                    re.trasform(new Point(0,getReport().getBandYLocation( re.band)+10- re.getPosition().y), TransformationType.TRANSFORMATION_MOVE);
                    re.updateBounds();
                    Rectangle newBounds = new Rectangle( re.getPosition().x, re.getPosition().y, re.getWidth(), re.getHeight());
                    undoOp.addElement(re, oldBounds, newBounds );
                }
                break;
                
                /* Begin code Robert Lamping, 12 July 2004 */
            case OperationType.ALIGN_BOTTOM_TO_BAND:
                while (e.hasMoreElements()){
                    re = (ReportElement)e.nextElement();
                    Rectangle oldBounds = new Rectangle( re.getPosition().x, re.getPosition().y, re.getWidth(), re.getHeight());
                    //re.trasform(new Point(0,getReport().getBandYLocation( re.band)+10- re.getPosition().y), TransformationType.TRANSFORMATION_MOVE);
                    re.trasform( new Point(0, getReport().getBandYLocation( re.band)+10 + re.band.getHeight() -
                    ( re.getPosition().y + re.getHeight() ) ), TransformationType.TRANSFORMATION_MOVE);
                    re.updateBounds();
                    Rectangle newBounds = new Rectangle( re.getPosition().x, re.getPosition().y, re.getWidth(), re.getHeight());
                    undoOp.addElement(re, oldBounds, newBounds );
                }
                break;
                
            case OperationType.ALIGN_TO_LEFT_MARGIN:
                int leftMargin= getReport().getLeftMargin();
                //((ReportElement)getSelectedElements().firstElement()).getPosition().x;
                
                while (e.hasMoreElements()){
                    re = (ReportElement)e.nextElement();
                    Rectangle oldBounds = new Rectangle( re.getPosition().x, re.getPosition().y, re.getWidth(), re.getHeight());
                    re.setPosition(new Point(leftMargin + 10, re.getPosition().y));
                    re.updateBounds();
                    Rectangle newBounds = new Rectangle( re.getPosition().x, re.getPosition().y, re.getWidth(), re.getHeight());
                    undoOp.addElement(re, oldBounds, newBounds );
                }
                break;
                
            case OperationType.ALIGN_TO_RIGHT_MARGIN:
                int rightMargin= getReport().getRightMargin();
                
                while (e.hasMoreElements()){
                    re = (ReportElement)e.nextElement();
                    Rectangle oldBounds = new Rectangle( re.getPosition().x, re.getPosition().y, re.getWidth(), re.getHeight());
                    re.setPosition(new Point(this.getReport().getWidth() - rightMargin-re.getWidth()+ 10, re.getPosition().y));
                    re.updateBounds();
                    Rectangle newBounds = new Rectangle( re.getPosition().x, re.getPosition().y, re.getWidth(), re.getHeight());
                    undoOp.addElement(re, oldBounds, newBounds );
                }
                break;
            case OperationType.MOVE_TO_LEFT_MARGIN:
                // Move all elements to the left over the distance between first element and left margin
                re = (ReportElement)getSelectedElements().firstElement();
                int deltaLeft = re.getPosition().x - getReport().getLeftMargin();
                
                while (e.hasMoreElements()){
                    re = (ReportElement)e.nextElement();
                    Rectangle oldBounds = new Rectangle( re.getPosition().x, re.getPosition().y, re.getWidth(), re.getHeight());
                    re.setPosition(new Point(re.getPosition().x + 10 - deltaLeft,  re.getPosition().y));
                    re.updateBounds();
                    Rectangle newBounds = new Rectangle( re.getPosition().x, re.getPosition().y, re.getWidth(), re.getHeight());
                    undoOp.addElement(re, oldBounds, newBounds );
                }
                break;
                /* End code Robert Lamping, 12 July 2004 */
            case OperationType.ORGANIZE_AS_A_TABLE:
                
                e = getSelectedElements().elements();
                while (e.hasMoreElements()){
                    re = (ReportElement)e.nextElement();
                    Rectangle oldBounds = new Rectangle( re.getPosition().x, re.getPosition().y, re.getWidth(), re.getHeight());
                    Rectangle newBounds = new Rectangle( re.getPosition().x, re.getPosition().y, re.getWidth(), re.getHeight());
                    undoOp.addElement(re, oldBounds, newBounds );
                }
                
                makeOperation( OperationType.ALIGN_TOP_TO_BAND);
                // Remove all operations from the index...
                while (this.undoOperations.size() > undoIndex) {
                    this.undoOperations.removeElementAt( undoIndex);
                }
                undoIndex--;
                this.getReport().decrementDirty();
                makeOperation( OperationType.JOIN_LEFT);
                // Remove all operations from the index...
                while (this.undoOperations.size() > undoIndex) {
                    this.undoOperations.removeElementAt( undoIndex);
                }
                undoIndex--;
                this.getReport().decrementDirty();
                makeOperation( OperationType.MOVE_TO_LEFT_MARGIN);
                // Remove all operations from the index...
                while (this.undoOperations.size() > undoIndex) {
                    this.undoOperations.removeElementAt( undoIndex);
                }
                undoIndex--;
                this.getReport().decrementDirty();
                makeOperation( OperationType.SAME_HEIGHT_MIN);
                // Remove all operations from the index...
                while (this.undoOperations.size() > undoIndex) {
                    this.undoOperations.removeElementAt( undoIndex);
                }
                undoIndex--;
                this.getReport().decrementDirty();
                makeOperation( OperationType.INCREASE_SPACE_H);
                // Remove all operations from the index...
                while (this.undoOperations.size() > undoIndex) {
                    this.undoOperations.removeElementAt( undoIndex);
                }
                undoIndex--;
                this.getReport().decrementDirty();
                
                e = getSelectedElements().elements();
                int kkk = 0;
                while (e.hasMoreElements()){
                    re = (ReportElement)e.nextElement();
                    Rectangle newBounds = new Rectangle( re.getPosition().x, re.getPosition().y, re.getWidth(), re.getHeight());
                    ((ElementTransformation)undoOp.getTransformations().elementAt(kkk)).newBounds = newBounds;
                    kkk++;
                }
                break;
            case OperationType.JOIN_LEFT:
            case OperationType.REMOVE_SPACE_H:
                // 1 Search for all different bands...
                
                Vector used_bands = new Vector();
                enum2 = getSelectedElements().elements();
                while (enum2.hasMoreElements()) {
                    re = (ReportElement)enum2.nextElement();
                    if (!used_bands.contains(re.getBand())) {
                        used_bands.add(re.getBand());
                    }
                }
                // 2 For any bands, create a vector of elements of this bands order by left position...
                //      2b Set positions using the array....
                Enumeration bands_enum = used_bands.elements();
                while (bands_enum.hasMoreElements()) {
                    
                    Band b = (Band)bands_enum.nextElement();
                    
                    Vector myElements = new Vector();
                    enum2 = getSelectedElements().elements();
                    while (enum2.hasMoreElements()) {
                        re = (ReportElement)enum2.nextElement();
                        if (re.getBand() == b) {
                            // insert this element in the right position...
                            if (myElements.size() == 0) myElements.add(re);
                            else {
                                boolean inserted=false;
                                for (int i=0; i<myElements.size(); ++i) {
                                    ReportElement re2 = (ReportElement)myElements.elementAt(i);
                                    if (re.getPosition().x < re2.getPosition().x) {
                                        myElements.insertElementAt(re, i);
                                        inserted = true;
                                        
                                        break;
                                    }
                                }
                                if (!inserted)
                                    myElements.addElement(re);
                            }
                        }
                    }
                    
                    // Repositioning elements...
                    int actual_x =0;
                    for (int k=0; k<myElements.size(); ++k) {
                        re = (ReportElement)myElements.elementAt(k);
                        if (k==0) {
                            actual_x = ((ReportElement)myElements.elementAt(k)).getPosition().x;
                        }
                        
                        Rectangle oldBounds = new Rectangle( re.getPosition().x, re.getPosition().y, re.getWidth(), re.getHeight());
                        re.setPosition( new Point(actual_x, re.getPosition().y) );
                        actual_x += re.getWidth();
                        re.updateBounds();
                        Rectangle newBounds = new Rectangle( re.getPosition().x, re.getPosition().y, re.getWidth(), re.getHeight());
                        undoOp.addElement(re, oldBounds, newBounds );
                    }
                }
                break;
            case OperationType.JOIN_RIGHT:
                
                // 1 Search for all different bands...
                
                used_bands = new Vector();
                enum2 = getSelectedElements().elements();
                while (enum2.hasMoreElements()) {
                    re = (ReportElement)enum2.nextElement();
                    if (!used_bands.contains(re.getBand())) {
                        used_bands.add(re.getBand());
                    }
                }
                
                // 2 For any bands, create a vector of elements of this bands order by left position...
                //      2b Set positions using the array....
                bands_enum = used_bands.elements();
                while (bands_enum.hasMoreElements()) {
                    
                    Band b = (Band)bands_enum.nextElement();
                    Vector myElements = new Vector();
                    enum2 = getSelectedElements().elements();
                    while (enum2.hasMoreElements()) {
                        re = (ReportElement)enum2.nextElement();
                        if (re.getBand() == b) {
                            // insert this element in the right position...
                            if (myElements.size() == 0) myElements.add(re);
                            else {
                                boolean inserted=false;
                                for (int i=0; i<myElements.size(); ++i) {
                                    ReportElement re2 = (ReportElement)myElements.elementAt(i);
                                    if (re.getPosition().x > re2.getPosition().x) {
                                        myElements.insertElementAt(re, i);
                                        inserted = true;
                                        //System.out.println("Inserito re:" + re.getPosition().x + " pos:" + i );
                                        break;
                                    }
                                }
                                if (!inserted)
                                    myElements.addElement(re);
                            }
                        }
                    }
                    
                    // Repositioning elements...
                    int actual_x =0;
                    for (int k=0; k<myElements.size(); ++k) {
                        re = (ReportElement)myElements.elementAt(k);
                        if (k==0) {
                            actual_x = re.getPosition().x+re.getWidth();
                        }
                        
                        Rectangle oldBounds = new Rectangle( re.getPosition().x, re.getPosition().y, re.getWidth(), re.getHeight());
                        re.setPosition( new Point(actual_x-re.getWidth(), re.getPosition().y) );
                        actual_x -= re.getWidth();
                        re.updateBounds();
                        Rectangle newBounds = new Rectangle( re.getPosition().x, re.getPosition().y, re.getWidth(), re.getHeight());
                        undoOp.addElement(re, oldBounds, newBounds );
                    }
                }
                break;
            case OperationType.EQUALS_SPACE_H:
                // 1. Use an ordered array...
                if (getSelectedElements().size() <= 1) break;
                Vector myElements = new Vector();
                
                enum2 = getSelectedElements().elements();
                while (enum2.hasMoreElements()) {
                    re = (ReportElement)enum2.nextElement();
                    // insert this element in the right position...
                    if (myElements.size() == 0) myElements.add(re);
                    else {
                        boolean inserted=false;
                        for (int i=0; i<myElements.size(); ++i) {
                            ReportElement re2 = (ReportElement)myElements.elementAt(i);
                            if (re.getPosition().x < re2.getPosition().x) {
                                myElements.insertElementAt(re, i);
                                inserted = true;
                                //System.out.println("Inserito re:" + re.getPosition().x + " pos:" + i );
                                break;
                            }
                        }
                        if (!inserted)
                            myElements.addElement(re);
                    }
                }
                
                
                
                // Find the rightest element...
                
                int total_width=0;
                int available_width=0;
                int min_x = 0;
                int max_x = 0;
                re = (ReportElement)myElements.firstElement();
                min_x = re.getPosition().x;
                max_x = re.getPosition().x+re.getWidth();
                enum2 = myElements.elements();
                ReportElement leftElement = re;
                ReportElement rightElement = re;
                while (enum2.hasMoreElements()) {
                    re = (ReportElement)enum2.nextElement();
                    if (min_x > re.getPosition().x) {
                        min_x =re.getPosition().x;
                    }
                    if (max_x < re.getPosition().x+re.getWidth()) {
                        max_x =re.getPosition().x+re.getWidth();
                        rightElement = re;
                    }
                    available_width += re.getWidth();
                }
                available_width = max_x - min_x - available_width;
                available_width /= myElements.size()-1;
                System.out.println("Space: " + available_width);
                
                int actual_x = leftElement.getPosition().x + leftElement.getWidth() + available_width;
                e = myElements.elements();
                while (e.hasMoreElements()){
                    re = (ReportElement)e.nextElement();
                    if (re == leftElement) continue;
                    if (re == rightElement) continue;
                    
                    Rectangle oldBounds = new Rectangle( re.getPosition().x, re.getPosition().y, re.getWidth(), re.getHeight());
                    re.setPosition(new Point(actual_x, re.getPosition().y) );
                    re.updateBounds();
                    actual_x += re.getWidth() + available_width;
                    Rectangle newBounds = new Rectangle( re.getPosition().x, re.getPosition().y, re.getWidth(), re.getHeight());
                    undoOp.addElement(re, oldBounds, newBounds );
                }
                break;
            case OperationType.INCREASE_SPACE_H:
                // 1. Use an ordered array...
                if (getSelectedElements().size() <= 1) break;
                myElements = new Vector();
                
                enum2 = getSelectedElements().elements();
                while (enum2.hasMoreElements()) {
                    re = (ReportElement)enum2.nextElement();
                    // insert this element in the right position...
                    if (myElements.size() == 0) myElements.add(re);
                    else {
                        boolean inserted=false;
                        for (int i=0; i<myElements.size(); ++i) {
                            ReportElement re2 = (ReportElement)myElements.elementAt(i);
                            if (re.getPosition().x < re2.getPosition().x) {
                                myElements.insertElementAt(re, i);
                                inserted = true;
                                //System.out.println("Inserito re:" + re.getPosition().x + " pos:" + i );
                                break;
                            }
                        }
                        if (!inserted)
                            myElements.addElement(re);
                    }
                }
                
                e = myElements.elements();
                
                for (int i=1; i< myElements.size(); ++i){
                    re = (ReportElement)myElements.elementAt(i);
                    Rectangle oldBounds = new Rectangle( re.getPosition().x, re.getPosition().y, re.getWidth(), re.getHeight());
                    re.setPosition(new Point(re.getPosition().x+5*i, re.getPosition().y) );
                    re.updateBounds();
                    Rectangle newBounds = new Rectangle( re.getPosition().x, re.getPosition().y, re.getWidth(), re.getHeight());
                    undoOp.addElement(re, oldBounds, newBounds );
                }
                break;
            case OperationType.DECREASE_SPACE_H:
                // 1. Use an ordered array...
                if (getSelectedElements().size() <= 1) break;
                myElements = new Vector();
                
                enum2 = getSelectedElements().elements();
                while (enum2.hasMoreElements()) {
                    re = (ReportElement)enum2.nextElement();
                    // insert this element in the right position...
                    if (myElements.size() == 0) myElements.add(re);
                    else {
                        boolean inserted=false;
                        for (int i=0; i<myElements.size(); ++i) {
                            ReportElement re2 = (ReportElement)myElements.elementAt(i);
                            if (re.getPosition().x < re2.getPosition().x) {
                                myElements.insertElementAt(re, i);
                                inserted = true;
                                //System.out.println("Inserito re:" + re.getPosition().x + " pos:" + i );
                                break;
                            }
                        }
                        if (!inserted)
                            myElements.addElement(re);
                    }
                }
                
                e = myElements.elements();
                
                for (int i=1; i< myElements.size(); ++i){
                    re = (ReportElement)myElements.elementAt(i);
                    Rectangle oldBounds = new Rectangle( re.getPosition().x, re.getPosition().y, re.getWidth(), re.getHeight());
                    re.setPosition(new Point(Math.max( re.getPosition().x-5*i, ((ReportElement)myElements.elementAt(i-1)).getPosition().x), re.getPosition().y) );
                    re.updateBounds();
                    Rectangle newBounds = new Rectangle( re.getPosition().x, re.getPosition().y, re.getWidth(), re.getHeight());
                    undoOp.addElement(re, oldBounds, newBounds );
                }
                break;
                
            case OperationType.DECREASE_SPACE_V:
                // 1. Use an ordered array...
                if (getSelectedElements().size() <= 1) break;
                myElements = new Vector();
                
                enum2 = getSelectedElements().elements();
                while (enum2.hasMoreElements()) {
                    re = (ReportElement)enum2.nextElement();
                    // insert this element in the right position...
                    if (myElements.size() == 0) myElements.add(re);
                    else {
                        boolean inserted=false;
                        for (int i=0; i<myElements.size(); ++i) {
                            ReportElement re2 = (ReportElement)myElements.elementAt(i);
                            if (re.getPosition().y < re2.getPosition().y) {
                                myElements.insertElementAt(re, i);
                                inserted = true;
                                //System.out.println("Inserito re:" + re.getPosition().x + " pos:" + i );
                                break;
                            }
                        }
                        if (!inserted)
                            myElements.addElement(re);
                    }
                }
                
                e = myElements.elements();
                
                for (int i=1; i< myElements.size(); ++i){
                    re = (ReportElement)myElements.elementAt(i);
                    Rectangle oldBounds = new Rectangle( re.getPosition().x, re.getPosition().y, re.getWidth(), re.getHeight());
                    re.setPosition(new Point(re.getPosition().x, Math.max( re.getPosition().y-5*i, ((ReportElement)myElements.elementAt(i-1)).getPosition().y)) );
                    re.updateBounds();
                    Rectangle newBounds = new Rectangle( re.getPosition().x, re.getPosition().y, re.getWidth(), re.getHeight());
                    undoOp.addElement(re, oldBounds, newBounds );
                }
                break;
            case OperationType.INCREASE_SPACE_V:
                // 1. Use an ordered array...
                if (getSelectedElements().size() <= 1) break;
                myElements = new Vector();
                
                enum2 = getSelectedElements().elements();
                while (enum2.hasMoreElements()) {
                    re = (ReportElement)enum2.nextElement();
                    // insert this element in the right position...
                    if (myElements.size() == 0) myElements.add(re);
                    else {
                        boolean inserted=false;
                        for (int i=0; i<myElements.size(); ++i) {
                            ReportElement re2 = (ReportElement)myElements.elementAt(i);
                            if (re.getPosition().y < re2.getPosition().y) {
                                myElements.insertElementAt(re, i);
                                inserted = true;
                                //System.out.println("Inserito re:" + re.getPosition().x + " pos:" + i );
                                break;
                            }
                        }
                        if (!inserted)
                            myElements.addElement(re);
                    }
                }
                
                e = myElements.elements();
                
                for (int i=1; i< myElements.size(); ++i){
                    re = (ReportElement)myElements.elementAt(i);
                    Rectangle oldBounds = new Rectangle( re.getPosition().x, re.getPosition().y, re.getWidth(), re.getHeight());
                    re.setPosition(new Point(re.getPosition().x, re.getPosition().y+5*i) );
                    re.updateBounds();
                    Rectangle newBounds = new Rectangle( re.getPosition().x, re.getPosition().y, re.getWidth(), re.getHeight());
                    undoOp.addElement(re, oldBounds, newBounds );
                }
                break;
            case OperationType.REMOVE_SPACE_V:
                // 1. Use an ordered array...
                if (getSelectedElements().size() <= 1) break;
                myElements = new Vector();
                
                enum2 = getSelectedElements().elements();
                while (enum2.hasMoreElements()) {
                    re = (ReportElement)enum2.nextElement();
                    // insert this element in the right position...
                    if (myElements.size() == 0) myElements.add(re);
                    else {
                        boolean inserted=false;
                        for (int i=0; i<myElements.size(); ++i) {
                            ReportElement re2 = (ReportElement)myElements.elementAt(i);
                            if (re.getPosition().y < re2.getPosition().y) {
                                myElements.insertElementAt(re, i);
                                inserted = true;
                                //System.out.println("Inserito re:" + re.getPosition().x + " pos:" + i );
                                break;
                            }
                        }
                        if (!inserted)
                            myElements.addElement(re);
                    }
                }
                
                e = myElements.elements();
                
                for (int i=1; i< myElements.size(); ++i){
                    re = (ReportElement)myElements.elementAt(i);
                    Rectangle oldBounds = new Rectangle( re.getPosition().x, re.getPosition().y, re.getWidth(), re.getHeight());
                    re.setPosition(new Point(re.getPosition().x, ((ReportElement)myElements.elementAt(i-1)).getPosition().y +((ReportElement)myElements.elementAt(i-1)).getHeight() ) );
                    re.updateBounds();
                    Rectangle newBounds = new Rectangle( re.getPosition().x, re.getPosition().y, re.getWidth(), re.getHeight());
                    undoOp.addElement(re, oldBounds, newBounds );
                }
                break;
            case OperationType.EQUALS_SPACE_V:
                // 1. Use an ordered array...
                if (getSelectedElements().size() <= 1) break;
                myElements = new Vector();
                
                enum2 = getSelectedElements().elements();
                while (enum2.hasMoreElements()) {
                    re = (ReportElement)enum2.nextElement();
                    // insert this element in the right position...
                    if (myElements.size() == 0) myElements.add(re);
                    else {
                        boolean inserted=false;
                        for (int i=0; i<myElements.size(); ++i) {
                            ReportElement re2 = (ReportElement)myElements.elementAt(i);
                            if (re.getPosition().y < re2.getPosition().y) {
                                myElements.insertElementAt(re, i);
                                inserted = true;
                                //System.out.println("Inserito re:" + re.getPosition().x + " pos:" + i );
                                break;
                            }
                        }
                        if (!inserted)
                            myElements.addElement(re);
                    }
                }
                
                
                
                // Find the rightest element...
                
                int total_height=0;
                int available_height=0;
                int min_y = 0;
                int max_y = 0;
                re = (ReportElement)myElements.firstElement();
                min_y = re.getPosition().y;
                max_y = re.getPosition().y+re.getHeight();
                enum2 = myElements.elements();
                ReportElement topElement = re;
                ReportElement bottomElement = re;
                while (enum2.hasMoreElements()) {
                    re = (ReportElement)enum2.nextElement();
                    if (min_y > re.getPosition().y) {
                        min_y =re.getPosition().y;
                    }
                    if (max_y < re.getPosition().y+re.getHeight()) {
                        max_y =re.getPosition().y+re.getHeight();
                        bottomElement = re;
                    }
                    available_height += re.getHeight();
                }
                available_height = max_y - min_y - available_height;
                available_height /= myElements.size()-1;
                
                int actual_y = topElement.getPosition().y + topElement.getHeight() + available_height;
                e = myElements.elements();
                while (e.hasMoreElements()){
                    re = (ReportElement)e.nextElement();
                    if (re == topElement) continue;
                    if (re == bottomElement) continue;
                    
                    Rectangle oldBounds = new Rectangle( re.getPosition().x, re.getPosition().y, re.getWidth(), re.getHeight());
                    re.setPosition(new Point(re.getPosition().x,actual_y) );
                    re.updateBounds();
                    actual_y += re.getHeight() + available_height;
                    Rectangle newBounds = new Rectangle( re.getPosition().x, re.getPosition().y, re.getWidth(), re.getHeight());
                    undoOp.addElement(re, oldBounds, newBounds );
                }
                break;
        }
        this.getReportPanel().repaint();
        addUndoOperation(undoOp);
    }
    
     public TextFieldReportElement dropNewTextField(Point newObjectOrigin, String textfieldExpression, String classExpression) {
         
            return dropNewTextField(newObjectOrigin, textfieldExpression, classExpression, "Now");
     }
     
    public Band getBandAt(Point newObjectOrigin)
    {
        Enumeration enum_bands = report.getBands().elements();
        Band bname = null;
        
        int delta_h = 0;
        delta_h = gridMultiple(18);
        int delta_y = (delta_h<0) ? delta_h : 0;
        int originY = getLogicalDim(  Math.min(newObjectOrigin.y-10+jVerticalScrollBar.getValue(),newObjectOrigin.y+delta_y-10+jVerticalScrollBar.getValue()))+10;

        while (enum_bands.hasMoreElements()) {
            Band b = (Band)enum_bands.nextElement();
            if (report.getBandYLocation(b)+10 <= originY) {
                bname = b;
            }
        }
        
        return bname;
        
    }
    
    public TextFieldReportElement dropNewTextField(Point newObjectOrigin, String textfieldExpression, String classExpression, String time) {
        TextFieldReportElement re = null;
        // Find the band to associate to the new element...
        Enumeration enum_bands = report.getBands().elements();
        Band bname = null;
        
        int delta_w = 0;
        int delta_h = 0;
        delta_w = gridMultiple(100);
        delta_h = gridMultiple(18);
        int delta_x = (delta_w<0) ? delta_w: 0;
        int delta_y = (delta_h<0) ? delta_h : 0;
        
        
        int originX = getLogicalDim(   Math.min(newObjectOrigin.x-10+jHorizontalScrollBar.getValue(),newObjectOrigin.x+delta_x-10+jHorizontalScrollBar.getValue()))+10;
        int originY = getLogicalDim(  Math.min(newObjectOrigin.y-10+jVerticalScrollBar.getValue(),newObjectOrigin.y+delta_y-10+jVerticalScrollBar.getValue()))+10;
        int width  =  getLogicalDim(  Math.abs( delta_w) );
        int height =  getLogicalDim( Math.abs(delta_h) );
        while (enum_bands.hasMoreElements()) {
            Band b = (Band)enum_bands.nextElement();
            if (report.getBandYLocation(b)+10 <= originY) {
                bname = b;
            }
        }
        
        re = new TextFieldReportElement( originX,originY,width,height);
        re.setBand( bname );
        if (classExpression.equals("java.lang.Object"))
            re.setClassExpression( "java.lang.String" );
        else
            re.setClassExpression( classExpression );
        re.setText(textfieldExpression);
        re.setEvaluationTime( time );
        
        fireReportListenerReportElementsChanged(new ReportElementChangedEvent(this, re , ReportElementChangedEvent.ADDED));
        addUndoOperation( new  InsertElementOperation(this, re) );
        
        
        
        report.getElements().addElement(re);
        setSelectedElement(re);
        jPanelReport.setCursor( Cursor.getDefaultCursor());
        getMainFrame().setActiveTool(0);
        
        return re;
    }
    
    public void moveUp() {
        if (this.getSelectedElements().size() == 0) return;
        
        Enumeration e = this.getSelectedElements().elements();
        
        ChangeEmentsOrderOperation undoOp = new ChangeEmentsOrderOperation(this);
        
        while  (e.hasMoreElements()) {
            ReportElement element = (ReportElement)e.nextElement();
            
            int oldPosition = getReport().getElements().indexOf(element);
            getReport().getElements().remove(element);
            int newPosition = Math.max(0, oldPosition - 1);
            getReport().getElements().insertElementAt(element, newPosition);
            newPosition = getReport().getElements().indexOf(element);
            undoOp.addElement(element,oldPosition, newPosition);
        }
        
        addUndoOperation(undoOp);
        getReportPanel().repaint();
        // We must update the tree... the order i changed...
        /* TODO */
    }
    
    public void moveDown() {
        if (getSelectedElements().size() == 0) return;
        
        ChangeEmentsOrderOperation undoOp = new ChangeEmentsOrderOperation(this);
        
        Vector selected = getSelectedElements();
        for(int i = selected.size() - 1; i >= 0; i--) {
            ReportElement element = (ReportElement) selected.get(i);
            
            int oldPosition = getReport().getElements().indexOf(element);
            int newPosition = Math.min(getReport().getElements().size() - 1, oldPosition + 1);
            getReport().getElements().remove(element);
            getReport().getElements().insertElementAt(element, newPosition);
            newPosition = getReport().getElements().indexOf(element);
            undoOp.addElement(element,oldPosition, newPosition);
        }
        
        
        
        addUndoOperation(undoOp);
        getReportPanel().repaint();
        
        // We must update the tree... the order i changed...
        /* TODO */
    }
    
    public void  transformStaticInTextFields() {
        // Begin code Robert Lamping, 13 july 2004
        String keyStaticText = (new StaticTextReportElement(0,0,0,0)).getKey();
        String keyTextField  = (new TextFieldReportElement(0,0,0,0)).getKey();
        // End code Robert Lamping, 13 july 2004
        
        
        // Edit static Text
        Enumeration e = selectedElements.elements();
        
        ReplacedElementsOperation undoOp = new ReplacedElementsOperation(this);
        
        while (e.hasMoreElements()) {
            ReportElement re = (ReportElement) e.nextElement();
            if(re instanceof StaticTextReportElement){
                // 1.
                TextFieldReportElement tfre = new TextFieldReportElement(re.getPosition().x, re.getPosition().y, re.width, re.height);
                // Set base characteristics...
                tfre.copyBaseReportElement(tfre, re);
                // Set Text characteristics...
                tfre.setBold(((TextReportElement)re).isBold() );
                tfre.setUnderline( ((TextReportElement)re).isUnderline() );
                tfre.setStrikeTrought( ((TextReportElement)re).isStrikeTrought() );
                tfre.setItalic( ((TextReportElement)re).isItalic() );
                
                tfre.setLineSpacing( ((TextReportElement)re).getLineSpacing() );
                tfre.setPDFFontName( ((TextReportElement)re).getPDFFontName() );
                tfre.setPdfEncoding( ((TextReportElement)re).getPdfEncoding() );
                tfre.setReportFont( ((TextReportElement)re).getReportFont() );
                tfre.setRotate( ((TextReportElement)re).getRotate() );
                tfre.setTTFFont( ((TextReportElement)re).getTTFFont() );
                tfre.setVerticalAlign( ((TextReportElement)re).getVerticalAlign());
                tfre.setFont( ((TextReportElement)re).getFont() );
                tfre.setFontName( ((TextReportElement)re).getFontName() );
                tfre.setFontSize(((TextReportElement)re).getFontSize() );
                
                tfre.setClassExpression( "java.lang.String" );
                
                // Begin code Robert Lamping, 13 july 2004
                // Changing key element name
                if (re.getKey().indexOf( keyStaticText + "-" ) == 0 ) {
                    // key indeed begins with "staticText-"
                    //Okay then request the next available key for a normal field text
                    tfre.setKey( getNextElementKey( keyTextField ) );
                }
                /* else{
                    // key text begins with something else then the standard.
                    // Leave unchanged
                  )
                }
                 */
                // End code Robert Lamping, 13 july 2004
                
                String te = ((TextReportElement)re).getText();
                String result = javax.swing.JOptionPane.showInputDialog(this, "Please enter new Value", "\"" +te + "\"");
                if(result != null && !result.equals("")){
                    ((TextReportElement)tfre).setText(result);
                    // 1. remove element
                    int index = getReport().getElements().indexOf( re );
                    getReport().getElements().remove( re );
                    getReport().getElements().add( index, tfre);
                    
                    int index2 = getSelectedElements().indexOf( re );
                    getSelectedElements().remove( re );
                    getSelectedElements().add( index2, tfre);
                    
                    // 2. add element
                    undoOp.addElement( re, tfre);
                    fireReportListenerReportElementsChanged(new ReportElementChangedEvent(this, re , ReportElementChangedEvent.REMOVED));
                    fireReportListenerReportElementsChanged(new ReportElementChangedEvent(this, tfre , ReportElementChangedEvent.ADDED));
                    
                }
            }
        }
        this.addUndoOperation(undoOp);
        fireReportListenerReportElementsSelectionChanged(new ReportElementsSelectionEvent( this, getSelectedElements()));
        jPanelReport.repaint();
    }
    
    public void pasteStyle() {
        if (this.getSelectedElements().size() == 0) return;
        if (this.getMainFrame().getStyleClipboard() == null) return;
        
        // Style are relative to:
        ReportElement templateElement = this.getMainFrame().getStyleClipboard();
        
        PasteStyleOperation undoOp = new PasteStyleOperation(this);
        
        Enumeration elements = getSelectedElements().elements();
        while (elements.hasMoreElements()) {
            ReportElement re = (ReportElement)elements.nextElement();
            undoOp.addElement(re, re.cloneMe(), templateElement);
            applyStyle(re, templateElement);
        }
        this.addUndoOperation(undoOp);
        fireReportListenerReportElementsSelectionChanged(new ReportElementsSelectionEvent( this, getSelectedElements()));
        jPanelReport.repaint();
        
    }
    
    public static void applyStyle(ReportElement re, ReportElement templateElement) {
        if (re == null || templateElement == null) return;
        // Colors...
        re.setBgcolor(templateElement.getBgcolor());
        re.setFgcolor(templateElement.getFgcolor());
        
        if (re instanceof GraphicReportElement && templateElement instanceof GraphicReportElement ) {
            ((GraphicReportElement)re).setFill( ((GraphicReportElement)templateElement).getFill());
            ((GraphicReportElement)re).setGraphicElementPen( ((GraphicReportElement)templateElement).getGraphicElementPen());
        }
        if (re instanceof TextReportElement && templateElement instanceof TextReportElement ) {
            ((TextReportElement)re).setFont(((TextReportElement)templateElement).getFont());
            ((TextReportElement)re).setFontName(((TextReportElement)templateElement).getFontName());
            ((TextReportElement)re).setFontSize(((TextReportElement)templateElement).getFontSize());
            ((TextReportElement)re).setIReportFont(((TextReportElement)templateElement).getIReportFont());
            ((TextReportElement)re).setIsStyledText(((TextReportElement)templateElement).isIsStyledText());
            ((TextReportElement)re).setLineSpacing(((TextReportElement)templateElement).getLineSpacing());
            ((TextReportElement)re).setPDFFontName(((TextReportElement)templateElement).getPDFFontName());
            ((TextReportElement)re).setPdfEmbedded(((TextReportElement)templateElement).isPdfEmbedded());
            ((TextReportElement)re).setPdfEncoding(((TextReportElement)templateElement).getPdfEncoding());
            ((TextReportElement)re).setReportFont(((TextReportElement)templateElement).getReportFont());
            ((TextReportElement)re).setRotate(((TextReportElement)templateElement).getRotate());
            ((TextReportElement)re).setTTFFont(((TextReportElement)templateElement).getTTFFont());
            ((TextReportElement)re).setVerticalAlign(((TextReportElement)templateElement).getVerticalAlign());
            ((TextReportElement)re).setAlign(((TextReportElement)templateElement).getAlign());
            ((TextReportElement)re).setBold( ((TextReportElement)templateElement).isBold());
            ((TextReportElement)re).setStrikeTrought( ((TextReportElement)templateElement).isStrikeTrought());
            ((TextReportElement)re).setItalic( ((TextReportElement)templateElement).isItalic());
            ((TextReportElement)re).setUnderline( ((TextReportElement)templateElement).isUnderline());
        }
        
    }
    
    public void copyStyle() {
        // We should copy this element to use it as style template...
        if (this.getSelectedElements().size() == 0) return;
        this.getMainFrame().setStyleClipbardContent( ((ReportElement)this.getSelectedElements().elementAt(0)).cloneMe() );
        
    }
    
    public void updateScrollBars() {
        jPanelReportComponentResized(null);
    }
    
    // Begin code by Robert Lamping, 12 July 2004
    public String getNextElementKey(String keyElement) {
        int maxKey = 0;
        String prefix = keyElement;
        
        // check if there is already a "-"
        // if so shorten keyElement and assign to prefix
        if ( prefix.indexOf( "-")  > 0 ){
            prefix = prefix.substring(0,  prefix.indexOf("-") );
        }
        prefix = prefix + "-" ;
        
        int pos = prefix.indexOf( "-") + 1;
        
        for (Iterator i = report.getElements().iterator(); i.hasNext(); ) {
            ReportElement re = (ReportElement) i.next();
            if ( re.getKey().indexOf( prefix ) == 0 ) {
                try {
                    int elementNum = (int) Integer.valueOf( re.getKey().substring(pos) ).intValue();
                    maxKey = maxKey < elementNum ? elementNum: maxKey;
                }
                catch (NumberFormatException err) {
                    // do nothing.
                    // string behind contained something else than a number
                }
            }
        }
        
/*        if (maxKey == 0) {
            if (report.getElements().size() > 0  ) {
                // all keys were renamed to something else
                maxKey = report.getElements().size() ;
            }
            // else: No elements present: all deleted or start of new document.
        }
 */
        
        return ( prefix + (maxKey+1) ) ;
    }
    // End code by Robert Lamping, 12 July 2004
    
    // Begin code by Robert Lamping, 16 July 2004
    public void centerSelectedElements( ) {
        centerSelectedElements( null);
    }
    
    public void centerSelectedElements( Point center ) {
        
        // This action is done after zooming in or out.
        // logOnConsole ("centerSelectedElements \n");
        if ( getSelectedElements().size() > 0) {
            double minX = 999999999.0;  //a very high value
            double minY = 999999999.0;  //a very high value
            double maxX = 0.0;
            double maxY = 0.0;
            double centerX = 0.0;
            double centerY = 0.0;
            boolean intersects = true;
            Rectangle rect = new Rectangle( realPoint( 0.0, 0.0 ), new Dimension( this.getWidth(), this.getHeight()  ) ) ;
            
            for (Iterator i = this.getSelectedElements().iterator(); i.hasNext(); ) {
                ReportElement re = (ReportElement) i.next();
                
                minY = Math.min( minY, re.getPosition().y -10) ;
                minX = Math.min( minX, re.getPosition().x -10);
                
                maxY = Math.max( maxY, re.getPosition().y + re.getHeight() -10 ) ;
                maxX = Math.max( maxX, re.getPosition().x + re.getWidth() -10 );
                
            }
            centerX = ((minX + maxX)/2);
            centerY = ((minY + maxY)/2);
            
            repositionScrollBars( new Point( (int) centerX, (int) centerY));
            
        } else {
            // test: place object in Center, do not select, zoom in with 200%
            // and check whether is more or less in the center.
            if ( center != null ) {
                repositionScrollBars( center );
            }
            
        }
        this.setIsDocDirty(false);
        
    }
    /**
     * Try to reposition the scrollbars so that the point is in the center of the visible screen
     * If it is not possible to center it, this method will at least make sure
     * the point is visible.
     **/
    
    public void repositionScrollBars(Point center) {
        try{
            if (jHorizontalScrollBar.getVisibleAmount() < jHorizontalScrollBar.getMaximum() )  {
                double horbarvalue = this.jHorizontalScrollBar.getMaximum() * center.x /  this.report.getWidth();
                this.jHorizontalScrollBar.setValue( (int) ( horbarvalue - ( 0.5 * jHorizontalScrollBar.getVisibleAmount()  ))  );
            }
            if (jVerticalScrollBar.getVisibleAmount() < jVerticalScrollBar.getMaximum() )  {
                double verbarvalue = this.jVerticalScrollBar.getMaximum() * center.y /  this.report.getDesignHeight();
                this.jVerticalScrollBar.setValue( (int) ( verbarvalue - ( 0.5 * jVerticalScrollBar.getVisibleAmount() ) )  );
            }
        } catch (Exception ex) {
            /* Do nothing */
        }
    }
    
    /**
     * calculates center of visible (white) canvas (=report) .
     */
    public Point getCurrentCenter(){
        double centerX = 0.0 ;
        double centerY = 0.0 ;
        
        if (jVerticalScrollBar.getVisibleAmount() >= jVerticalScrollBar.getMaximum() )  {
            centerY = 0 ; // this.getReport().getDesignHeight() / 2;
        } else {
            centerY  = (double) this.jVerticalScrollBar.getValue();
            centerY += 0.5 * (double) this.jVerticalScrollBar.getVisibleAmount();
            centerY /= (double) this.jVerticalScrollBar.getMaximum();
            centerY *= (double) this.getReport().getDesignHeight();
        }
        
        if (jHorizontalScrollBar.getVisibleAmount() >= jHorizontalScrollBar.getMaximum() )  {
            //canvas width < frame boundary
            // so take report width
            centerX = 0 ; // this.getReport().getWidth() / 2;
        } else {
            centerX  = (double) this.jHorizontalScrollBar.getValue();
            centerX += 0.5 * (double) this.jHorizontalScrollBar.getVisibleAmount();
            centerX /= (double) this.jHorizontalScrollBar.getMaximum();
            centerX *= (double) this.getReport().getWidth();
        }
        return new Point( (int) centerX, (int) centerY);
        
    }
    
    public void logOnConsole(String s) {
        this.getMainFrame().logOnConsole(s);
    }
    
    public Point realPoint( double deltaX, double deltaY ){;
    double centerX = 0.0;
    double centerY = 0.0;
    
    centerX  = (double) this.jHorizontalScrollBar.getValue();
    centerX += (double) deltaX;
    centerX /= (double) this.jHorizontalScrollBar.getMaximum();
    centerX *= (double) this.getReport().getWidth();
    
    centerY  = (double) this.jVerticalScrollBar.getValue();
    centerY += (double) deltaY;
    centerY /= (double) this.jVerticalScrollBar.getMaximum();
    centerY *= (double) this.getReport().getDesignHeight();
    
    return new Point( (int) centerX, (int) centerY );
    }
    
    public java.util.Vector getBandElements(Band band) {
        Vector bandElements = new Vector();
        
        for (Iterator i = getReport().getElements().iterator(); i.hasNext(); ) {
            ReportElement re = (ReportElement) i.next();
            if ( re.getBand().equals(band) ) {
                bandElements.addElement(re);
            }
        }
        return bandElements;
    }

    
    /**
     * Resize the band, as a result of dragging or double click
     * @param Band band The band you wish to resize
     * @param int delta The change in height (plus or min) 
     * @param Boolean include (TRUE: move elements in current band too)
     * @author: Robert Lamping, 24 july 2004
     */    
    public void resizeBand( Band band, int delta, boolean include ) {
        
        BandDraggedOperation undoOp = new BandDraggedOperation(this, band );
        // Adjustband Height.
        band.setHeight( band.getHeight() + delta );
        // pass the change in bandheight to the undo operation
        undoOp.setBandDelta(delta);
        
        // adjust all elements that are positioned in the remaining bands.
        int edge_y = 0 ;
        
        if ( include ) {
            edge_y = band.getBandYLocation() + band.getHeight() + delta;
        } else {
            edge_y = band.getBandYLocation() + band.getHeight();
        }
        
        for (Iterator i = report.getElements().iterator(); i.hasNext(); ) {
            ReportElement re = (ReportElement) i.next();
            //logOnConsole( "re.position : " + re.position + "\n");
            //logOnConsole( "edge_y : " + edge_y + "\n");
            //logOnConsole( "edge_y + 10 : " + (edge_y + 10)  + "\n");
            if (re.position.y >= edge_y + 10 ) {
                // get the current position for the undo operation
                Rectangle oldBounds = re.getBounds();
                re.setPosition( new Point( re.getPosition().x, re.getPosition().y + delta) );
                // get the new position for the undo operation
                Rectangle newBounds = re.getBounds();
                // add another task to the undo operation.
                undoOp.addElement(re, oldBounds, newBounds );
            }
        }
        // Pass all undo tasks to the undo cluster.
        addUndoOperation(undoOp);
    }
    
    /**
     * Shrink the band to just hold the elements in it
     * No action if no elements present in band.
     * @param Band band The band you wish to shrink
     * @author: Robert Lamping, 24 july 2004
     */    
    public void shrinkBand( Band band ) {

        int maxY = 0;
        // Go through the list of elements and add elements if they belong to the band
        for (Iterator i = getBandElements( band ).iterator(); i.hasNext(); ) {
            ReportElement re = (ReportElement) i.next();
            maxY = Math.max( maxY , re.position.y + re.height );
            if (re instanceof LineReportElement) {
                /* a line can not be displayed if position on a band boundary */
                /* A lines height ==0 , that is why */
                maxY = Math.max( maxY , re.position.y + re.height + 1);
        
            } else {
                maxY = Math.max( maxY , re.position.y + re.height );
                
            }
        }
        
        if (maxY > 0 ) {
            /* There was an element in the band, so changing the band height is allowed */
            // Calculate delta
            int delta = maxY -  band.getBandYLocation() - 10 - band.getHeight();
            resizeBand( band , delta, false);  // false: do not included items in the band.
            // Work done. nothing else
        }
    }
    
    
    public Point straighten( int delta_w, int delta_h  ){
        // straighten on 90 % degrees
        double clipAngle = 15;
        
        double R = Math.sqrt(  (delta_w * delta_w) + (delta_h*delta_h) );
        double cos =  delta_w /  R;
        double angle = 180 * Math.acos( cos )/ Math.PI ;
        
        int repeat = (int) Math.floor((angle + (0.5 * clipAngle)) / clipAngle) ;
        
        double newAngle = repeat * clipAngle ;
        
        // keep the sign the same!
        delta_h =  (int) (Math.abs(( R * Math.sin( (newAngle / 180 )* Math.PI))) * delta_h / Math.abs(delta_h) );
        
        delta_w = (int) ( Math.abs(( R * Math.cos( (newAngle / 180) * Math.PI)))  * delta_w / Math.abs(delta_w) ) ;
        
        // aligning on  the grid if necessary
        if (Math.abs(delta_h) == Math.abs(delta_w) ) {
            delta_h = gridMultiple( delta_h);
            delta_w = gridMultiple( delta_w);
        } else {
            if (delta_w == 0) {
                delta_h = gridMultiple( delta_h);
            }
            if (delta_h == 0) {
                delta_w = gridMultiple( delta_w);
            }
        }

        return new Point( delta_w, delta_h);
    }
}

