Package org.pentaho.reporting.designer.core.util.table

Source Code of org.pentaho.reporting.designer.core.util.table.ElementMetaDataTable$LocaleSettingsListener

/*!
* 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.util.table;

import java.awt.Paint;
import java.awt.SystemColor;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyEditor;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.sql.Time;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
import javax.swing.JTable;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.pentaho.reporting.designer.core.DesignerContextComponent;
import org.pentaho.reporting.designer.core.ReportDesignerContext;
import org.pentaho.reporting.designer.core.editor.ReportDocumentContext;
import org.pentaho.reporting.designer.core.editor.ReportRenderContext;
import org.pentaho.reporting.designer.core.settings.SettingsListener;
import org.pentaho.reporting.designer.core.settings.WorkspaceSettings;
import org.pentaho.reporting.designer.core.util.table.expressions.ExpressionCellHandler;
import org.pentaho.reporting.designer.core.util.table.expressions.ReportPreProcessorCellEditor;
import org.pentaho.reporting.designer.core.util.table.expressions.ReportPreProcessorCellRenderer;
import org.pentaho.reporting.designer.core.util.table.expressions.StructureFunctionCellEditor;
import org.pentaho.reporting.engine.classic.core.ReportPreProcessor;
import org.pentaho.reporting.engine.classic.core.function.Expression;
import org.pentaho.reporting.engine.classic.core.function.StructureFunction;
import org.pentaho.reporting.libraries.base.util.StringUtils;
import org.pentaho.reporting.libraries.designtime.swing.FormattingTableCellRenderer;
import org.pentaho.reporting.libraries.designtime.swing.GenericCellEditor;
import org.pentaho.reporting.libraries.designtime.swing.GenericCellRenderer;
import org.pentaho.reporting.libraries.designtime.swing.PaintCellRenderer;
import org.pentaho.reporting.libraries.designtime.swing.date.DateCellEditor;
import org.pentaho.reporting.libraries.designtime.swing.date.TimeCellEditor;
import org.pentaho.reporting.libraries.designtime.swing.propertyeditors.PropertyEditorCellEditor;
import org.pentaho.reporting.libraries.designtime.swing.propertyeditors.PropertyEditorCellRenderer;
import org.pentaho.reporting.libraries.designtime.swing.settings.LocaleSettings;

/**
* A table implementation that selects the cell-renderer and editor based on some extended rules (and not just based on
* the current column).
*
* @author Thomas Morgner
*/
public class ElementMetaDataTable extends JTable implements DesignerContextComponent
{
  private class LocaleSettingsListener implements SettingsListener
  {
    private LocaleSettingsListener()
    {
    }

    public void settingsChanged()
    {
      applyLocaleSettings(WorkspaceSettings.getInstance());
    }
  }

  private class ActiveContextChangeHandler implements PropertyChangeListener
  {
    private ActiveContextChangeHandler()
    {
    }

    /**
     * This method gets called when a bound property is changed.
     *
     * @param evt A PropertyChangeEvent object describing the event source and the property that has changed.
     */

    public void propertyChange(final PropertyChangeEvent evt)
    {
      final ReportRenderContext oldContext = (ReportRenderContext) evt.getOldValue();
      final ReportRenderContext activeContext = (ReportRenderContext) evt.getNewValue();
      updateActiveContext(oldContext, activeContext);
    }
  }

  private static final Log logger = LogFactory.getLog(ElementMetaDataTable.class);

  private GroupingHeaderCellRenderer groupingCellRenderer;
  private PropertyEditorCellRenderer propertyEditorCellRenderer;
  private DesignerPropertyCellEditorWithEllipsis propertyEditorCellEditor;
  private PropertyEditorCellEditor taggedPropertyEditorCellEditor;
  private ArrayCellRenderer arrayCellRenderer;
  private ArrayCellEditor arrayCellEditor;
  private ExpressionCellHandler expressionsCellEditor;
  private ExpressionCellHandler expressionsCellRenderer;
  private StringValueCellEditor stringValueCellEditor;

  private StructureFunctionCellEditor structureFunctionCellEditor;
  private ReportPreProcessorCellEditor reportPreProcessorCellEditor;
  private ReportPreProcessorCellRenderer reportPreProcessorCellRenderer;
  private ActiveContextChangeHandler changeHandler;

  public ElementMetaDataTable()
  {
    putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);

