/** 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.Activator; import it.eng.spagobi.studio.chart.editors.model.chart.ChartModel; import it.eng.spagobi.studio.chart.editors.model.chart.Parameter; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.dom4j.Document; import org.dom4j.Node; import org.dom4j.io.SAXReader; import org.eclipse.core.runtime.Platform; 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.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.forms.widgets.FormToolkit; import org.osgi.framework.Bundle; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class ChartEditorUtils { private static Logger logger = LoggerFactory.getLogger(ChartEditorUtils.class); /** Get the chart template file path; if subtype is specified go and check in the configuration file wich is the particular template * otherwise getDefault * * @param chartType * @return * @throws Exception */ public static String getDefaultSubtype(String chartType) throws Exception { String toReturn = null; InputStream is = getInputStreamFromResource(ChartModel.CHART_INFO_FILE); Document document = new SAXReader().read(is); List charts = document.selectNodes("//CHARTS/CHART"); if (charts == null || charts.size() == 0) throw new Exception("No charts configured"); for (int i = 0; i < charts.size(); i++) { Node chart = (Node) charts.get(i); String type = chart.valueOf("@type"); if (chartType.equalsIgnoreCase(type)) { ChartEditorUtils.print("CHART", chart); String def = chart.valueOf("@defaultSubType"); toReturn = def; break; } } return toReturn; } /** Get the configuration file path for the selected type * * @param chartType * @return * @throws Exception */ public static String getChartConfigPath(String chartType) throws Exception { String toReturn = null; InputStream is = getInputStreamFromResource(ChartModel.CHART_INFO_FILE); Document document = new SAXReader().read(is); List charts = document.selectNodes("//CHARTS/CHART"); if (charts == null || charts.size() == 0) throw new Exception("No charts configured"); for (int i = 0; i < charts.size(); i++) { Node chart = (Node) charts.get(i); String type = chart.valueOf("@type"); if (chartType.equalsIgnoreCase(type)) { String templatePath = chart.valueOf("@configPath"); toReturn = templatePath; break; } } return toReturn; } /** Get the chart image path for the selected type * * @param imageType * @return * @throws Exception */ public static String getChartImagePath(String imageType) throws Exception { String toReturn = null; InputStream is = getInputStreamFromResource(ChartModel.CHART_INFO_FILE); Document document = new SAXReader().read(is); List charts = document.selectNodes("//CHARTS/CHART"); if (charts == null || charts.size() == 0) throw new Exception("No charts configured"); for (int i = 0; i < charts.size(); i++) { Node chart = (Node) charts.get(i); String type = chart.valueOf("@type"); if (imageType.equalsIgnoreCase(type)) { String imagePath = chart.valueOf("@imagePath"); toReturn = imagePath; break; } } return toReturn; } /** Get input stream from a resource * * @param resourcePath * @return * @throws IOException */ public static InputStream getInputStreamFromResource(String resourcePath) throws IOException { Bundle b = Platform.getBundle(Activator.PLUGIN_ID); URL res = b.getResource(resourcePath); InputStream is = res.openStream(); return is; } /** Draw a configuration parameter * * @param model * @param section * @param aParameter * @param toolkit */ static public void drawParameter(final ChartModel model, Composite section, final Parameter aParameter, FormToolkit toolkit){ logger.debug("Draw Parameter "+aParameter.getName()); Label parameterDescriptionLabel = new Label(section, SWT.NULL); parameterDescriptionLabel.setText(aParameter.getDescription() + ":"); int parameterType = aParameter.getType(); switch (parameterType) { case Parameter.COLOR_TYPE: Composite innerSection = toolkit.createComposite(section); 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(aParameter.getValue()!=null){ String hexadecimal = aParameter.getValue().toString(); try{ rgb= ChartEditor.convertHexadecimalToRGB(hexadecimal); } catch (Exception e) { rgb=new RGB(255,0,0); } } else{ rgb=new RGB(255,0,0); } final Color color = new org.eclipse.swt.graphics.Color(section.getDisplay(), rgb); colorLabel.setBackground(color); Button button = new Button(innerSection, SWT.PUSH); button.setText("Color..."); if(aParameter.getTooltip()!=null){ button.setToolTipText(aParameter.getTooltip()); } final Shell parentShell = section.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); model.getEditor().setIsDirty(true); String newHexadecimal = ChartEditor.convertRGBToHexadecimal(rgb); aParameter.setValue(newHexadecimal); } centerShell.dispose(); } }); break; case Parameter.BOOLEAN_TYPE: final Button check = toolkit.createButton(section, "", SWT.CHECK); if(aParameter.getValue()!=null){ check.setSelection(Boolean.parseBoolean(aParameter.getValue().toString())); } if(aParameter.getTooltip()!=null){ check.setToolTipText(aParameter.getTooltip()); } check.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent event) { model.getEditor().setIsDirty(true); aParameter.setValue(Boolean.toString(check.getSelection())); } }); break; case Parameter.INTEGER_TYPE: //final Text parameterNumberValueText = new Text(section, SWT.BORDER); final Spinner parIntegerSpinner = new Spinner (section, SWT.BORDER); parIntegerSpinner.setMaximum(1000); parIntegerSpinner.setMinimum(-1000); if(aParameter.getTooltip()!=null){ parIntegerSpinner.setToolTipText(aParameter.getTooltip()); } if(aParameter.getValue()!=null && !aParameter.getValue().toString().equals("")){ //parameterNumberValueText.setText(aParameter.getValue().toString()); parIntegerSpinner.setSelection((Integer.valueOf(aParameter.getValue().toString())).intValue()); } //parIntegerSpinner.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); parIntegerSpinner.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent event) { model.getEditor().setIsDirty(true); int parameterValue = parIntegerSpinner.getSelection(); // check it is a number aParameter.setValue(new Integer(parameterValue)); } }); break; case Parameter.FLOAT_TYPE: //final Text parameterNumberValueText = new Text(section, SWT.BORDER); final Spinner parFloatSpinner = new Spinner (section, SWT.BORDER); parFloatSpinner.setDigits(2); parFloatSpinner.setMaximum(100000); parFloatSpinner.setMinimum(-100000); if(aParameter.getTooltip()!=null){ parFloatSpinner.setToolTipText(aParameter.getTooltip()); } if(aParameter.getValue()!=null && !aParameter.getValue().toString().equals("")){ //parameterNumberValueText.setText(aParameter.getValue().toString()); String valueToSet = null; Double doubleVal=Double.valueOf(aParameter.getValue().toString()); String doubleString=doubleVal.toString(); int indexPoint = doubleString.indexOf('.'); if(indexPoint != -1){ String intPart= doubleString.substring(0, indexPoint); String decimalPart= doubleString.substring(indexPoint+1, doubleString.length()); if(decimalPart.length() == 1){ decimalPart+="0"; } valueToSet = intPart+decimalPart; } else{ valueToSet = doubleString; } //doubleString=removeChar(doubleString, '.'); Integer fakeIntVal=Integer.valueOf(valueToSet); parFloatSpinner.setSelection(fakeIntVal); } //parFloatSpinner.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); parFloatSpinner.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent event) { model.getEditor().setIsDirty(true); //int parameterValue = parFloatSpinner.getSelection(); double parameterValue = parFloatSpinner.getSelection()/ Math.pow(10, parFloatSpinner.getDigits()); // check it is a number aParameter.setValue(new Double(parameterValue)); } }); break; case Parameter.COMBO_TYPE: ArrayList<String> values=aParameter.getPredefinedValues(); if(values!=null && !values.isEmpty()){ final Combo combo = new Combo(section, SWT.SIMPLE | SWT.DROP_DOWN | SWT.READ_ONLY); boolean selected=false; if(aParameter.getTooltip()!=null){ combo.setToolTipText(aParameter.getTooltip()); } for (Iterator iterator = values.iterator(); iterator.hasNext();) { String val = (String) iterator.next(); combo.add(val); if(aParameter.getValue()!=null && val.equalsIgnoreCase(aParameter.getValue().toString())){ int index=combo.indexOf(val); combo.select(index); selected=true; } } if(selected==false){ combo.select(0); String comboValue=combo.getItem(0); aParameter.setValue(comboValue); } combo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); combo.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent event) { model.getEditor().setIsDirty(true); String parameterValueStr = combo.getText(); aParameter.setValue(parameterValueStr); } }); } else{ // if no predefined value are set it is a simple text form final Text parameterValueText = new Text(section, SWT.BORDER); if(aParameter.getValue()!=null){ parameterValueText.setText(aParameter.getValue().toString()); } if(aParameter.getTooltip()!=null){ parameterValueText.setToolTipText(aParameter.getTooltip()); } parameterValueText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); parameterValueText.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent event) { model.getEditor().setIsDirty(true); String parameterValueStr = parameterValueText.getText(); // System.out.println("modificato parametro "+aParameter.getName()); aParameter.setValue(parameterValueStr); } }); } break; default: final Text parameterValueText = new Text(section, SWT.BORDER); if(aParameter.getValue()!=null){ parameterValueText.setText(aParameter.getValue().toString()); } if(aParameter.getTooltip()!=null){ parameterValueText.setToolTipText(aParameter.getTooltip()); } parameterValueText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); parameterValueText.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent event) { model.getEditor().setIsDirty(true); String parameterValueStr = parameterValueText.getText(); // System.out.println("modificato parametro "+aParameter.getName()); aParameter.setValue(parameterValueStr); } }); } } /** Draw a specific configuration parameter * * @param model * @param editor * @param toolkit * @param form */ static public void drawSpecificParameter(final ChartModel model, Composite section, final Parameter aParameter, FormToolkit toolkit, int order){ logger.debug("Draw Parameter "+aParameter.getName()); Label parameterDescriptionLabel = new Label(section, SWT.NULL); parameterDescriptionLabel.setText(aParameter.getDescription() + ":"); //parameterDescriptionLabel.setLocation(5, 30*order); parameterDescriptionLabel.pack(); int parameterType = aParameter.getType(); switch (parameterType) { case Parameter.COLOR_TYPE: Composite innerSection = toolkit.createComposite(section); 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(aParameter.getValue()!=null){ String hexadecimal = aParameter.getValue().toString(); try{ rgb= ChartEditor.convertHexadecimalToRGB(hexadecimal); } catch (Exception e) { rgb=new RGB(255,0,0); } } else{ rgb=new RGB(255,0,0); } final Color color = new org.eclipse.swt.graphics.Color(section.getDisplay(), rgb); colorLabel.setBackground(color); Button button = new Button(innerSection, SWT.PUSH); button.setText("Color..."); if(aParameter.getTooltip()!=null){ button.setToolTipText(aParameter.getTooltip()); } final Shell parentShell = section.getShell(); button.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent event) { model.getEditor().setIsDirty(true); 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); model.getEditor().setIsDirty(true); String newHexadecimal = ChartEditor.convertRGBToHexadecimal(rgb); aParameter.setValue(newHexadecimal); } centerShell.dispose(); } }); break; case Parameter.BOOLEAN_TYPE: final Button check = toolkit.createButton(section, "", SWT.CHECK); if(aParameter.getValue()!=null){ check.setSelection(Boolean.parseBoolean(aParameter.getValue().toString())); } if(aParameter.getTooltip()!=null){ check.setToolTipText(aParameter.getTooltip()); } check.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent event) { model.getEditor().setIsDirty(true); boolean sel=check.getSelection(); String s=Boolean.valueOf(sel).toString(); aParameter.setValue(s); } }); //check.setLocation(100,order*30); check.pack(); break; case Parameter.INTEGER_TYPE: //final Text parameterNumberValueText = new Text(section, SWT.BORDER); final Spinner parIntegerSpinner = new Spinner (section, SWT.BORDER); parIntegerSpinner.setMaximum(1000); parIntegerSpinner.setMinimum(-1000); if(aParameter.getTooltip()!=null){ parIntegerSpinner.setToolTipText(aParameter.getTooltip()); } if(aParameter.getValue()!=null && !aParameter.getValue().toString().equals("")){ //parameterNumberValueText.setText(aParameter.getValue().toString()); parIntegerSpinner.setSelection((Integer.valueOf(aParameter.getValue().toString())).intValue()); } //parIntegerSpinner.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); parIntegerSpinner.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent event) { model.getEditor().setIsDirty(true); int parameterValue = parIntegerSpinner.getSelection(); // check it is a number aParameter.setValue(new Integer(parameterValue)); } }); break; case Parameter.FLOAT_TYPE: //final Text parameterNumberValueText = new Text(section, SWT.BORDER); final Spinner parFloatSpinner = new Spinner (section, SWT.BORDER); parFloatSpinner.setDigits(2); parFloatSpinner.setMaximum(100000); parFloatSpinner.setMinimum(-100000); if(aParameter.getTooltip()!=null){ parFloatSpinner.setToolTipText(aParameter.getTooltip()); } if(aParameter.getValue()!=null && !aParameter.getValue().toString().equals("")){ //parameterNumberValueText.setText(aParameter.getValue().toString()); Double doubleVal=Double.valueOf(aParameter.getValue().toString()); String doubleString=doubleVal.toString(); doubleString=removeChar(doubleString, '.'); Integer fakeIntVal=Integer.valueOf(doubleString); parFloatSpinner.setSelection(fakeIntVal); } //parFloatSpinner.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); parFloatSpinner.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent event) { model.getEditor().setIsDirty(true); //int parameterValue = parFloatSpinner.getSelection(); double parameterValue = parFloatSpinner.getSelection()/ Math.pow(10, parFloatSpinner.getDigits()); // check it is a number aParameter.setValue(new Double(parameterValue)); } }); break; case Parameter.COMBO_TYPE: ArrayList<String> values=aParameter.getPredefinedValues(); if(values!=null && !values.isEmpty()){ final Combo combo = new Combo(section, SWT.SIMPLE | SWT.DROP_DOWN | SWT.READ_ONLY); if(aParameter.getTooltip()!=null){ combo.setToolTipText(aParameter.getTooltip()); } boolean selected=false; for (Iterator iterator = values.iterator(); iterator.hasNext();) { String val = (String) iterator.next(); combo.add(val); if(aParameter.getValue()!=null && val.equalsIgnoreCase(aParameter.getValue().toString())){ int index=combo.indexOf(val); combo.select(index); selected=true; } } if(selected==false){ combo.select(0); String comboValue=combo.getItem(0); aParameter.setValue(comboValue); } combo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); combo.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent event) { model.getEditor().setIsDirty(true); String parameterValueStr = combo.getText(); aParameter.setValue(parameterValueStr); } }); //combo.setLocation(100,order*30); combo.pack(); } else{ // if no predefined value are set it is a simple text form final Text parameterValueText = new Text(section, SWT.BORDER); if(aParameter.getValue()!=null){ parameterValueText.setText(aParameter.getValue().toString()); } if(aParameter.getTooltip()!=null){ parameterValueText.setToolTipText(aParameter.getTooltip()); } parameterValueText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); parameterValueText.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent event) { model.getEditor().setIsDirty(true); String parameterValueStr = parameterValueText.getText(); aParameter.setValue(parameterValueStr); } }); //parameterValueText.setLocation(100, 30*order); parameterValueText.pack(); } break; default: final Text parameterValueText = new Text(section, SWT.BORDER); if(aParameter.getValue()!=null){ parameterValueText.setText(aParameter.getValue().toString()); } if(aParameter.getTooltip()!=null){ parameterValueText.setToolTipText(aParameter.getTooltip()); } parameterValueText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); parameterValueText.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent event) { model.getEditor().setIsDirty(true); String parameterValueStr = parameterValueText.getText(); aParameter.setValue(parameterValueStr); } }); //parameterValueText.setLocation(100, 30*order); parameterValueText.pack(); } } /** * return tru if chart inserted is a number or at most a . (for doubles) * @return */ static public boolean validateNumberField(String a){ // try to convert in Double, if succeed is ok, otherwise check if last chart is a ., then is ok try{ Double.valueOf(a); return true; } catch (Exception e) { logger.warn("Not a number"); } int len=a.length(); char c=a.charAt(len - 1); if(c=='.') return true; else return false; } static public void print(String titolo, Node node){ // System.out.println("******** "+titolo+" **********"); // System.out.println(node!=null ? node.asXML() : "NULLO"); // System.out.println("******************************"); } public static String removeChar(String s, char c) { String r = ""; for (int i = 0; i < s.length(); i ++) { if (s.charAt(i) != c) r += s.charAt(i); } return r; } public static void addBlanckSpace(Composite composite){ Label spaceLabel=new Label(composite,SWT.NULL); spaceLabel.setText(""); } }