java/src/jmri/jmrit/beantable/LRouteTableAction.java
package jmri.jmrit.beantable;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.beans.PropertyChangeListener;
import java.util.*;
import javax.annotation.Nonnull;
import javax.swing.*;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
import jmri.Conditional.Operator;
import jmri.*;
import jmri.implementation.DefaultConditionalAction;
import jmri.script.swing.ScriptFileChooser;
import jmri.util.FileUtil;
import jmri.util.JmriJFrame;
import jmri.util.swing.JmriJOptionPane;
/**
* Swing action to create and register groups of Logix Condtionals to perform a
* railroad control task.
*
* @author Pete Cressman Copyright (C) 2009
* @author Egbert Broerse i18n 2016
*
*/
public class LRouteTableAction extends AbstractTableAction<Logix> {
static final ResourceBundle rbx = ResourceBundle.getBundle("jmri.jmrit.beantable.LRouteTableBundle");
/**
* Create an action with a specific title.
* <p>
* Note that the argument is the Action title, not the title of the
* resulting frame. Perhaps this should be changed?
*
* @param s title of the action
*/
public LRouteTableAction(String s) {
super(s);
_logixManager = InstanceManager.getNullableDefault(jmri.LogixManager.class);
_conditionalManager = InstanceManager.getNullableDefault(jmri.ConditionalManager.class);
// disable ourself if there is no Logix manager or no Conditional manager available
if ((_logixManager == null) || (_conditionalManager == null)) {
setEnabled(false);
}
createModel();
}
public LRouteTableAction() {
this(Bundle.getMessage("TitleLRouteTable"));
}
/**
* Create the JTable DataModel, along with the changes for the specific case
* of Road Conditionals.
*/
@Override
protected void createModel() {
m = new LBeanTableDataModel();
}
class LBeanTableDataModel extends BeanTableDataModel<Logix> {
// overlay the value column with the enable column
// overlay the delete column with the edit column
static public final int ENABLECOL = VALUECOL;
static public final int EDITCOL = DELETECOL;
protected String enabledString = Bundle.getMessage("ColumnHeadEnabled");
/**
* Override to filter out the LRoutes from the rest of Logix.
*/
@Override
protected synchronized void updateNameList() {
// first, remove listeners from the individual objects
if (sysNameList != null) {
for (int i = 0; i < sysNameList.size(); i++) {
// if object has been deleted, it's not here; ignore it
NamedBean b = getBySystemName(sysNameList.get(i));
if (b != null) {
b.removePropertyChangeListener(this);
}
}
}
sysNameList = new ArrayList<>();
// and add them back in
getManager().getNamedBeanSet().forEach(b -> {
if (b.getSystemName().startsWith(getLogixSystemPrefix())) {
sysNameList.add(b.getSystemName());
b.addPropertyChangeListener(this);
}
});
log.debug("updateNameList: sysNameList size= {}", sysNameList.size());
}
@Override
public String getColumnName(int col) {
switch (col) {
case EDITCOL:
return ""; // no heading on "Edit"
case ENABLECOL:
return enabledString;
default:
return super.getColumnName(col);
}
}
@Override
public Class<?> getColumnClass(int col) {
switch (col) {
case EDITCOL:
return JButton.class;
case ENABLECOL:
return Boolean.class;
default:
return super.getColumnClass(col);
}
}
@Override
public int getPreferredWidth(int col) {
// override default value for SystemName and UserName columns
switch (col) {
case SYSNAMECOL:
return new JTextField(20).getPreferredSize().width;
case USERNAMECOL:
case COMMENTCOL:
return new JTextField(25).getPreferredSize().width;
case EDITCOL:
// not actually used due to the configDeleteColumn, setColumnToHoldButton, configureButton
return new JTextField(Bundle.getMessage("ButtonEdit")).getPreferredSize().width+4;
case ENABLECOL:
// not actually used due to the configValueColumn, setColumnToHoldButton, configureButton
return new JTextField(5).getPreferredSize().width;
default:
return super.getPreferredWidth(col);
}
}
@Override
public boolean isCellEditable(int row, int col) {
switch (col) {
case EDITCOL:
case ENABLECOL:
return true;
default:
return super.isCellEditable(row, col);
}
}
@Override
public Object getValueAt(int row, int col) {
switch (col) {
case EDITCOL:
return Bundle.getMessage("ButtonEdit");
case ENABLECOL:
return ((Logix) getValueAt(row, SYSNAMECOL)).getEnabled();
default:
return super.getValueAt(row, col);
}
}
@Override
public void setValueAt(Object value, int row, int col) {
switch (col) {
case EDITCOL:
// set up to edit
String sName = ((Logix) getValueAt(row, SYSNAMECOL)).getSystemName();
editPressed(sName);
break;
case ENABLECOL:
// alternate
Logix x = (Logix) getValueAt(row, SYSNAMECOL);
boolean v = x.getEnabled();
x.setEnabled(!v);
break;
default:
super.setValueAt(value, row, col);
break;
}
}
/**
* Delete the bean after all the checking has been done.
* <p>
* Deactivate the Logix and remove its conditionals.
*/
@Override
protected void doDelete(Logix logix) {
if (logix != null) {
logix.deActivateLogix();
// delete the Logix and all its Conditionals
_logixManager.deleteLogix(logix);
}
}
@Override
protected boolean matchPropertyName(java.beans.PropertyChangeEvent e) {
if (e.getPropertyName().equals(enabledString)) {
return true;
} else {
return super.matchPropertyName(e);
}
}
@Override
public Manager<Logix> getManager() {
return _logixManager;
}
@Override
public Logix getBySystemName(@Nonnull String name) {
return _logixManager.getBySystemName(name);
}
@Override
public Logix getByUserName(@Nonnull String name) {
return _logixManager.getByUserName(name);
}
/*public int getDisplayDeleteMsg() { return InstanceManager.getDefault(jmri.UserPreferencesManager.class).getMultipleChoiceOption(getClassName(),"delete"); }
public void setDisplayDeleteMsg(int boo) { InstanceManager.getDefault(jmri.UserPreferencesManager.class).setMultipleChoiceOption(getClassName(), "delete", boo); }*/
@Override
protected String getMasterClassName() {
return getClassName();
}
@Override
public void configureTable(JTable table) {
table.setDefaultRenderer(Boolean.class, new EnablingCheckboxRenderer());
table.setDefaultRenderer(JComboBox.class, new jmri.jmrit.symbolicprog.ValueRenderer());
table.setDefaultEditor(JComboBox.class, new jmri.jmrit.symbolicprog.ValueEditor());
super.configureTable(table);
}
// Not needed - here for interface compatibility
@Override
public void clickOn(Logix t) {
}
@Override
public String getValue(String s) {
return "";
}
// typical to get correct width
@Override
protected void configDeleteColumn(JTable table) {
// have the DELETECOL = EDITCOL column hold a button
setColumnToHoldButton(table, DELETECOL,
new JButton(Bundle.getMessage("ButtonEdit")));
}
@Override
protected void configValueColumn(JTable table) {
}
@Override
protected String getBeanType() {
return "LRoute";
}
}
@Override
protected void setTitle() {
f.setTitle(Bundle.getMessage("TitleLRouteTable"));
}
@Override
protected String helpTarget() {
return "package.jmri.jmrit.beantable.LRouteTable";
}
///////////////////////////////////// Edit window //////////////////////////////
ConditionalManager _conditionalManager = null;
LogixManager _logixManager = null;
JTextField _systemName = new JTextField(15);
JTextField _userName = new JTextField(25);
JmriJFrame _addFrame = null;
JTabbedPane _tabbedPane = null;
RouteInputModel _inputModel;
JScrollPane _inputScrollPane;
JComboBox<String> _testStateCombo;
JRadioButton _inputAllButton;
boolean _showAllInput;
RouteOutputModel _outputModel;
JScrollPane _outputScrollPane;
JComboBox<String> _setStateCombo;
JRadioButton _outputAllButton;
boolean _showAllOutput;
AlignmentModel _alignModel;
JComboBox<String> _alignCombo;
JRadioButton _alignAllButton;
boolean _showAllAlign;
JCheckBox _lockCheckBox;
boolean _lock = false;
JPanel _typePanel;
JRadioButton _newRouteButton;
boolean _newRouteType = true;
JRadioButton _initializeButton;
boolean _initialize = false;
JTextField soundFile = new JTextField(30);
JTextField scriptFile = new JTextField(30);
JButton cancelButton = new JButton(Bundle.getMessage("ButtonCancel"));
JButton createButton = new JButton(Bundle.getMessage("ButtonCreate"));
JButton deleteButton = new JButton(Bundle.getMessage("ButtonDelete"));
JButton updateButton = new JButton(Bundle.getMessage("ButtonUpdate"));
boolean routeDirty = false; // true to fire reminder to save work
private boolean checkEnabled = jmri.InstanceManager.getDefault(jmri.configurexml.ShutdownPreferences.class).isStoreCheckEnabled();
ArrayList<RouteInputElement> _inputList;
private HashMap<String, RouteInputElement> _inputMap;
private HashMap<String, RouteInputElement> _inputUserMap;
private ArrayList<RouteInputElement> _includedInputList;
ArrayList<RouteOutputElement> _outputList;
private HashMap<String, RouteOutputElement> _outputMap;
private HashMap<String, RouteOutputElement> _outputUserMap;
private ArrayList<RouteOutputElement> _includedOutputList;
ArrayList<AlignElement> _alignList;
private HashMap<String, AlignElement> _alignMap;
private HashMap<String, AlignElement> _alignUserMap;
private ArrayList<AlignElement> _includedAlignList;
void buildLists() {
TreeSet<RouteInputElement> inputTS = new TreeSet<>(new RouteElementComparator());
TreeSet<RouteOutputElement> outputTS = new TreeSet<>(new RouteElementComparator());
//TreeSet <RouteInputElement>inputTS = new TreeSet<RouteInputElement>();
//TreeSet <RouteOutputElement>outputTS = new TreeSet<RouteOutputElement>();
jmri.TurnoutManager tm = InstanceManager.turnoutManagerInstance();
tm.getNamedBeanSet().forEach((nb) -> {
String userName = nb.getUserName();
String systemName = nb.getSystemName();
inputTS.add(new RouteInputTurnout(systemName, userName));
outputTS.add(new RouteOutputTurnout(systemName, userName));
});
TreeSet<AlignElement> alignTS = new TreeSet<>(new RouteElementComparator());
jmri.SensorManager sm = InstanceManager.sensorManagerInstance();
sm.getNamedBeanSet().forEach((nb) -> {
String userName = nb.getUserName();
String systemName = nb.getSystemName();
inputTS.add(new RouteInputSensor(systemName, userName));
outputTS.add(new RouteOutputSensor(systemName, userName));
alignTS.add(new AlignElement(systemName, userName));
});
jmri.LightManager lm = InstanceManager.lightManagerInstance();
lm.getNamedBeanSet().forEach((nb) -> {
String userName = nb.getUserName();
String systemName = nb.getSystemName();
inputTS.add(new RouteInputLight(systemName, userName));
outputTS.add(new RouteOutputLight(systemName, userName));
});
jmri.SignalHeadManager shm = InstanceManager.getDefault(jmri.SignalHeadManager.class);
shm.getNamedBeanSet().forEach((nb) -> {
String userName = nb.getUserName();
String systemName = nb.getSystemName();
inputTS.add(new RouteInputSignal(systemName, userName));
outputTS.add(new RouteOutputSignal(systemName, userName));
});
_includedInputList = new ArrayList<>();
_includedOutputList = new ArrayList<>();
_inputList = new ArrayList<>(inputTS.size());
_outputList = new ArrayList<>(outputTS.size());
_inputMap = new HashMap<>(inputTS.size());
_outputMap = new HashMap<>(outputTS.size());
_inputUserMap = new HashMap<>();
_outputUserMap = new HashMap<>();
Iterator<RouteInputElement> it = inputTS.iterator();
while (it.hasNext()) {
RouteInputElement elt = it.next();
_inputList.add(elt);
String key = elt.getType() + elt.getSysName();
_inputMap.put(key, elt);
String user = elt.getUserName();
if (user != null) {
key = elt.getType() + user;
_inputUserMap.put(key, elt);
}
}
Iterator<RouteOutputElement> itOut = outputTS.iterator();
while (itOut.hasNext()) {
RouteOutputElement elt = itOut.next();
_outputList.add(elt);
String key = elt.getType() + elt.getSysName();
_outputMap.put(key, elt);
String user = elt.getUserName();
if (user != null) {
key = elt.getType() + user;
_outputUserMap.put(key, elt);
}
}
_includedAlignList = new ArrayList<>();
_alignList = new ArrayList<>(alignTS.size());
_alignMap = new HashMap<>(alignTS.size());
_alignUserMap = new HashMap<>();
Iterator<AlignElement> itAlign = alignTS.iterator();
while (itAlign.hasNext()) {
AlignElement elt = itAlign.next();
_alignList.add(elt);
String key = elt.getType() + elt.getSysName();
_alignMap.put(key, elt);
String user = elt.getUserName();
if (user != null) {
key = elt.getType() + user;
_alignUserMap.put(key, elt);
}
}
}
/**
* Edit button in Logix Route table pressed.
*
* @param sName system name of Logix to edit
*/
void editPressed(String sName) {
// Logix was found, initialize for edit
Logix logix = _logixManager.getBySystemName(sName);
if (logix == null) {
log.error("Logix \"{}\" not Found.", sName);
return;
}
// deactivate this Logix
_systemName.setText(sName);
// create the Edit Logix Window
// Use separate Runnable so window is created on top
Runnable t = () -> {
setupEdit(null);
_addFrame.setVisible(true);
};
javax.swing.SwingUtilities.invokeLater(t);
}
/**
* Interprets the conditionals from the Logix that was selected for editing
* and attempts to reconstruct the window entries.
*
* @param e the action event
*/
void setupEdit(ActionEvent e) {
makeEditWindow();
Logix logix = checkNamesOK();
if (logix == null) {
return;
}
logix.deActivateLogix();
// get information for this route
_systemName.setEnabled(false);
_userName.setEnabled(false);
_systemName.setText(logix.getSystemName());
_userName.setText(logix.getUserName());
String logixSysName = logix.getSystemName();
int numConditionals = logix.getNumConditionals();
log.debug("setupEdit: logixSysName= {}, numConditionals= {}", logixSysName, numConditionals);
for (int i = 0; i < numConditionals; i++) {
String cSysName = logix.getConditionalByNumberOrder(i);
switch (getRouteConditionalType(logixSysName, cSysName)) {
case 'T':
getControlsAndActions(cSysName);
break;
case 'A':
getAlignmentSensors(cSysName);
break;
case 'L':
getLockConditions(cSysName);
break;
default:
log.warn("Unexpected getRouteConditionalType {}", getRouteConditionalType(logixSysName, cSysName));
break;
}
}
// set up buttons and notes
deleteButton.setVisible(true);
cancelButton.setVisible(true);
updateButton.setVisible(true);
_typePanel.setVisible(false);
_initialize = getLogixInitializer().equals(logixSysName);
if (_initialize) {
_initializeButton.doClick();
} else {
_newRouteButton.doClick();
}
createButton.setVisible(false);
_addFrame.setTitle(rbx.getString("LRouteEditTitle"));
}
/**
* Get the type letter from the possible LRoute conditional.
*
* @param logixSysName logix system name
* @param cSysName conditional system name
* @return the type letter
*/
char getRouteConditionalType(String logixSysName, String cSysName) {
if (cSysName.startsWith(logixSysName)) {
char[] chNum = cSysName.substring(logixSysName.length()).toCharArray();
int i = 0;
while (Character.isDigit(chNum[i])) {
i++;
}
return chNum[i];
}
return 0;
}
/**
* Extract the Control (input) and Action (output) elements and their
* states.
*
* @param cSysName the conditional system name
*/
void getControlsAndActions(String cSysName) {
Conditional c = _conditionalManager.getBySystemName(cSysName);
if (c != null) {
List<ConditionalAction> actionList = c.getCopyOfActions();
boolean onChange = false;
for (int k = 0; k < actionList.size(); k++) {
ConditionalAction action = actionList.get(k);
int type;
switch (action.getType()) {
case SET_SENSOR:
type = SENSOR_TYPE;
break;
case SET_TURNOUT:
type = TURNOUT_TYPE;
break;
case SET_LIGHT:
type = LIGHT_TYPE;
break;
case SET_SIGNAL_APPEARANCE:
case SET_SIGNAL_HELD:
case CLEAR_SIGNAL_HELD:
case SET_SIGNAL_DARK:
case SET_SIGNAL_LIT:
type = SIGNAL_TYPE;
break;
case RUN_SCRIPT:
scriptFile.setText(action.getActionString());
continue;
case PLAY_SOUND:
soundFile.setText(action.getActionString());
continue;
default:
JmriJOptionPane.showMessageDialog(
_addFrame, java.text.MessageFormat.format(rbx.getString("TypeWarn"),
new Object[]{action.toString(), c.getSystemName()}),
rbx.getString("EditDiff"), JmriJOptionPane.WARNING_MESSAGE);
continue;
}
String name = action.getDeviceName();
String key = type + name;
RouteOutputElement elt = _outputUserMap.get(key);
if (elt == null) { // try in system name map
elt = _outputMap.get(key);
}
if (elt == null) {
JmriJOptionPane.showMessageDialog(
_addFrame, java.text.MessageFormat.format(rbx.getString("TypeWarn"),
new Object[]{action.toString(), c.getSystemName()}),
rbx.getString("EditDiff"), JmriJOptionPane.WARNING_MESSAGE);
} else {
elt.setIncluded(true);
elt.setState(action.getActionData());
boolean change = (action.getOption() == Conditional.ACTION_OPTION_ON_CHANGE);
if (k == 0) {
onChange = change;
} else if (change != onChange) {
JmriJOptionPane.showMessageDialog(
_addFrame, java.text.MessageFormat.format(rbx.getString("OnChangeWarn"),
new Object[]{action.toString(), c.getSystemName()}),
rbx.getString("EditDiff"), JmriJOptionPane.WARNING_MESSAGE);
}
}
}
List<ConditionalVariable> varList = c.getCopyOfStateVariables();
for (int k = 0; k < varList.size(); k++) {
ConditionalVariable variable = varList.get(k);
Conditional.Type testState = variable.getType();
//boolean negated = variable.isNegated();
int type;
switch (testState) {
case SENSOR_ACTIVE:
type = SENSOR_TYPE;
//if (negated) testState = Conditional.TYPE_SENSOR_INACTIVE;
break;
case SENSOR_INACTIVE:
type = SENSOR_TYPE;
//if (negated) testState = Conditional.TYPE_SENSOR_ACTIVE;
break;
case TURNOUT_CLOSED:
type = TURNOUT_TYPE;
//if (negated) testState = Conditional.TYPE_TURNOUT_THROWN;
break;
case TURNOUT_THROWN:
type = TURNOUT_TYPE;
//if (negated) testState = Conditional.TYPE_TURNOUT_CLOSED;
break;
case LIGHT_ON:
type = LIGHT_TYPE;
//if (negated) testState = Conditional.TYPE_LIGHT_OFF;
break;
case LIGHT_OFF:
type = LIGHT_TYPE;
//if (negated) testState = Conditional.TYPE_LIGHT_ON;
break;
case SIGNAL_HEAD_LIT:
case SIGNAL_HEAD_RED:
case SIGNAL_HEAD_YELLOW:
case SIGNAL_HEAD_GREEN:
case SIGNAL_HEAD_DARK:
case SIGNAL_HEAD_FLASHRED:
case SIGNAL_HEAD_FLASHYELLOW:
case SIGNAL_HEAD_FLASHGREEN:
case SIGNAL_HEAD_HELD:
type = SIGNAL_TYPE;
break;
default:
if (!getLogixInitializer().equals(variable.getName())) {
JmriJOptionPane.showMessageDialog(
_addFrame, java.text.MessageFormat.format(rbx.getString("TypeWarnVar"),
new Object[]{variable.toString(), c.getSystemName()}),
rbx.getString("EditDiff"), JmriJOptionPane.WARNING_MESSAGE);
}
continue;
}
int testStateInt = testState.getIntValue();
Operator opern = variable.getOpern();
if (k != 0 && (opern == Conditional.Operator.AND)) {
// guess this is a VETO
testStateInt += VETO;
} else if (onChange) {
testStateInt = Route.ONCHANGE;
}
String name = variable.getName();
String key = type + name;
RouteInputElement elt = _inputUserMap.get(key);
if (elt == null) { // try in system name map
elt = _inputMap.get(key);
}
if (elt == null) {
if (!getLogixInitializer().equals(name)) {
JmriJOptionPane.showMessageDialog(
_addFrame, java.text.MessageFormat.format(rbx.getString("TypeWarnVar"),
new Object[]{variable.toString(), c.getSystemName()}),
rbx.getString("EditDiff"), JmriJOptionPane.WARNING_MESSAGE);
}
} else {
elt.setIncluded(true);
elt.setState(testStateInt);
}
}
}
} // getControlsAndActions
/**
* Extract the Alignment Sensors and their types.
*
* @param cSysName the conditional system name
*/
void getAlignmentSensors(String cSysName) {
Conditional c = _conditionalManager.getBySystemName(cSysName);
if (c != null) {
AlignElement element = null;
List<ConditionalAction> actionList = c.getCopyOfActions();
for (int k = 0; k < actionList.size(); k++) {
ConditionalAction action = actionList.get(k);
if (action.getType() != Conditional.Action.SET_SENSOR) {
JmriJOptionPane.showMessageDialog(
_addFrame, java.text.MessageFormat.format(rbx.getString("AlignWarn1"),
new Object[]{action.toString(), c.getSystemName()}),
rbx.getString("EditDiff"), JmriJOptionPane.WARNING_MESSAGE);
} else {
String name = action.getDeviceName();
String key = SENSOR_TYPE + name;
element = _alignUserMap.get(key);
if (element == null) { // try in system name map
element = _alignMap.get(key);
}
if (element == null) {
JmriJOptionPane.showMessageDialog(
_addFrame, java.text.MessageFormat.format(rbx.getString("TypeWarn"),
new Object[]{action.toString(), c.getSystemName()}),
rbx.getString("EditDiff"), JmriJOptionPane.WARNING_MESSAGE);
} else if (!name.equals(action.getDeviceName())) {
JmriJOptionPane.showMessageDialog(
_addFrame, java.text.MessageFormat.format(rbx.getString("AlignWarn2"),
new Object[]{action.toString(), action.getDeviceName(), c.getSystemName()}),
rbx.getString("EditDiff"), JmriJOptionPane.WARNING_MESSAGE);
} else {
element.setIncluded(true);
}
}
}
// the action elements are identified in getControlsAndActions().
// Just identify the type of sensing
List<ConditionalVariable> varList = c.getCopyOfStateVariables();
int atype = 0;
for (int k = 0; k < varList.size(); k++) {
ConditionalVariable variable = varList.get(k);
Conditional.Type testState = variable.getType();
int type;
switch (testState) {
case SENSOR_ACTIVE:
case SENSOR_INACTIVE:
type = SENSOR_TYPE;
break;
case TURNOUT_CLOSED:
case TURNOUT_THROWN:
type = TURNOUT_TYPE;
break;
case LIGHT_ON:
case LIGHT_OFF:
type = LIGHT_TYPE;
break;
case SIGNAL_HEAD_LIT:
case SIGNAL_HEAD_RED:
case SIGNAL_HEAD_YELLOW:
case SIGNAL_HEAD_GREEN:
case SIGNAL_HEAD_DARK:
case SIGNAL_HEAD_FLASHRED:
case SIGNAL_HEAD_FLASHYELLOW:
case SIGNAL_HEAD_FLASHGREEN:
case SIGNAL_HEAD_HELD:
type = SIGNAL_TYPE;
break;
default:
if (!getLogixInitializer().equals(variable.getName())) {
JmriJOptionPane.showMessageDialog(
_addFrame, java.text.MessageFormat.format(rbx.getString("TypeWarnVar"),
new Object[]{variable.toString(), c.getSystemName()}),
rbx.getString("EditDiff"), JmriJOptionPane.WARNING_MESSAGE);
}
continue;
}
if (k == 0) {
atype = type;
} else if (atype != type) {
// more than one type. therefor, ALL
atype = ALL_TYPE;
break;
}
}
if (element != null) {
element.setState(atype);
}
}
}
/**
* Extract the Lock expression. For now, same as action control expression.
*
* @param cSysName the conditional system name
*/
void getLockConditions(String cSysName) {
Conditional c = _conditionalManager.getBySystemName(cSysName);
if (c != null) {
_lock = true;
// Verify conditional is what we think it is
ArrayList<RouteOutputElement> tList = makeTurnoutLockList();
List<ConditionalAction> actionList = c.getCopyOfActions();
if (actionList.size() != tList.size()) {
JmriJOptionPane.showMessageDialog(
_addFrame, java.text.MessageFormat.format(rbx.getString("LockWarn1"),
new Object[]{Integer.toString(tList.size()), c.getSystemName(),
Integer.toString(actionList.size())}),
rbx.getString("EditDiff"), JmriJOptionPane.WARNING_MESSAGE);
}
for (int k = 0; k < actionList.size(); k++) {
ConditionalAction action = actionList.get(k);
if (action.getType() != Conditional.Action.LOCK_TURNOUT) {
JmriJOptionPane.showMessageDialog(
_addFrame, java.text.MessageFormat.format(rbx.getString("LockWarn2"),
new Object[]{action.getDeviceName(), c.getSystemName()}),
rbx.getString("EditDiff"), JmriJOptionPane.WARNING_MESSAGE);
} else {
String name = action.getDeviceName();
boolean found = false;
ArrayList<RouteOutputElement> lockList = makeTurnoutLockList();
for (int j = 0; j < lockList.size(); j++) {
RouteOutputElement elt = lockList.get(j);
if (name.equals(elt.getUserName()) || name.equals(elt.getSysName())) {
found = true;
break;
}
}
if (!found) {
JmriJOptionPane.showMessageDialog(
_addFrame, java.text.MessageFormat.format(rbx.getString("LockWarn3"),
new Object[]{name, c.getSystemName()}),
rbx.getString("EditDiff"), JmriJOptionPane.WARNING_MESSAGE);
}
}
}
}
}
/**
* Responds to the Cancel button.
*
* @param e the action event
*/
void cancelPressed(ActionEvent e) {
if (_addFrame.getTitle().equals(rbx.getString("LRouteEditTitle"))) { // Warnings shown are useless when cancelling Add New LRoute
Logix logix = checkNamesOK();
if (logix != null) {
logix.activateLogix();
}
}
clearPage();
}
@Override
protected void addPressed(ActionEvent e) {
makeEditWindow();
_tabbedPane.setSelectedIndex(0);
createButton.setVisible(true);
cancelButton.setVisible(true);
_typePanel.setVisible(true);
_addFrame.setVisible(true);
_systemName.setEnabled(true);
_userName.setEnabled(true);
_addFrame.setTitle(rbx.getString("LRouteAddTitle"));
_addFrame.setEscapeKeyClosesWindow(true);
_addFrame.getRootPane().setDefaultButton(createButton);
}
/**
* Set up Create/Edit LRoute pane
*/
void makeEditWindow() {
buildLists();
if (_addFrame == null) {
_addFrame = new JmriJFrame(rbx.getString("LRouteAddTitle"), false, false);
_addFrame.addHelpMenu("package.jmri.jmrit.beantable.LRouteAddEdit", true);
_addFrame.setLocation(100, 30);
_tabbedPane = new JTabbedPane();
//////////////////////////////////// Tab 1 /////////////////////////////
JPanel tab1 = new JPanel();
tab1.setLayout(new BoxLayout(tab1, BoxLayout.Y_AXIS));
tab1.add(Box.createVerticalStrut(10));
// add system name
JPanel p = new JPanel();
p.setLayout(new FlowLayout());
p.add(new JLabel(Bundle.getMessage("LabelSystemName")));
p.add(_systemName);
_systemName.setToolTipText(rbx.getString("SystemNameHint"));
tab1.add(p);
// add user name
p = new JPanel();
p.setLayout(new FlowLayout());
p.add(new JLabel(Bundle.getMessage("LabelUserName")));
p.add(_userName);
_userName.setToolTipText(rbx.getString("UserNameHint"));
tab1.add(p);
JPanel pa = new JPanel();
p = new JPanel();
p.setLayout(new BoxLayout(p, BoxLayout.Y_AXIS));
p.add(new JLabel(rbx.getString("Guide1")));
p.add(new JLabel(rbx.getString("Guide2")));
p.add(new JLabel(rbx.getString("Guide3")));
p.add(new JLabel(rbx.getString("Guide4")));
pa.add(p);
tab1.add(pa);
_newRouteButton = new JRadioButton(rbx.getString("NewRoute"), true);
JRadioButton oldRoute = new JRadioButton(rbx.getString("OldRoute"), false);
_initializeButton = new JRadioButton(rbx.getString("Initialize"), false);
_newRouteButton.setToolTipText(rbx.getString("NewRouteHint"));
_newRouteButton.addActionListener((ActionEvent e) -> {
_newRouteType = true;
_systemName.setEnabled(true);
});
oldRoute.setToolTipText(rbx.getString("OldRouteHint"));
oldRoute.addActionListener((ActionEvent e) -> {
_newRouteType = false;
_systemName.setEnabled(true);
});
_initializeButton.setToolTipText(rbx.getString("InitializeHint"));
_initializeButton.addActionListener((ActionEvent e) -> {
_initialize = true;
_newRouteType = true;
_systemName.setEnabled(false);
_systemName.setText(getLogixInitializer());
});
_typePanel = makeShowButtons(_newRouteButton, oldRoute, _initializeButton, rbx.getString("LRouteType") + ":");
_typePanel.setBorder(BorderFactory.createEtchedBorder());
tab1.add(_typePanel);
tab1.add(Box.createVerticalGlue());
// add buttons
JPanel pb = new JPanel();
pb.setLayout(new FlowLayout());
// Cancel button
pb.add(cancelButton);
cancelButton.addActionListener(this::cancelPressed);
cancelButton.setToolTipText(Bundle.getMessage("TooltipCancelRoute"));
cancelButton.setName("CancelButton");
// Add Route button
pb.add(createButton);
createButton.addActionListener(this::createPressed);
createButton.setToolTipText(rbx.getString("CreateHint"));
createButton.setName("CreateButton");
// Delete Route button
pb.add(deleteButton);
deleteButton.addActionListener(this::deletePressed);
deleteButton.setToolTipText(rbx.getString("DeleteHint"));
// Update Route button
pb.add(updateButton);
updateButton.addActionListener((ActionEvent e) -> {
updatePressed();
});
updateButton.setToolTipText(rbx.getString("UpdateHint"));
updateButton.setName("UpdateButton");
// Show the initial buttons, and hide the others
cancelButton.setVisible(true);
updateButton.setVisible(false);
createButton.setVisible(false);
deleteButton.setVisible(false);
tab1.add(pb);
tab1.setVisible(true);
_tabbedPane.addTab(rbx.getString("BasicTab"), null, tab1, rbx.getString("BasicTabHint"));
//////////////////////////////////// Tab 2 /////////////////////////////
JPanel tab2 = new JPanel();
tab2.setLayout(new BoxLayout(tab2, BoxLayout.Y_AXIS));
tab2.add(new JLabel(rbx.getString("OutputTitle") + ":"));
_outputAllButton = new JRadioButton(Bundle.getMessage("All"), true);
JRadioButton includedOutputButton = new JRadioButton(Bundle.getMessage("Included"), false);
tab2.add(makeShowButtons(_outputAllButton, includedOutputButton, null, Bundle.getMessage("Show") + ":"));
_outputAllButton.addActionListener((ActionEvent e) -> {
// Setup for display of all Turnouts, if needed
if (!_showAllOutput) {
_showAllOutput = true;
_outputModel.fireTableDataChanged();
}
});
includedOutputButton.addActionListener((ActionEvent e) -> {
// Setup for display of included Turnouts only, if needed
if (_showAllOutput) {
_showAllOutput = false;
initializeIncludedOutputList();
_outputModel.fireTableDataChanged();
}
});
tab2.add(new JLabel(rbx.getString("PickOutput")));
_outputModel = new RouteOutputModel();
JTable routeOutputTable = new JTable(_outputModel);
_outputScrollPane = makeColumns(routeOutputTable, _setStateCombo, true);
tab2.add(_outputScrollPane, BorderLayout.CENTER);
tab2.setVisible(true);
_tabbedPane.addTab(rbx.getString("ActionTab"), null, tab2, rbx.getString("ActionTabHint"));
//////////////////////////////////// Tab 3 /////////////////////////////
JPanel tab3 = new JPanel();
tab3.setLayout(new BoxLayout(tab3, BoxLayout.Y_AXIS));
tab3.add(new JLabel(rbx.getString("InputTitle") + ":"));
_inputAllButton = new JRadioButton(Bundle.getMessage("All"), true);
JRadioButton includedInputButton = new JRadioButton(Bundle.getMessage("Included"), false);
tab3.add(makeShowButtons(_inputAllButton, includedInputButton, null, Bundle.getMessage("Show") + ":"));
_inputAllButton.addActionListener((ActionEvent e) -> {
// Setup for display of all Turnouts, if needed
if (!_showAllInput) {
_showAllInput = true;
_inputModel.fireTableDataChanged();
}
});
includedInputButton.addActionListener((ActionEvent e) -> {
// Setup for display of included Turnouts only, if needed
if (_showAllInput) {
_showAllInput = false;
initializeIncludedInputList();
_inputModel.fireTableDataChanged();
}
});
tab3.add(new JLabel(rbx.getString("PickInput")));
_inputModel = new RouteInputModel();
JTable routeInputTable = new JTable(_inputModel);
//ROW_HEIGHT = routeInputTable.getRowHeight();
_inputScrollPane = makeColumns(routeInputTable, _testStateCombo, true);
tab3.add(_inputScrollPane, BorderLayout.CENTER);
tab3.setVisible(true);
_tabbedPane.addTab(rbx.getString("TriggerTab"), null, tab3, rbx.getString("TriggerTabHint"));
////////////////////// Tab 4 /////////////////
JPanel tab4 = new JPanel();
tab4.setLayout(new BoxLayout(tab4, BoxLayout.Y_AXIS));
tab4.add(new JLabel(rbx.getString("MiscTitle") + ":"));
// Enter filenames for sound, script
JPanel p25 = new JPanel();
p25.setLayout(new FlowLayout());
p25.add(new JLabel(Bundle.getMessage("LabelPlaySound")));
JButton ss = new JButton("...");
ss.addActionListener((ActionEvent e) -> {
setSoundPressed();
});
p25.add(ss);
p25.add(soundFile);
tab4.add(p25);
p25 = new JPanel();
p25.setLayout(new FlowLayout());
p25.add(new JLabel(Bundle.getMessage("LabelRunScript")));
ss = new JButton("...");
ss.addActionListener((ActionEvent e) -> {
setScriptPressed();
});
p25.add(ss);
p25.add(scriptFile);
tab4.add(p25);
p25 = new JPanel();
p25.setLayout(new FlowLayout());
p25.add(new JLabel(rbx.getString("SetLocks") + ":"));
_lockCheckBox = new JCheckBox(rbx.getString("Lock"), true);
_lockCheckBox.addActionListener((ActionEvent e) -> {
// Setup for display of all Turnouts, if needed
_lock = _lockCheckBox.isSelected();
});
p25.add(_lockCheckBox);
tab4.add(p25);
_alignAllButton = new JRadioButton(Bundle.getMessage("All"), true);
JRadioButton includedAlignButton = new JRadioButton(Bundle.getMessage("Included"), false);
tab4.add(makeShowButtons(_alignAllButton, includedAlignButton, null, Bundle.getMessage("Show") + ":"));
_alignAllButton.addActionListener((ActionEvent e) -> {
// Setup for display of all Turnouts, if needed
if (!_showAllAlign) {
_showAllAlign = true;
_alignModel.fireTableDataChanged();
}
});
includedAlignButton.addActionListener((ActionEvent e) -> {
// Setup for display of included Turnouts only, if needed
if (_showAllAlign) {
_showAllAlign = false;
initializeIncludedAlignList();
_alignModel.fireTableDataChanged();
}
});
tab4.add(new JLabel(rbx.getString("PickAlign")));
_alignModel = new AlignmentModel();
JTable alignTable = new JTable(_alignModel);
_alignCombo = new JComboBox<>();
for (String state : ALIGNMENT_STATES) {
_alignCombo.addItem(state);
}
JScrollPane alignScrollPane = makeColumns(alignTable, _alignCombo, false);
//alignTable.setPreferredScrollableViewportSize(new java.awt.Dimension(250,200));
_alignCombo = new JComboBox<>();
for (String state : ALIGNMENT_STATES) {
_alignCombo.addItem(state);
}
tab4.add(alignScrollPane, BorderLayout.CENTER);
tab4.setVisible(true);
_tabbedPane.addTab(rbx.getString("MiscTab"), null, tab4, rbx.getString("MiscTabHint"));
Container contentPane = _addFrame.getContentPane();
//tabbedPane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
///////////////////////////////////
JPanel pt = new JPanel();
pt.add(_tabbedPane);
contentPane.add(pt);
// set listener for window closing
_addFrame.addWindowListener(new java.awt.event.WindowAdapter() {
@Override
public void windowClosing(java.awt.event.WindowEvent e) {
// remind to save, if Route was created or edited
if (routeDirty) {
showReminderMessage();
}
clearPage();
_addFrame.setVisible(false);
_inputModel.dispose();
_outputModel.dispose();
routeDirty = false;
}
});
_addFrame.pack();
_inputAllButton.doClick();
_outputAllButton.doClick();
_alignAllButton.doClick();
_newRouteButton.doClick();
if (_initialize) {
_initializeButton.doClick();
}
} else {
_addFrame.setVisible(true);
}
}
void showReminderMessage() {
if (checkEnabled) return;
InstanceManager.getDefault(jmri.UserPreferencesManager.class).
showInfoMessage(Bundle.getMessage("ReminderTitle"), Bundle.getMessage("ReminderSaveString", Bundle.getMessage("BeanNameLRoute")),
getClassName(),
"remindSaveRoute"); // NOI18N
}
/*
* Utility for addPressed
*/
JPanel makeShowButtons(JRadioButton allButton, JRadioButton includeButton,
JRadioButton extraButton, String msg) {
JPanel panel = new JPanel();
panel.add(new JLabel(msg));
panel.add(allButton);
panel.add(includeButton);
ButtonGroup selGroup = new ButtonGroup();
selGroup.add(allButton);
selGroup.add(includeButton);
if (extraButton != null) {
panel.add(extraButton);
selGroup.add(extraButton);
}
return panel;
}
/*
* Utility for addPressed
*/
JScrollPane makeColumns(JTable table, JComboBox<String> box, boolean specialBox) {
table.setRowSelectionAllowed(false);
//table.setPreferredScrollableViewportSize(new java.awt.Dimension(250,450));
TableColumnModel columnModel = table.getColumnModel();
TableColumn sNameColumnT = columnModel.getColumn(RouteElementModel.SNAME_COLUMN);
sNameColumnT.setResizable(true);
sNameColumnT.setMinWidth(75);
//sNameColumnT.setMaxWidth(110);
TableColumn uNameColumnT = columnModel.getColumn(RouteElementModel.UNAME_COLUMN);
uNameColumnT.setResizable(true);
uNameColumnT.setMinWidth(75);
//uNameColumnT.setMaxWidth(260);
TableColumn typeColumnT = columnModel.getColumn(RouteElementModel.TYPE_COLUMN);
typeColumnT.setResizable(true);
typeColumnT.setMinWidth(50);
//typeColumnT.setMaxWidth(110);
TableColumn includeColumnT = columnModel.getColumn(RouteElementModel.INCLUDE_COLUMN);
includeColumnT.setResizable(false);
includeColumnT.setMinWidth(30);
includeColumnT.setMaxWidth(60);
TableColumn stateColumnT = columnModel.getColumn(RouteElementModel.STATE_COLUMN);
if (specialBox) {
box = new JComboBox<>();
stateColumnT.setCellEditor(new ComboBoxCellEditor(box));
} else {
stateColumnT.setCellEditor(new DefaultCellEditor(box));
}
stateColumnT.setResizable(false);
stateColumnT.setMinWidth(75);
//stateColumnT.setMaxWidth(1310);
return new JScrollPane(table);
}
/**
* Initialize list of included input elements
*/
void initializeIncludedInputList() {
_includedInputList = new ArrayList<>();
for (int i = 0; i < _inputList.size(); i++) {
if (_inputList.get(i).isIncluded()) {
_includedInputList.add(_inputList.get(i));
}
}
}
/**
* Initialize list of included input elements
*/
void initializeIncludedOutputList() {
_includedOutputList = new ArrayList<>();
for (int i = 0; i < _outputList.size(); i++) {
if (_outputList.get(i).isIncluded()) {
_includedOutputList.add(_outputList.get(i));
}
}
}
/**
* Initialize list of included alignment sensors
*/
void initializeIncludedAlignList() {
_includedAlignList = new ArrayList<>();
for (int i = 0; i < _alignList.size(); i++) {
if (_alignList.get(i).isIncluded()) {
_includedAlignList.add(_alignList.get(i));
}
}
}
ArrayList<RouteOutputElement> makeTurnoutLockList() {
ArrayList<RouteOutputElement> list = new ArrayList<>();
for (int i = 0; i < _outputList.size(); i++) {
if (_outputList.get(i).isIncluded()) {
RouteOutputElement elt = _outputList.get(i);
if ((elt.getType() == TURNOUT_TYPE) && (elt.getState() != Route.TOGGLE)) {
list.add(elt);
}
}
}
return list;
}
void showMessage(String msg) {
JmriJOptionPane.showMessageDialog(
_addFrame, rbx.getString(msg), Bundle.getMessage("WarningTitle"),
JmriJOptionPane.WARNING_MESSAGE);
}
boolean checkNewNamesOK() {
// Get system name and user name
String sName = _systemName.getText();
if (sName.length() == 0 || sName.equals(getLogixSystemPrefix())) {
showMessage("EnterNames");
return false;
}
if (!sName.startsWith(getLogixSystemPrefix())) {
sName = getLogixSystemPrefix() + sName;
}
// check if a Route with this system name already exists
if (_logixManager.getBySystemName(sName) != null) {
// Route already exists
showMessage("DuplicateSys");
updateButton.setVisible(true);
return false;
}
String uName = _userName.getText();
// check if a Route with the same user name exists
if (!uName.isEmpty()) {
if (_logixManager.getByUserName(uName) != null) {
// Route with this user name already exists
showMessage("DuplicateUser");
updateButton.setVisible(true);
return false;
} else {
return true;
}
}
_systemName.setText(sName);
return true;
}
Logix checkNamesOK() {
// Get system name and user name
String sName = _systemName.getText();
if (sName.length() == 0) {
showMessage("EnterNames");
return null;
}
Logix logix = _logixManager.getBySystemName(sName);
if (!sName.startsWith(getLogixSystemPrefix())) {
sName = getLogixSystemPrefix() + sName;
}
if (logix != null) {
return logix;
}
String uName = _userName.getText();
if (uName.length() != 0) {
logix = _logixManager.getByUserName(uName);
if (logix != null) {
return logix;
}
}
logix = _logixManager.createNewLogix(sName, uName);
if (logix == null) {
// should never get here
log.error("Unknown failure to create Route with System Name: {}", sName);
}
return logix;
}
JFileChooser soundChooser = null;
/**
* Set the sound file
*/
void setSoundPressed() {
if (soundChooser == null) {
soundChooser = new jmri.util.swing.JmriJFileChooser(FileUtil.getUserFilesPath());
soundChooser.setFileFilter(new jmri.util.NoArchiveFileFilter());
}
soundChooser.rescanCurrentDirectory();
int retVal = soundChooser.showOpenDialog(null);
// handle selection or cancel
if (retVal == JFileChooser.APPROVE_OPTION) {
try {
soundFile.setText(FileUtil.getPortableFilename(soundChooser.getSelectedFile().getCanonicalPath()));
} catch (java.io.IOException e) {
log.error("exception setting sound file", e);
}
}
}
ScriptFileChooser scriptChooser = null;
/**
* Set the script file
*/
void setScriptPressed() {
if (scriptChooser == null) {
scriptChooser = new ScriptFileChooser();
}
scriptChooser.rescanCurrentDirectory();
int retVal = scriptChooser.showOpenDialog(null);
// handle selection or cancel
if (retVal == JFileChooser.APPROVE_OPTION) {
try {
scriptFile.setText(FileUtil.getPortableFilename(scriptChooser.getSelectedFile().getCanonicalPath()));
} catch (java.io.IOException e) {
log.error("exception setting script file", e);
}
}
}
/**
* Responds to the Add Route button.
*
* @param e the action event
*/
void createPressed(ActionEvent e) {
if (!checkNewNamesOK()) {
return;
}
updatePressed();
}
/**
* Responds to the Delete button.
*
* @param e the action event
*/
void deletePressed(ActionEvent e) {
Logix l = checkNamesOK();
if (l != null) {
l.deActivateLogix();
// delete the Logix and all its Conditionals
_logixManager.deleteLogix(l);
}
finishUpdate();
}
/**
* Update the Route Table.
*/
void updatePressed() {
Logix logix = checkNamesOK();
if (logix == null) {
log.error("No Logix found!");
return;
}
String sName = logix.getSystemName();
// Check if the User Name has been changed
String uName = _userName.getText();
logix.setUserName(uName);
initializeIncludedInputList();
initializeIncludedOutputList();
initializeIncludedAlignList();
if (log.isDebugEnabled()) {
log.debug("updatePressed: _includedInputList.size()= {}, _includedOutputList.size()= {}, _includedAlignList.size()= {}", _includedInputList.size(), _includedOutputList.size(), _includedAlignList.size());
}
////// Construct output actions for trigger conditionals ///////////
ArrayList<ConditionalAction> actionList = new ArrayList<>();
for (int i = 0; i < _includedOutputList.size(); i++) {
RouteOutputElement elt = _includedOutputList.get(i);
String name = elt.getUserName();
if (name == null || name.length() == 0) {
name = elt.getSysName();
}
int state = elt.getState(); // actionData
Conditional.Action actionType = Conditional.Action.NONE;
String params = "";
switch (elt.getType()) {
case SENSOR_TYPE:
actionType = Conditional.Action.SET_SENSOR;
break;
case TURNOUT_TYPE:
actionType = Conditional.Action.SET_TURNOUT;
break;
case LIGHT_TYPE:
actionType = Conditional.Action.SET_LIGHT;
break;
case SIGNAL_TYPE:
actionType = Conditional.Action.SET_SIGNAL_APPEARANCE;
if (state > OFFSET) {
actionType = Conditional.Action.getOperatorFromIntValue(state & ~OFFSET);
}
break;
default:
log.debug("updatePressed: Unknown action type {}", elt.getType());
}
actionList.add(new DefaultConditionalAction(Conditional.ACTION_OPTION_ON_CHANGE_TO_TRUE,
actionType, name, state, params));
}
String file = scriptFile.getText();
if (file.length() > 0) {
actionList.add(new DefaultConditionalAction(Conditional.ACTION_OPTION_ON_CHANGE_TO_TRUE,
Conditional.Action.RUN_SCRIPT, "", -1, file));
}
file = soundFile.getText();
if (file.length() > 0) {
actionList.add(new DefaultConditionalAction(Conditional.ACTION_OPTION_ON_CHANGE_TO_TRUE,
Conditional.Action.PLAY_SOUND, "", -1, file));
}
ArrayList<ConditionalAction> onChangeList = cloneActionList(actionList, Conditional.ACTION_OPTION_ON_CHANGE);
/////// Construct 'AND' clause from 'VETO' controls ////////
ArrayList<ConditionalVariable> vetoList = new ArrayList<>();
if (!_initialize) {
for (int i = 0; i < _includedInputList.size(); i++) {
RouteInputElement elt = _includedInputList.get(i);
String name = elt.getUserName();
if (name == null || name.length() == 0) {
name = elt.getSysName();
}
//int opern = newRouteType ? Conditional.OPERATOR_AND : Conditional.OPERATOR_OR;
Operator opern = Conditional.Operator.AND;
if (i == 0) {
opern = Conditional.Operator.NONE;
}
int state = elt.getState();
if (VETO < state) {
vetoList.add(new ConditionalVariable(true, opern,
Conditional.Type.getOperatorFromIntValue(state & ~VETO), name, _newRouteType));
}
}
}
///////////////// Make Trigger Conditional Controls /////////////////
ArrayList<ConditionalVariable> oneTriggerList = new ArrayList<>();
ArrayList<ConditionalVariable> twoTriggerList = new ArrayList<>();
if (!_initialize) {
for (int i = 0; i < _includedInputList.size(); i++) {
RouteInputElement elt = _includedInputList.get(i);
String name = elt.getUserName();
if (name == null || name.length() == 0) {
name = elt.getSysName();
}
Operator opern = _newRouteType ? Conditional.Operator.OR : Conditional.Operator.AND;
if (i == 0) {
opern = Conditional.Operator.NONE;
}
int type = elt.getState();
if (VETO > type) {
if (Route.ONCHANGE == type) {
switch (elt.getType()) {
case SENSOR_TYPE:
type = Conditional.TYPE_SENSOR_ACTIVE;
break;
case TURNOUT_TYPE:
type = Conditional.TYPE_TURNOUT_CLOSED;
break;
case LIGHT_TYPE:
type = Conditional.TYPE_LIGHT_ON;
break;
case SIGNAL_TYPE:
type = Conditional.TYPE_SIGNAL_HEAD_LIT;
break;
default:
log.debug("updatePressed: Unknown state variable type {}", elt.getType());
}
twoTriggerList.add(new ConditionalVariable(false, opern, Conditional.Type.getOperatorFromIntValue(type), name, true));
} else {
oneTriggerList.add(new ConditionalVariable(false, opern, Conditional.Type.getOperatorFromIntValue(type), name, true));
}
}
}
if (actionList.isEmpty()) {
JmriJOptionPane.showMessageDialog(
_addFrame, rbx.getString("noAction"),
rbx.getString("addErr"), JmriJOptionPane.ERROR_MESSAGE);
return;
}
} else {
oneTriggerList.add(new ConditionalVariable(false, Conditional.Operator.NONE,
Conditional.Type.NONE, getLogixInitializer(), true));
}
if (log.isDebugEnabled()) {
log.debug("actionList.size()= {}, oneTriggerList.size()= {}, twoTriggerList.size()= {}, onChangeList.size()= {}, vetoList.size()= {}", actionList.size(), oneTriggerList.size(), twoTriggerList.size(), onChangeList.size(), vetoList.size());
}
logix.deActivateLogix();
// remove old Conditionals for actions (ver 2.5.2 only -remove a bad idea)
char[] ch = sName.toCharArray();
int hash = 0;
for (int i = 0; i < ch.length; i++) {
hash += ch[i];
}
String cSystemName = getConditionalSystemPrefix() + "T" + hash;
removeConditionals(cSystemName, logix);
cSystemName = getConditionalSystemPrefix() + "F" + hash;
removeConditionals(cSystemName, logix);
cSystemName = getConditionalSystemPrefix() + "A" + hash;
removeConditionals(cSystemName, logix);
cSystemName = getConditionalSystemPrefix() + "L" + hash;
removeConditionals(cSystemName, logix);
int n = 0;
do {
n++;
cSystemName = sName + n + "A";
} while (removeConditionals(cSystemName, logix));
n = 0;
do {
n++;
cSystemName = sName + n + "T";
} while (removeConditionals(cSystemName, logix));
cSystemName = sName + "L";
removeConditionals(cSystemName, logix);
//String cUserName = null;
int numConds = 1;
if (_newRouteType) {
numConds = makeRouteConditional(numConds, /*false,*/ actionList, oneTriggerList,
vetoList, logix, sName, uName, "T");
if (!_initialize && twoTriggerList.size() > 0) {
numConds = makeRouteConditional(numConds, /*true, actionList,*/ onChangeList, twoTriggerList,
null, logix, sName, uName, "T");
}
} else {
for (int i = 0; i < oneTriggerList.size(); i++) {
ArrayList<ConditionalVariable> vList = new ArrayList<>();
vList.add(oneTriggerList.get(i));
numConds = makeRouteConditional(numConds, /*false,*/ actionList, vList,
vetoList, logix, sName, uName, "T");
}
for (int i = 0; i < twoTriggerList.size(); i++) {
ArrayList<ConditionalVariable> vList = new ArrayList<>();
vList.add(twoTriggerList.get(i));
numConds = makeRouteConditional(numConds, /*true, actionList,*/ onChangeList, vList,
vetoList, logix, sName, uName, "T");
}
}
if (numConds == 1) {
JmriJOptionPane.showMessageDialog(
_addFrame, rbx.getString("noVars"),
rbx.getString("addErr"), JmriJOptionPane.ERROR_MESSAGE);
return;
}
///////////////// Make Alignment Conditionals //////////////////////////
numConds = 1;
for (int i = 0; i < _includedAlignList.size(); i++) {
ArrayList<ConditionalVariable> vList = new ArrayList<>();
ArrayList<ConditionalAction> aList = new ArrayList<>();
AlignElement sensor = _includedAlignList.get(i);
String name = sensor.getUserName();
if (name == null || name.length() == 0) {
name = sensor.getSysName();
}
aList.add(new DefaultConditionalAction(Conditional.ACTION_OPTION_ON_CHANGE_TO_TRUE,
Conditional.Action.SET_SENSOR, name, Sensor.ACTIVE, ""));
aList.add(new DefaultConditionalAction(Conditional.ACTION_OPTION_ON_CHANGE_TO_FALSE,
Conditional.Action.SET_SENSOR, name, Sensor.INACTIVE, ""));
int alignType = sensor.getState();
for (int k = 0; k < _includedOutputList.size(); k++) {
RouteOutputElement elt = _includedOutputList.get(k);
Conditional.Type varType = Conditional.Type.NONE;
boolean add = (ALL_TYPE == alignType);
switch (elt.getType()) {
case SENSOR_TYPE:
if (alignType == SENSOR_TYPE) {
add = true;
}
switch (elt.getState()) {
case Sensor.INACTIVE:
varType = Conditional.Type.SENSOR_INACTIVE;
break;
case Sensor.ACTIVE:
varType = Conditional.Type.SENSOR_ACTIVE;
break;
case Route.TOGGLE:
add = false;
break;
default:
log.warn("Unexpected state {} from elt.getState() in SENSOR_TYPE", elt.getState());
break;
}
break;
case TURNOUT_TYPE:
if (alignType == TURNOUT_TYPE) {
add = true;
}
switch (elt.getState()) {
case Turnout.CLOSED:
varType = Conditional.Type.TURNOUT_CLOSED;
break;
case Turnout.THROWN:
varType = Conditional.Type.TURNOUT_THROWN;
break;
case Route.TOGGLE:
add = false;
break;
default:
log.warn("Unexpected state {} from elt.getState() in TURNOUT_TYPE", elt.getState());
break;
}
break;
case LIGHT_TYPE:
if (alignType == LIGHT_TYPE) {
add = true;
}
switch (elt.getState()) {
case Light.ON:
varType = Conditional.Type.LIGHT_ON;
break;
case Light.OFF:
varType = Conditional.Type.LIGHT_OFF;
break;
case Route.TOGGLE:
add = false;
break;
default:
log.warn("Unexpected state {} from elt.getState() in LIGHT_TYPE", elt.getState());
break;
}
break;
case SIGNAL_TYPE:
if (alignType == SIGNAL_TYPE) {
add = true;
}
switch (elt.getState()) {
case SET_SIGNAL_DARK:
case SignalHead.DARK:
varType = Conditional.Type.SIGNAL_HEAD_DARK;
break;
case SignalHead.RED:
varType = Conditional.Type.SIGNAL_HEAD_RED;
break;
case SignalHead.FLASHRED:
varType = Conditional.Type.SIGNAL_HEAD_FLASHRED;
break;
case SignalHead.YELLOW:
varType = Conditional.Type.SIGNAL_HEAD_YELLOW;
break;
case SignalHead.FLASHYELLOW:
varType = Conditional.Type.SIGNAL_HEAD_FLASHYELLOW;
break;
case SignalHead.GREEN:
varType = Conditional.Type.SIGNAL_HEAD_GREEN;
break;
case SignalHead.FLASHGREEN:
varType = Conditional.Type.SIGNAL_HEAD_FLASHGREEN;
break;
case SET_SIGNAL_HELD:
varType = Conditional.Type.SIGNAL_HEAD_HELD;
break;
case CLEAR_SIGNAL_HELD:
add = false; // don't know how to test for this
break;
case SET_SIGNAL_LIT:
varType = Conditional.Type.SIGNAL_HEAD_LIT;
break;
default:
log.warn("Unexpected state {} from elt.getState() in SIGNAL_TYPE", elt.getState());
break;
}
break;
default:
log.debug("updatePressed: Unknown Alignment state variable type {}", elt.getType());
}
if (add && !_initialize) {
String eltName = elt.getUserName();
if (eltName == null || eltName.length() == 0) {
eltName = elt.getSysName();
}
vList.add(new ConditionalVariable(false, Conditional.Operator.AND,
varType, eltName, true));
}
}
if (vList.size() > 0) {
numConds = makeAlignConditional(numConds, aList, vList, logix, sName, uName);
} else {
JmriJOptionPane.showMessageDialog(
_addFrame, java.text.MessageFormat.format(rbx.getString("NoAlign"),
new Object[]{name, sensor.getAlignType()}),
Bundle.getMessage("WarningTitle"), JmriJOptionPane.WARNING_MESSAGE);
}
}
///////////////// Make Lock Conditional //////////////////////////
if (_lock) {
ArrayList<ConditionalAction> aList = new ArrayList<>();
for (int k = 0; k < _includedOutputList.size(); k++) {
RouteOutputElement elt = _includedOutputList.get(k);
if (elt.getType() != TURNOUT_TYPE) {
continue;
}
if (elt.getState() == Route.TOGGLE) {
continue;
}
String eltName = elt.getUserName();
if (eltName == null || eltName.length() == 0) {
eltName = elt.getSysName();
}
aList.add(new DefaultConditionalAction(Conditional.ACTION_OPTION_ON_CHANGE_TO_TRUE,
Conditional.Action.LOCK_TURNOUT,
eltName, Turnout.LOCKED, ""));
aList.add(new DefaultConditionalAction(Conditional.ACTION_OPTION_ON_CHANGE_TO_FALSE,
Conditional.Action.LOCK_TURNOUT,
eltName, Turnout.UNLOCKED, ""));
}
makeRouteConditional(numConds, /*false,*/ aList, oneTriggerList,
vetoList, logix, sName, uName, "L");
}
log.debug("Conditionals added= {}", logix.getNumConditionals());
for (int i = 0; i < logix.getNumConditionals(); i++) {
log.debug("Conditional SysName= \"{}\"", logix.getConditionalByNumberOrder(i));
}
logix.activateLogix();
log.debug("Conditionals added= {}", logix.getNumConditionals());
for (int i = 0; i < logix.getNumConditionals(); i++) {
log.debug("Conditional SysName= \"{}\"", logix.getConditionalByNumberOrder(i));
}
finishUpdate();
} //updatePressed
boolean removeConditionals(String cSystemName, Logix logix) {
Conditional c = _conditionalManager.getBySystemName(cSystemName);
if (c != null) {
logix.deleteConditional(cSystemName);
return true;
}
return false;
}
/**
* Create a new Route conditional.
*
* @param numConds number of existing route conditionals
* @param actionList actions to take in conditional
* @param triggerList triggers for conditional to take actions
* @param vetoList controls that veto taking actions
* @param logix Logix to add the conditional to
* @param sName system name for conditional
* @param uName user name for conditional
* @param type type of conditional
* @return number of conditionals after the creation
* @throws IllegalArgumentException if "user input no good"
*/
int makeRouteConditional(int numConds, /*boolean onChange,*/ ArrayList<ConditionalAction> actionList,
ArrayList<ConditionalVariable> triggerList, ArrayList<ConditionalVariable> vetoList,
Logix logix, String sName, String uName, String type) {
if (log.isDebugEnabled()) {
log.debug("makeRouteConditional: numConds= {}, triggerList.size()= {}", numConds, triggerList.size());
}
if (triggerList.isEmpty() && (vetoList == null || vetoList.isEmpty())) {
return numConds;
}
StringBuilder antecedent = new StringBuilder();
ArrayList<ConditionalVariable> varList = new ArrayList<>();
int tSize = triggerList.size();
if (tSize > 0) {
if (tSize > 1) {
antecedent.append("(");
}
antecedent.append("R1"); // NOI18N
for (int i = 1; i < tSize; i++) {
antecedent.append(" ").append(Bundle.getMessage("LogicOR")).append(" R").append(i + 1); // NOI18N
}
if (tSize > 1) {
antecedent.append(")");
}
for (int i = 0; i < triggerList.size(); i++) {
//varList.add(cloneVariable(triggerList.get(i)));
varList.add(triggerList.get(i));
}
} else {
}
if (vetoList != null && vetoList.size() > 0) {
int vSize = vetoList.size();
if (tSize > 0) {
antecedent.append(" ").append(Bundle.getMessage("LogicAND")).append(" ");
}
if (vSize > 1) {
antecedent.append("(");
}
antecedent.append(Bundle.getMessage("LogicNOT")).append(" R").append(1 + tSize); // NOI18N
for (int i = 1; i < vSize; i++) {
antecedent.append(" ").append(Bundle.getMessage("LogicAND")).append(" ").append(Bundle.getMessage("LogicNOT")).append(" R").append(i + 1 + tSize); // NOI18N
}
if (vSize > 1) {
antecedent.append(")");
}
for (int i = 0; i < vetoList.size(); i++) {
//varList.add(cloneVariable(vetoList.get(i)));
varList.add(vetoList.get(i));
}
}
String cSystemName = sName + numConds + type;
String cUserName = CONDITIONAL_USER_PREFIX + numConds + "C " + uName;
Conditional c = null;
try {
c = _conditionalManager.createNewConditional(cSystemName, cUserName);
} catch (Exception ex) {
// user input no good
handleCreateException(sName);
// throw without creating any
throw new IllegalArgumentException("user input no good");
}
c.setStateVariables(varList);
//int option = onChange ? Conditional.ACTION_OPTION_ON_CHANGE : Conditional.ACTION_OPTION_ON_CHANGE_TO_TRUE;
//c.setAction(cloneActionList(actionList, option));
c.setAction(actionList);
Conditional.AntecedentOperator logicType =
_newRouteType
? Conditional.AntecedentOperator.MIXED
: Conditional.AntecedentOperator.ALL_AND;
c.setLogicType(logicType, antecedent.toString());
logix.addConditional(cSystemName, 0);
log.debug("Conditional added: SysName= \"{}\"", cSystemName);
c.calculate(true, null);
numConds++;
return numConds;
}
void handleCreateException(String sysName) {
JmriJOptionPane.showMessageDialog(_addFrame,
Bundle.getMessage("ErrorLRouteAddFailed", sysName) + "\n" + Bundle.getMessage("ErrorAddFailedCheck"),
Bundle.getMessage("ErrorTitle"),
JmriJOptionPane.ERROR_MESSAGE);
}
/**
* Create a new alignment conditional.
*
* @param numConds number of existing route conditionals
* @param actionList actions to take in conditional
* @param triggerList triggers for conditional to take actions
* @param logix Logix to add the conditional to
* @param sName system name for conditional
* @param uName user name for conditional
* @return number of conditionals after the creation
* @throws IllegalArgumentException if "user input no good"
*/
int makeAlignConditional(int numConds, ArrayList<ConditionalAction> actionList,
ArrayList<ConditionalVariable> triggerList,
Logix logix, String sName, String uName) {
if (triggerList.isEmpty()) {
return numConds;
}
String cSystemName = sName + numConds + "A";
String cUserName = CONDITIONAL_USER_PREFIX + numConds + "A " + uName;
Conditional c = null;
try {
c = _conditionalManager.createNewConditional(cSystemName, cUserName);
} catch (Exception ex) {
// user input no good
handleCreateException(sName);
// throw without creating any
throw new IllegalArgumentException("user input no good");
}
c.setStateVariables(triggerList);
//c.setAction(cloneActionList(actionList, Conditional.ACTION_OPTION_ON_CHANGE_TO_TRUE));
c.setAction(actionList);
c.setLogicType(Conditional.AntecedentOperator.ALL_AND, "");
logix.addConditional(cSystemName, 0);
log.debug("Conditional added: SysName= \"{}\"", cSystemName);
c.calculate(true, null);
numConds++;
return numConds;
}
ArrayList<ConditionalAction> cloneActionList(ArrayList<ConditionalAction> actionList, int option) {
ArrayList<ConditionalAction> list = new ArrayList<>();
for (int i = 0; i < actionList.size(); i++) {
ConditionalAction action = actionList.get(i);
ConditionalAction clone = new DefaultConditionalAction();
clone.setType(action.getType());
clone.setOption(option);
clone.setDeviceName(action.getDeviceName());
clone.setActionData(action.getActionData());
clone.setActionString(action.getActionString());
list.add(clone);
}
return list;
}
void finishUpdate() {
routeDirty = true;
clearPage();
}
void clearPage() {
// move to show all turnouts if not there
cancelIncludedOnly();
deleteButton.setVisible(false);
cancelButton.setVisible(false);
updateButton.setVisible(false);
createButton.setVisible(false);
_systemName.setText("");
_userName.setText("");
soundFile.setText("");
scriptFile.setText("");
for (int i = _inputList.size() - 1; i >= 0; i--) {
_inputList.get(i).setIncluded(false);
}
for (int i = _outputList.size() - 1; i >= 0; i--) {
_outputList.get(i).setIncluded(false);
}
for (int i = _alignList.size() - 1; i >= 0; i--) {
_alignList.get(i).setIncluded(false);
}
_lock = false;
_newRouteType = true;
_newRouteButton.doClick();
_lockCheckBox.setSelected(_lock);
if (routeDirty) {
showReminderMessage();
routeDirty = false;
}
_addFrame.setVisible(false);
}
/**
* Cancels included only option
*/
void cancelIncludedOnly() {
if (!_showAllInput) {
_inputAllButton.doClick();
}
if (!_showAllOutput) {
_outputAllButton.doClick();
}
if (!_showAllAlign) {
_alignAllButton.doClick();
}
}
private String[] getInputComboBoxItems(int type) {
switch (type) {
case SENSOR_TYPE:
return INPUT_SENSOR_STATES;
case TURNOUT_TYPE:
return INPUT_TURNOUT_STATES;
case LIGHT_TYPE:
return INPUT_LIGHT_STATES;
case SIGNAL_TYPE:
return INPUT_SIGNAL_STATES;
default:
log.warn("Unhandled object type: {}", type);
break;
}
return new String[]{};
}
private String[] getOutputComboBoxItems(int type) {
switch (type) {
case SENSOR_TYPE:
return OUTPUT_SENSOR_STATES;
case TURNOUT_TYPE:
return OUTPUT_TURNOUT_STATES;
case LIGHT_TYPE:
return OUTPUT_LIGHT_STATES;
case SIGNAL_TYPE:
return OUTPUT_SIGNAL_STATES;
default:
log.warn("Unhandled type: {}", type);
}
return new String[]{};
}
////////////////////////////// Internal Utility Classes ////////////////////////////////
public class ComboBoxCellEditor extends DefaultCellEditor {
ComboBoxCellEditor() {
super(new JComboBox<String>());
}
ComboBoxCellEditor(JComboBox<String> comboBox) {
super(comboBox);
}
@SuppressWarnings("unchecked") // getComponent call requires an unchecked cast
@Override
public Component getTableCellEditorComponent(JTable table, Object value,
boolean isSelected, int row, int column) {
//RouteElementModel model = (RouteElementModel)((jmri.util.com.sun.TableSorter)table.getModel()).getTableModel();
RouteElementModel model = (RouteElementModel) table.getModel();
//ArrayList <RouteElement> elementList = null;
//int type = 0;
RouteElement elt;
String[] items;
if (model.isInput()) {
if (_showAllInput) {
elt = _inputList.get(row);
} else {
elt = _includedInputList.get(row);
}
items = getInputComboBoxItems(elt.getType());
} else {
if (_showAllOutput) {
elt = _outputList.get(row);
} else {
elt = _includedOutputList.get(row);
}
items = getOutputComboBoxItems(elt.getType());
}
JComboBox<String> comboBox = (JComboBox<String>) getComponent();
comboBox.removeAllItems();
for (String item : items) {
comboBox.addItem(item);
}
return super.getTableCellEditorComponent(table, value, isSelected, row, column);
}
}
/**
* Base Table model for selecting Route elements
*/
public abstract class RouteElementModel extends AbstractTableModel implements PropertyChangeListener {
abstract public boolean isInput();
@Override
public Class<?> getColumnClass(int c) {
if (c == INCLUDE_COLUMN) {
return Boolean.class;
} else {
return String.class;
}
}
@Override
public int getColumnCount() {
return 5;
}
@Override
public String getColumnName(int c) {
switch (c) {
case SNAME_COLUMN:
return Bundle.getMessage("ColumnSystemName");
case UNAME_COLUMN:
return Bundle.getMessage("ColumnUserName");
case TYPE_COLUMN:
return rbx.getString("Type");
case INCLUDE_COLUMN:
return Bundle.getMessage("Include");
default:
log.warn("Unhandled column type: {}", c);
break;
}
return "";
}
@Override
public boolean isCellEditable(int r, int c) {
return ((c == INCLUDE_COLUMN) || (c == STATE_COLUMN));
}
@Override
public void propertyChange(java.beans.PropertyChangeEvent e) {
if (e.getPropertyName().equals("length")) {
// a new NamedBean is available in the manager
fireTableDataChanged();
}
}
public void dispose() {
InstanceManager.turnoutManagerInstance().removePropertyChangeListener(this);
}
public static final int SNAME_COLUMN = 0;
public static final int UNAME_COLUMN = 1;
public static final int TYPE_COLUMN = 2;
public static final int INCLUDE_COLUMN = 3;
public static final int STATE_COLUMN = 4;
}
/**
* Table model for selecting input variables
*/
class RouteInputModel extends RouteElementModel {
@Override
public boolean isInput() {
return true;
}
@Override
public String getColumnName(int c) {
if (c == STATE_COLUMN) {
return rbx.getString("SetTrigger");
}
return super.getColumnName(c);
}
@Override
public int getRowCount() {
if (_showAllInput) {
return _inputList.size();
} else {
return _includedInputList.size();
}
}
@Override
public Object getValueAt(int r, int c) {
ArrayList<RouteInputElement> inputList;
if (_showAllInput) {
inputList = _inputList;
} else {
inputList = _includedInputList;
}
// some error checking
if (r >= inputList.size()) {
log.debug("row out of range");
return null;
}
switch (c) {
case SNAME_COLUMN:
return inputList.get(r).getSysName();
case UNAME_COLUMN:
return inputList.get(r).getUserName();
case TYPE_COLUMN:
return inputList.get(r).getTypeString();
case INCLUDE_COLUMN:
return inputList.get(r).isIncluded();
case STATE_COLUMN:
return inputList.get(r).getTestState();
default:
return null;
}
}
@Override
public void setValueAt(Object type, int r, int c) {
ArrayList<RouteInputElement> inputList;
if (_showAllInput) {
inputList = _inputList;
} else {
inputList = _includedInputList;
}
switch (c) {
case INCLUDE_COLUMN:
inputList.get(r).setIncluded(((Boolean) type));
break;
case STATE_COLUMN:
inputList.get(r).setTestState((String) type);
break;
default:
log.warn("Unexpected column {} in setValueAt", c);
break;
}
}
}
/**
* Table model for selecting output variables
*/
class RouteOutputModel extends RouteElementModel {
@Override
public boolean isInput() {
return false;
}
@Override
public String getColumnName(int c) {
if (c == STATE_COLUMN) {
return rbx.getString("SetAction");
}
return super.getColumnName(c);
}
@Override
public int getRowCount() {
if (_showAllOutput) {
return _outputList.size();
} else {
return _includedOutputList.size();
}
}
@Override
public Object getValueAt(int r, int c) {
ArrayList<RouteOutputElement> outputList;
if (_showAllOutput) {
outputList = _outputList;
} else {
outputList = _includedOutputList;
}
// some error checking
if (r >= outputList.size()) {
log.debug("row out of range");
return null;
}
switch (c) {
case SNAME_COLUMN: // slot number
return outputList.get(r).getSysName();
case UNAME_COLUMN: //
return outputList.get(r).getUserName();
case INCLUDE_COLUMN:
return outputList.get(r).isIncluded();
case TYPE_COLUMN:
return outputList.get(r).getTypeString();
case STATE_COLUMN: //
return outputList.get(r).getSetToState();
default:
return null;
}
}
@Override
public void setValueAt(Object type, int r, int c) {
ArrayList<RouteOutputElement> outputList;
if (_showAllOutput) {
outputList = _outputList;
} else {
outputList = _includedOutputList;
}
switch (c) {
case INCLUDE_COLUMN:
outputList.get(r).setIncluded(((Boolean) type));
break;
case STATE_COLUMN:
outputList.get(r).setSetToState((String) type);
break;
default:
log.warn("Unexpected column {} in setValueAt", c);
break;
}
}
}
/**
* Table model for selecting output variables
*/
class AlignmentModel extends RouteElementModel {
@Override
public boolean isInput() {
return false;
}
@Override
public String getColumnName(int c) {
if (c == STATE_COLUMN) {
return rbx.getString("Alignment");
}
return super.getColumnName(c);
}
@Override
public int getRowCount() {
if (_showAllAlign) {
return _alignList.size();
} else {
return _includedAlignList.size();
}
}
@Override
public Object getValueAt(int r, int c) {
ArrayList<AlignElement> alignList;
if (_showAllAlign) {
alignList = _alignList;
} else {
alignList = _includedAlignList;
}
// some error checking
if (r >= alignList.size()) {
log.debug("row out of range");
return null;
}
switch (c) {
case SNAME_COLUMN: // slot number
return alignList.get(r).getSysName();
case UNAME_COLUMN: //
return alignList.get(r).getUserName();
case INCLUDE_COLUMN:
return alignList.get(r).isIncluded();
case TYPE_COLUMN:
return Bundle.getMessage("BeanNameSensor");
case STATE_COLUMN: //
return alignList.get(r).getAlignType();
default:
return null;
}
}
@Override
public void setValueAt(Object type, int r, int c) {
ArrayList<AlignElement> alignList;
if (_showAllAlign) {
alignList = _alignList;
} else {
alignList = _includedAlignList;
}
switch (c) {
case INCLUDE_COLUMN:
alignList.get(r).setIncluded(((Boolean) type));
break;
case STATE_COLUMN:
alignList.get(r).setAlignType((String) type);
break;
default:
log.warn("Unexpected column {} in setValueAt", c);
break;
}
}
}
public final static String CONDITIONAL_USER_PREFIX = "Route ";
public final static int SENSOR_TYPE = 1;
public final static int TURNOUT_TYPE = 2;
public final static int LIGHT_TYPE = 3;
public final static int SIGNAL_TYPE = 4;
public final static int CONDITIONAL_TYPE = 5;
public final static int ALL_TYPE = 6;
// Should not conflict with state variable types
public final static int VETO = 0x80;
// due to the unecessary bit assignments in SignalHead for appearances,
// offset the following
public static final int OFFSET = 0x30;
public static final int SET_SIGNAL_HELD = Conditional.ACTION_SET_SIGNAL_HELD + OFFSET;
public static final int CLEAR_SIGNAL_HELD = Conditional.ACTION_CLEAR_SIGNAL_HELD + OFFSET;
public static final int SET_SIGNAL_DARK = Conditional.ACTION_SET_SIGNAL_DARK + OFFSET;
public static final int SET_SIGNAL_LIT = Conditional.ACTION_SET_SIGNAL_LIT + OFFSET;
//private static int ROW_HEIGHT;
private static final String ALIGN_SENSOR = rbx.getString("AlignSensor");
private static final String ALIGN_TURNOUT = rbx.getString("AlignTurnout");
private static final String ALIGN_LIGHT = rbx.getString("AlignLight");
private static final String ALIGN_SIGNAL = rbx.getString("AlignSignal");
private static final String ALIGN_ALL = rbx.getString("AlignAll");
private static final String ON_CHANGE = Bundle.getMessage("OnConditionChange"); //rbx.getString("xOnChange");
private static final String ON_ACTIVE = Bundle.getMessage("OnCondition") + " " + Bundle.getMessage("SensorStateActive"); //rbx.getString("xOnActive");
private static final String ON_INACTIVE = Bundle.getMessage("OnCondition") + " " + Bundle.getMessage("SensorStateInactive"); //rbx.getString("xOnInactive");
private static final String VETO_ON_ACTIVE = "Veto " + Bundle.getMessage("WhenCondition") + " " + Bundle.getMessage("SensorStateActive"); //rbx.getString("xVetoActive");
private static final String VETO_ON_INACTIVE = "Veto " + Bundle.getMessage("WhenCondition") + " " + Bundle.getMessage("SensorStateInactive"); //rbx.getString("xVetoInactive");
private static final String ON_THROWN = Bundle.getMessage("OnCondition") + " " + Bundle.getMessage("TurnoutStateThrown"); //rbx.getString("xOnThrown");
private static final String ON_CLOSED = Bundle.getMessage("OnCondition") + " " + Bundle.getMessage("TurnoutStateClosed"); //rbx.getString("xOnClosed");
private static final String VETO_ON_THROWN = "Veto " + Bundle.getMessage("WhenCondition") + " " + Bundle.getMessage("TurnoutStateThrown"); //rbx.getString("xVetoThrown");
private static final String VETO_ON_CLOSED = "Veto " + Bundle.getMessage("WhenCondition") + " " + Bundle.getMessage("TurnoutStateClosed"); //rbx.getString("xVetoClosed");
private static final String ON_LIT = Bundle.getMessage("OnCondition") + " " + Bundle.getMessage("ColumnHeadLit"); //rbx.getString("xOnLit");
private static final String ON_UNLIT = rbx.getString("OnUnLit");
private static final String VETO_ON_LIT = "Veto " + Bundle.getMessage("WhenCondition") + " " + Bundle.getMessage("ColumnHeadLit"); //rbx.getString("xVetoLit");
private static final String VETO_ON_UNLIT = rbx.getString("VetoUnLit");
private static final String ON_RED = Bundle.getMessage("OnCondition") + " " + Bundle.getMessage("SignalHeadStateRed"); //rbx.getString("xOnRed");
private static final String ON_FLASHRED = Bundle.getMessage("OnCondition") + " " + Bundle.getMessage("SignalHeadStateFlashingRed"); //rbx.getString("xOnFlashRed");
private static final String ON_YELLOW = Bundle.getMessage("OnCondition") + " " + Bundle.getMessage("SignalHeadStateYellow"); //rbx.getString("xOnYellow");
private static final String ON_FLASHYELLOW = Bundle.getMessage("OnCondition") + " " + Bundle.getMessage("SignalHeadStateFlashingYellow"); //rbx.getString("xOnFlashYellow");
private static final String ON_GREEN = Bundle.getMessage("OnCondition") + " " + Bundle.getMessage("SignalHeadStateGreen"); //rbx.getString("xOnGreen");
private static final String ON_FLASHGREEN = Bundle.getMessage("OnCondition") + " " + Bundle.getMessage("SignalHeadStateFlashingGreen"); //rbx.getString("xOnFlashGreen");
private static final String ON_DARK = Bundle.getMessage("OnCondition") + " " + Bundle.getMessage("SignalHeadStateDark"); //rbx.getString("xOnDark");
private static final String ON_SIGNAL_LIT = Bundle.getMessage("OnCondition") + " " + Bundle.getMessage("ColumnHeadLit"); //rbx.getString("xOnLit");
private static final String ON_SIGNAL_HELD = Bundle.getMessage("OnCondition") + " " + Bundle.getMessage("SignalHeadStateHeld"); //rbx.getString("xOnHeld");
private static final String VETO_ON_RED = "Veto " + Bundle.getMessage("WhenCondition") + " " + Bundle.getMessage("SignalHeadStateRed"); //rbx.getString("xVetoOnRed");
private static final String VETO_ON_FLASHRED = "Veto " + Bundle.getMessage("WhenCondition") + " " + Bundle.getMessage("SignalHeadStateFlashingRed"); //rbx.getString("xVetoOnFlashRed");
private static final String VETO_ON_YELLOW = "Veto " + Bundle.getMessage("WhenCondition") + " " + Bundle.getMessage("SignalHeadStateYellow"); //rbx.getString("xVetoOnYellow");
private static final String VETO_ON_FLASHYELLOW = "Veto " + Bundle.getMessage("WhenCondition") + " " + Bundle.getMessage("SignalHeadStateFlashingYellow"); //rbx.getString("xVetoOnFlashYellow");
private static final String VETO_ON_GREEN = "Veto " + Bundle.getMessage("WhenCondition") + " " + Bundle.getMessage("SignalHeadStateGreen"); //rbx.getString("xVetoOnGreen");
private static final String VETO_ON_FLASHGREEN = "Veto " + Bundle.getMessage("WhenCondition") + " " + Bundle.getMessage("SignalHeadStateFlashingGreen"); //rbx.getString("xVetoOnFlashGreen");
private static final String VETO_ON_DARK = "Veto " + Bundle.getMessage("WhenCondition") + " " + Bundle.getMessage("SignalHeadStateDark"); //rbx.getString("xVetoOnDark");
private static final String VETO_ON_SIGNAL_LIT = "Veto " + Bundle.getMessage("WhenCondition") + " " + Bundle.getMessage("ColumnHeadLit"); //rbx.getString("xVetoOnLit");
private static final String VETO_ON_SIGNAL_HELD = "Veto " + Bundle.getMessage("WhenCondition") + " " + Bundle.getMessage("SignalHeadStateHeld"); //rbx.getString("xVetoOnHeld");
private static final String SET_TO_ACTIVE = Bundle.getMessage("SetBeanState", Bundle.getMessage("BeanNameSensor"), Bundle.getMessage("SensorStateActive")); // rbx.getString("xSetActive");
private static final String SET_TO_INACTIVE = Bundle.getMessage("SetBeanState", Bundle.getMessage("BeanNameSensor"), Bundle.getMessage("SensorStateInactive")); // rbx.getString("xSetInactive");
private static final String SET_TO_CLOSED = Bundle.getMessage("SetBeanState", Bundle.getMessage("BeanNameTurnout"), Bundle.getMessage("TurnoutStateClosed")); //rbx.getString("xSetClosed");
private static final String SET_TO_THROWN = Bundle.getMessage("SetBeanState", Bundle.getMessage("BeanNameTurnout"), Bundle.getMessage("TurnoutStateThrown")); //rbx.getString("xSetThrown");
private static final String SET_TO_TOGGLE = Bundle.getMessage("SetBeanState", "", Bundle.getMessage("Toggle"));
private static final String SET_TO_ON = Bundle.getMessage("SetBeanState", Bundle.getMessage("BeanNameLight"), Bundle.getMessage("StateOn")); //rbx.getString("xSetLightOn");
private static final String SET_TO_OFF = Bundle.getMessage("SetBeanState", Bundle.getMessage("BeanNameLight"), Bundle.getMessage("StateOff")); //rbx.getString("xSetLightOff");
private static final String SET_TO_DARK = Bundle.getMessage("SetBeanState", Bundle.getMessage("BeanNameSignalHead"), Bundle.getMessage("SignalHeadStateDark")); //rbx.getString("xSetDark");
private static final String SET_TO_LIT = Bundle.getMessage("SetBeanState", Bundle.getMessage("BeanNameSignalHead"), Bundle.getMessage("ColumnHeadLit")); //rbx.getString("xSetLit");
private static final String SET_TO_HELD = Bundle.getMessage("SetBeanState", Bundle.getMessage("BeanNameSignalHead"), Bundle.getMessage("SignalHeadStateHeld")); //rbx.getString("xSetHeld");
private static final String SET_TO_CLEAR = rbx.getString("SetClear");
private static final String SET_TO_RED = Bundle.getMessage("SetBeanState", Bundle.getMessage("BeanNameSignalHead"), Bundle.getMessage("SignalHeadStateRed")); //rbx.getString("xSetRed");
private static final String SET_TO_FLASHRED = Bundle.getMessage("SetBeanState", Bundle.getMessage("BeanNameSignalHead"), Bundle.getMessage("SignalHeadStateFlashingRed")); //rbx.getString("xSetFlashRed");
private static final String SET_TO_YELLOW = Bundle.getMessage("SetBeanState", Bundle.getMessage("BeanNameSignalHead"), Bundle.getMessage("SignalHeadStateYellow")); //rbx.getString("xSetYellow");
private static final String SET_TO_FLASHYELLOW = Bundle.getMessage("SetBeanState", Bundle.getMessage("BeanNameSignalHead"), Bundle.getMessage("SignalHeadStateFlashingYellow")); //rbx.getString("xSetFlashYellow");
private static final String SET_TO_GREEN = Bundle.getMessage("SetBeanState", Bundle.getMessage("BeanNameSignalHead"), Bundle.getMessage("SignalHeadStateGreen")); //rbx.getString("xSetGreen");
private static final String SET_TO_FLASHGREEN = Bundle.getMessage("SetBeanState", Bundle.getMessage("BeanNameSignalHead"), Bundle.getMessage("SignalHeadStateFlashingGreen")); //rbx.getString("xSetFlashGreen");
private static String[] ALIGNMENT_STATES = new String[]{ALIGN_SENSOR, ALIGN_TURNOUT, ALIGN_LIGHT, ALIGN_SIGNAL, ALIGN_ALL};
private static String[] INPUT_SENSOR_STATES = new String[]{ON_ACTIVE, ON_INACTIVE, ON_CHANGE, VETO_ON_ACTIVE, VETO_ON_INACTIVE};
private static String[] INPUT_TURNOUT_STATES = new String[]{ON_THROWN, ON_CLOSED, ON_CHANGE, VETO_ON_THROWN, VETO_ON_CLOSED};
private static String[] INPUT_LIGHT_STATES = new String[]{ON_LIT, ON_UNLIT, ON_CHANGE, VETO_ON_LIT, VETO_ON_UNLIT};
private static String[] INPUT_SIGNAL_STATES = new String[]{ON_RED, ON_FLASHRED, ON_YELLOW, ON_FLASHYELLOW, ON_GREEN,
ON_FLASHGREEN, ON_DARK, ON_SIGNAL_LIT, ON_SIGNAL_HELD, VETO_ON_RED,
VETO_ON_FLASHRED, VETO_ON_YELLOW, VETO_ON_FLASHYELLOW, VETO_ON_GREEN,
VETO_ON_FLASHGREEN, VETO_ON_DARK, VETO_ON_SIGNAL_LIT, VETO_ON_SIGNAL_HELD};
private static String[] OUTPUT_SENSOR_STATES = new String[]{SET_TO_ACTIVE, SET_TO_INACTIVE, SET_TO_TOGGLE};
private static String[] OUTPUT_TURNOUT_STATES = new String[]{SET_TO_CLOSED, SET_TO_THROWN, SET_TO_TOGGLE};
private static String[] OUTPUT_LIGHT_STATES = new String[]{SET_TO_ON, SET_TO_OFF, SET_TO_TOGGLE};
private static String[] OUTPUT_SIGNAL_STATES = new String[]{SET_TO_DARK, SET_TO_LIT, SET_TO_HELD, SET_TO_CLEAR,
SET_TO_RED, SET_TO_FLASHRED, SET_TO_YELLOW,
SET_TO_FLASHYELLOW, SET_TO_GREEN, SET_TO_FLASHGREEN};
private static String getLogixSystemPrefix() {
// Note: RouteExportToLogix uses ":RTX:" which is right?
return InstanceManager.getDefault(LogixManager.class).getSystemNamePrefix() + ":RTX";
}
// should be private or package protected, but hey, its Logix! so its public
// because Logix is scattered across all of JMRI without rhyme or reason
public static String getLogixInitializer() {
return getLogixSystemPrefix() + "INITIALIZER";
}
private String getConditionalSystemPrefix() {
return getLogixSystemPrefix() + "C";
}
/**
* Sorts RouteElement
*/
public static class RouteElementComparator implements java.util.Comparator<RouteElement> {
// RouteElement objects aren't really NamedBeans, as they don't inherit
// so we have to create our own comparator object here. This assumes they
// the do have a named-bean-like system name format.
RouteElementComparator() {
}
static jmri.util.AlphanumComparator ac = new jmri.util.AlphanumComparator();
@Override
public int compare(RouteElement e1, RouteElement e2) {
String s1 = e1.getSysName();
String s2 = e2.getSysName();
int p1len = Manager.getSystemPrefixLength(s1);
int p2len = Manager.getSystemPrefixLength(s2);
int comp = ac.compare(s1.substring(0, p1len), s2.substring(0, p2len));
if (comp != 0) return comp;
char c1 = s1.charAt(p1len);
char c2 = s2.charAt(p2len);
if (c1 == c2) return ac.compare(s1.substring(p1len+1), s2.substring(p2len+1));
else return (c1 > c2) ? +1 : -1 ;
}
}
/**
* Base class for all the output (ConditionalAction) and input
* (ConditionalVariable) elements
*/
static class RouteElement {
String _sysName;
String _userName;
int _type;
String _typeString;
boolean _included;
int _state;
RouteElement(String sysName, String userName, int type) {
_sysName = sysName;
_userName = userName;
_type = type;
_included = false;
switch (type) {
case SENSOR_TYPE:
_typeString = Bundle.getMessage("BeanNameSensor");
break;
case TURNOUT_TYPE:
_typeString = Bundle.getMessage("BeanNameTurnout");
break;
case LIGHT_TYPE:
_typeString = Bundle.getMessage("BeanNameLight");
break;
case SIGNAL_TYPE:
_typeString = Bundle.getMessage("BeanNameSignalHead");
break;
case CONDITIONAL_TYPE:
_typeString = Bundle.getMessage("BeanNameConditional");
break;
default:
log.warn("Unexpected type {} in RouteElement constructor", type);
break;
}
}
String getSysName() {
return _sysName;
}
String getUserName() {
return _userName;
}
int getType() {
return _type;
}
String getTypeString() {
return _typeString;
}
boolean isIncluded() {
return _included;
}
void setIncluded(boolean include) {
_included = include;
}
int getState() {
return _state;
}
void setState(int state) {
_state = state;
}
}
abstract class RouteInputElement extends RouteElement {
RouteInputElement(String sysName, String userName, int type) {
super(sysName, userName, type);
}
abstract String getTestState();
abstract void setTestState(String state);
}
class RouteInputSensor extends RouteInputElement {
RouteInputSensor(String sysName, String userName) {
super(sysName, userName, SENSOR_TYPE);
setState(Conditional.TYPE_SENSOR_ACTIVE);
}
@Override
String getTestState() {
switch (_state) {
case Conditional.TYPE_SENSOR_INACTIVE:
return ON_INACTIVE;
case Conditional.TYPE_SENSOR_ACTIVE:
return ON_ACTIVE;
case Route.ONCHANGE:
return ON_CHANGE;
case VETO + Conditional.TYPE_SENSOR_INACTIVE:
return VETO_ON_INACTIVE;
case VETO + Conditional.TYPE_SENSOR_ACTIVE:
return VETO_ON_ACTIVE;
default:
log.error("Unhandled test state type: {}", _state);
break;
}
return "";
}
@Override
void setTestState(String state) {
if (ON_INACTIVE.equals(state)) {
_state = Conditional.TYPE_SENSOR_INACTIVE;
} else if (ON_ACTIVE.equals(state)) {
_state = Conditional.TYPE_SENSOR_ACTIVE;
} else if (ON_CHANGE.equals(state)) {
_state = Route.ONCHANGE;
} else if (VETO_ON_INACTIVE.equals(state)) {
_state = VETO + Conditional.TYPE_SENSOR_INACTIVE;
} else if (VETO_ON_ACTIVE.equals(state)) {
_state = VETO + Conditional.TYPE_SENSOR_ACTIVE;
}
}
}
class RouteInputTurnout extends RouteInputElement {
RouteInputTurnout(String sysName, String userName) {
super(sysName, userName, TURNOUT_TYPE);
setState(Conditional.TYPE_TURNOUT_CLOSED);
}
@Override
String getTestState() {
switch (_state) {
case Conditional.TYPE_TURNOUT_CLOSED:
return ON_CLOSED;
case Conditional.TYPE_TURNOUT_THROWN:
return ON_THROWN;
case Route.ONCHANGE:
return ON_CHANGE;
case VETO + Conditional.TYPE_TURNOUT_CLOSED:
return VETO_ON_CLOSED;
case VETO + Conditional.TYPE_TURNOUT_THROWN:
return VETO_ON_THROWN;
default:
log.warn("Unhandled test state type: {}", _state);
}
return "";
}
@Override
void setTestState(String state) {
if (ON_CLOSED.equals(state)) {
_state = Conditional.TYPE_TURNOUT_CLOSED;
} else if (ON_THROWN.equals(state)) {
_state = Conditional.TYPE_TURNOUT_THROWN;
} else if (ON_CHANGE.equals(state)) {
_state = Route.ONCHANGE;
} else if (VETO_ON_CLOSED.equals(state)) {
_state = VETO + Conditional.TYPE_TURNOUT_CLOSED;
} else if (VETO_ON_THROWN.equals(state)) {
_state = VETO + Conditional.TYPE_TURNOUT_THROWN;
}
}
}
class RouteInputLight extends RouteInputElement {
RouteInputLight(String sysName, String userName) {
super(sysName, userName, LIGHT_TYPE);
setState(Conditional.TYPE_LIGHT_OFF);
}
@Override
String getTestState() {
switch (_state) {
case Conditional.TYPE_LIGHT_OFF:
return ON_UNLIT;
case Conditional.TYPE_LIGHT_ON:
return ON_LIT;
case Route.ONCHANGE:
return ON_CHANGE;
case VETO + Conditional.TYPE_LIGHT_OFF:
return VETO_ON_UNLIT;
case VETO + Conditional.TYPE_LIGHT_ON:
return VETO_ON_LIT;
default:
log.warn("Unhandled test state: {}", _state);
break;
}
return "";
}
@Override
void setTestState(String state) {
if (ON_UNLIT.equals(state)) {
_state = Conditional.TYPE_LIGHT_OFF;
} else if (ON_LIT.equals(state)) {
_state = Conditional.TYPE_LIGHT_ON;
} else if (ON_CHANGE.equals(state)) {
_state = Route.ONCHANGE;
} else if (VETO_ON_UNLIT.equals(state)) {
_state = VETO + Conditional.TYPE_LIGHT_OFF;
} else if (VETO_ON_LIT.equals(state)) {
_state = VETO + Conditional.TYPE_LIGHT_ON;
}
}
}
class RouteInputSignal extends RouteInputElement {
RouteInputSignal(String sysName, String userName) {
super(sysName, userName, SIGNAL_TYPE);
setState(Conditional.TYPE_SIGNAL_HEAD_LIT);
}
@Override
String getTestState() {
switch (_state) {
case Conditional.TYPE_SIGNAL_HEAD_RED:
return ON_RED;
case Conditional.TYPE_SIGNAL_HEAD_FLASHRED:
return ON_FLASHRED;
case Conditional.TYPE_SIGNAL_HEAD_YELLOW:
return ON_YELLOW;
case Conditional.TYPE_SIGNAL_HEAD_FLASHYELLOW:
return ON_FLASHYELLOW;
case Conditional.TYPE_SIGNAL_HEAD_GREEN:
return ON_GREEN;
case Conditional.TYPE_SIGNAL_HEAD_FLASHGREEN:
return ON_FLASHGREEN;
case Conditional.TYPE_SIGNAL_HEAD_DARK:
return ON_DARK;
case Conditional.TYPE_SIGNAL_HEAD_LIT:
return ON_SIGNAL_LIT;
case Conditional.TYPE_SIGNAL_HEAD_HELD:
return ON_SIGNAL_HELD;
case VETO + Conditional.TYPE_SIGNAL_HEAD_RED:
return VETO_ON_RED;
case VETO + Conditional.TYPE_SIGNAL_HEAD_FLASHRED:
return VETO_ON_FLASHRED;
case VETO + Conditional.TYPE_SIGNAL_HEAD_YELLOW:
return VETO_ON_YELLOW;
case VETO + Conditional.TYPE_SIGNAL_HEAD_FLASHYELLOW:
return VETO_ON_FLASHYELLOW;
case VETO + Conditional.TYPE_SIGNAL_HEAD_GREEN:
return VETO_ON_GREEN;
case VETO + Conditional.TYPE_SIGNAL_HEAD_FLASHGREEN:
return VETO_ON_FLASHGREEN;
case VETO + Conditional.TYPE_SIGNAL_HEAD_DARK:
return VETO_ON_DARK;
case VETO + Conditional.TYPE_SIGNAL_HEAD_LIT:
return VETO_ON_SIGNAL_LIT;
case VETO + Conditional.TYPE_SIGNAL_HEAD_HELD:
return VETO_ON_SIGNAL_HELD;
default:
log.warn("Unhandled test state: {}", _state);
break;
}
return "";
}
@Override
void setTestState(String state) {
if (ON_RED.equals(state)) {
_state = Conditional.TYPE_SIGNAL_HEAD_RED;
} else if (ON_FLASHRED.equals(state)) {
_state = Conditional.TYPE_SIGNAL_HEAD_FLASHRED;
} else if (ON_YELLOW.equals(state)) {
_state = Conditional.TYPE_SIGNAL_HEAD_YELLOW;
} else if (ON_FLASHYELLOW.equals(state)) {
_state = Conditional.TYPE_SIGNAL_HEAD_FLASHYELLOW;
} else if (ON_GREEN.equals(state)) {
_state = Conditional.TYPE_SIGNAL_HEAD_GREEN;
} else if (ON_FLASHGREEN.equals(state)) {
_state = Conditional.TYPE_SIGNAL_HEAD_FLASHGREEN;
} else if (ON_DARK.equals(state)) {
_state = Conditional.TYPE_SIGNAL_HEAD_DARK;
} else if (ON_SIGNAL_LIT.equals(state)) {
_state = Conditional.TYPE_SIGNAL_HEAD_LIT;
} else if (ON_SIGNAL_HELD.equals(state)) {
_state = Conditional.TYPE_SIGNAL_HEAD_HELD;
} else if (VETO_ON_RED.equals(state)) {
_state = VETO + Conditional.TYPE_SIGNAL_HEAD_RED;
} else if (VETO_ON_FLASHRED.equals(state)) {
_state = VETO + Conditional.TYPE_SIGNAL_HEAD_FLASHRED;
} else if (VETO_ON_YELLOW.equals(state)) {
_state = VETO + Conditional.TYPE_SIGNAL_HEAD_YELLOW;
} else if (VETO_ON_FLASHYELLOW.equals(state)) {
_state = VETO + Conditional.TYPE_SIGNAL_HEAD_FLASHYELLOW;
} else if (VETO_ON_GREEN.equals(state)) {
_state = VETO + Conditional.TYPE_SIGNAL_HEAD_GREEN;
} else if (VETO_ON_FLASHGREEN.equals(state)) {
_state = VETO + Conditional.TYPE_SIGNAL_HEAD_FLASHGREEN;
} else if (VETO_ON_DARK.equals(state)) {
_state = VETO + Conditional.TYPE_SIGNAL_HEAD_DARK;
} else if (VETO_ON_SIGNAL_LIT.equals(state)) {
_state = VETO + Conditional.TYPE_SIGNAL_HEAD_LIT;
} else if (VETO_ON_SIGNAL_HELD.equals(state)) {
_state = VETO + Conditional.TYPE_SIGNAL_HEAD_HELD;
}
}
}
abstract class RouteOutputElement extends RouteElement {
RouteOutputElement(String sysName, String userName, int type) {
super(sysName, userName, type);
}
abstract String getSetToState();
abstract void setSetToState(String state);
}
class RouteOutputSensor extends RouteOutputElement {
RouteOutputSensor(String sysName, String userName) {
super(sysName, userName, SENSOR_TYPE);
setState(Sensor.ACTIVE);
}
@Override
String getSetToState() {
switch (_state) {
case Sensor.INACTIVE:
return SET_TO_INACTIVE;
case Sensor.ACTIVE:
return SET_TO_ACTIVE;
case Route.TOGGLE:
return SET_TO_TOGGLE;
default:
log.warn("Unhandled set to state: {}", _state);
break;
}
return "";
}
@Override
void setSetToState(String state) {
if (SET_TO_INACTIVE.equals(state)) {
_state = Sensor.INACTIVE;
} else if (SET_TO_ACTIVE.equals(state)) {
_state = Sensor.ACTIVE;
} else if (SET_TO_TOGGLE.equals(state)) {
_state = Route.TOGGLE;
}
}
}
class RouteOutputTurnout extends RouteOutputElement {
RouteOutputTurnout(String sysName, String userName) {
super(sysName, userName, TURNOUT_TYPE);
setState(Turnout.CLOSED);
}
@Override
String getSetToState() {
switch (_state) {
case Turnout.CLOSED:
return SET_TO_CLOSED;
case Turnout.THROWN:
return SET_TO_THROWN;
case Route.TOGGLE:
return SET_TO_TOGGLE;
default:
log.warn("Unhandled set to state: {}", _state);
}
return "";
}
@Override
void setSetToState(String state) {
if (SET_TO_CLOSED.equals(state)) {
_state = Turnout.CLOSED;
} else if (SET_TO_THROWN.equals(state)) {
_state = Turnout.THROWN;
} else if (SET_TO_TOGGLE.equals(state)) {
_state = Route.TOGGLE;
}
}
}
class RouteOutputLight extends RouteOutputElement {
RouteOutputLight(String sysName, String userName) {
super(sysName, userName, LIGHT_TYPE);
setState(Light.ON);
}
@Override
String getSetToState() {
switch (_state) {
case Light.ON:
return SET_TO_ON;
case Light.OFF:
return SET_TO_OFF;
case Route.TOGGLE:
return SET_TO_TOGGLE;
default:
log.warn("Unhandled set to state: {}", _state);
}
return "";
}
@Override
void setSetToState(String state) {
if (SET_TO_ON.equals(state)) {
_state = Light.ON;
} else if (SET_TO_OFF.equals(state)) {
_state = Light.OFF;
} else if (SET_TO_TOGGLE.equals(state)) {
_state = Route.TOGGLE;
}
}
}
class RouteOutputSignal extends RouteOutputElement {
RouteOutputSignal(String sysName, String userName) {
super(sysName, userName, SIGNAL_TYPE);
setState(SignalHead.RED);
}
@Override
String getSetToState() {
switch (_state) {
case SignalHead.DARK:
return SET_TO_DARK;
case SignalHead.RED:
return SET_TO_RED;
case SignalHead.FLASHRED:
return SET_TO_FLASHRED;
case SignalHead.YELLOW:
return SET_TO_YELLOW;
case SignalHead.FLASHYELLOW:
return SET_TO_FLASHYELLOW;
case SignalHead.GREEN:
return SET_TO_GREEN;
case SignalHead.FLASHGREEN:
return SET_TO_FLASHGREEN;
case CLEAR_SIGNAL_HELD:
return SET_TO_CLEAR;
case SET_SIGNAL_LIT:
return SET_TO_LIT;
case SET_SIGNAL_HELD:
return SET_TO_HELD;
default:
log.warn("Unhandled set to state: {}", _state);
break;
}
return "";
}
@Override
void setSetToState(String state) {
if (SET_TO_DARK.equals(state)) {
_state = SignalHead.DARK;
} else if (SET_TO_RED.equals(state)) {
_state = SignalHead.RED;
} else if (SET_TO_FLASHRED.equals(state)) {
_state = SignalHead.FLASHRED;
} else if (SET_TO_YELLOW.equals(state)) {
_state = SignalHead.YELLOW;
} else if (SET_TO_FLASHYELLOW.equals(state)) {
_state = SignalHead.FLASHYELLOW;
} else if (SET_TO_GREEN.equals(state)) {
_state = SignalHead.GREEN;
} else if (SET_TO_FLASHGREEN.equals(state)) {
_state = SignalHead.FLASHGREEN;
} else if (SET_TO_CLEAR.equals(state)) {
_state = CLEAR_SIGNAL_HELD;
} else if (SET_TO_LIT.equals(state)) {
_state = SET_SIGNAL_LIT;
} else if (SET_TO_HELD.equals(state)) {
_state = SET_SIGNAL_HELD;
}
}
}
class AlignElement extends RouteElement {
AlignElement(String sysName, String userName) {
super(sysName, userName, SENSOR_TYPE);
setState(TURNOUT_TYPE);
}
String getAlignType() {
switch (_state) {
case SENSOR_TYPE:
return ALIGN_SENSOR;
case TURNOUT_TYPE:
return ALIGN_TURNOUT;
case LIGHT_TYPE:
return ALIGN_LIGHT;
case SIGNAL_TYPE:
return ALIGN_SIGNAL;
case ALL_TYPE:
return ALIGN_ALL;
default:
log.warn("Unhandled align type state: {}", _state);
break;
}
return "";
}
void setAlignType(String state) {
if (ALIGN_SENSOR.equals(state)) {
_state = SENSOR_TYPE;
} else if (ALIGN_TURNOUT.equals(state)) {
_state = TURNOUT_TYPE;
} else if (ALIGN_LIGHT.equals(state)) {
_state = LIGHT_TYPE;
} else if (ALIGN_SIGNAL.equals(state)) {
_state = SIGNAL_TYPE;
} else if (ALIGN_ALL.equals(state)) {
_state = ALL_TYPE;
}
}
}
@Override
public void setMessagePreferencesDetails() {
InstanceManager.getDefault(jmri.UserPreferencesManager.class).setPreferenceItemDetails(getClassName(), "remindSaveRoute", Bundle.getMessage("HideSaveReminder"));
super.setMessagePreferencesDetails();
}
@Override
protected String getClassName() {
return LRouteTableAction.class.getName();
}
@Override
public String getClassDescription() {
return Bundle.getMessage("TitleLRouteTable");
}
private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LRouteTableAction.class);
}