    // This is a hack as Mac chooses white on white for grids.
    this.setShowHorizontalLines(true);
    this.setShowVerticalLines(true);
    this.setGridColor(SystemColor.controlShadow);

    changeHandler = new ActiveContextChangeHandler();
    structureFunctionCellEditor = new StructureFunctionCellEditor();
    reportPreProcessorCellEditor = new ReportPreProcessorCellEditor();
    expressionsCellEditor = new ExpressionCellHandler();
    expressionsCellRenderer = new ExpressionCellHandler();
    reportPreProcessorCellRenderer = new ReportPreProcessorCellRenderer();
    groupingCellRenderer = new GroupingHeaderCellRenderer();
    taggedPropertyEditorCellEditor = new PropertyEditorCellEditor();
    propertyEditorCellEditor = new DesignerPropertyCellEditorWithEllipsis();
    propertyEditorCellRenderer = new PropertyEditorCellRenderer();
    arrayCellRenderer = new ArrayCellRenderer();
    arrayCellEditor = new ArrayCellEditor();
    stringValueCellEditor = new StringValueCellEditor();

    setDefaultEditor(Object.class, null);
    setDefaultEditor(GroupingHeader.class, new GroupingHeaderCellEditor());
    setDefaultEditor(Expression.class, expressionsCellEditor);
    setDefaultEditor(StructureFunction.class, structureFunctionCellEditor);
    setDefaultEditor(ReportPreProcessor.class, reportPreProcessorCellEditor);

    setDefaultEditor(Number.class, new GenericCellEditor(BigDecimal.class));
    setDefaultEditor(Integer.class, new GenericCellEditor(Integer.class));
    setDefaultEditor(Float.class, new GenericCellEditor(Float.class));
    setDefaultEditor(Double.class, new GenericCellEditor(Double.class));
    setDefaultEditor(Short.class, new GenericCellEditor(Short.class));
    setDefaultEditor(Byte.class, new GenericCellEditor(Byte.class));
    setDefaultEditor(Long.class, new GenericCellEditor(Long.class));
    setDefaultEditor(BigInteger.class, new GenericCellEditor(BigInteger.class));
    setDefaultEditor(BigDecimal.class, new GenericCellEditor(BigDecimal.class));
    setDefaultEditor(String.class, stringValueCellEditor);
    setDefaultEditor(Date.class, new DateCellEditor(Date.class));
    setDefaultEditor(java.sql.Date.class, new DateCellEditor(Date.class));
    setDefaultEditor(Time.class, new TimeCellEditor(Time.class));
    setDefaultEditor(Timestamp.class, new DateCellEditor(Timestamp.class));

    setDefaultRenderer(GroupingHeader.class, new GroupingHeaderCellRenderer());
    setDefaultRenderer(GroupedName.class, new GroupedNameCellRenderer());
    setDefaultRenderer(StructureFunction.class, expressionsCellRenderer);
    setDefaultRenderer(Expression.class, expressionsCellRenderer);
    setDefaultRenderer(Paint.class, new PaintCellRenderer());
    setDefaultRenderer(Object.class, new GenericCellRenderer());
    setDefaultRenderer(String.class, new GenericCellRenderer());
    setDefaultRenderer(ReportPreProcessor.class, reportPreProcessorCellRenderer);

    final SimpleDateFormat isoDateFormat =
        new SimpleDateFormat(WorkspaceSettings.DATETIME_FORMAT_DEFAULT, Locale.ENGLISH);
    setDefaultRenderer(Date.class, new FormattingTableCellRenderer(isoDateFormat));
    setDefaultRenderer(java.sql.Date.class, new FormattingTableCellRenderer
        (new SimpleDateFormat(WorkspaceSettings.DATE_FORMAT_DEFAULT, Locale.ENGLISH)));
    setDefaultRenderer(Time.class, new FormattingTableCellRenderer
        (new SimpleDateFormat(WorkspaceSettings.TIME_FORMAT_DEFAULT, Locale.ENGLISH)));
    setDefaultRenderer(Timestamp.class, new FormattingTableCellRenderer(isoDateFormat));

