/*!
* 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-2016 Pentaho Corporation.. All rights reserved.
*/
package org.pentaho.reporting.designer.core.editor.drilldown;
import org.pentaho.reporting.designer.core.Messages;
import org.pentaho.reporting.designer.core.ReportDesignerContext;
import org.pentaho.reporting.designer.core.editor.drilldown.model.DrillDownModel;
import org.pentaho.reporting.designer.core.editor.drilldown.model.DrillDownParameter;
import org.pentaho.reporting.designer.core.util.IconLoader;
import org.pentaho.reporting.designer.core.util.table.ElementMetaDataTable;
import org.pentaho.reporting.designer.core.util.table.FormulaFragmentCellRenderer;
import org.pentaho.reporting.designer.core.util.table.GroupedMetaTableModel;
import org.pentaho.reporting.designer.core.util.table.GroupedName;
import org.pentaho.reporting.designer.core.util.table.GroupedNameCellEditor;
import org.pentaho.reporting.designer.core.util.table.GroupedTableModel;
import org.pentaho.reporting.libraries.designtime.swing.BorderlessButton;
import org.pentaho.reporting.libraries.designtime.swing.LibSwingUtil;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import java.awt.BorderLayout;
import java.awt.Dialog;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.ArrayList;
import java.util.Arrays;
public class DrillDownParameterTable extends JComponent {
private class AddParameterAction extends AbstractAction {
/**
* Defines an <code>Action</code> object with a default description string and default icon.
*/
private AddParameterAction() {
putValue( Action.SMALL_ICON, IconLoader.getInstance().getAddIcon() );
putValue( Action.SHORT_DESCRIPTION, Messages.getString( "DrillDownParameterTable.AddParameter" ) );
}
/**
* Invoked when an action occurs.
*/
public void actionPerformed( final ActionEvent e ) {
final DrillDownParameter[] data = parameterTableModel.getData();
final DrillDownParameter[] data2 = new DrillDownParameter[ data.length + 1 ];
System.arraycopy( data, 0, data2, 0, data.length );
data2[ data.length ] =
new DrillDownParameter( Messages.getString( "DrillDownParameterTable.Parameter.DefaultName" ) );
data2[ data.length ].setPosition( data.length );
parameterTableModel.setData( data2 );
}
}
private class RemoveParameterAction extends AbstractAction implements ListSelectionListener {
private GroupedTableModel model;
private JTable table;
/**
* Defines an <code>Action</code> object with a default description string and default icon.
*
* @param table the table.
*/
private RemoveParameterAction( final JTable table ) {
this.model = (GroupedTableModel) table.getModel();
this.table = table;
putValue( Action.SMALL_ICON, IconLoader.getInstance().getRemoveIcon() );
putValue( Action.SHORT_DESCRIPTION, Messages.getString( "DrillDownParameterTable.RemoveParameter" ) );
setEnabled( false );
table.getSelectionModel().addListSelectionListener( this );
}
/**
* Called whenever the value of the selection changes.
*
* @param e the event that characterizes the change.
*/
public void valueChanged( final ListSelectionEvent e ) {
final int[] selectedRows = table.getSelectedRows();
for ( int i = 0; i < selectedRows.length; i++ ) {
final int row = selectedRows[ i ];
final DrillDownParameter.Type type = parameterTableModel.getParameterType( model.mapToModel( row ) );
if ( DrillDownParameter.Type.MANUAL == type ) {
setEnabled( true );
return;
}
}
setEnabled( false );
}
/**
* Invoked when an action occurs.
*/
public void actionPerformed( final ActionEvent e ) {
if ( isEnabled() == false ) {
return;
}
final DrillDownParameter[] data = parameterTableModel.getGroupedData();
final ListSelectionModel listSelectionModel = table.getSelectionModel();
final ArrayList<DrillDownParameter> result = new ArrayList<DrillDownParameter>( data.length );
for ( int i = 0; i < data.length; i++ ) {
final DrillDownParameter parameter = data[ i ];
if ( parameter == null ) {
continue;
}
if ( listSelectionModel.isSelectedIndex( model.mapFromModel( i ) ) == false
|| parameter.getType() != DrillDownParameter.Type.MANUAL ) {
result.add( data[ i ] );
}
}
parameterTableModel.setData( result.toArray( new DrillDownParameter[ result.size() ] ) );
}
}
private class RefreshParameterAction extends AbstractAction {
/**
* Defines an <code>Action</code> object with a default description string and default icon.
*/
private RefreshParameterAction() {
putValue( Action.SMALL_ICON, IconLoader.getInstance().getRefreshIcon() );
putValue( Action.SHORT_DESCRIPTION, Messages.getString( "DrillDownParameterTable.RefreshParameter" ) );
setEnabled( false );
}
/**
* Invoked when an action occurs.
*/
public void actionPerformed( final ActionEvent e ) {
// rescue all manual parameter ...
fireRefreshEvent();
}
}
private class DrillDownParameterChangeHandler implements TableModelListener {
private DrillDownParameter[] oldData;
private DrillDownParameterChangeHandler() {
oldData = parameterTableModel.getData();
}
/**
* This fine grain notification tells listeners the exact range of cells, rows, or columns that changed.
*/
public void tableChanged( final TableModelEvent e ) {
final DrillDownParameter[] newParams = getDrillDownParameter();
firePropertyChange( DRILL_DOWN_PARAMETER_PROPERTY, oldData, newParams );
this.oldData = newParams;
}
}
private class HideParamUiSelectionListener implements ItemListener {
private boolean hideParameterUiValue;
private HideParamUiSelectionListener() {
}
/**
* Invoked when an item has been selected or deselected by the user. The code written for this method performs the
* operations that need to occur when an item is selected (or deselected).
*/
public void itemStateChanged( final ItemEvent e ) {
final boolean oldValue = this.hideParameterUiValue;
this.hideParameterUiValue = hideParameterUiCheckbox.isSelected();
firePropertyChange( HIDE_PARAMETER_UI_PARAMETER_PROPERTY, oldValue, hideParameterUiValue );
}
}
private class ShowAdvancedEditorAction extends AbstractAction {
/**
* Defines an <code>Action</code> object with a default description string and default icon.
*/
private ShowAdvancedEditorAction() {
putValue( Action.NAME, Messages.getString( "DrillDownParameterTable.Advanced" ) );
}
/**
* Invoked when an action occurs.
*/
public void actionPerformed( final ActionEvent e ) {
final Window window = LibSwingUtil.getWindowAncestor( DrillDownParameterTable.this );
final SystemParameterDialog dialog;
if ( window instanceof Dialog ) {
dialog = new SystemParameterDialog( (Dialog) window, parameterTableModel, reportDesignerContext );
} else if ( window instanceof Frame ) {
dialog = new SystemParameterDialog( (Frame) window, parameterTableModel, reportDesignerContext );
} else {
dialog = new SystemParameterDialog( parameterTableModel, reportDesignerContext );
}
dialog.showAdvancedEditor();
dialog.dispose();
}
}
public static final String DRILL_DOWN_PARAMETER_PROPERTY = "drillDownParameter";
public static final String HIDE_PARAMETER_UI_PARAMETER_PROPERTY = "hideParameterUi";
private DrillDownParameterTableModel parameterTableModel;
private boolean allowCustomParameter;
private boolean showRefreshButton;
private JLabel title;
private ArrayList<DrillDownParameterRefreshListener> listeners;
private DrillDownParameterTable.RefreshParameterAction refreshParameterAction;
private boolean singleTabMode;
private JCheckBox hideParameterUiCheckbox;
private ElementMetaDataTable allInOneTable;
private ElementMetaDataTable systemParameterTable;
private ElementMetaDataTable manualParameterTable;
private ElementMetaDataTable predefinedParameterTable;
private RemoveParameterAction allInOneRemoveAction;
private RemoveParameterAction manualParameterRemoveAction;
private ReportDesignerContext reportDesignerContext;
private AddParameterAction addParameterAction;
private DrillDownParameterTable.ShowAdvancedEditorAction advancedEditorAction;
public DrillDownParameterTable() {
setLayout( new BorderLayout() );
listeners = new ArrayList<DrillDownParameterRefreshListener>();
refreshParameterAction = new RefreshParameterAction();
addParameterAction = new AddParameterAction();
advancedEditorAction = new ShowAdvancedEditorAction();
parameterTableModel = new DrillDownParameterTableModel();
parameterTableModel.addTableModelListener( new DrillDownParameterChangeHandler() );
allInOneTable = new ElementMetaDataTable();
allInOneTable.setFormulaFragment( true );
allInOneTable.setDefaultEditor( GroupedName.class, new GroupedNameCellEditor() );
allInOneTable.setDefaultRenderer( String.class, new FormulaFragmentCellRenderer() );
allInOneTable.setModel( new GroupedMetaTableModel( parameterTableModel ) );
allInOneRemoveAction = new RemoveParameterAction( allInOneTable );
systemParameterTable = new ElementMetaDataTable();
systemParameterTable.setFormulaFragment( true );
systemParameterTable.setDefaultEditor( GroupedName.class, new GroupedNameCellEditor() );
systemParameterTable.setDefaultRenderer( String.class, new FormulaFragmentCellRenderer() );
systemParameterTable.setModel(
new FilteringParameterTableModel( DrillDownParameter.Type.SYSTEM, parameterTableModel, true ) );
manualParameterTable = new ElementMetaDataTable();
manualParameterTable.setFormulaFragment( true );
manualParameterTable.setDefaultEditor( GroupedName.class, new GroupedNameCellEditor() );
manualParameterTable.setDefaultRenderer( String.class, new FormulaFragmentCellRenderer() );
manualParameterTable.setModel(
new FilteringParameterTableModel( DrillDownParameter.Type.MANUAL, parameterTableModel ) );
manualParameterRemoveAction = new RemoveParameterAction( manualParameterTable );
predefinedParameterTable = new ElementMetaDataTable();
predefinedParameterTable.setFormulaFragment( true );
predefinedParameterTable.setDefaultEditor( GroupedName.class, new GroupedNameCellEditor() );
predefinedParameterTable.setDefaultRenderer( String.class, new FormulaFragmentCellRenderer() );
predefinedParameterTable.setModel(
new FilteringParameterTableModel( DrillDownParameter.Type.PREDEFINED, parameterTableModel ) );
hideParameterUiCheckbox = new JCheckBox( Messages.getString( "DrillDownParameterTable.HideParameterUI" ) );
hideParameterUiCheckbox.addItemListener( new HideParamUiSelectionListener() );
title = new JLabel( Messages.getString( "DrillDownParameterTable.Title" ) );
rebuildUi();
}
private void rebuildUi() {
removeAll();
if ( isSingleTabMode() ) {
final JPanel buttonPanel = new JPanel();
buttonPanel.setLayout( new FlowLayout( FlowLayout.RIGHT ) );
if ( isShowRefreshButton() ) {
buttonPanel.add( new BorderlessButton( refreshParameterAction ) );
if ( isAllowCustomParameter() ) {
buttonPanel.add( Box.createHorizontalStrut( 10 ) );
}
}
if ( isAllowCustomParameter() ) {
buttonPanel.add( new BorderlessButton( addParameterAction ) );
buttonPanel.add( new BorderlessButton( allInOneRemoveAction ) );
}
final JPanel tablePanel = new JPanel( new BorderLayout() );
tablePanel.add( new JScrollPane( allInOneTable ), BorderLayout.CENTER );
if ( isShowHideParameterUiCheckbox() ) {
tablePanel.add( hideParameterUiCheckbox, BorderLayout.NORTH );
}
final JPanel headerPanel = new JPanel();
headerPanel.setLayout( new BorderLayout() );
headerPanel.add( title, BorderLayout.WEST );
headerPanel.add( buttonPanel, BorderLayout.EAST );
final JPanel centralPanel = new JPanel();
centralPanel.setLayout( new BorderLayout() );
//centralPanel.setBorder( new EmptyBorder( 5, 5, 5, 5 ) ); // Better layout --Kaa
centralPanel.add( headerPanel, BorderLayout.NORTH );
centralPanel.add( tablePanel, BorderLayout.CENTER );
add( centralPanel, BorderLayout.CENTER );
} else {
final JPanel systemTablePanel = new JPanel( new BorderLayout() );
systemTablePanel.add( new JScrollPane( systemParameterTable ), BorderLayout.CENTER );
systemTablePanel.add( createButtonPanel( null, isShowHideParameterUiCheckbox() ), BorderLayout.NORTH );
systemTablePanel.add( createAdvancedParameterPanel(), BorderLayout.SOUTH );
final JPanel predefinedTablePanel = new JPanel( new BorderLayout() );
predefinedTablePanel.add( new JScrollPane( predefinedParameterTable ), BorderLayout.CENTER );
predefinedTablePanel.add( createButtonPanel( null, false ), BorderLayout.NORTH );
final JPanel manualTablePanel = new JPanel( new BorderLayout() );
manualTablePanel.add( new JScrollPane( manualParameterTable ), BorderLayout.CENTER );
manualTablePanel.add( createButtonPanel( manualParameterRemoveAction, false ), BorderLayout.NORTH );
final JTabbedPane tabbedPane = new JTabbedPane();
tabbedPane.addTab( Messages.getString( "DrillDownParameterTable.Tab.Report" ), predefinedTablePanel );
tabbedPane.addTab( Messages.getString( "DrillDownParameterTable.Tab.System" ), systemTablePanel );
tabbedPane.addTab( Messages.getString( "DrillDownParameterTable.Tab.Manual" ), manualTablePanel );
add( tabbedPane, BorderLayout.CENTER );
}
}
private JPanel createAdvancedParameterPanel() {
final JPanel buttonPanel = new JPanel();
buttonPanel.setLayout( new FlowLayout( FlowLayout.RIGHT ) );
buttonPanel.add( new JButton( advancedEditorAction ) );
return buttonPanel;
}
private JPanel createButtonPanel( final Action removeAction,
final boolean addHideParamUiCheckbox ) {
final JPanel buttonPanel = new JPanel();
buttonPanel.setLayout( new FlowLayout( FlowLayout.RIGHT ) );
if ( isShowRefreshButton() ) {
buttonPanel.add( new BorderlessButton( refreshParameterAction ) );
if ( removeAction != null ) {
buttonPanel.add( Box.createHorizontalStrut( 10 ) );
}
}
if ( removeAction != null ) {
buttonPanel.add( new BorderlessButton( addParameterAction ) );
buttonPanel.add( new BorderlessButton( removeAction ) );
}
if ( addHideParamUiCheckbox == false ) {
return buttonPanel;
}
final JPanel panel = new JPanel();
panel.setLayout( new BorderLayout() );
panel.add( buttonPanel, BorderLayout.CENTER );
panel.add( hideParameterUiCheckbox, BorderLayout.NORTH );
return panel;
}
public void addDrillDownParameterRefreshListener( final DrillDownParameterRefreshListener listener ) {
if ( listener == null ) {
throw new NullPointerException();
}
listeners.add( listener );
refreshParameterAction.setEnabled( isEnabled() && listeners.isEmpty() == false );
}
public void removeDrillDownParameterRefreshListener( final DrillDownParameterRefreshListener listener ) {
if ( listener == null ) {
throw new NullPointerException();
}
listeners.remove( listener );
refreshParameterAction.setEnabled( isEnabled() && listeners.isEmpty() == false );
}
public String getTitle() {
return title.getText();
}
public void setTitle( final String title ) {
this.title.setText( title );
}
public void setReportDesignerContext( final ReportDesignerContext context ) {
reportDesignerContext = context;
allInOneTable.setReportDesignerContext( context );
systemParameterTable.setReportDesignerContext( context );
manualParameterTable.setReportDesignerContext( context );
predefinedParameterTable.setReportDesignerContext( context );
}
public ReportDesignerContext getReportDesignerContext() {
return allInOneTable.getReportDesignerContext();
}
public void setDrillDownParameter( final DrillDownParameter[] parameter ) {
final DrillDownParameter[] oldParameter = parameterTableModel.getData();
parameterTableModel.setData( parameter );
if ( Arrays.equals( oldParameter, parameter ) == false ) {
firePropertyChange( DrillDownModel.DRILL_DOWN_PARAMETER_PROPERTY, oldParameter, parameter );
}
}
public String[] getExtraFields() {
return parameterTableModel.getExtraFields();
}
public void setExtraFields( final String[] extraFields ) {
parameterTableModel.setExtraFields( extraFields );
}
public DrillDownParameter[] getDrillDownParameter() {
return parameterTableModel.getData();
}
public String[] getFilteredParameterNames() {
return parameterTableModel.getFilteredParameterNames();
}
public void setFilteredParameterNames( final String[] names ) {
parameterTableModel.setFilteredParameterNames( names );
}
public boolean isAllowCustomParameter() {
return allowCustomParameter;
}
public void setAllowCustomParameter( final boolean allowCustomParameter ) {
this.allowCustomParameter = allowCustomParameter;
rebuildUi();
}
public boolean isShowRefreshButton() {
return showRefreshButton;
}
public void setShowRefreshButton( final boolean showRefreshButton ) {
this.showRefreshButton = showRefreshButton;
rebuildUi();
}
public void refreshParameterData() {
fireRefreshEvent();
}
protected void fireRefreshEvent() {
if ( listeners.isEmpty() ) {
return;
}
final DrillDownParameterRefreshEvent event = new DrillDownParameterRefreshEvent( this, getDrillDownParameter() );
for ( int i = 0; i < listeners.size(); i++ ) {
final DrillDownParameterRefreshListener listener = listeners.get( i );
listener.requestParameterRefresh( event );
}
}
public boolean isSingleTabMode() {
return singleTabMode;
}
public void setSingleTabMode( final boolean singleTabMode ) {
this.singleTabMode = singleTabMode;
rebuildUi();
}
public boolean isHideParameterUi() {
return hideParameterUiCheckbox.isSelected();
}
public void setHideParameterUi( final boolean hideParameterUi ) {
this.hideParameterUiCheckbox.setSelected( hideParameterUi );
}
public boolean isShowHideParameterUiCheckbox() {
return hideParameterUiCheckbox.isVisible();
}
public void setShowHideParameterUiCheckbox( final boolean showHideParameterUiCheckbox ) {
this.hideParameterUiCheckbox.setVisible( showHideParameterUiCheckbox );
rebuildUi();
}
public void setEnabled( final boolean enabled ) {
super.setEnabled( enabled );
hideParameterUiCheckbox.setEnabled( enabled );
allInOneTable.setEnabled( enabled );
systemParameterTable.setEnabled( enabled );
manualParameterTable.setEnabled( enabled );
predefinedParameterTable.setEnabled( enabled );
refreshParameterAction.setEnabled( enabled && listeners.isEmpty() == false );
allInOneRemoveAction.setEnabled( enabled );
manualParameterRemoveAction.setEnabled( enabled );
addParameterAction.setEnabled( enabled );
advancedEditorAction.setEnabled( enabled );
}
}