/*
* 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 2008 - 2009 Pentaho Corporation. All rights reserved.
*
*
* Created June 9, 2009
* @author rmansoor
*/
package org.pentaho.platform.dataaccess.datasource.wizard.controllers;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.pentaho.metadata.model.concept.types.AggregationType;
import org.pentaho.platform.dataaccess.datasource.wizard.DatasourceMessages;
import org.pentaho.platform.dataaccess.datasource.wizard.models.Aggregation;
import org.pentaho.ui.xul.XulComponent;
import org.pentaho.ui.xul.XulEventSourceAdapter;
import org.pentaho.ui.xul.XulException;
import org.pentaho.ui.xul.binding.Binding;
import org.pentaho.ui.xul.binding.BindingConvertor;
import org.pentaho.ui.xul.binding.BindingFactory;
import org.pentaho.ui.xul.components.XulButton;
import org.pentaho.ui.xul.components.XulCheckbox;
import org.pentaho.ui.xul.components.XulLabel;
import org.pentaho.ui.xul.components.XulMenuList;
import org.pentaho.ui.xul.containers.XulDialog;
import org.pentaho.ui.xul.containers.XulGroupbox;
import org.pentaho.ui.xul.containers.XulHbox;
import org.pentaho.ui.xul.containers.XulMenupopup;
import org.pentaho.ui.xul.containers.XulVbox;
import org.pentaho.ui.xul.dom.Document;
import org.pentaho.ui.xul.gwt.AbstractGwtXulContainer;
import org.pentaho.ui.xul.stereotype.Bindable;
import org.pentaho.ui.xul.util.TreeCellEditor;
import org.pentaho.ui.xul.util.TreeCellEditorCallback;
public class CustomAggregateCellEditor extends XulEventSourceAdapter implements TreeCellEditor {
DatasourceMessages datasourceMessages = null;
Document document = null;
XulDialog dialog = null;
BindingFactory bf = null;
Aggregation aggregation = null;
List<XulCheckbox> aggregationCheckboxList = new ArrayList<XulCheckbox>();
XulMenuList listbox = null;
XulVbox rightAggregateBox = null;
XulVbox leftAggregateBox = null;
TreeCellEditorCallback callback = null;
public CustomAggregateCellEditor(XulDialog dialog, DatasourceMessages datasourceMessages, Document document,
BindingFactory bf) {
super();
this.dialog = dialog;
this.datasourceMessages = datasourceMessages;
this.document = document;
this.bf = bf;
}
public Object getValue() {
// TODO Auto-generated method stub
return null;
}
public void hide() {
dialog.hide();
}
@Bindable
public void setCheckboxChanged() {
List<AggregationType> aggTypeList = new ArrayList<AggregationType>();
for (XulCheckbox checkbox : aggregationCheckboxList) {
if (checkbox.isChecked()) {
aggTypeList.add(AggregationType.valueOf(checkbox.getId()));
}
}
aggregation.setAggregationList(aggTypeList);
}
public void setValue(Object val) {
// Clear the dialog box with all the existing checkboxes if any
AggregationType currentAggregationType = null;
for (XulComponent component : dialog.getChildNodes()) {
if (!(component instanceof XulButton)) {
dialog.removeChild(component);
}
}
// Create the list of check box in XulDialog
aggregation = (Aggregation) val;
currentAggregationType = aggregation.getDefaultAggregationType();
aggregationCheckboxList.clear();
List<AggregationType> aggregationList = aggregation.getAggregationList();
AggregationType[] aggregationTypeArray = AggregationType.values();
try {
XulGroupbox groupBox = (XulGroupbox) document.createElement("groupbox");//$NON-NLS-1$
XulHbox mainAggregateBox = (XulHbox) document.createElement("hbox");//$NON-NLS-1$
leftAggregateBox = (XulVbox) document.createElement("vbox");//$NON-NLS-1$
rightAggregateBox = (XulVbox) document.createElement("vbox");//$NON-NLS-1$
for (int i = 0; i < aggregationTypeArray.length/2; i++) {
XulCheckbox aggregationCheckBox;
aggregationCheckBox = (XulCheckbox) document.createElement("checkbox");//$NON-NLS-1$
aggregationCheckBox.setLabel(datasourceMessages.getString(aggregationTypeArray[i].getDescription()));
aggregationCheckBox.setId(aggregationTypeArray[i].name());
aggregationCheckBox.setCommand(null);
if (aggregationList.contains(aggregationTypeArray[i])) {
aggregationCheckBox.setChecked(true);
} else {
aggregationCheckBox.setChecked(false);
}
aggregationCheckboxList.add(aggregationCheckBox);
leftAggregateBox.addComponent(aggregationCheckBox);
bf.createBinding(aggregationCheckBox, "checked", this, "checkboxChanged");//$NON-NLS-1$ //$NON-NLS-2$
}
for (int j = aggregationTypeArray.length/2; j < aggregationTypeArray.length; j++) {
XulCheckbox aggregationCheckBox;
aggregationCheckBox = (XulCheckbox) document.createElement("checkbox"); //$NON-NLS-1$
aggregationCheckBox.setLabel(datasourceMessages.getString(aggregationTypeArray[j].getDescription()));
aggregationCheckBox.setId(aggregationTypeArray[j].name());
aggregationCheckBox.setCommand(null);
if (aggregationList.contains(aggregationTypeArray[j])) {
aggregationCheckBox.setChecked(true);
} else {
aggregationCheckBox.setChecked(false);
}
aggregationCheckboxList.add(aggregationCheckBox);
rightAggregateBox.addComponent(aggregationCheckBox);
bf.createBinding(aggregationCheckBox, "checked", this, "checkboxChanged"); //$NON-NLS-1$ //$NON-NLS-2$
}
mainAggregateBox.addComponent(leftAggregateBox);
mainAggregateBox.addComponent(rightAggregateBox);
groupBox.setCaption(datasourceMessages.getString("aggregationEditorDialog.available")); //$NON-NLS-1$
groupBox.addChild(mainAggregateBox);
groupBox.setHeight(130);
groupBox.setWidth(200);
((AbstractGwtXulContainer) groupBox).layout();
dialog.addChild(groupBox);
XulLabel label = (XulLabel) document.createElement("label");//$NON-NLS-1$
label.setValue(datasourceMessages.getString("aggregationEditorDialog.default"));//$NON-NLS-1$
listbox = (XulMenuList) document.createElement("menulist");//$NON-NLS-1$
XulMenupopup menuPopup = (XulMenupopup) document.createElement("menupopup");//$NON-NLS-1$
listbox.addChild(menuPopup);
listbox.setId("DefaultAggregationType");//$NON-NLS-1$
listbox.setBinding("name");//$NON-NLS-1$
dialog.addChild(label);
dialog.addChild(listbox);
bf.setBindingType(Binding.Type.BI_DIRECTIONAL);
BindingConvertor<List<AggregationType>, List<Object>> externalizedAggregationLabelConverter = new BindingConvertor<List<AggregationType>, List<Object>>() {
Map<String,AggregationType> aggregationLabelMap = null;
@Override
public List<Object> sourceToTarget(List<AggregationType> value) {
List<Object> returnValue = new ArrayList<Object>();
aggregationLabelMap = new HashMap<String,AggregationType>();
for(AggregationType aggType:value) {
aggregationLabelMap.put(datasourceMessages.getString(aggType.getDescription()),aggType);
returnValue.add(datasourceMessages.getString(aggType.getDescription()));
}
return returnValue;
}
@Override
public List<AggregationType> targetToSource(List<Object> value) {
List<AggregationType> returnValue = new ArrayList<AggregationType>();
for(Object currentValue:value) {
if(currentValue instanceof String && aggregationLabelMap != null) {
returnValue.add(aggregationLabelMap.get((String) currentValue));
}
}
return returnValue;
}
};
Binding binding = bf.createBinding(aggregation, "aggregationList", listbox, "elements",externalizedAggregationLabelConverter); //$NON-NLS-1$ //$NON-NLS-2$
BindingConvertor<AggregationType, Integer> aggregationTypeToIntegerConverter = new BindingConvertor<AggregationType, Integer>() {
@Override
public Integer sourceToTarget(AggregationType value) {
int index = 0;
for(Object obj:listbox.getElements()) {
if(obj.toString().equals(datasourceMessages.getString(value.getDescription()))) {
break;
}
index++;
}
return index;
}
@Override
public AggregationType targetToSource(Integer value) {
Map<String,AggregationType> aggregationLabelMap = null;
aggregationLabelMap = new HashMap<String,AggregationType>();
for(AggregationType aggType:aggregation.getAggregationList()) {
aggregationLabelMap.put(datasourceMessages.getString(aggType.getDescription()),aggType);
}
return aggregationLabelMap.get(listbox.getSelectedItem());
}
};
bf.createBinding(aggregation, "defaultAggregationType", listbox, "selectedIndex", aggregationTypeToIntegerConverter); //$NON-NLS-1$ //$NON-NLS-2$
try {
binding.fireSourceChanged();
} catch (IllegalArgumentException e) {
throw new XulException(e);
} catch (InvocationTargetException e) {
throw new XulException(e);
}
aggregation.setDefaultAggregationType(currentAggregationType);
} catch (XulException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void show(int row, int col, Object boundObj, String columnBinding, TreeCellEditorCallback callback) {
this.callback = callback;
dialog.show();
}
public void notifyListeners() {
hide();
// Construct a new array list of aggregation based on what user selected
// pass it to listener
ArrayList<AggregationType> aggregationTypeList = new ArrayList<AggregationType>();
for (XulComponent component : leftAggregateBox.getChildNodes()) {
if (component instanceof XulCheckbox) {
XulCheckbox checkbox = (XulCheckbox) component;
if (checkbox.isChecked()) {
aggregationTypeList.add(AggregationType.valueOf(checkbox.getId()));
}
}
}
for (XulComponent component : rightAggregateBox.getChildNodes()) {
if (component instanceof XulCheckbox) {
XulCheckbox checkbox = (XulCheckbox) component;
if (checkbox.isChecked()) {
aggregationTypeList.add(AggregationType.valueOf(checkbox.getId()));
}
}
}
Object item = listbox.getSelectedItem();
Aggregation aggregation = null;
if(item != null) {
Map<String,AggregationType> aggregationLabelMap = null;
aggregationLabelMap = new HashMap<String,AggregationType>();
for(AggregationType aggType:AggregationType.values()) {
aggregationLabelMap.put(datasourceMessages.getString(aggType.getDescription()),aggType);
}
aggregation = new Aggregation(aggregationTypeList, aggregationLabelMap.get(item));
}
this.callback.onCellEditorClosed(aggregation);
}
}