    WorkspaceSettings.getInstance().addSettingsListener(new LocaleSettingsListener());
    applyLocaleSettings(WorkspaceSettings.getInstance());
  }

  private static SimpleDateFormat createSafely(final String pattern, final String defaultPattern, final Locale locale)
  {
    try
    {
      if (StringUtils.isEmpty(pattern) == false)
      {
        return new SimpleDateFormat(pattern, locale);
      }
    }
    catch (Exception e)
    {
      logger.warn("Invalid format string found in locale settings", e); // NON-NLS
    }
    return new SimpleDateFormat(defaultPattern, locale);
  }

  public void applyLocaleSettings(final LocaleSettings localeSettings)
  {
    final SimpleDateFormat isoDateFormat = createSafely(localeSettings.getDatetimeFormatPattern(),
        WorkspaceSettings.DATETIME_FORMAT_DEFAULT, localeSettings.getLocale());
    final TimeZone timeZone = localeSettings.getTimeZone();
    isoDateFormat.setTimeZone(timeZone);
    setDefaultRenderer(Date.class, new FormattingTableCellRenderer(isoDateFormat));
    setDefaultRenderer(Timestamp.class, new FormattingTableCellRenderer(isoDateFormat));

    final DateCellEditor dateCellEditor = new DateCellEditor(Date.class);
    dateCellEditor.setDateFormat(isoDateFormat);
    setDefaultEditor(Date.class, dateCellEditor);

    final DateCellEditor timestampEditor = new DateCellEditor(Timestamp.class);
    timestampEditor.setDateFormat(isoDateFormat);
    setDefaultEditor(Timestamp.class, timestampEditor);

    final SimpleDateFormat dateFormat = createSafely(localeSettings.getDateFormatPattern(),
        WorkspaceSettings.DATE_FORMAT_DEFAULT, localeSettings.getLocale());
    dateFormat.setTimeZone(timeZone);
    setDefaultRenderer(java.sql.Date.class, new FormattingTableCellRenderer(dateFormat));

    final DateCellEditor sqlDateCellEditor = new DateCellEditor(java.sql.Date.class);
    sqlDateCellEditor.setDateFormat(dateFormat);
    setDefaultEditor(java.sql.Date.class, sqlDateCellEditor);

    final SimpleDateFormat timeFormat = createSafely(localeSettings.getTimeFormatPattern(),
        WorkspaceSettings.TIME_FORMAT_DEFAULT, localeSettings.getLocale());
    timeFormat.setTimeZone(timeZone);
    setDefaultRenderer(Time.class, new FormattingTableCellRenderer(timeFormat));

    final TimeCellEditor timeCellEditor = new TimeCellEditor(Time.class);
    timeCellEditor.setDateFormat(timeFormat);
    setDefaultEditor(Time.class, timeCellEditor);
  }

  /**
   * Returns true if the cell at <code>row</code> and <code>column</code> is editable.  Otherwise, invoking
   * <code>setValueAt</code> on the cell will have no effect.
   * <p/>
   * <b>Note</b>: The column is specified in the table view's display order, and not in the <code>TableModel</code>'s
   * column order.  This is an important distinction because as the user rearranges the columns in the table, the column
   * at a given index in the view will change. Meanwhile the user's actions never affect the model's column ordering.
   *
   * @param row    the row whose value is to be queried
   * @param column the column whose value is to be queried
   * @return true if the cell is editable
   * @see #setValueAt
   */
  public boolean isCellEditable(final int row, final int column)
  {
    final int columnIndex = convertColumnIndexToModel(column);
    if (getModel().isCellEditable(row, columnIndex))
    {
      if (getCellEditor(row, columnIndex) == null)
      {
        // no editor, so not editable ...
        return false;
      }
      return true;
    }
    return false;
  }

  public TableCellRenderer getCellRenderer(final int row, final int viewColumn)
  {
    final int column = convertColumnIndexToModel(viewColumn);
    final Object value = getModel().getValueAt(row, column);
    if (value instanceof GroupingHeader)
    {
      return groupingCellRenderer;
    }

    final ElementMetaDataTableModel model = (ElementMetaDataTableModel) getModel();
    final Class columnClass = model.getClassForCell(row, column);
    if (columnClass.isArray())
    {
      return arrayCellRenderer;
    }

    final PropertyEditor propertyEditor = model.getEditorForCell(row, column);
    if (propertyEditor != null)
    {
      propertyEditorCellRenderer.setPropertyEditor(propertyEditor);
      return propertyEditorCellRenderer;
    }
    final TableColumn tableColumn = getColumnModel().getColumn(column);
    final TableCellRenderer renderer = tableColumn.getCellRenderer();
    if (renderer != null)
    {
      return renderer;
    }


    final TableCellRenderer defaultRenderer = getDefaultRenderer(columnClass);
    if (defaultRenderer != null)
    {
      return defaultRenderer;
    }

    if (logger.isTraceEnabled())
    {
      logger.trace("No renderer for column class " + columnClass); // NON-NLS
    }
    return getDefaultRenderer(Object.class);
  }

  public TableCellEditor getCellEditor(final int row, final int viewColumn)
  {
    final int column = convertColumnIndexToModel(viewColumn);
    final Object value = getModel().getValueAt(row, column);
    if (value instanceof GroupingHeader)
    {
      return getDefaultEditor(GroupingHeader.class);
    }

    final ElementMetaDataTableModel model = (ElementMetaDataTableModel) getModel();
    final PropertyEditor propertyEditor = model.getEditorForCell(row, column);
    final Class columnClass = model.getClassForCell(row, column);

    if (propertyEditor != null)
    {
      final String[] tags = propertyEditor.getTags();
      if (columnClass.isArray())
      {
        arrayCellEditor.setPropertyEditorType(propertyEditor.getClass());
      }
      else if (tags == null || tags.length == 0)
      {
        propertyEditorCellEditor.setPropertyEditor(propertyEditor);
        return propertyEditorCellEditor;
      }
      else
      {
        taggedPropertyEditorCellEditor.setPropertyEditor(propertyEditor);
        return taggedPropertyEditorCellEditor;
      }
    }

    final TableColumn tableColumn = getColumnModel().getColumn(column);
    final TableCellEditor renderer = tableColumn.getCellEditor();
    if (renderer != null)
    {
      return renderer;
    }

    if (columnClass.isArray())
    {
      return arrayCellEditor;
    }

    final TableCellEditor editor = getDefaultEditor(columnClass);
    if (editor != null && logger.isTraceEnabled())
    {
      logger.trace("Using preconfigured default editor for column class " + columnClass + ": " + editor); // NON-NLS
    }
    return editor;
  }

  public void setReportDesignerContext(final ReportDesignerContext newContext)
  {
    final ReportDesignerContext oldContext = arrayCellEditor.getReportDesignerContext();
    if (oldContext != null)
    {
      oldContext.removePropertyChangeListener(this.changeHandler);
      final ReportDocumentContext oldActiveContext = getReportRenderContext();
      updateActiveContext(oldActiveContext, null);
    }

    arrayCellEditor.setReportDesignerContext(newContext);
    stringValueCellEditor.setReportDesignerContext(newContext);
    expressionsCellRenderer.setReportDesignerContext(newContext);
    expressionsCellEditor.setReportDesignerContext(newContext);
    structureFunctionCellEditor.setReportDesignerContext(newContext);

    if (newContext != null)
    {
      newContext.addPropertyChangeListener(ReportDesignerContext.ACTIVE_CONTEXT_PROPERTY, changeHandler);
      updateActiveContext(null, newContext.getActiveContext());
    }
  }

  protected void updateActiveContext(final ReportDocumentContext oldContext,
                                     final ReportDocumentContext activeContext)
  {
    structureFunctionCellEditor.setRenderContext(activeContext);
    reportPreProcessorCellEditor.setRenderContext(activeContext);
  }

  public ReportDesignerContext getReportDesignerContext()
  {
    return arrayCellEditor.getReportDesignerContext();
  }

  public ReportDocumentContext getReportRenderContext()
  {
    final ReportDesignerContext reportDesignerContext = getReportDesignerContext();
    if (reportDesignerContext == null)
    {
      return null;
    }
    return reportDesignerContext.getActiveContext();
  }

  public boolean isFormulaFragment()
  {
    return stringValueCellEditor.isFormulaFragment();
  }

  public void setFormulaFragment(final boolean formulaFragment)
  {
    stringValueCellEditor.setFormulaFragment(formulaFragment);
  }

  public void stopEditing()
  {
    final TableCellEditor cellEditor = getCellEditor();
    if (cellEditor != null)
    {
      cellEditor.stopCellEditing();
    }
  }
}
TOP

Related Classes of org.pentaho.reporting.designer.core.util.table.ElementMetaDataTable$LocaleSettingsListener

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.