/*!
* 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.pms.ui.concept.editor;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.ICellModifier;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TextCellEditor;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.pentaho.pms.locale.LocaleInterface;
import org.pentaho.pms.locale.Locales;
import org.pentaho.pms.schema.concept.types.localstring.LocalizedStringSettings;
/**
* A specialized table for holding localized string values. Automatically persists changes to the model as they occur.
* @author mlowery
*/
public class LocalizedStringTableWidget extends Composite {
// ~ Static fields/initializers ======================================================================================
private static final Log logger = LogFactory.getLog(LocalizedStringTableWidget.class);
// ~ Instance fields =================================================================================================
private Table table;
private TableViewer tableViewer;
private String[] columnNames = new String[] { "Locale", "String" };
private Locales locales;
private IConceptModel conceptModel;
private String propertyId;
// ~ Constructors ====================================================================================================
public LocalizedStringTableWidget(final Composite parent, final int style, final IConceptModel conceptModel,
final String propertyId, final Locales locales) {
super(parent, style);
this.conceptModel = conceptModel;
this.propertyId = propertyId;
this.locales = locales;
createContents();
}
// ~ Methods =========================================================================================================
private LocalizedStringSettings getLocalizedStringSettings() {
return (LocalizedStringSettings) conceptModel.getEffectiveProperty(propertyId).getValue();
}
private List getColumnNames() {
return Arrays.asList(columnNames);
}
private void createContents() {
setLayout(new FormLayout());
// Create the table
createTable(this);
// Create and setup the TableViewer
createTableViewer();
tableViewer.setContentProvider(new LocalizedStringTableContentProvider());
tableViewer.setLabelProvider(new LocalizedStringTableLabelProvider());
// The input for the table viewer is the instance of ExampleTaskList
tableViewer.setInput(getLocalizedStringSettings());
}
public void setEnabled(boolean enabled) {
super.setEnabled(enabled);
table.setEnabled(enabled);
}
/**
* Create the Table
*/
private void createTable(Composite parent) {
int style = SWT.SINGLE | SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.HIDE_SELECTION;
table = new Table(parent, style);
FormData fdTable = new FormData();
fdTable.top = new FormAttachment(0, 0);
fdTable.left = new FormAttachment(0, 0);
fdTable.right = new FormAttachment(100, 0);
fdTable.bottom = new FormAttachment(100, 0);
table.setLayoutData(fdTable);
table.setLinesVisible(true);
table.setHeaderVisible(true);
TableColumn column = new TableColumn(table, SWT.LEFT, 0);
column.setText(columnNames[0]);
column.setWidth(100);
// 3rd column with task Owner
column = new TableColumn(table, SWT.LEFT, 1);
column.setText(columnNames[1]);
column.setWidth(300);
}
/**
* Create the TableViewer
*/
private void createTableViewer() {
tableViewer = new TableViewer(table);
tableViewer.setUseHashlookup(true);
tableViewer.setColumnProperties(columnNames);
CellEditor[] editors = new CellEditor[columnNames.length];
// Column 0 : Description (Free text)
TextCellEditor textEditor0 = new TextCellEditor(table);
// ((Text) textEditor.getControl()).setTextLimit(60);
editors[0] = textEditor0;
TextCellEditor textEditor1 = new TextCellEditor(table);
// ((Text) textEditor.getControl()).setTextLimit(60);
editors[1] = textEditor1;
// Assign the cell editors to the viewer
tableViewer.setCellEditors(editors);
// Set the cell modifier for the viewer
tableViewer.setCellModifier(new LocalizedStringTableCellModifier());
// Set the default sorter for the viewer
// tableViewer.setSorter(new ExampleTaskSorter(LocaleSorter.LOCALE_NAME));
}
class LocalizedStringTableContentProvider implements IStructuredContentProvider {
public void inputChanged(Viewer v, Object oldInput, Object newInput) {
}
public void dispose() {
}
public Object[] getElements(final Object parent) {
LocalizedStringEntry[] entries = new LocalizedStringEntry[locales.getLocaleList().size()];
List localeList = locales.getLocaleList();
int i = 0;
for (Iterator iter = localeList.iterator(); iter.hasNext();) {
LocaleInterface l = (LocaleInterface) iter.next();
entries[i++] = new LocalizedStringEntry(l.getCode(), getLocalizedStringSettings().getString(l.getCode()));
}
return entries;
}
}
private class LocalizedStringEntry {
private String name;
private String value;
public LocalizedStringEntry(final String name, final String value) {
this.name = name;
this.value = value;
}
public String getName() {
return name;
}
public String getValue() {
return value;
}
public boolean equals(Object obj) {
if (obj instanceof LocalizedStringEntry == false) {
return false;
}
if (this == obj) {
return true;
}
LocalizedStringEntry rhs = (LocalizedStringEntry) obj;
return new EqualsBuilder().append(name, rhs.name).append(value, rhs.value).isEquals();
}
public int hashCode() {
return new HashCodeBuilder(43, 149).append(name).append(value).toHashCode();
}
public String toString() {
return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE).append(name).append(value).toString();
}
}
public class LocalizedStringTableCellModifier implements ICellModifier {
public boolean canModify(final Object element, final String property) {
return getColumnNames().indexOf(property) == 1;
}
public Object getValue(final Object element, final String property) {
// Find the index of the column
int columnIndex = getColumnNames().indexOf(property);
Object result = null;
LocalizedStringEntry entry = (LocalizedStringEntry) element;
switch (columnIndex) {
case 0: // locale name
result = entry.getName();
break;
case 1: // value for property for locale
result = LocalizedStringTableWidget.this.getValue(entry);
break;
default:
result = "";
}
if (logger.isDebugEnabled()) {
logger.debug("returning \"" + result + "\"");
}
return result;
}
public void modify(final Object element, final String property, final Object value) {
if (logger.isDebugEnabled()) {
logger.debug("value = \"" + value + "\"");
}
// Find the index of the column
int columnIndex = getColumnNames().indexOf(property);
TableItem item = (TableItem) element;
LocalizedStringEntry entry = (LocalizedStringEntry) item.getData();
switch (columnIndex) {
case 0:
break;
case 1:
// TODO mlowery the result concept event shows an old value with the same value as the new value;
// this is because the code directly accesses the mutable value of the property in the line below;
// properties should return immutable or copies of their values
getLocalizedStringSettings().setLocaleString(entry.getName(), (String) value);
conceptModel.setPropertyValue(propertyId, getLocalizedStringSettings());
tableViewer.refresh();
break;
default:
}
}
}
private class LocalizedStringTableLabelProvider extends LabelProvider implements ITableLabelProvider {
public String getColumnText(final Object element, final int columnIndex) {
String result = "";
LocalizedStringEntry entry = (LocalizedStringEntry) element;
switch (columnIndex) {
case 0:
result = entry.getName();
break;
case 1:
result = getValue(entry);
break;
default:
break;
}
return result;
}
public Image getColumnImage(final Object element, final int columnIndex) {
return null;
}
}
public void refresh() {
tableViewer.refresh();
}
protected String getValue(final LocalizedStringEntry entry) {
String result = getLocalizedStringSettings().getString(entry.getName());
return null != result ? result : "";
}
}