Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

VeLaObSource: code editor undo/redo; new "Check" button: check code and parameters before execution #443

Merged
merged 2 commits into from
Jul 16, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
300 changes: 191 additions & 109 deletions plugin/src/org/aavso/tools/vstar/external/plugin/VeLaObSource.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.HeadlessException;
import java.awt.LayoutManager;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
Expand All @@ -37,9 +39,12 @@
import java.util.Map;
import java.util.Optional;

import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.InputMap;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
Expand All @@ -49,6 +54,10 @@
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.event.UndoableEditEvent;
import javax.swing.event.UndoableEditListener;
import javax.swing.undo.CannotUndoException;
import javax.swing.undo.UndoManager;
import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
Expand Down Expand Up @@ -233,6 +242,21 @@ private String getStringWithNumber(String s, int i) {
return s;
}

private VeLaInterpreter createVeLaInterpreter(String veLaCode) throws ObservationReadError {
// Create a VeLa interpreter instance.
VeLaInterpreter vela = new VeLaInterpreter();

// Evaluate the VeLa model code.
vela.program(veLaCode);

// Has a model function been defined?
if (!vela.lookupFunctions(FUNC_NAME).isPresent()) {
throw new ObservationReadError("A function " + FUNC_NAME + "(T:REAL):REAL is not defined in the model");
}

return vela;
}

class VeLaModelObsRetriever extends AbstractObservationRetriever {

public VeLaModelObsRetriever() {
Expand All @@ -249,42 +273,15 @@ public void retrieveObservations() throws ObservationReadError {
}

private void retrieveVeLaModelObservations() throws ObservationReadError {

if (points < 2) {
throw new ObservationReadError("Number of points must be >1");
}

double step = (maxJD - minJD) / (points - 1);

if (step <= 0) {
throw new ObservationReadError("Maximum JD must be greater than Minimum JD");
}

if (jDflavour == JDflavour.UNKNOWN) {
throw new ObservationReadError("Undefined datetype");
}

if (veLaCode == null || "".equals(veLaCode.trim())) {
throw new ObservationReadError("VeLa model is not defined");
}


setJDflavour(jDflavour);

// Create a VeLa interpreter instance.
VeLaInterpreter vela = new VeLaInterpreter();

// Evaluate the VeLa model code.
// A univariate function f(t:real):real is
// assumed to exist after this completes.
vela.program(veLaCode);

// Has a model function been defined?
if (!vela.lookupFunctions(FUNC_NAME).isPresent()) {
throw new ObservationReadError("A function " + FUNC_NAME + "(T:REAL):REAL is not defined in the model");
}
VeLaInterpreter vela = createVeLaInterpreter(veLaCode);

Double magVal = null;

double step = (maxJD - minJD) / (points - 1);

for (int i = 0; i < points && !wasInterrupted(); i++) {

double time = minJD + i * step;
Expand Down Expand Up @@ -365,9 +362,99 @@ private class ParameterDialog extends AbstractOkCancelDialog {
private TextField objectNameField;
private JButton clearButton;
private JButton testButton;
private JButton checkButton;
private JButton loadButton;
private JButton saveButton;

private UndoManager undo;

/**
* Constructor
*/
public ParameterDialog() {
super("Function Code [model: f(t)]");

cancelListener = createCancelButtonListener();
getRootPane().registerKeyboardAction(cancelListener,
KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0),
JComponent.WHEN_IN_FOCUSED_WINDOW);

Container contentPane = this.getContentPane();

JPanel topPane = new JPanel();
topPane.setLayout((LayoutManager) new BoxLayout(topPane, BoxLayout.PAGE_AXIS));
topPane.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));

topPane.add(createControlPane());
topPane.add(createControlPane2());

topPane.add(createCodePane());
//topPane.add(createFileControlPane());

// OK, Cancel
topPane.add(createButtonPane());

contentPane.add(topPane);

addCodeAreaUndoManager();

this.pack();
//this.setResizable(false);
// Singleton mode! Use showDialog()!
//setLocationRelativeTo(Mediator.getUI().getContentPane());
//this.setVisible(true);

clearInput();
}

private void addCodeAreaUndoManager() {

int keyMask;
try {
keyMask = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
} catch (HeadlessException ex) {
return;
}

undo = new UndoManager();
javax.swing.text.Document doc = codeArea.getDocument();
doc.addUndoableEditListener(new UndoableEditListener() {
public void undoableEditHappened(UndoableEditEvent e) {
undo.addEdit(e.getEdit());
}
});

InputMap im = codeArea.getInputMap(JComponent.WHEN_FOCUSED);
ActionMap am = codeArea.getActionMap();

im.put(KeyStroke.getKeyStroke(KeyEvent.VK_Z, keyMask), "Undo");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_Y, keyMask), "Redo");

am.put("Undo", new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
if (undo.canUndo())
try {
undo.undo();
} catch (CannotUndoException ex) {
//ex.printStackTrace();
}
}
});

am.put("Redo", new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
if (undo.canRedo())
try {
undo.redo();
} catch (CannotUndoException ex) {
//ex.printStackTrace();
}
}
});
}

