/*! * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Lesser General Public License for more details. * * Copyright (c) 2002-2013 Pentaho Corporation.. All rights reserved. */ package org.pentaho.reporting.designer.core.editor.structuretree; import org.pentaho.reporting.designer.core.ReportDesignerContext; import org.pentaho.reporting.designer.core.actions.global.CopyAction; import org.pentaho.reporting.designer.core.actions.global.CutAction; import org.pentaho.reporting.designer.core.actions.global.PasteAction; import org.pentaho.reporting.designer.core.editor.ContextMenuUtility; import org.pentaho.reporting.designer.core.editor.ReportDocumentContext; import org.pentaho.reporting.designer.core.model.selection.DocumentContextSelectionModel; import org.pentaho.reporting.designer.core.util.SidePanel; import javax.swing.*; import javax.swing.event.TreeSelectionEvent; import javax.swing.event.TreeSelectionListener; import javax.swing.tree.TreePath; import java.awt.*; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; /** * By listening for update events, we could keep track of the trees and use a separate JTree for each report which * enables us to preserve the tree state on context switches. * * @author Thomas Morgner */ public class StructureTreePanel extends SidePanel { private class TreeLeadSelectionListener implements TreeSelectionListener { /** * Called whenever the value of the selection changes. * * @param e the event that characterizes the change. */ public void valueChanged( final TreeSelectionEvent e ) { final JTree tree = getTree(); final TreePath selectionPath = tree.getLeadSelectionPath(); if ( selectionPath == null ) { setLeadSelection( null ); return; } setLeadSelection( selectionPath.getLastPathComponent() ); } } private class ReportTreeContextMenuHandler extends MouseAdapter { private ReportTreeContextMenuHandler() { } private void createPopupMenu( final MouseEvent e ) { final JTree tree = getTree(); final ReportDesignerContext context = getReportDesignerContext(); if ( context.getActiveContext() == null ) { return; } final TreePath path = tree.getPathForLocation( e.getX(), e.getY() ); if ( path == null ) { return; } if ( tree.getSelectionModel().isPathSelected( path ) == false ) { tree.getSelectionModel().setSelectionPath( path ); } final Object o = path.getLastPathComponent(); final JPopupMenu pop = ContextMenuUtility.getMenu( context, o ); if ( pop == null ) { return; } pop.show( tree, e.getX(), e.getY() ); } public void mouseClicked( final MouseEvent e ) { if ( e.isPopupTrigger() ) { createPopupMenu( e ); } } public void mousePressed( final MouseEvent e ) { if ( e.isPopupTrigger() ) { createPopupMenu( e ); } } public void mouseReleased( final MouseEvent e ) { if ( e.isPopupTrigger() ) { createPopupMenu( e ); } } } private AbstractReportTree tree; private Object leadSelection; private CutAction cutAction; private CopyAction copyAction; private PasteAction pasteAction; public static final String LEAD_SELECTION_PROPERTY = "leadSelection"; public StructureTreePanel( final AbstractReportTree.RenderType renderType ) { cutAction = new CutAction(); copyAction = new CopyAction(); pasteAction = new PasteAction(); if ( renderType == AbstractReportTree.RenderType.REPORT ) { tree = new LayoutReportTree(); } else { tree = new DataReportTree(); } tree.getSelectionModel().addTreeSelectionListener( new TreeLeadSelectionListener() ); tree.addMouseListener( new ReportTreeContextMenuHandler() ); final ActionMap map = tree.getActionMap(); map.put( TransferHandler.getCutAction().getValue( Action.NAME ), cutAction ); map.put( TransferHandler.getCopyAction().getValue( Action.NAME ), copyAction ); map.put( TransferHandler.getPasteAction().getValue( Action.NAME ), pasteAction ); setLayout( new BorderLayout() ); add( new JScrollPane( tree ), BorderLayout.CENTER ); } protected void updateDesignerContext( final ReportDesignerContext oldContext, final ReportDesignerContext newContext ) { super.updateDesignerContext( oldContext, newContext ); cutAction.setReportDesignerContext( newContext ); copyAction.setReportDesignerContext( newContext ); pasteAction.setReportDesignerContext( newContext ); tree.setReportDesignerContext( newContext ); } protected void updateSelection( final DocumentContextSelectionModel model ) { // do nothing. We *do* define the selection, we dont really listen to it.. } protected void updateActiveContext( final ReportDocumentContext oldContext, final ReportDocumentContext newContext ) { super.updateActiveContext( oldContext, newContext ); tree.setRenderContext( newContext ); } /** * Sets whether or not this component is enabled. A component that is enabled may respond to user input, while a * component that is not enabled cannot respond to user input. Some components may alter their visual representation * when they are disabled in order to provide feedback to the user that they cannot take input. <p>Note: Disabling a * component does not disable it's children. * <p/> * <p>Note: Disabling a lightweight component does not prevent it from receiving MouseEvents. * * @param enabled true if this component should be enabled, false otherwise */ public void setEnabled( final boolean enabled ) { super.setEnabled( enabled ); tree.setEnabled( enabled ); } public Object getLeadSelection() { return leadSelection; } protected void setLeadSelection( final Object leadSelection ) { final Object oldvalue = this.leadSelection; this.leadSelection = leadSelection; firePropertyChange( LEAD_SELECTION_PROPERTY, oldvalue, leadSelection ); } protected JTree getTree() { return tree; } }