/*
 * 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
 */

package it.businesslogic.ireport.gui;
import it.businesslogic.ireport.gui.event.*;
import it.businesslogic.ireport.*;
import it.businesslogic.ireport.undo.*;
import it.businesslogic.ireport.util.*;
import java.awt.geom.*;
import java.awt.image.*;
import java.util.*;
import java.io.*;
import java.awt.*;
import java.awt.image.*;
/**
 *
 * @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;
    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;
    
    
    
    /*  
     *  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();
        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.setIcon(new javax.swing.ImageIcon(""));
        jMenuItemElementProperties.setText("Properties");
        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.setIcon(new javax.swing.ImageIcon(getClass().getResource("/it/businesslogic/ireport/icons/menu/paste.gif")));
        jMenuItemPaste.setText("Paste");
        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.setIcon(new javax.swing.ImageIcon(getClass().getResource("/it/businesslogic/ireport/icons/menu/delete.gif")));
        jMenuItemDelete.setText("Delete");
        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);

        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 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 = null;
            
            Enumeration enum_bands = getReport().getBands().elements();
            while (enum_bands.hasMoreElements())
   	    {
		Band b = (Band)enum_bands.nextElement();
		if (report.getBandYLocation(b)+10 <= y)
		{
			myBand = b;
		}
	    }
            
            if (myBand == null) return;
             
            String thisBand = myBand.getName();
            getMainFrame().jMenuItemBandsActionPerformed(evt);
            getMainFrame().getBandsDialog().setSelectedBand( thisBand );
            
        }
    }//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);

           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);

 	    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 )
        {
          mf.undo();
          return;
        }
        
        if (( evt.getModifiers() & evt.CTRL_MASK ) != 0 &&
            evt.getKeyCode() == java.awt.event.KeyEvent.VK_Y)
        {
          mf.redo();
          return;
        }
        */
        
        int x=1, y=1;
        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;
        }
        else if (evt.getKeyCode() == java.awt.event.KeyEvent.VK_UP)
        {
            y *= -1;
            x = 0;
            // Remove selected elements...
            Enumeration e = selectedElements.elements();
            // Up of x...
            while (e.hasMoreElements())
            {
                ReportElement element = (ReportElement)e.nextElement();
                element.trasform(new Point(x,y), TransformationType.TRANSFORMATION_MOVE);
            }
            jPanelReport.repaint();
        }
        else if (evt.getKeyCode() == java.awt.event.KeyEvent.VK_LEFT)
        {
            x *= -1;
            y = 0;
            Enumeration e = selectedElements.elements();
            // Up of x...
            while (e.hasMoreElements())
            {
                ReportElement element = (ReportElement)e.nextElement();
                element.trasform(new Point(x,y), TransformationType.TRANSFORMATION_MOVE);
            }
            jPanelReport.repaint();
        }
        else if (evt.getKeyCode() == java.awt.event.KeyEvent.VK_RIGHT)
        {
            y=0;
            // Remove selected elements...
            Enumeration e = selectedElements.elements();
            // Up of x...
            while (e.hasMoreElements())
            {
                ReportElement element = (ReportElement)e.nextElement();
                element.trasform(new Point(x,y), TransformationType.TRANSFORMATION_MOVE);
            }
            jPanelReport.repaint();
        }
         else if (evt.getKeyCode() == java.awt.event.KeyEvent.VK_DOWN)
        {
            x = 0;
            // Remove selected elements...
            Enumeration e = selectedElements.elements();
            // Up of x...
            while (e.hasMoreElements())
            {
                ReportElement element = (ReportElement)e.nextElement();
                element.trasform(new Point(x,y), TransformationType.TRANSFORMATION_MOVE);
            }
            jPanelReport.repaint();
        }
         else if (evt.getKeyCode() == java.awt.event.KeyEvent.VK_F2)
        {
            // Edit static Text
            Enumeration e = selectedElements.elements();
  
            DeleteElementsOperation undoOp = new DeleteElementsOperation(this);
            
            while (e.hasMoreElements())
            {
                ReportElement re = (ReportElement) e.nextElement();     
                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.REMOVED));  
	                }
        	}
            }
            this.addUndoOperation(undoOp);
            jPanelReport.repaint();
        }
         
    }//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 = 0;
                    int delta_h = 0;
                    delta_w = evt.getX()- drag_selection_origin.x;
                    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);
                    Enumeration e = getReport().getElements().elements();
                    while (e.hasMoreElements())
                    {
                        ReportElement re = (ReportElement)e.nextElement();
                        
                        if (re.intersects( rect ) ) addSelectedElement(re);
                    }
                    
                }
                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;
				Enumeration e = report.getElements().elements();
				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.
             ******/
				if (report.getDesignHeight()+delta > report.getHeight()) 
                                {
                                    delta = report.getHeight()- report.getDesignHeight();
                                }
                                // 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... 
                                 */
                                while (e.hasMoreElements())
				{
					ReportElement re = (ReportElement)e.nextElement();
					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)
		{
			
			firstXORDraw = true;
			
                        ReportElement 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(evt.getX()-newObjectOrigin.x);
                        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) );
			while (enum_bands.hasMoreElements())
			{
				Band b = (Band)enum_bands.nextElement();
				if (report.getBandYLocation(b)+10 <= originY)
				{
					bname = b;
				}
			}
			
                        //System.out.println("new: "+newObjectType);
			if (newObjectType == ReportElementType.RECTANGLE_ELEMENT)
			{
				re = new RectangleReportElement( originX,originY,width,height); 
			}
			else if (newObjectType == ReportElementType.ROUND_RECTANGLE_ELEMENT)
			{
				re = new RectangleReportElement( originX,originY,width,height, 5); 
			}
                        else if (newObjectType == ReportElementType.ELLIPSE_ELEMENT)
			{
				re = new EllipseReportElement( originX,originY,width,height); 
			}
                        else if (newObjectType == ReportElementType.SUBREPORT_ELEMENT)
			{
				re = new SubReportElement( originX,originY,width,height);
			}
                        else if (newObjectType == ReportElementType.IMAGE_ELEMENT)
			{
				re = new ImageReportElement( originX,originY,width,height);
			}
                        else if (newObjectType == ReportElementType.CHART_ELEMENT)
			{
				re = new ChartReportElement( originX,originY,width,height);
			}
                        else if (newObjectType == ReportElementType.STATICTEXT_ELEMENT)
			{
				re = new StaticTextReportElement( originX,originY,width,height);
			}
			else if (newObjectType == ReportElementType.LINE_ELEMENT)
			{
				String direction="BottomUp";
				if (newObjectOrigin.x<= evt.getX() && newObjectOrigin.y <= evt.getY()) direction="TopDown";
				else if (newObjectOrigin.x<= evt.getX() && newObjectOrigin.y > evt.getY()) direction="BottomUp";
				else if (newObjectOrigin.x > evt.getX() && newObjectOrigin.y > evt.getY()) direction="TopDown";	
				else if (newObjectOrigin.x > evt.getX() && newObjectOrigin.y <= evt.getY()) direction="BottomUp";	
				
				re = new LineReportElement( originX,originY,width,height,  direction);
			}
                        
			else if (newObjectType == ReportElementType.TEXTFIELD_ELEMENT)
			{
				re = new TextFieldReportElement( originX,originY,width,height);
			}
                        else if (newObjectType == ReportElementType.BARCODE_ELEMENT)
			{
				if ((width == 0) || (height == 0)) {
					width = 1;
					height = 1;
				}
				re = new BarcodeReportElement(originX, originY, width, height);
			}
                        else
			{
				re = new ReportElement( originX,originY,width,height);
			}
			
			
			re.setBand( bname );
                        
                        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);
                            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); 
                                Rectangle newBounds = new Rectangle( re.getPosition().x, re.getPosition().y, re.getWidth(), re.getHeight());
                                undoOp.addElement(re, oldBounds, newBounds);          
                                addUndoOperation(undoOp);
                                fireReportListenerReportElementsChanged(new ReportElementChangedEvent(this, re , 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

    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;
            }
        
            if (jPanelReport.getCursor() == hsplit)
            {
                
		first_draw_band=true;
        	int bl = evt.getY() + jVerticalScrollBar.getValue();
		Enumeration e = report.getBands().elements();
		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
		{
			while (e.hasMoreElements())
			{
				band = (Band)e.nextElement();
				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;
            	}
            }
            
            if (selectedElements.size() > 0 && (( evt.getModifiers() & evt.SHIFT_MASK ) == 0))
            {
		// We are trasformation 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;
            	}
            }
        
        
            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();
                                getMainFrame().getElementPropertiesDialog().updateSelection();
                            }
                            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;
			
             }
	
            }
            /*	
            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)
                    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) 
        { 
            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);
            }
            else
            {
                this.jMenuItemCopy.setEnabled(false);
                this.jMenuItemCut.setEnabled(false);
                this.jMenuItemDelete.setEnabled(false);
            }
            
            if (getMainFrame().getClipBoard().size() > 0)
            {
                this.jMenuItemPaste.setEnabled(true);
            }
            else
            {
                this.jMenuItemPaste.setEnabled(false);
            }
            
	    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(this,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(this,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)
        {
		openElementPropertiesDialog();
        }
    }//GEN-LAST:event_jPanelReportMousePressed

    private void jHorizontalScrollBarAdjustmentValueChanged(java.awt.event.AdjustmentEvent evt) {//GEN-FIRST:event_jHorizontalScrollBarAdjustmentValueChanged
        isDocDirty = true;
        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());
		}
		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());
		}	
                getMainFrame().updateFitToPage(this);
                //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 è possibile andare più su...
					// Non possiamo andare più 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)
	{
                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 (!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);
                        gg.drawLine( newObjectOrigin.x, newObjectOrigin.y, newObjectOrigin.x+delta_w,newObjectOrigin.y+delta_h); 
                        
                }
		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 jMenuItemCut;
    private javax.swing.JMenuItem jMenuItemDelete;
    private javax.swing.JMenuItem jMenuItemElementProperties;
    private javax.swing.JMenuItem jMenuItemPaste;
    private javax.swing.JMenuItem jMenuItemPasteOnBand;
    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.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);
		
	Enumeration e = report.getBands().elements();
	int y=report.getTopMargin();
	
	Band page_header=null;
	Band page_footer=null;
	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(page_header);
	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;
            // Retrive 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)
	{
		// 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();
			}
		}
                 */
                    
                ReportElementsSelectionEvent rece = new ReportElementsSelectionEvent(this, this.getSelectedElements()) ;
               
                this.fireReportListenerReportElementsSelectionChanged(rece );
                getMainFrame().getElementPropertiesDialog().updateSelection();
	}
        
        public void addSelectedElement(ReportElement el)
	{
                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();
                
                ReportElementsSelectionEvent rece = new ReportElementsSelectionEvent(this, this.getSelectedElements());               
                this.fireReportListenerReportElementsSelectionChanged(rece );
                getMainFrame().getElementPropertiesDialog().updateSelection();
                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)
        {
            // Round ++...
            if (!isSnapToGrid()) return zoomedDim;
            
            int zoomed_grid_size = getZoomedDim(this.gridSize);
            int val = Math.abs(zoomedDim);
            
            while ( val%zoomed_grid_size != 0)
            {
                val++;
            }
            
            return (zoomedDim >= 0) ? val : -val;
        }
        
        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();
                mf.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();
                 mf.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++;
            this.getReport().incrementDirty();
            mf.updateOpenedDocumentsList();
            mf.updateUndoMenu(this);
        }    
        
        public void deleteSelectedElements()
        {
            // Remove selected elements...
            Enumeration e = selectedElements.elements();
  
            DeleteElementsOperation undoOp = new DeleteElementsOperation(this);
            
            while (e.hasMoreElements())
            {
                ReportElement re = (ReportElement) e.nextElement();     
                undoOp.addElement(  re, getReport().getElements().indexOf(re));
                getReport().getElements().remove( re );
                fireReportListenerReportElementsChanged(new ReportElementChangedEvent(this, re , 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)
            {
                mf.setClipBoardContent(copiedElements);
            }
                        
            // Remove selected elements...
            this.deleteSelectedElements();
            
            mf.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)
            {
                mf.setClipBoardContent(copiedElements);
            }
            
            mf.updateCutAndPasteMenu(this);
            
        }
        
        public void paste()
        {
            // Add elements...
            Enumeration e = mf.getClipBoard().elements();
            setSelectedElement(null);
            while (e.hasMoreElements())
            {
                ReportElement re = ((ReportElement)e.nextElement()).cloneMe();
              
                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);
                addSelectedElement(re);
            }
            
            mf.updateCutAndPasteMenu(this);
            
        }
        
        public void pasteHere(Point p)
        {
            // Add elements...
            int y = getLogicalDim( p.y-10+jVerticalScrollBar.getValue())+10; 
            Enumeration e = mf.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);
            }
            
            mf.updateCutAndPasteMenu(this);
            
        }

	public void openElementPropertiesDialog(){
        	// If there is at least an element selected, open the properties window...
            	if (getSelectedElements().size() > 0)
            	{
                	if (!this.mf.getElementPropertiesDialog().isVisible())
                	{
                		this.mf.getElementPropertiesDialog().updateSelection();
                		this.mf.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;
                        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 void dropNewTextField(Point newObjectOrigin, String textfieldExpression, String classExpression)
        {
            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 );
            re.setClassExpression( classExpression );
            re.setText(textfieldExpression);
            
            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);
        }
        
        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 */
        }        
}
