/*!
* 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.ui.datasources.table;
import org.pentaho.reporting.engine.classic.core.ClassicEngineBoot;
import org.pentaho.reporting.engine.classic.core.MasterReport;
import org.pentaho.reporting.engine.classic.core.TableDataFactory;
import org.pentaho.reporting.engine.classic.core.designtime.DefaultDesignTimeContext;
import org.pentaho.reporting.engine.classic.core.designtime.DesignTimeContext;
import org.pentaho.reporting.engine.classic.core.designtime.datafactory.DataSetQuery;
import org.pentaho.reporting.engine.classic.core.designtime.datafactory.NamedQueryModel;
import org.pentaho.reporting.engine.classic.core.designtime.datafactory.QueryAddAction;
import org.pentaho.reporting.engine.classic.core.designtime.datafactory.QueryNameListCellRenderer;
import org.pentaho.reporting.engine.classic.core.designtime.datafactory.QueryNameTextFieldDocumentListener;
import org.pentaho.reporting.engine.classic.core.designtime.datafactory.QueryRemoveAction;
import org.pentaho.reporting.engine.classic.core.designtime.datafactory.QuerySelectedHandler;
import org.pentaho.reporting.engine.classic.core.util.TypedTableModel;
import org.pentaho.reporting.libraries.base.util.FilesystemFilter;
import org.pentaho.reporting.libraries.designtime.swing.BorderlessButton;
import org.pentaho.reporting.libraries.designtime.swing.CommonDialog;
import org.pentaho.reporting.libraries.designtime.swing.background.BackgroundCancellableProcessHelper;
import org.pentaho.reporting.libraries.designtime.swing.filechooser.CommonFileChooser;
import org.pentaho.reporting.libraries.designtime.swing.filechooser.FileChooserService;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.filechooser.FileFilter;
import javax.swing.table.TableModel;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.io.File;
import java.net.URL;
/**
* @author Ezequiel Cuellar
*/
public class TableDataSourceEditor extends CommonDialog {
private class ImportAction extends AbstractAction {
/**
* Defines an <code>Action</code> object with a default description string and default icon.
*/
private ImportAction() {
//putValue(Action.NAME, "Import");
setEnabled( false );
final URL resource = TableDataSourceEditor.class.getResource
( "/org/pentaho/reporting/ui/datasources/table/resources/Spreadsheet.png" ); // NON-NLS
if ( resource != null ) {
putValue( Action.SMALL_ICON, new ImageIcon( resource ) );
}
putValue( Action.NAME, Messages.getString( "TableDataSourceEditor.ImportSpreadsheet.Name" ) );
putValue( Action.SHORT_DESCRIPTION, Messages.getString( "TableDataSourceEditor.ImportSpreadsheet.Description" ) );
}
/**
* Invoked when an action occurs.
*/
public void actionPerformed( final ActionEvent e ) {
final FileFilter[] fileFilters =
{ new FilesystemFilter( new String[] { ".xls", ".xlsx" }, // NON-NLS
Messages.getString( "TableDataSourceEditor.ExcelFileDescription" ), true ) };
final CommonFileChooser fileChooser = FileChooserService.getInstance().getFileChooser( "xls" );
fileChooser.setFilters( fileFilters );
if ( fileChooser.showDialog( TableDataSourceEditor.this, JFileChooser.OPEN_DIALOG ) == false ) {
return;
}
final File file = fileChooser.getSelectedFile();
final ImportFromFileTask importFromFileTask =
new ImportFromFileTask( file, useFirstRowAsHeader.isSelected(), TableDataSourceEditor.this );
final Thread workerThread = new Thread( importFromFileTask );
workerThread.setName( "PRD-import-table-data-task" ); // NON-NLS
BackgroundCancellableProcessHelper.executeProcessWithCancelDialog( workerThread, importFromFileTask,
TableDataSourceEditor.this, Messages.getString( "TableDataSourceEditor.ImportSpeadsheet.TaskName" ) );
}
}
private class QueryNameHandler extends QueryNameTextFieldDocumentListener<TableModel> {
private QueryNameHandler( final NamedQueryModel<TableModel> dialogModel ) {
super( dialogModel );
}
protected void setEditorQuery( final DataSetQuery<TableModel> dataSetQuery ) {
if ( dataSetQuery == null ) {
queryNameTextField.setText( null );
table.setTableEditorModel( null );
return;
}
queryNameTextField.setText( dataSetQuery.getQueryName() );
table.setTableEditorModel( dataSetQuery.getQuery() );
}
}
private class TableUpdateHandler implements ChangeListener {
private TableUpdateHandler() {
}
public void stateChanged( final ChangeEvent e ) {
final DataSetQuery<TableModel> selectedQuery = queries.getQueries().getSelectedQuery();
if ( selectedQuery != null ) {
selectedQuery.setQuery( table.getTableEditorModel() );
}
}
}
private class TableQueryModel extends NamedQueryModel<TableModel> {
private TableQueryModel() {
}
protected TableModel createDefaultObject() {
final TypedTableModel defaultTableModel = new TypedTableModel();
defaultTableModel.addColumn( Messages.getString( "TableDataSourceEditor.IDColumn" ), String.class );
defaultTableModel.addColumn( Messages.getString( "TableDataSourceEditor.ValueColumn" ), String.class );
defaultTableModel.addRow();
return defaultTableModel;
}
public void setSelectedDataSetQuery( final DataSetQuery<TableModel> tableModelDataSetQuery ) {
table.stopEditing();
super.setSelectedDataSetQuery( tableModelDataSetQuery );
}
protected void setQuerySelected( final boolean querySelected ) {
super.setQuerySelected( querySelected );
updateComponents();
}
}
private JTextField queryNameTextField;
private TableEditorPanel table;
private JList queryNameList;
private TableQueryModel queries;
private JCheckBox useFirstRowAsHeader;
private ImportAction importAction;
private DesignTimeContext designTimeContext;
public TableDataSourceEditor( final Dialog aOwner ) {
super( aOwner );
init();
}
public TableDataSourceEditor( final Frame aOwner ) {
super( aOwner );
init();
}
/**
* Creates a non-modal dialog without a title and without a specified <code>Frame</code> owner. A shared, hidden
* frame will be set as the owner of the dialog.
* <p/>
* This constructor sets the component's locale property to the value returned by
* <code>JComponent.getDefaultLocale</code>.
*
* @throws java.awt.HeadlessException if GraphicsEnvironment.isHeadless() returns true.
* @see java.awt.GraphicsEnvironment#isHeadless
* @see javax.swing.JComponent#getDefaultLocale
*/
public TableDataSourceEditor() {
init();
}
protected void init() {
queries = new TableQueryModel();
final QueryNameHandler queryNameHandler = new QueryNameHandler( queries );
queryNameList = new JList( queries.getQueries() );
queryNameList.setSelectionMode( ListSelectionModel.SINGLE_SELECTION );
queryNameList.setVisibleRowCount( 5 );
queryNameList.setCellRenderer( new QueryNameListCellRenderer() );
queryNameTextField = new JTextField( null, 0 );
queryNameTextField.setColumns( 35 );
queryNameTextField.getDocument().addDocumentListener( queryNameHandler );
queryNameTextField.setEnabled( false );
QuerySelectedHandler querySelectedHandler = new QuerySelectedHandler( queries, queryNameList );
table = new TableEditorPanel();
table.addChangeListener( new TableUpdateHandler() );
importAction = new ImportAction();
useFirstRowAsHeader = new JCheckBox( Messages.getString( "TableDataSourceEditor.UseFirstRowAsHeader" ) );
useFirstRowAsHeader.setEnabled( false );
useFirstRowAsHeader.setSelected( true );
setTitle( Messages.getString( "TableDataSourceEditor.Title" ) );
super.init();
}
protected String getDialogId() {
return "TableDataSourceEditor";
}
protected Component createContentPane() {
final JPanel namePanel = new JPanel( new BorderLayout() );
namePanel.setBorder( BorderFactory.createEmptyBorder( 5, 5, 0, 0 ) );
namePanel.add( BorderLayout.NORTH, new JLabel( Messages.getString( "TableDataSourceEditor.QueryName" ) ) );
namePanel.add( BorderLayout.CENTER, queryNameTextField );
final JPanel leftButtonsPanel = new JPanel( new FlowLayout( FlowLayout.LEFT, 5, 5 ) );
leftButtonsPanel.add( useFirstRowAsHeader );
leftButtonsPanel.add( new JButton( importAction ) );
final JPanel buttonsPanel = new JPanel( new BorderLayout() );
buttonsPanel.setBorder( BorderFactory.createMatteBorder( 1, 0, 0, 0, Color.LIGHT_GRAY ) );
buttonsPanel.add( leftButtonsPanel, BorderLayout.WEST );
final JPanel queryConfigPane = new JPanel( new BorderLayout() );
queryConfigPane.add( createQuerySelectionPanel(), BorderLayout.NORTH );
queryConfigPane.add( namePanel, BorderLayout.CENTER );
final JPanel contentPane = new JPanel();
contentPane.setLayout( new BorderLayout() );
contentPane.add( queryConfigPane, BorderLayout.NORTH );
contentPane.add( table, BorderLayout.CENTER );
contentPane.add( buttonsPanel, BorderLayout.SOUTH );
return contentPane;
}
private JPanel createQuerySelectionPanel() {
final QueryRemoveAction removeQueryAction = new QueryRemoveAction( queries );
final JPanel queryListButtonsPanel = new JPanel( new FlowLayout( FlowLayout.RIGHT ) );
queryListButtonsPanel.add( new BorderlessButton( new QueryAddAction( queries ) ) );
queryListButtonsPanel.add( new BorderlessButton( removeQueryAction ) );
final JPanel queryListDetailsPanel = new JPanel( new BorderLayout() );
queryListDetailsPanel
.add( new JLabel( Messages.getString( "TableDataSourceEditor.QueryDetailsLabel" ) ), BorderLayout.WEST );
queryListDetailsPanel.add( queryListButtonsPanel, BorderLayout.EAST );
// Create the query list panel
final JPanel queryListPanel = new JPanel( new BorderLayout() );
queryListPanel.setBorder( BorderFactory.createEmptyBorder( 0, 5, 5, 5 ) );
queryListPanel.add( BorderLayout.NORTH, queryListDetailsPanel );
queryListPanel.add( BorderLayout.CENTER, new JScrollPane( queryNameList ) );
return queryListPanel;
}
public TableDataFactory performConfiguration( final DesignTimeContext designTimeContext,
final TableDataFactory dataFactory,
final String selectedQuery ) {
if ( designTimeContext == null ) {
throw new NullPointerException();
}
this.designTimeContext = designTimeContext;
this.table.applyLocaleSettings( designTimeContext.getLocaleSettings() );
if ( dataFactory != null ) {
final String[] queryNames = dataFactory.getQueryNames();
for ( int i = 0; i < queryNames.length; i++ ) {
final String queryName = queryNames[ i ];
final TableModel query = dataFactory.getTable( queryName );
queries.addQuery( queryName, query );
}
}
queries.setSelectedQuery( selectedQuery );
if ( performEdit() == false ) {
return null;
}
table.stopEditing();
final TableDataFactory retval = new TableDataFactory();
for ( final DataSetQuery<TableModel> query : this.queries.getQueries() ) {
retval.addTable( query.getQueryName(), query.getQuery() );
}
return retval;
}
protected void updateComponents() {
final boolean querySelected = queryNameList.getSelectedIndex() != -1;
queryNameTextField.setEnabled( querySelected );
table.setEnabled( querySelected );
importAction.setEnabled( querySelected );
useFirstRowAsHeader.setEnabled( querySelected );
}
public void importComplete( final TypedTableModel tableModel ) {
table.setTableEditorModel( tableModel );
}
public void importFailed( final Exception e ) {
designTimeContext.error( e );
}
public static void main( String[] args ) {
ClassicEngineBoot.getInstance().start();
TableDataSourceEditor ed = new TableDataSourceEditor();
ed.performConfiguration( new DefaultDesignTimeContext( new MasterReport() ), null, null );
}
}