/**
SpagoBI, the Open Source Business Intelligence suite
Copyright (C) 2012 Engineering Ingegneria Informatica S.p.A. - SpagoBI Competency Center
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this file,
You can obtain one at http://mozilla.org/MPL/2.0/.
**/
package it.eng.spagobi.studio.chart.editors;
import it.eng.spagobi.studio.chart.editors.model.chart.ChartModel;
import it.eng.spagobi.studio.chart.editors.model.chart.ChartModelFactory;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.io.SAXReader;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.ColorDialog;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Spinner;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.forms.events.ExpansionAdapter;
import org.eclipse.ui.forms.events.ExpansionEvent;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.ScrolledForm;
import org.eclipse.ui.forms.widgets.Section;
import org.eclipse.ui.forms.widgets.TableWrapData;
import org.eclipse.ui.forms.widgets.TableWrapLayout;
import org.eclipse.ui.part.EditorPart;
import org.eclipse.ui.part.FileEditorInput;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* @author gavardi
*
* The chart document editor
*
*/
public final class ChartEditor extends EditorPart {
protected boolean isDirty = false;
protected ChartModel model = null;
static public final int COLORDIALOG_WIDTH = 222;
static public final int COLORDIALOG_HEIGHT = 306;
String projectname = null;
protected ChartEditorComponents components = null;
private static Logger logger = LoggerFactory.getLogger(ChartEditor.class);
public ChartEditor() {
super();
}
public void doSave(IProgressMonitor monitor) {
logger.debug("Start Saving Chart Template File");
ByteArrayInputStream bais = null;
try {
FileEditorInput fei = (FileEditorInput) getEditorInput();
IFile file = fei.getFile();
String newContent = model.toXML();
byte[] bytes = newContent.getBytes();
bais = new ByteArrayInputStream(bytes);
file.setContents(bais, IFile.FORCE, null);
// reload the this document for the model!
InputStream thisIs = null;
thisIs = file.getContents();
SAXReader reader = new SAXReader();
Document thisDocument = reader.read(thisIs);
model.setThisDocument(thisDocument);
} catch (CoreException e) {
logger.error("Error while Saving Chart Template File",e);
e.printStackTrace();
} catch (DocumentException e) {
logger.error("Error while reloading current template",e);
e.printStackTrace();
}
finally {
if (bais != null)
try {
bais.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
setIsDirty(false);
}
public void doSaveAs() {
}
public void init(IEditorSite site, IEditorInput input) {
this.setPartName(input.getName());
logger.debug("Start Editor Initialization");
FileEditorInput fei = (FileEditorInput) input;
IFile file = fei.getFile();
projectname = file.getProject().getName();
try {
// Create the model of the chart that will store informations
components=new ChartEditorComponents();
components.setProjectname(projectname);
model = ChartModelFactory.createChartModel(file, site.getShell());
model.setEditor(this);
} catch (Exception e) {
logger.error("Error during Editor Initialization "+e.getMessage(),e);
MessageDialog.openError(site.getShell(), "Error", e.getMessage());
return;
}
setInput(input);
setSite(site);
}
public boolean isDirty() {
return isDirty;
}
public boolean isSaveAsAllowed() {
return false;
}
public void createPartControl(final Composite parent) {
logger.debug("Creating the editor for charts");
final FormToolkit toolkit = new FormToolkit(parent.getDisplay());
final ScrolledForm form = toolkit.createScrolledForm(parent);
TableWrapLayout layout = new TableWrapLayout();
layout.numColumns = 1;
layout.horizontalSpacing = 20;
layout.verticalSpacing = 10;
layout.topMargin = 20;
layout.leftMargin = 20;
form.getBody().setLayout(layout);
// ++++++++++++++ Chart common settings section ++++++++++++++
logger.debug("Creating the common informations section");
Section sectionInformation = toolkit.createSection(form.getBody(),
Section.DESCRIPTION|Section.TITLE_BAR|Section.TWISTIE|Section.EXPANDED);
TableWrapData td = new TableWrapData(TableWrapData.FILL);
sectionInformation.setLayoutData(td);
sectionInformation.addExpansionListener(new ExpansionAdapter() {
public void expansionStateChanged(ExpansionEvent e) {
form.reflow(true);
}
});
sectionInformation.setText("Chart information");
sectionInformation.setDescription("Below you see some chart general informations");
components.setSectionClientInformation(toolkit.createComposite(sectionInformation));
Composite sectionClientInformation = components.getSectionClientInformation();
GridLayout gl = new GridLayout();
gl.numColumns = 2;
sectionClientInformation.setLayout(gl);
Label typeLabel = new Label(sectionClientInformation, SWT.NULL);
typeLabel.setText("Title:");
final Text titleText=new Text(sectionClientInformation, SWT.BORDER);
titleText.setText(model.getTitle());
titleText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
titleText.addModifyListener(new ModifyListener() {
public void modifyText(ModifyEvent event) {
model.getEditor().setIsDirty(true);
String titleValue = titleText.getText();
model.setTitle(titleValue);
}
});
Label subTitleLabel = new Label(sectionClientInformation, SWT.NULL);
subTitleLabel.setText("Sub Title:");
final Text subTitleText=new Text(sectionClientInformation, SWT.BORDER);
subTitleText.setText(model.getSubTitle());
subTitleText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
subTitleText.addModifyListener(new ModifyListener() {
public void modifyText(ModifyEvent event) {
model.getEditor().setIsDirty(true);
String subTitleValue = subTitleText.getText();
model.setSubTitle(subTitleValue);
}
});
Label movieLabel = new Label(sectionClientInformation, SWT.NULL);
movieLabel.setText("Type:");
Label movie = new Label(sectionClientInformation, SWT.NULL);
movie.setText(model.getType());
sectionInformation.setClient(sectionClientInformation);
sectionInformation.pack();
sectionClientInformation.pack();
// ++++++++++++++ Chart dimension settings section ++++++++++++++
logger.debug("Creating the dimension informations section");
Section sectionDimension = toolkit.createSection(form.getBody(),
Section.DESCRIPTION|Section.TITLE_BAR|Section.TWISTIE|Section.EXPANDED);
td = new TableWrapData(TableWrapData.FILL);
sectionDimension.setLayoutData(td);
sectionDimension.addExpansionListener(new ExpansionAdapter() {
public void expansionStateChanged(ExpansionEvent e) {
form.reflow(true);
}
});
sectionDimension.setText("Chart dimension");
sectionDimension.setDescription("Below you see the chart dimension settings:");
components.setSectionClientDimension(toolkit.createComposite(sectionDimension));
Composite sectionClientDimension = components.getSectionClientDimension();
gl = new GridLayout();
gl.numColumns = 2;
sectionClientDimension.setLayout(gl);
GridData gd = new GridData();
gd.horizontalSpan = 2;
Label widthLabel = new Label(sectionClientDimension, SWT.NULL);
widthLabel.setText("Width (in pixel):");
final Spinner widthText = new Spinner (sectionClientDimension, SWT.BORDER);
widthText.setMaximum(100000);
widthText.setMinimum(0);
widthText.setSelection(new Integer(model.getDimension().getWidth()));
widthText.addModifyListener(new ModifyListener() {
public void modifyText(ModifyEvent event) {
setIsDirty(true);
int val = widthText.getSelection();
// check it is a number
model.getDimension().setWidth(val);
}
});
// final Text widthText = new Text(sectionClientDimension, SWT.BORDER);
// widthText.setText(new Integer(model.getDimension().getWidth()).toString());
// widthText.addModifyListener(new ModifyListener() {
// public void modifyText(ModifyEvent event) {
// setIsDirty(true);
// String widthStr = widthText.getText();
// model.getDimension().setWidth(Integer.parseInt(widthStr));
// int i=model.getSeriesPersonalizationHashMap().size();
// int j=0;
// }
// });
Label heightLabel = new Label(sectionClientDimension, SWT.NULL);
heightLabel.setText("Height (in pixel):");
final Spinner heightText = new Spinner (sectionClientDimension, SWT.BORDER);
heightText.setMaximum(100000);
heightText.setMinimum(0);
heightText.setSelection(new Integer(model.getDimension().getHeight()));
heightText.addModifyListener(new ModifyListener() {
public void modifyText(ModifyEvent event) {
setIsDirty(true);
int val = heightText.getSelection();
// check it is a number
model.getDimension().setHeight(val);
}
});
sectionDimension.setClient(sectionClientDimension);
// ++++++++++++++ Chart Style Settings ++++++++++++++
logger.debug("Creating style informations section");
final Section sectionStyle = toolkit.createSection(form.getBody(),
Section.DESCRIPTION|Section.TITLE_BAR|Section.TWISTIE);
td = new TableWrapData(TableWrapData.FILL);
sectionStyle.setLayoutData(td);
sectionStyle.addExpansionListener(new ExpansionAdapter() {
public void expansionStateChanged(ExpansionEvent e) {
form.reflow(true);
}
});
sectionStyle.setText("Chart Style settings");
sectionStyle.setDescription("Below you see the chart style youc an define:");
components.setSectionClientStyle(toolkit.createComposite(sectionStyle));
Composite sectionClientStyle = components.getSectionClientStyle();
components.createStyleParametersForm(model,this, sectionClientStyle, toolkit);
sectionStyle.setClient(sectionClientStyle);
// ++++++++++++++ Chart Conf Settings ++++++++++++++
logger.debug("Creating Common configuration informations section");
components.setConfigurationEditor(new ConfigurationEditor(toolkit,form));
components.createConfigurationSection(model,null, toolkit, form);
// ****************** get subtypes COMBO ******************
logger.debug("Create the sub type combo: ");
List<String> subTypes=null;
try {
logger.debug("Get all configured sub types");
subTypes=ChartModel.getConfiguredChartSubTypes(model.getType());
} catch (Exception e1) {
logger.error("Error while retrieving possible subtypes",e1);
e1.printStackTrace();
return;
}
Label subTypeLabel = new Label(sectionClientInformation, SWT.NULL);
subTypeLabel.setText("SubType:");
final Combo combo = new Combo(sectionClientInformation, SWT.SIMPLE | SWT.DROP_DOWN | SWT.READ_ONLY);
for (Iterator iterator = subTypes.iterator(); iterator.hasNext();) {
String subType = (String) iterator.next();
combo.add(subType);
}
combo.setToolTipText("Select the chart subtype among "+model.getType()+": the specific configuration parameters and the forms will change accordingly");
// Put default subtype on combo
logger.debug("Model subtype is "+subTypeLabel);
int index=combo.indexOf(model.getSubType());
combo.select(index);
// ****************** Background color ******************
Label labelColor=new Label(sectionClientInformation, SWT.NULL);
labelColor.setText("Background color");
labelColor.setToolTipText("Background color for the chart");
Composite innerSection = toolkit.createComposite(sectionClientInformation);
GridLayout colorGd = new GridLayout();
colorGd.numColumns = 2;
colorGd.marginHeight = 0;
colorGd.marginBottom = 0;
innerSection.setLayout(colorGd);
final Label colorLabel = new Label(innerSection, SWT.BORDER);
colorLabel.setText(" ");
RGB rgb=null;
if(model.getBackgroundColor()!=null){
rgb = model.getBackgroundColor();
}
else{
rgb=new RGB(255,0,0);
}
final Color color = new Color(sectionClientInformation.getDisplay(), rgb);
colorLabel.setBackground(color);
Button button = new Button(innerSection, SWT.PUSH);
button.setText("Color...");
final Shell parentShell = sectionClientInformation.getShell();
button.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
final Shell centerShell = new Shell(parentShell, SWT.NO_TRIM);
centerShell.setLocation(
(parentShell.getSize().x - ChartEditor.COLORDIALOG_WIDTH) / 2,
(parentShell.getSize().y - ChartEditor.COLORDIALOG_HEIGHT) / 2);
ColorDialog colorDg = new ColorDialog(centerShell,
SWT.APPLICATION_MODAL);
colorDg.setRGB(colorLabel.getBackground().getRGB());
//colorDg.setText("Choose a color");
RGB rgb = colorDg.open();
if (rgb != null) {
// Dispose the old color, create the
// new one, and set into the label
color.dispose();
Color newColor = new Color(parentShell.getDisplay(), rgb);
colorLabel.setBackground(newColor);
String newHexadecimal = ChartEditor.convertRGBToHexadecimal(rgb);
model.setBackgroundColor(ChartEditor.convertHexadecimalToRGB(newHexadecimal));
setIsDirty(true);
}
centerShell.dispose();
}
});
//setIsDirty(true);
try{
model.initializeEditor(this,components,toolkit,form);
}
catch (Exception e) {
logger.error("Error while generating static form",e);
e.printStackTrace();
}
//*********** DATASET INFORMATION SECTION **********
components.createDataSetInformationSection(model, toolkit, form);
//************************* CHANGE SUBTYPE: ERASE PREVIOUS SPECIFIC MODEL and CREATE NEW FORM *********************
logger.debug("Add listener for subtype selection combo: erase specific settings defined in model and change form according to new subtype");
combo.addSelectionListener(new SelectionListener() {
public void widgetSelected(SelectionEvent e) {
if(model.getSubType()!=null && model.getSubType().equalsIgnoreCase(combo.getText())){
logger.warn("Already Selected");
}
else{
try{
model.setSubType(combo.getText());
// close configuration parameter section
(components.getConfigurationEditor().getSectionConf()).setExpanded(false);
model.refreshEditor(null, components, toolkit, form);
}
catch (Exception ex) {
logger.error("Error while changing subtype form",ex);
ex.printStackTrace();
}
}
setIsDirty(true);
}
public void widgetDefaultSelected(SelectionEvent e) {
}
});
setIsDirty(true); // first time must be dirty
}
public void setFocus() {
}
public void setIsDirty(boolean isDirty) {
this.isDirty = isDirty;
firePropertyChange(PROP_DIRTY);
}
public static String convertRGBToHexadecimal(RGB rgb) {
int red = rgb.red;
int green = rgb.green;
int blue = rgb.blue;
String redHexadecimal = Integer.toHexString(red);
String greenHexadecimal = Integer.toHexString(green);
String blueHexadecimal = Integer.toHexString(blue);
if (redHexadecimal.length() == 1) redHexadecimal = "0" + redHexadecimal;
if (greenHexadecimal.length() == 1) greenHexadecimal = "0" + greenHexadecimal;
if (blueHexadecimal.length() == 1) blueHexadecimal = "0" + blueHexadecimal;
return "#" + redHexadecimal + greenHexadecimal + blueHexadecimal;
}
public static RGB convertHexadecimalToRGB(String hexadecimal) throws NumberFormatException{
java.awt.Color col=null;
try{
col=java.awt.Color.decode(hexadecimal);
}
catch (Exception e) {
col=java.awt.Color.WHITE;
}
int red=col.getRed();
int blue=col.getBlue();
int green=col.getGreen();
return new RGB(red, green, blue);
}
public ChartModel getModel() {
return model;
}
}