public boolean isAdditive() {
return addToCurrent.isSelected();
}
Expand Down Expand Up @@ -437,43 +524,6 @@ private String jDflavourToString(JDflavour jDflavour) {
}
}

/**
* Constructor
*/
public ParameterDialog() {
super("Function Code [model: f(t)]");

cancelListener = createCancelButtonListener();
getRootPane().registerKeyboardAction(cancelListener,
KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0),
JComponent.WHEN_IN_FOCUSED_WINDOW);

Container contentPane = this.getContentPane();

JPanel topPane = new JPanel();
topPane.setLayout((LayoutManager) new BoxLayout(topPane, BoxLayout.PAGE_AXIS));
topPane.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));

topPane.add(createControlPane());
topPane.add(createControlPane2());

topPane.add(createCodePane());
//topPane.add(createFileControlPane());

// OK, Cancel
topPane.add(createButtonPane());

contentPane.add(topPane);

this.pack();
//this.setResizable(false);
// Singleton mode! Use showDialog()!
//setLocationRelativeTo(Mediator.getUI().getContentPane());
//this.setVisible(true);

clearInput();
}

private JPanel createControlPane() {
JPanel panel = new JPanel(new FlowLayout());

Expand Down Expand Up @@ -550,6 +600,10 @@ private JPanel createFileControlPane() {
panel.add(testButton);
testButton.addActionListener(createTestButtonActionListener());

checkButton = new JButton("Check");
panel.add(checkButton);
checkButton.addActionListener(createCheckButtonActionListener());

loadButton = new JButton(LocaleProps.get("LOAD_BUTTON"));
panel.add(loadButton);
loadButton.addActionListener(createLoadButtonActionListener());
Expand Down Expand Up @@ -603,6 +657,15 @@ public void actionPerformed(ActionEvent arg0) {
};
}

ActionListener createCheckButtonActionListener() {
return new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
checkInput();
}
};
}

private ActionListener createLoadButtonActionListener() {
return new ActionListener() {
@Override
Expand Down Expand Up @@ -656,6 +719,65 @@ private void testInput() {
objectNameField.setValue("");
}

private boolean checkInput() {

Double minJDval = getMinJD();
Double maxJDval = getMaxJD();
Integer pointsval = getPoints();

if (minJDval == null) {
valueError(minJD);
return false;
}

if (maxJDval == null) {
valueError(maxJD);
return false;
}

if (pointsval == null) {
valueError(points);
return false;
}

if (pointsval < 2) {
MessageBox.showErrorDialog(this, getTitle(), "Number of points must be >1");
return false;
}

double step = (maxJDval - minJDval) / (pointsval - 1);
if (step <= 0) {
MessageBox.showErrorDialog(this, "Error", "Maximum JD must be greater than Minimum JD");
return false;
}

if ("".equals(getCode().trim())) {
MessageBox.showErrorDialog(this, getTitle(), "VeLa model must be defined.");
return false;
}

if (getJDflavour() == JDflavour.UNKNOWN) {
MessageBox.showErrorDialog(this, getTitle(), "Undefined DATE type");
return false;
}

String veLaCode = getCode();
if (veLaCode == null || "".equals(veLaCode.trim())) {
MessageBox.showErrorDialog(this, getTitle(), "VeLa model is not defined");
return false;
}

try {
createVeLaInterpreter(veLaCode);
} catch (Exception ex) {
MessageBox.showErrorDialog(this, getTitle(), ex.getLocalizedMessage());
return false;
}

return true;

}

private void readVelaXML() {
try {
Pair<byte[], String> content = Mediator.getInstance().getVelaXMLloadDialog().readFileAsBytes(ParameterDialog.this);
Expand Down Expand Up @@ -812,47 +934,7 @@ protected void cancelAction() {
*/
@Override
protected void okAction() {
boolean ok = true;

Double minJDval = getMinJD();
Double maxJDval = getMaxJD();
Integer pointsval = getPoints();

if (minJDval == null) {
valueError(minJD);
ok = false;
}

if (ok) {
if (maxJDval == null) {
valueError(maxJD);
ok = false;
}
}

if (ok) {
if (pointsval == null) {
valueError(points);
ok = false;
}
}

if (ok) {
double step = (maxJDval - minJDval) / pointsval;
if (step <= 0) {
MessageBox.showErrorDialog(this, "Error", "Maximum JD must be greater than Minimum JD");
ok = false;
}
}

if (ok) {
if ("".equals(getCode().trim())) {
MessageBox.showErrorDialog(this, getTitle(), "VeLa model must be defined.");
ok = false;
}
}

if (ok) {
if (checkInput()) {
cancelled = false;
setVisible(false);
dispose();
Expand Down
4 changes: 2 additions & 2 deletions src/org/aavso/tools/vstar/ui/resources/RevisionAccessor.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@

public class RevisionAccessor {

private static String REVISION = "340bf501";
private static String BUILD_TIME = "2024-04-11 22:06";
private static String REVISION = "708423d5";
private static String BUILD_TIME = "2024-07-12 12:44";

/**
* Get the latest git revision
Expand Down
Loading