/**
* Copyright 2009 Red Hat, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package org.safehaus.penrose.studio.expression.wizard;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.*;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.*;
import org.eclipse.ui.forms.widgets.Hyperlink;
import org.eclipse.ui.forms.events.HyperlinkAdapter;
import org.eclipse.ui.forms.events.HyperlinkEvent;
import org.eclipse.jface.wizard.WizardPage;
import org.safehaus.penrose.studio.views.CodeAssist;
import org.safehaus.penrose.mapping.Expression;
import org.apache.log4j.Logger;
import java.util.ArrayList;
import java.util.Collection;
import java.io.*;
/**
* @author Endi S. Dewata
*/
public class ExpressionWizardPage extends WizardPage {
Logger log = Logger.getLogger(getClass());
public final static String NAME = "Expression";
public final static int TEXT = 0;
public final static int BINARY = 1;
public final static int VARIABLE = 2;
public final static int EXPRESSION = 3;
Font font;
Composite blankPanel;
Composite currentPanel;
Button binaryRadio;
Text binaryText;
Button textRadio;
Text textText;
Button variableRadio;
Combo variableCombo;
Button expressionRadio;
Text scriptText;
Combo foreachCombo;
Text varText;
int type;
String text;
byte[] binary;
String variable;
Expression expression = new Expression();
public Collection<String> variables = new ArrayList<String>();
public ExpressionWizardPage() {
super(NAME);
setDescription("Enter attribute value.");
}
public void createControl(final Composite parent) {
font = new Font(parent.getDisplay(), "Courier New", 8, SWT.NONE);
Composite composite = new Composite(parent, SWT.NONE);
setControl(composite);
composite.setLayout(new GridLayout());
Composite types = new Composite(composite, SWT.NONE);
types.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
types.setLayout(new GridLayout(2, false));
Label typeLabel = new Label(types, SWT.NONE);
typeLabel.setText("Type:");
GridData gd = new GridData();
gd.widthHint = 80;
typeLabel.setLayoutData(gd);
Composite typeButtons = new Composite(types, SWT.NONE);
typeButtons.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
typeButtons.setLayout(new RowLayout());
textRadio = new Button(typeButtons, SWT.RADIO);
textRadio.setText("text");
textRadio.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
try {
if (!textRadio.getSelection()) return;
setType(TEXT);
refresh();
} catch (Exception e) {
log.error(e.getMessage(), e);
throw new RuntimeException(e);
}
}
});
binaryRadio = new Button(typeButtons, SWT.RADIO);
binaryRadio.setText("binary");
binaryRadio.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
try {
if (!binaryRadio.getSelection()) return;
setType(BINARY);
refresh();
} catch (Exception e) {
log.error(e.getMessage(), e);
throw new RuntimeException(e);
}
}
});
variableRadio = new Button(typeButtons, SWT.RADIO);
variableRadio.setText("variable");
variableRadio.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
try {
if (!variableRadio.getSelection()) return;
setType(VARIABLE);
refresh();
} catch (Exception e) {
log.error(e.getMessage(), e);
throw new RuntimeException(e);
}
}
});
expressionRadio = new Button(typeButtons, SWT.RADIO);
expressionRadio.setText("expression");
expressionRadio.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
try {
if (!expressionRadio.getSelection()) return;
setType(EXPRESSION);
refresh();
} catch (Exception e) {
log.error(e.getMessage(), e);
throw new RuntimeException(e);
}
}
});
Label separator = new Label(composite, SWT.SEPARATOR | SWT.HORIZONTAL);
separator.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
blankPanel = new Composite(composite, SWT.NONE);
blankPanel.setLayoutData(new GridData(GridData.FILL_BOTH));
blankPanel.setLayout(new FillLayout());
refresh();
}
public Composite createTextPanel(Composite parent) {
log.debug("Creating text panel.");
Composite composite = new Composite(parent, SWT.NONE);
composite.setLayout(new GridLayout(2, false));
Label label = new Label(composite, SWT.NONE);
label.setText("Text:");
GridData gd = new GridData();
gd.widthHint = 80;
label.setLayoutData(gd);
textText = new Text(composite, SWT.BORDER | SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
gd = new GridData(GridData.FILL_BOTH);
gd.verticalSpan = 2;
textText.setLayoutData(gd);
textText.setText(text == null ? "" : text);
textText.addModifyListener(new ModifyListener() {
public void modifyText(ModifyEvent event) {
text = textText.getText().trim();
text = "".equals(text) ? null : text;
}
});
textText.setFocus();
return composite;
}
public Composite createBinaryPanel(Composite parent) {
log.debug("Creating binary panel.");
Composite composite = new Composite(parent, SWT.NONE);
composite.setLayout(new GridLayout(2, false));
Label label = new Label(composite, SWT.NONE);
label.setText("Binary:");
GridData gd = new GridData();
gd.widthHint = 80;
label.setLayoutData(gd);
binaryText = new Text(composite, SWT.BORDER | SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.READ_ONLY);
binaryText.setFont(font);
gd = new GridData(GridData.FILL_BOTH);
gd.verticalSpan = 2;
binaryText.setLayoutData(gd);
new Label(composite, SWT.NONE);
new Label(composite, SWT.NONE);
Composite actions = new Composite(composite, SWT.NONE);
actions.setLayout(new RowLayout());
actions.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
Hyperlink importData = new Hyperlink(actions, SWT.NONE);
importData.setText("Import");
importData.setUnderlined(true);
importData.addHyperlinkListener(new HyperlinkAdapter() {
public void linkActivated(HyperlinkEvent event) {
try {
FileDialog dialog = new FileDialog(getShell(), SWT.OPEN);
dialog.setText("Import Binary Data");
String filename = dialog.open();
if (filename == null) return;
File file = new File(filename);
binary = new byte[(int)file.length()];
FileInputStream out = new FileInputStream(file);
int length = out.read(binary);
if (length != file.length()) {
throw new Exception("Error reading file.");
}
out.close();
String s = getBinaryText();
binaryText.setText(s);
} catch (Exception e) {
log.error(e.getMessage(), e);
throw new RuntimeException(e);
}
}
});
Hyperlink exportData = new Hyperlink(actions, SWT.NONE);
exportData.setText("Export");
exportData.setUnderlined(true);
exportData.addHyperlinkListener(new HyperlinkAdapter() {
public void linkActivated(HyperlinkEvent event) {
try {
FileDialog dialog = new FileDialog(getShell(), SWT.SAVE);
dialog.setText("Export Binary Data");
String filename = dialog.open();
if (filename == null) return;
FileOutputStream out = new FileOutputStream(filename);
out.write(binary);
out.close();
} catch (Exception e) {
log.error(e.getMessage(), e);
throw new RuntimeException(e);
}
}
});
String s = getBinaryText();
binaryText.setText(s);
return composite;
}
public String getBinaryText() {
if (binary == null) return "";
StringBuilder sb = new StringBuilder();
int lines = binary.length / 16 + 1;
int pos = 0;
for (int i=0; i<lines && pos < binary.length; i++) {
String index = Integer.toHexString(pos);
for (int j=0; j<8-index.length(); j++) sb.append("0");
sb.append(index);
sb.append(": ");
StringBuilder text = new StringBuilder();
for (int j=0; j<16; j++) {
if (pos < binary.length) {
int b = binary[pos++] & 0xff;
String hex = Integer.toHexString(b).toUpperCase();
if (hex.length() == 1) sb.append("0");
sb.append(hex);
if (b >= '!' && b <= '~') {
text.append((char)b);
} else {
text.append(".");
}
} else {
sb.append(" ");
}
if (j % 2 == 1) sb.append(" ");
}
sb.append(text);
sb.append("\n");
}
return sb.toString();
}
public Composite createVariablePanel(Composite parent) {
log.debug("Creating variable panel.");
Composite composite = new Composite(parent, SWT.NONE);
composite.setLayout(new GridLayout(2, false));
Label label = new Label(composite, SWT.NONE);
label.setText("Variable:");
GridData gd = new GridData();
gd.widthHint = 80;
label.setLayoutData(gd);
variableCombo = new Combo(composite, SWT.BORDER);
variableCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
variableCombo.add("");
for (String variable : variables) variableCombo.add(variable);
variableCombo.setText(variable == null ? "" : variable);
variableCombo.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
variable = variableCombo.getText().trim();
variable = "".equals(variable) ? null : variable;
}
});
variableCombo.addModifyListener(new ModifyListener() {
public void modifyText(ModifyEvent event) {
variable = variableCombo.getText().trim();
variable = "".equals(variable) ? null : variable;
}
});
variableCombo.setFocus();
return composite;
}
public Composite createExpressionPanel(Composite parent) {
log.debug("Creating expression panel.");
Composite composite = new Composite(parent, SWT.NONE);
composite.setLayout(new GridLayout(2, false));
Label expressionLabel = new Label(composite, SWT.NONE);
expressionLabel.setText("Expression:");
GridData gd = new GridData();
gd.widthHint = 80;
expressionLabel.setLayoutData(gd);
scriptText = new Text(composite, SWT.BORDER | SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
gd = new GridData(GridData.FILL_BOTH);
gd.verticalSpan = 2;
scriptText.setLayoutData(gd);
String script = expression.getScript();
scriptText.setText(script == null ? "" : script);
scriptText.addModifyListener(new ModifyListener() {
public void modifyText(ModifyEvent event) {
String script = scriptText.getText().trim();
expression.setScript("".equals(script) ? null : script);
}
});
new Label(composite, SWT.NONE);
Label foreachLabel = new Label(composite, SWT.NONE);
foreachLabel.setText("Repeat for each:");
foreachLabel.setLayoutData(new GridData());
foreachCombo = new Combo(composite, SWT.BORDER);
foreachCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
foreachCombo.add("");
for (String variable : variables) foreachCombo.add(variable);
String foreach = expression.getForeach();
foreachCombo.setText(foreach == null ? "" : foreach);
foreachCombo.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
String foreach = foreachCombo.getText().trim();
expression.setForeach("".equals(foreach) ? null : foreach);
}
});
foreachCombo.addModifyListener(new ModifyListener() {
public void modifyText(ModifyEvent event) {
String foreach = foreachCombo.getText().trim();
expression.setForeach("".equals(foreach) ? null : foreach);
}
});
Label varLabel = new Label(composite, SWT.NONE);
varLabel.setText("Variable name:");
varLabel.setLayoutData(new GridData());
varText = new Text(composite, SWT.BORDER);
varText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
String var = expression.getVar();
varText.setText(var == null ? "" : var);
varText.addModifyListener(new ModifyListener() {
public void modifyText(ModifyEvent event) {
String var = varText.getText().trim();
expression.setVar("".equals(var) ? null : var);
}
});
scriptText.addKeyListener(new KeyListener() {
boolean ctrlPressed;
public void keyPressed(KeyEvent e) {
switch (e.keyCode) {
case SWT.CTRL:
ctrlPressed = true;
break;
case ' ':
if (ctrlPressed) {
e.doit = false;
}
}
}
public void keyReleased(KeyEvent e) {
switch (e.keyCode) {
case SWT.CTRL:
ctrlPressed = false;
break;
}
}
});
scriptText.setFocus();
return composite;
}
public void setCurrentPanel(Composite panel) {
if (currentPanel != null) currentPanel.dispose();
currentPanel = panel;
blankPanel.layout();
}
public void refresh() {
boolean isText = type == TEXT;
textRadio.setSelection(isText);
if (isText) {
setCurrentPanel(createTextPanel(blankPanel));
}
boolean isBinary = type == BINARY;
binaryRadio.setSelection(isBinary);
if (isBinary) {
setCurrentPanel(createBinaryPanel(blankPanel));
}
boolean isVariable = type == VARIABLE;
variableRadio.setSelection(isVariable);
if (isVariable) {
setCurrentPanel(createVariablePanel(blankPanel));
}
boolean isExpression = type == EXPRESSION;
expressionRadio.setSelection(isExpression);
if (isExpression) {
setCurrentPanel(createExpressionPanel(blankPanel));
}
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public Collection<String> getVariables() {
return variables;
}
public void setVariables(Collection<String> variables) {
if (this.variables == variables) return;
this.variables.clear();
if (variables == null) return;
this.variables.addAll(variables);
}
public Expression getExpression() {
return expression;
}
public void setExpression(Expression expression) {
this.expression.copy(expression);
}
public void setText(String text) {
this.text = text;
}
public String getText() {
return text;
}
public void setBinary(byte[] binary) {
this.binary = binary;
}
public byte[] getBinary() {
return binary;
}
public void setVariable(String variable) {
this.variable = variable;
}
public String getVariable() {
return variable;
}
void showHints() {
CodeAssist codeAssist = new CodeAssist(getShell(), scriptText);
codeAssist.open();
}
public interface NameChecker {
public String checkName(String name);
}
}