diff --git a/src/clp/edit/graphics/dial/ActionOrStepDialog.java b/src/clp/edit/graphics/dial/ActionOrStepDialog.java new file mode 100644 index 0000000..36c18d5 --- /dev/null +++ b/src/clp/edit/graphics/dial/ActionOrStepDialog.java @@ -0,0 +1,525 @@ +package clp.edit.graphics.dial; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Frame; +import java.awt.Point; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.ArrayList; +import java.util.List; + +import javax.swing.BorderFactory; +import javax.swing.Box; +import javax.swing.BoxLayout; +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JComboBox; +import javax.swing.JDialog; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JTextField; +import javax.swing.SpringLayout; +import javax.swing.SwingUtilities; +import javax.swing.border.EtchedBorder; +import javax.swing.border.TitledBorder; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; + +import clp.edit.GeneralContext; +import clp.edit.dialog.ADialog; +import clp.edit.graphics.code.ClappInstruction; +import clp.edit.graphics.code.InstructionDialog; +import clp.edit.graphics.code.asn.AssignDialog; +import clp.edit.graphics.code.exit.ExitDialog; +import clp.edit.graphics.code.gui.GuiActionDialog; +import clp.edit.graphics.code.java.ClappJavaInstruction; +import clp.edit.graphics.code.java.JavaCallDialog; +import clp.edit.graphics.code.java.JavaContext; +import clp.edit.graphics.code.prt.PrintDialog; +import clp.edit.graphics.code.ref.ReflectDialog; +import clp.edit.graphics.code.web.WEBcallDialog; +import clp.edit.graphics.panel.GeneralShapesContainer; +import clp.edit.graphics.shapes.ActionShape; + + +public class ActionOrStepDialog extends ADialog implements ActionListener { + + private static final long serialVersionUID = 4917878048633714108L; + + static public enum IntructionType { + NONE(""), + ASSIGN("Assignment"), // conditional assignment (A if b) or normal one + PRINT("Print"), // print to the console + REFLECT("Reflect"), // reflect internal structure + STOP("Stop"), // exit the simulation + UI("UI call"), // allows building of UI + JAVA("Java call"), // java startall + WEB("WEB sender call"); // send, request + + private String value; + private IntructionType(String s) { + value = s; + } + static IntructionType getName(String selectedItem) { + IntructionType[] names = values(); + for (IntructionType t : names) { + if (t.value.equalsIgnoreCase(selectedItem)) { + return t; + } + } + return null; + } + public String getValue() { + return value; + } + } + + private JTextField namefield; + private JTextField descriptionfield; + private List instructionDialogs; + + private GenericActionListener gal; + + private JButton okButton; + + private ActionShape caller; + private List instructions; + + private JCheckBox jcheck; + transient private JComboBox jcombo; + + + /** + * CONSTRUCTOR + * + * @param parent frame + * @param cal ActionShape caller + */ + public ActionOrStepDialog(Frame parent, ActionShape cal) { + this(parent, cal, null); + } + + /** + * CONSTRUCTOR + * + * @param parent frame + * @param cal ActionShape caller + * @param instList instructions list + */ + public ActionOrStepDialog(Frame parent, ActionShape cal, List instList) { + super(parent, "Defining an Action Item", true); + Dimension parentSize = parent.getSize(); + Point p = parent.getLocation(); + setLocation(p.x + parentSize.width / 4, p.y + parentSize.height / 4); + caller = cal; + setLayout(new SpringLayout()); + + okButton = new JButton("ok"); + gal = new GenericActionListener(this); + okButton.addActionListener(gal); + namefield = new JTextField(15); + namefield.setEnabled(false); + descriptionfield = new JTextField(25); + if (instList != null) { + setInstructions(instList); + } + else { + instructionDialogs = new ArrayList<>(); + instructions = new ArrayList<>(); + } + + defineContent(); + + setDefaultCloseOperation(DISPOSE_ON_CLOSE); + pack(); + } + + // + private void setupBciContent(JavaContext jc) { + if (jcombo == null) { + jcombo = new JComboBox<>(); + jcombo.setEnabled(false); + jcombo.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + if (jcombo.isEnabled()) { + String name = (String) jcombo.getSelectedItem(); + caller.setBciName(name); + refresh(); + } + } + }); + } + if (jcombo.getItemCount() != jc.getBciList().size()+1) { + jcombo.removeAllItems(); + jcombo.addItem(null); + for (String key : jc.getBciList()) { + jcombo.addItem(key); + } + if (jcheck == null && jcombo.getItemCount() > 0) { + jcheck = new JCheckBox("Use Byte-Code Injection:"); + jcheck.addChangeListener(new ChangeListener() { + @Override + public void stateChanged(ChangeEvent e) { + if (jcheck.isSelected()) { + jcombo.setEnabled(true); + jcombo.setSelectedItem(caller.getBciName()); + } + else { + jcombo.setEnabled(false); + caller.setBciName(null); + } + } + }); + if (caller.getBciName() != null && !caller.getBciName().isBlank()) { + jcheck.setSelected(true); + } + } + } + } + + // + private void refresh() { + SwingUtilities.invokeLater(new Runnable() { + public void run() { + defineContent(); + pack(); + } + }); + } + + // + public void defineContent() { + getContentPane().removeAll(); + + getContentPane().add(createDescriptionPanel()); + getContentPane().add(createInstructionsPanel()); + getContentPane().add(createControlsPanel()); + + makeCompactGrid(getContentPane(), 3, 1, 6, 6, 6, 6); + } + + public JPanel createDescriptionPanel() { + JPanel p = new JPanel(new SpringLayout()); + TitledBorder border = BorderFactory.createTitledBorder( + BorderFactory.createBevelBorder(EtchedBorder.RAISED), + "Actions Description"); + p.setBorder(border); + + JLabel l = new JLabel("Action name:", JLabel.TRAILING); + p.add(l); + l.setLabelFor(namefield); + p.add(namefield); + + l = new JLabel("Action description:", JLabel.TRAILING); + p.add(l); + l.setLabelFor(descriptionfield); + p.add(descriptionfield); + + makeCompactGrid(p, 2, 2, 6, 6, 6, 6); + p.setOpaque(true); + return p; + } + + public JPanel createInstructionsPanel() { + JPanel p = new JPanel(new SpringLayout()); + TitledBorder border = BorderFactory.createTitledBorder( + BorderFactory.createBevelBorder(EtchedBorder.RAISED), + "Instructions"); + p.setBorder(border); + + boolean isJavaCall = false; + int rows = 0; + for (; rows itypefield = new JComboBox<>(); + GeneralShapesContainer sc = GeneralContext.getInstance().getGraphicsPanel().getShapesContainer(); + for (IntructionType itype : IntructionType.values()) { + if (itype == IntructionType.UI && !sc.getUiList().isEmpty() || + itype == IntructionType.WEB && !sc.getWebInfoNames().isEmpty() || + itype != IntructionType.UI && itype != IntructionType.WEB) { + + itypefield.addItem(itype.getValue()); + } + } + setActionListenerToITypeField(itypefield); + l.setLabelFor(itypefield); + p.add(itypefield); + p.add(new JLabel()); + p.add(new JLabel()); + + makeCompactGrid(p, rows+1, 4, 6, 6, 6, 6); + p.setOpaque(true); + return p; + } + + public JPanel createControlsPanel() { + JPanel p = new JPanel(new SpringLayout()); + TitledBorder border = BorderFactory.createTitledBorder( + BorderFactory.createBevelBorder(EtchedBorder.RAISED), + "Control"); + p.setBorder(border); + + p.add(new JLabel()); + JButton cbtn = new JButton("cancel"); + cbtn.setForeground(Color.blue); + cbtn.addActionListener(gal); + p.add(cbtn); + JButton okbtn = new JButton("ok"); + okbtn.setForeground(Color.blue); + okbtn.addActionListener(gal); + p.add(okbtn); + + makeCompactGrid(p, 1, 3, 6, 6, 6, 6); + + p.setOpaque(true); + return p; + } + + // + private void proposeBCIOption(JPanel p) { + setupBciContent(GeneralContext.getInstance().getGraphicsPanel().getShapesContainer().getJavaContext()); + + p.add(jcheck); + p.add(jcombo); + p.add(new JLabel()); + p.add(new JLabel()); + } + + // + private JPanel createInfoFrom(InstructionDialog insDial) { + JPanel jp = new JPanel(); + jp.setBorder( + BorderFactory.createTitledBorder( + BorderFactory.createBevelBorder(EtchedBorder.RAISED), + "Instruction Details")); + jp.setLayout(new BoxLayout(jp, BoxLayout.Y_AXIS)); + jp.add(Box.createHorizontalStrut(100)); + String str = insDial.getRefName() + " -> "; + if (insDial.isOk()) { + str += insDial.getInstructionContent(); + } + else { + str += insDial.getInstruction().getOldStatement(); + } + if (str.length() > 32) { + str = str.substring(0, 32) + "..."; + } + jp.add(new JLabel(str)); + return jp; + } + + @Override + public void actionPerformed(ActionEvent e) { + setVisible(false); + } + + public String getTransitionText() { + return namefield.getText(); + } + + public void edit(String t, String d) { + namefield.setText(t); + descriptionfield.setText(d); + defineContent(); + setVisible(true); + } + + // + public void setActionListenerToITypeField(JComboBox itypefield) { + Frame parent = (Frame) getOwner(); + itypefield.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + IntructionType t = IntructionType.getName((String)itypefield.getSelectedItem()); + InstructionDialog insDial = null; + if (t == null) { + return; + } + GeneralShapesContainer sc = GeneralContext.getInstance().getGraphicsPanel().getShapesContainer(); + switch (t) { + case ASSIGN: + insDial = new AssignDialog(parent, caller); + break; + case PRINT: + insDial = new PrintDialog(parent, caller); + break; + case REFLECT: + insDial = new ReflectDialog(parent); + break; + case STOP: + insDial = new ExitDialog(parent); + break; + case UI: + insDial = new GuiActionDialog(parent, sc.getUiList(), caller); + break; + case JAVA: + insDial = new JavaCallDialog(parent, caller); + break; + case WEB: + insDial = new WEBcallDialog(parent, sc.getWebInfoNames(), caller); + break; + default: + return; + } + if (insDial.isOk()) { + instructionDialogs.add(insDial); + if (insDial.setupInstruction()) { + caller.addToInstructions(insDial.getInstruction()); + } + refresh(); + } + } + }); + } + + /** + * @return the instructions + */ + public List getInstructions() { + if (instructions == null) { + instructions = new ArrayList<>(); + } + else { + instructions.clear(); + } + for (InstructionDialog id : instructionDialogs) { + instructions.add(id.getInstruction()); + } + return instructions; + } + + /** + * @param instructions the instructions to set + */ + public void setInstructions(List instructions) { + this.instructions = instructions; + if (instructions != null) { + instructionDialogs = new ArrayList<>(); + for (ClappInstruction inst : instructions) { + String tp = inst.getInstructionType(); + if (tp != null) { + IntructionType t = IntructionType.valueOf(tp); + InstructionDialog insDial = null; + if (t != null) { + GeneralShapesContainer sc = GeneralContext.getInstance().getGraphicsPanel().getShapesContainer(); + switch (t) { + case ASSIGN: + insDial = new AssignDialog((Frame) getOwner(), caller, inst); + break; + case PRINT: + insDial = new PrintDialog((Frame) getOwner(), caller, inst); + break; + case REFLECT: + insDial = new ReflectDialog((Frame) getOwner(), inst); + break; + case STOP: + insDial = new ExitDialog((Frame) getOwner(), inst); + break; + case UI: + insDial = new GuiActionDialog((Frame) getOwner(), sc.getUiList(), caller, inst); + break; + case JAVA: + insDial = new JavaCallDialog((Frame) getOwner(), caller, (ClappJavaInstruction) inst); + break; + case WEB: + insDial = new WEBcallDialog((Frame) getOwner(), inst.getSendInfoList(), sc.getWebInfoNames(), inst, caller); + break; + default: + return; + } + instructionDialogs.add(insDial); + insDial.setInstruction(inst); + } + } + } + } + } + + /** + * @return the namefield + */ + public JTextField getNamefield() { + return namefield; + } + + /** + * @return the okButton + */ + public JButton getOkButton() { + return okButton; + } + + public boolean isOk() { + return gal.isOk(); + } + + /** + * @return the descriptionfield + */ + public JTextField getDescriptionfield() { + return descriptionfield; + } + + /** + * @return the description + */ + public String getDescription() { + return descriptionfield.getText(); + } + + /** + * @return the instructionDialogs + */ + public List getInstructionDialogs() { + return instructionDialogs; + } + + /** + * @return the caller + */ + public synchronized ActionShape getCaller() { + return caller; + } +} diff --git a/src/clp/edit/graphics/dial/ActivityDialog.java b/src/clp/edit/graphics/dial/ActivityDialog.java new file mode 100644 index 0000000..a9010b7 --- /dev/null +++ b/src/clp/edit/graphics/dial/ActivityDialog.java @@ -0,0 +1,240 @@ +package clp.edit.graphics.dial; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Frame; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Point; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; + +import javax.swing.Box; +import javax.swing.JButton; +import javax.swing.JLabel; +import javax.swing.JTextArea; +import javax.swing.JTextField; + +import clp.edit.GeneralContext; +import clp.edit.dialog.ADialog; +import clp.edit.graphics.shapes.act.ActivityShape; + +public class ActivityDialog extends ADialog implements ActionListener { + + private static final long serialVersionUID = 4380597140182866078L; + + private JTextField field; + private String name; + private JTextArea area; + + private GenericActionListener gal; + + private ActivityShape activityShape; + + private JTextField wfield; + private JTextField hfield; + + /** + * CONSTRUCTOR + * + * @param t + * @param activityShape + */ + public ActivityDialog(String t, ActivityShape activityShape) { + super(GeneralContext.getInstance().getFrame(), "Defining an Activity", true); + this.activityShape = activityShape; + this.name = t; + Frame parent = GeneralContext.getInstance().getFrame(); + if (parent != null) { + Dimension parentSize = parent.getSize(); + Point p = parent.getLocation(); + setLocation(p.x + parentSize.width / 4, p.y + parentSize.height / 4); + } + setPreferredSize(new Dimension(800, 350)); + setLayout(new GridBagLayout()); + GridBagConstraints c = new GridBagConstraints(); + c.fill = GridBagConstraints.HORIZONTAL; + + gal = new GenericActionListener(this); + + JButton okButton = new JButton("ok"); + okButton.addActionListener(gal); + + c.gridx = 0; + c.gridy = 0; + getContentPane().add(new JLabel("Activity"), c); + c.gridx = 1; + getContentPane().add(Box.createVerticalStrut(5), c); + c.gridx = 2; + field = new JTextField(); + field.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + String n = getCurrentName(); + if (!n.equals(field.getText()) && !updateName(n, field.getText())) { + field.setBackground(Color.red); + } + else { + field.setBackground(Color.white); + } + } + }); + field.addFocusListener(new FocusListener() { + @Override + public void focusLost(FocusEvent e) { + String n = getCurrentName(); + if (!n.equals(field.getText()) && !updateName(n, field.getText())) { + field.setBackground(Color.red); + } + else { + field.setBackground(Color.white); + } + } + @Override + public void focusGained(FocusEvent e) { + } + }); + field.setText(t); + getContentPane().add(field, c); + + c.gridx = 0; + c.gridy++; + getContentPane().add(new JLabel("Width"), c); + c.gridx = 1; + getContentPane().add(Box.createVerticalStrut(5), c); + c.gridx = 2; + wfield = new JTextField(); + wfield.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + updateSize(wfield.getText(), true); + } + }); + wfield.addFocusListener(new FocusListener() { + @Override + public void focusLost(FocusEvent e) { + updateSize(wfield.getText(), true); + } + @Override + public void focusGained(FocusEvent e) { + } + }); + wfield.setText(""+activityShape.getWidth()); + getContentPane().add(wfield, c); + + c.gridx = 0; + c.gridy++; + getContentPane().add(new JLabel("Height"), c); + c.gridx = 1; + getContentPane().add(Box.createVerticalStrut(5), c); + c.gridx = 2; + hfield = new JTextField(); + hfield.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + updateSize(hfield.getText(), false); + } + }); + hfield.addFocusListener(new FocusListener() { + @Override + public void focusLost(FocusEvent e) { + updateSize(hfield.getText(), false); + } + @Override + public void focusGained(FocusEvent e) { + } + }); + hfield.setText(""+activityShape.getHeight()); + getContentPane().add(hfield, c); + + c.gridx = 0; + c.gridy++; + getContentPane().add(new JLabel("Activity description"), c); + c.gridx = 1; + getContentPane().add(Box.createVerticalStrut(5), c); + c.gridx = 2; + area = new JTextArea(3, 40); + getContentPane().add(area, c); + + c.gridx = 0; + c.gridy++; + getContentPane().add(Box.createVerticalStrut(5), c); + + c.gridx = 1; + c.gridy++; + getContentPane().add(okButton, c); + + setDefaultCloseOperation(DISPOSE_ON_CLOSE); + pack(); + } + + // + private String getCurrentName() { + return name; + } + + public void updateFields() { + hfield.setText(""+activityShape.getHeight()); + wfield.setText(""+activityShape.getWidth()); + area.setText(activityShape.getDesc()); + } + + // + private boolean updateName(String oldName, String newName) { + if (activityShape.rename(oldName.replace(" ", "_"), newName.replace(" ", "_"))) { + name = newName; + activityShape.setSimpleName(newName); + return true; + } + return false; + } + + // + private void updateSize(String text, boolean isWidth) { + int x = 0; + try { + x = Integer.parseInt(text); + if (isWidth) { + activityShape.setWidth(x); + } + else { + activityShape.setHeight(x); + } + activityShape.refresh(); + } + catch(NumberFormatException e) { + } + } + + @Override + public void actionPerformed(ActionEvent e) { + setVisible(false); + } + + @Override + public boolean isOk() { + return gal.isOk(); + } + + public void edit(String t, String d) { + field.setText(t); + updateFields(); + setVisible(true); + } + + public String getTransitionText() { + if (gal.isOk() || gal.isInitial()) { + return field.getText(); + } + return null; + } + + public String getDescription() { + if (gal.isOk() || gal.isInitial()) { + return area.getText(); + } + return null; + } +} diff --git a/src/clp/edit/graphics/dial/ClassicGroup.java b/src/clp/edit/graphics/dial/ClassicGroup.java new file mode 100644 index 0000000..285e182 --- /dev/null +++ b/src/clp/edit/graphics/dial/ClassicGroup.java @@ -0,0 +1,202 @@ +package clp.edit.graphics.dial; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.Serializable; + +import javax.swing.JComboBox; +import javax.swing.JTextField; + +public class ClassicGroup implements Serializable { + + private static final long serialVersionUID = -710978414754124130L; + + public static final char upArrow = '\u2191'; + public static final char downArrow = '\u2193'; + + transient private JComboBox arrowfield; + private char selectedArrow; + private JTextField eventfield; + private JTextField eventdescriptionfield; + private JTextField conditionfield; + private JTextField conditiondescriptionfield; + + public ClassicGroup() { + setArrow(upArrow); + eventfield = new JTextField(5); + eventfield.setText("e"); + conditionfield = new JTextField(10); + conditionfield.setText("a"); + eventdescriptionfield = new JTextField(10); + eventdescriptionfield.setText("event variable"); + conditiondescriptionfield = new JTextField(10); + conditiondescriptionfield.setText("boolean condition"); + } + + public void parse(String t) { + if (t != null && !t.isEmpty()) { + String event; + String condition = ""; + if (t.charAt(0) == upArrow || t.charAt(0) == downArrow) { + selectedArrow = t.charAt(0); + int i = t.indexOf('.'); + if (i < 0) { + event = t.substring(1).trim(); + } + else { + event = t.substring(1, i).trim(); + condition = t.substring(i+1).trim(); + if (condition.charAt(0) == '(') { + condition = condition.substring(1, condition.length()-1); + } + } + } + else { + selectedArrow = 0; + event = ""; + condition = t; + } + getArrowfield().setSelectedItem(selectedArrow); + eventfield.setText(event); + conditionfield.setText(condition); + } + } + + /** + * @return the arrowfield + */ + public JComboBox getArrowfield() { + if (arrowfield == null) { + arrowfield = new JComboBox<>(new Character[] { 0, upArrow, downArrow }); + arrowfield.setSelectedItem(selectedArrow); + arrowfield.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + if (arrowfield.getSelectedIndex() == 0) { + eventfield.setText(""); + } + selectedArrow = (char) arrowfield.getSelectedItem(); + } + }); + } + return arrowfield; + } + + /** + * @param arrowfield the arrowfield to set + */ + public void setArrowfield(JComboBox arrowfield) { + this.arrowfield = arrowfield; + } + + /** + * @return the eventfield + */ + public JTextField getEventfield() { + return eventfield; + } + + /** + * @param eventfield the eventfield to set + */ + public void setEventfield(JTextField eventfield) { + this.eventfield = eventfield; + } + + /** + * @return the conditionfield + */ + public JTextField getConditionfield() { + return conditionfield; + } + + /** + * @param conditionfield the conditionfield to set + */ + void setConditionfield(JTextField conditionfield) { + this.conditionfield = conditionfield; + } + @Override + public String toString() { + String text; + char arrow = (char) getArrow(); + if (arrow == 0) { + text = conditionfield.getText().trim(); + } + else { + String cnd = getCondition(); + if (cnd.isEmpty()) { + text = arrow + eventfield.getText().trim(); + } + else { + text = arrow + eventfield.getText().trim() + " . " + cnd; + } + } + return text; + } + + public char getArrow() { + return selectedArrow; + } + + public String getEvent() { + return eventfield.getText().trim(); + } + + public String getCondition() { + String text = conditionfield.getText().trim(); + if (!eventfield.getText().isBlank() && text.contains("+")) { + text = "(" + text + ")"; + } + text = text.replaceAll(" and ", " AND "); + text = text.replaceAll(" or ", " OR "); + text = text.replaceAll("not ", "NOT "); + String[] sp = text.split("\\."); + if (sp.length > 1) { + text = sp[0]; + for (int i=1; i 1) { + text = sp[0]; + for (int i=1; i 1) { + text = sp[0]; + for (int i=1; i unitfield; + private Unit selectedUnit; + + public DelayGroup(int delayNo) { + timeIdentifier = "t" + delayNo; + stepfield = new JTextField(5); + stepfield.setText(GeneralContext.getInstance().getGraphicsPanel().getShapesContainer().getCurrentContainer().getStringActionNo()); + delayfield = new JTextField(5); + delayfield.setText("1"); + setUnit(Unit.SECONDS); + } + + public void parse(String t) { + if (t != null && !t.isEmpty()) { + if (t.charAt(0) == 't') { + String[] sp = t.split("/"); + try { + if (sp.length != 3) { + System.err.println("ERROR found on parsing delay term "+t); + } + else { + String s = sp[1].trim().toUpperCase(); + if (s.equals("C")) { + stepfield.setText(s); + } + else { + int stepnumber = Integer.parseInt(s); + stepfield.setText(""+stepnumber); + } + String[] ssp = sp[2].trim().split(" "); + int delay = Integer.parseInt(ssp[0].trim()); + String uni = ssp[1].trim(); + for (Unit u : Unit.values()) { + if (u.getVal().equalsIgnoreCase(uni)) { + selectedUnit = u; + getUnitfield().setSelectedItem(u); + break; + } + } + delayfield.setText(""+delay); + } + } + catch (NumberFormatException e) { + System.err.println("ERROR found on parsing delay number "+t); + } + } + } + } + + /** + * @return the stepfield + */ + public JTextField getStepfield() { + return stepfield; + } + + /** + * @param stepfield the stepfield to set + */ + public void setStepfield(JTextField stepfield) { + this.stepfield = stepfield; + } + + /** + * @return the delayfield + */ + public JTextField getDelayfield() { + return delayfield; + } + + /** + * @param delayfield the delayfield to set + */ + public void setDelayfield(JTextField delayfield) { + this.delayfield = delayfield; + } + + /** + * @return the unitfield + */ + public JComboBox getUnitfield() { + if (unitfield == null) { + unitfield = new JComboBox(Unit.values()); + unitfield.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + selectedUnit = (Unit) unitfield.getSelectedItem(); + } + }); + unitfield.setSelectedItem(selectedUnit); + } + return unitfield; + } + + @Override + public String toString() { + return timeIdentifier + " / " + stepfield.getText() + " / " + delayfield.getText() + " " + getUnit().getVal(); + } + + public String getStep(char prefix) { + String s = stepfield.getText().trim().toUpperCase(); + if (s.equals("C")) { + return "C"; + } + return prefix + s; + } + + public int getDelay() { + try { + return Integer.parseInt(delayfield.getText().trim()); + } + catch (NumberFormatException e) { + System.err.println("ERROR found on parsing delay number "+delayfield.getText()); + } + return 0; + } + + /** + * @return the timeIdentifier + */ + public String getTimeIdentifier() { + return timeIdentifier; + } + + public Unit getUnit() { + if (selectedUnit == null) { + if (unitfield == null) { + setUnit(Unit.SECONDS); + } + else { + selectedUnit = (Unit) unitfield.getSelectedItem(); + } + } + return selectedUnit; + } + + public void setUnit(Unit selUnit) { + unitfield = new JComboBox<>(Unit.values()); + unitfield.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + selectedUnit = (Unit) unitfield.getSelectedItem(); + } + }); + unitfield.setSelectedItem(selUnit); + selectedUnit = selUnit; + } +} diff --git a/src/clp/edit/graphics/dial/EventNodeDialog.java b/src/clp/edit/graphics/dial/EventNodeDialog.java new file mode 100644 index 0000000..de54171 --- /dev/null +++ b/src/clp/edit/graphics/dial/EventNodeDialog.java @@ -0,0 +1,166 @@ +package clp.edit.graphics.dial; + +import java.awt.Dimension; +import java.awt.Frame; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Point; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import javax.swing.Box; +import javax.swing.JButton; +import javax.swing.JLabel; +import javax.swing.SwingUtilities; + +import clp.edit.dialog.ADialog; +import clp.edit.graphics.shapes.ATransitionRoot; +import clp.edit.graphics.shapes.act.EventNodeShape.InfoGroup; + + +public class EventNodeDialog extends ADialog implements ActionListener { + + private static final long serialVersionUID = 1263715839017787680L; + + private InfoGroup info; + + private GenericActionListener gal; + + private GridBagConstraints c; + + private JButton okButton; + + private ATransitionRoot transition; + + + /** + * CONSTRUCTOR + * + * @param frame + * @param info + * @param t transition + */ + public EventNodeDialog(Frame frame, InfoGroup info, ATransitionRoot t) { + super(frame, "Event Node", true); + this.info = info; + transition = t; + if (frame != null) { + Dimension frameSize = frame.getSize(); + Point p = frame.getLocation(); + setLocation(p.x + frameSize.width / 4, p.y + frameSize.height / 4); + } + + setLayout(new GridBagLayout()); + c = new GridBagConstraints(); + c.fill = GridBagConstraints.HORIZONTAL; + setPreferredSize(new Dimension(800, 400)); + + okButton = new JButton("ok"); + gal = new GenericActionListener(this); + okButton.addActionListener(gal); + + defineContent(c, okButton); + + setDefaultCloseOperation(DISPOSE_ON_CLOSE); + pack(); + } + + // + public void defineContent(GridBagConstraints c, JButton okButton) { + getContentPane().removeAll(); + c.gridy = 0; + c.gridx = 0; + c.gridwidth = 1; + getContentPane().add(Box.createVerticalStrut(5), c); + + c.gridy++; + c.gridx = 0; + getContentPane().add(new JLabel("Crossing"), c); + c.gridx++; + getContentPane().add(Box.createVerticalStrut(5), c); + c.gridx++; + boolean isDescriptionRequested = createCrossing(c); + + if (isDescriptionRequested) { + c.gridy++; + c.gridx = 0; + getContentPane().add(new JLabel("Description"), c); + c.gridx++; + getContentPane().add(Box.createVerticalStrut(5), c); + c.gridx++; + c.gridwidth = 3; + getContentPane().add(info.getEventDescriptionField(), c); + } + + c.gridy++; + c.gridx = 0; + getContentPane().add(Box.createVerticalStrut(5), c); + + c.gridy++; + c.gridx = 1; + c.gridwidth = 2; + getContentPane().add(okButton, c); + } + + // + protected boolean createCrossing(GridBagConstraints c) { + getContentPane().add(info.getArrowfield(), c); + c.gridx++; + getContentPane().add(Box.createVerticalStrut(5), c); + c.gridx++; + getContentPane().add(info.getEventfield(), c); + return true; + } + + @Override + public void actionPerformed(ActionEvent e) { + setVisible(false); + } + + public String getTransitionText() { + return info.toString(); + } + + public void edit(String t, String d) { + info.parse(t); + setVisible(true); + } + + public void refresh() { + SwingUtilities.invokeLater(new Runnable() { + public void run() { + defineContent(c, okButton); + getRootPane().updateUI(); + } + }); + } + + @Override + public boolean isOk() { + return gal.isOk(); + } + + /** + * @return the okButton + */ + public JButton getOkButton() { + return okButton; + } + + @Override + public String getDescription() { + return null; + } + + public String getActivationCondition() { + switch (info.getArrow()) { + case ClassicGroup.upArrow: + transition.addInputVariable(info.getEvent(), info.getEventDescription(), null); + return "isSetUp(" + info.getEvent() + ")"; + case ClassicGroup.downArrow: + transition.addInputVariable(info.getEvent(), info.getEventDescription(), null); + return "isSetDown(" + info.getEvent() + ")"; + } + return null; + } +} diff --git a/src/clp/edit/graphics/dial/ForkDialog.java b/src/clp/edit/graphics/dial/ForkDialog.java new file mode 100644 index 0000000..16600d8 --- /dev/null +++ b/src/clp/edit/graphics/dial/ForkDialog.java @@ -0,0 +1,104 @@ +package clp.edit.graphics.dial; + +import java.awt.Dimension; +import java.awt.Frame; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Point; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import javax.swing.Box; +import javax.swing.JButton; +import javax.swing.JLabel; +import javax.swing.JTextField; + +import clp.edit.GeneralContext; +import clp.edit.dialog.ADialog; +import clp.edit.graphics.shapes.AForkShape; + +public class ForkDialog extends ADialog implements ActionListener { + + private static final long serialVersionUID = -5185977863757606895L; + + private AForkShape shape; + + private JTextField wfield; + + public ForkDialog(AForkShape shape) { + super(GeneralContext.getInstance().getFrame(), "Defining Width", true); + Frame parent = GeneralContext.getInstance().getFrame(); + if (parent != null) { + Dimension parentSize = parent.getSize(); + Point p = parent.getLocation(); + setLocation(p.x + parentSize.width / 4, p.y + parentSize.height / 4); + } + this.shape = shape; + setPreferredSize(new Dimension(400, 150)); + setLayout(new GridBagLayout()); + GridBagConstraints c = new GridBagConstraints(); + c.fill = GridBagConstraints.HORIZONTAL; + + JButton okButton = new JButton("ok"); + okButton.addActionListener(this); + + c.gridx = 0; + c.gridy = 0; + getContentPane().add(new JLabel("Width"), c); + c.gridx = 1; + getContentPane().add(Box.createVerticalStrut(5), c); + c.gridx = 2; + wfield = new JTextField(); + wfield.setText(""+shape.getWidth()); + getContentPane().add(wfield, c); + + c.gridx = 0; + c.gridy++; + getContentPane().add(Box.createVerticalStrut(5), c); + + c.gridx = 1; + c.gridy++; + getContentPane().add(okButton, c); + + setDefaultCloseOperation(DISPOSE_ON_CLOSE); + pack(); + } + + public void updateFields() { + wfield.setText(""+shape.getWidth()); + } + + private void updateSize(String text) { + int x = 0; + try { + x = Integer.parseInt(text); + shape.setWidth(x); + } + catch(NumberFormatException e) { + } + } + + @Override + public void actionPerformed(ActionEvent e) { + updateSize(wfield.getText()); + setVisible(false); + } + + @Override + public boolean isOk() { + return true; + } + + public void edit(String t, String d) { + updateFields(); + setVisible(true); + } + + public String getTransitionText() { + return null; + } + + public String getDescription() { + return null; + } +} diff --git a/src/clp/edit/graphics/dial/GenericActionListener.java b/src/clp/edit/graphics/dial/GenericActionListener.java new file mode 100644 index 0000000..eeb0d48 --- /dev/null +++ b/src/clp/edit/graphics/dial/GenericActionListener.java @@ -0,0 +1,68 @@ +package clp.edit.graphics.dial; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.Serializable; + +import javax.swing.JButton; +import javax.swing.JDialog; + +public class GenericActionListener implements ActionListener, Serializable { + + private static final long serialVersionUID = -2161874054986636126L; + + private JDialog dialog; + + private boolean isOk; + + private boolean isCancel; + + private boolean isInitial; + + private boolean isListenerAlone; + + public GenericActionListener(JDialog d) { + dialog = d; + isOk = false; + isCancel = false; + isInitial = true; + isListenerAlone = true; + } + + @Override + public void actionPerformed(ActionEvent e) { + if (((JButton)e.getSource()).getText().equals("ok")) { + isOk = true; + } + else { + isOk = false; + isCancel = true; + } + isInitial = false; + if (isListenerAlone) { + dialog.dispose(); + } + } + + public boolean isOk() { + return isOk; + } + + public boolean isInitial() { + return isInitial; + } + + /** + * @return the isCancel + */ + public boolean isCancel() { + return isCancel; + } + + /** + * @param isListenerAlone the isListenerAlone to set + */ + public void setListenerAlone(boolean isListenerAlone) { + this.isListenerAlone = isListenerAlone; + } +} diff --git a/src/clp/edit/graphics/dial/GrafcetDialog.java b/src/clp/edit/graphics/dial/GrafcetDialog.java new file mode 100644 index 0000000..565ac19 --- /dev/null +++ b/src/clp/edit/graphics/dial/GrafcetDialog.java @@ -0,0 +1,289 @@ +package clp.edit.graphics.dial; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Frame; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.GridLayout; +import java.awt.Point; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; + +import javax.swing.BorderFactory; +import javax.swing.Box; +import javax.swing.ButtonGroup; +import javax.swing.JButton; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JRadioButton; +import javax.swing.JTextArea; +import javax.swing.JTextField; +import javax.swing.border.EtchedBorder; +import javax.swing.border.TitledBorder; + +import clp.edit.GeneralContext; +import clp.edit.dialog.ADialog; +import clp.edit.graphics.shapes.gc.GrafcetShape; + +public class GrafcetDialog extends ADialog implements ActionListener { + + private static final long serialVersionUID = 5214139773538020781L; + + private JTextField field; + private String name; + private JTextArea area; + + private GenericActionListener gal; + + private GrafcetShape grafcetShape; + + private JTextField wfield; + + private JTextField hfield; + + public GrafcetDialog(String t, GrafcetShape grafcetShape) { + super(GeneralContext.getInstance().getFrame(), "Defining a Grafcet (Sequencial Flow Chart)", true); + this.grafcetShape = grafcetShape; + this.name = t; + Frame parent = GeneralContext.getInstance().getFrame(); + if (parent != null) { + Dimension parentSize = parent.getSize(); + Point p = parent.getLocation(); + setLocation(p.x + parentSize.width / 4, p.y + parentSize.height / 4); + } + setPreferredSize(new Dimension(800, 350)); + setLayout(new GridBagLayout()); + GridBagConstraints c = new GridBagConstraints(); + c.fill = GridBagConstraints.HORIZONTAL; + + gal = new GenericActionListener(this); + + JButton okButton = new JButton("ok"); + okButton.addActionListener(gal); + + c.gridx = 0; + c.gridy = 0; + getContentPane().add(new JLabel("Grafcet name"), c); + c.gridx = 1; + getContentPane().add(Box.createVerticalStrut(5), c); + c.gridx = 2; + field = new JTextField(); + field.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + String n = getCurrentName(); + if (!n.equals(field.getText()) && !updateName(n, field.getText())) { + field.setBackground(Color.red); + } + else { + field.setBackground(Color.white); + } + } + }); + field.addFocusListener(new FocusListener() { + @Override + public void focusLost(FocusEvent e) { + String n = getCurrentName(); + if (!n.equals(field.getText()) && !updateName(n, field.getText())) { + field.setBackground(Color.red); + } + else { + field.setBackground(Color.white); + } + } + @Override + public void focusGained(FocusEvent e) { + } + }); + field.setText(t); + getContentPane().add(field, c); + + c.gridx = 0; + c.gridy++; + getContentPane().add(new JLabel("Width"), c); + c.gridx = 1; + getContentPane().add(Box.createVerticalStrut(5), c); + c.gridx = 2; + wfield = new JTextField(); + wfield.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + updateSize(wfield.getText(), true); + } + }); + wfield.addFocusListener(new FocusListener() { + @Override + public void focusLost(FocusEvent e) { + updateSize(wfield.getText(), true); + } + @Override + public void focusGained(FocusEvent e) { + } + }); + wfield.setText(""+grafcetShape.getWidth()); + getContentPane().add(wfield, c); + + c.gridx = 0; + c.gridy++; + getContentPane().add(new JLabel("Height"), c); + c.gridx = 1; + getContentPane().add(Box.createVerticalStrut(5), c); + c.gridx = 2; + hfield = new JTextField(); + hfield.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + updateSize(hfield.getText(), false); + } + }); + hfield.addFocusListener(new FocusListener() { + @Override + public void focusLost(FocusEvent e) { + updateSize(hfield.getText(), false); + } + @Override + public void focusGained(FocusEvent e) { + } + }); + hfield.setText(""+grafcetShape.getHeight()); + getContentPane().add(hfield, c); + + c.gridx = 0; + c.gridy++; + getContentPane().add(new JLabel("Default Transition Type"), c); + c.gridx = 1; + getContentPane().add(Box.createVerticalStrut(5), c); + c.gridx = 2; + JPanel jp1 = createRadioButtonsForType(); + getContentPane().add(jp1, c); + + c.gridx = 0; + c.gridy++; + getContentPane().add(new JLabel("Grafcet description"), c); + c.gridx = 1; + getContentPane().add(Box.createVerticalStrut(5), c); + c.gridx = 2; + area = new JTextArea(3, 40); + getContentPane().add(area, c); + + c.gridx = 0; + c.gridy++; + getContentPane().add(Box.createVerticalStrut(5), c); + + c.gridx = 1; + c.gridy++; + getContentPane().add(okButton, c); + + setDefaultCloseOperation(DISPOSE_ON_CLOSE); + pack(); + } + + // + private String getCurrentName() { + return name; + } + + // + private boolean updateName(String oldName, String newName) { + if (grafcetShape.rename(oldName.replace(" ", "_"), newName.replace(" ", "_"))) { + name = newName; + grafcetShape.setSimpleName(newName); + return true; + } + return false; + } + + // + private JPanel createRadioButtonsForType() { + JPanel jp = new JPanel(); + jp.setLayout(new GridLayout()); + TitledBorder border = BorderFactory.createTitledBorder( + BorderFactory.createBevelBorder(EtchedBorder.LOWERED), + "Choose Transition Type"); + jp.setBorder(border); + + ItemListener radioListener = new ItemListener() { + @Override + public void itemStateChanged(ItemEvent e) { + JRadioButton rb = (JRadioButton) e.getSource(); + if (rb.isSelected()) { + grafcetShape.setDefaultTransitionType( TransitionType.getName(rb.getText()) ); + } + } + }; + ButtonGroup group = new ButtonGroup(); + TransitionType deftype = grafcetShape.getDefaultTransitionType(); + if (deftype == null) { + deftype = TransitionType.TAUTOLOGY; + grafcetShape.setDefaultTransitionType(deftype); + } + for (TransitionType t : TransitionType.values()) { + JRadioButton rb = new JRadioButton(t.getVal(), true); + jp.add(rb); rb.addItemListener(radioListener); + if (t == deftype) { + rb.setSelected(true); + } + else { + rb.setSelected(false); + } + group.add(rb); + } + return jp; + } + + public void updateFields() { + hfield.setText(""+grafcetShape.getHeight()); + wfield.setText(""+grafcetShape.getWidth()); + } + + private void updateSize(String text, boolean isWidth) { + int x = 0; + try { + x = Integer.parseInt(text); + if (isWidth) { + grafcetShape.setWidth(x); + } + else { + grafcetShape.setHeight(x); + } + grafcetShape.refresh(); + } + catch(NumberFormatException e) { + } + } + + @Override + public void actionPerformed(ActionEvent e) { + setVisible(false); + } + + @Override + public boolean isOk() { + return gal.isOk(); + } + + public void edit(String t, String d) { + field.setText(t); + updateFields(); + setVisible(true); + } + + public String getTransitionText() { + if (gal.isOk() || gal.isInitial()) { + return field.getText(); + } + return null; + } + + public String getDescription() { + if (gal.isOk() || gal.isInitial()) { + return area.getText(); + } + return null; + } +} diff --git a/src/clp/edit/graphics/dial/InputVariablePanel.java b/src/clp/edit/graphics/dial/InputVariablePanel.java new file mode 100644 index 0000000..382abbf --- /dev/null +++ b/src/clp/edit/graphics/dial/InputVariablePanel.java @@ -0,0 +1,92 @@ +package clp.edit.graphics.dial; + +import java.awt.GridLayout; + +import javax.swing.BorderFactory; +import javax.swing.Box; +import javax.swing.JPanel; +import javax.swing.JTextField; +import javax.swing.border.EtchedBorder; + +import clp.edit.graphics.shapes.AEventShape; + +public class InputVariablePanel extends JPanel { + + private static final long serialVersionUID = 1805358252096725711L; + + private JTextField varfield; + private JTextField description; + + private AEventShape event; + + public InputVariablePanel(String name) { + super(); + setBorder( + BorderFactory.createTitledBorder( + BorderFactory.createBevelBorder(EtchedBorder.RAISED), + "Variable name")); + setLayout(new GridLayout(2,1)); + varfield = new JTextField(name); + add(varfield); + add(Box.createHorizontalStrut(5)); + description = new JTextField("variable description"); + add(description); + } + + public InputVariablePanel(AEventShape event) { + this(event.getName()); + this.event = event; + } + + + public String getVariableName() { + String text = varfield.getText(); + text = text.replaceAll(" and ", " AND "); + text = text.replaceAll(" or ", " OR "); + text = text.replaceAll("not ", "NOT "); + String[] sp = text.split("\\."); + if (sp.length > 1) { + text = sp[0]; + for (int i=1; i 1) { + text = sp[0]; + for (int i=1; i 1) { + text = sp[0]; + for (int i=1; i bititles; + private ArrayList trititles; + + private UpWeightingType selectedUpType; + private int selectedDownIndex; + + /** + * CONSTRUCTOR + * + * @param parent + * @param pnShape + * @param transitionNodeShape + * @param tt: transition type + * @param tp: transition position + * @param height + */ + public PNCTransitionDialog(Frame parent, PetriNetsShape pnShape, TransitionNodeShape transitionNodeShape, TransitionType tt, TransitionPosition tp, int height) { + super(parent, pnShape, transitionNodeShape, tt, tp, height); + selectedUpType = UpWeightingType.LEFT; + selectedDownIndex = 0; + bititles = new ArrayList<>(); + trititles = new ArrayList<>(); + bititles.add("Down Left"); + bititles.add("Down Right"); + trititles.add("Down Left"); + trititles.add("Down Middle"); + trititles.add("Down Right"); + } + + // + private JPanel createRadioButtonsForUpWeighting(UpWeightingType exclude) { + JPanel jp = new JPanel(); + jp.setLayout(new GridLayout()); + TitledBorder border = BorderFactory.createTitledBorder( + BorderFactory.createBevelBorder(EtchedBorder.LOWERED), + "Choose Up Branch"); + jp.setBorder(border); + + ItemListener radioListener = new ItemListener() { + @Override + public void itemStateChanged(ItemEvent e) { + JRadioButton rb = (JRadioButton) e.getSource(); + if (rb.isSelected()) { + selectedUpType = UpWeightingType.getName(rb.getText()); + refresh(); + } + } + }; + ButtonGroup group = new ButtonGroup(); + for (UpWeightingType t : UpWeightingType.values()) { + if (t != exclude) { + JRadioButton rb = new JRadioButton(t.getVal(), true); + jp.add(rb); rb.addItemListener(radioListener); + if (t == selectedUpType) { + if (!rb.isSelected()) { + rb.setSelected(true); + } + } + else if (rb.isSelected()) { + rb.setSelected(false); + } + group.add(rb); + } + } + return jp; + } + + // + private JPanel createRadioButtonsForDownWeighting(ArrayList titles) { + JPanel jp = new JPanel(); + jp.setLayout(new GridLayout()); + TitledBorder border = BorderFactory.createTitledBorder( + BorderFactory.createBevelBorder(EtchedBorder.LOWERED), + "Choose Down Branch"); + jp.setBorder(border); + + ItemListener radioListener = new ItemListener() { + @Override + public void itemStateChanged(ItemEvent e) { + JRadioButton rb = (JRadioButton) e.getSource(); + if (rb.isSelected()) { + selectedDownIndex = titles.indexOf( rb.getText() ); + refresh(); + } + } + }; + ButtonGroup group = new ButtonGroup(); + for (String t : titles) { + JRadioButton rb = new JRadioButton(t, true); + jp.add(rb); rb.addItemListener(radioListener); + if (t.equals(titles.get(selectedDownIndex))) { + if (!rb.isSelected()) { + rb.setSelected(true); + } + } + else if (rb.isSelected()) { + rb.setSelected(false); + } + group.add(rb); + } + return jp; + } + + @Override + protected void createUpWeightingPanels(GridBagConstraints c) { + if (getUplefthelper() == null && getUprighthelper() == null) { + addComponent(createWeightingPanel(getUphelper(), "Up"), 1, 1, 10, c); + return; + } + else if (getUplefthelper() != null && getUprighthelper() != null) { + addComponent(createRadioButtonsForUpWeighting(null), 1, 1, 10, c); + } + else if (getUplefthelper() != null) { + addComponent(createRadioButtonsForUpWeighting(UpWeightingType.RIGHT), 1, 1, 10, c); + } + else { + addComponent(createRadioButtonsForUpWeighting(UpWeightingType.LEFT), 1, 1, 10, c); + } + switch (selectedUpType) { + case LEFT: + if (getUplefthelper() != null) { + addComponent(createWeightingPanel(getUplefthelper(), "Up Left"), 1, 2, 10, c); + } + break; + case MIDDLE: + if (getUphelper() != null) { + addComponent(createWeightingPanel(getUphelper(), "Up"), 1, 2, 10, c); + } + break; + case RIGHT: + if (getUprighthelper() != null) { + addComponent(createWeightingPanel(getUprighthelper(), "Up Right"), 1, 2, 10, c); + } + break; + + default: + break; + } + } + + @Override + protected void createDownWeightingPanels(GridBagConstraints c) { + switch (getDowntype()) { + case MONO: + addComponent(createWeightingPanel(getDownhelper(), "Down"), 1, 3, 10, c); + break; + case BI: + addComponent(createRadioButtonsForDownWeighting(bititles), 1, 3, 10, c); + if (selectedDownIndex == 0) { + addComponent(createWeightingPanel(getDownlefthelper(), bititles.get(0)), 1, 4, 10, c); + } + else { + addComponent(createWeightingPanel(getDownhelper(), bititles.get(1)), 1, 4, 10, c); + } + break; + case TRI: + addComponent(createRadioButtonsForDownWeighting(trititles), 1, 3, 10, c); + switch (selectedDownIndex) { + case 0: + addComponent(createWeightingPanel(getDownlefthelper(), trititles.get(0)), 1, 4, 10, c); + break; + case 1: + addComponent(createWeightingPanel(getDownhelper(), trititles.get(1)), 1, 4, 10, c); + break; + case 2: + addComponent(createWeightingPanel(getDownrighthelper(), trititles.get(2)), 1, 4, 10, c); + break; + + default: + break; + } + break; + + default: + break; + } + } + + @Override + protected JPanel createWeightingPanel(PNDialogHelper helper, String string) { + JPanel jp = new JPanel(); + jp.setBorder( + BorderFactory.createTitledBorder( + BorderFactory.createBevelBorder(EtchedBorder.RAISED), + string + " Weighting")); + jp.setLayout(new GridBagLayout()); + GridBagConstraints gc = new GridBagConstraints(); + + gc.gridy = 0; + gc.gridx = 0; + jp.add(new JLabel("Red"), gc); + gc.gridx++; + jp.add(new JLabel("Green"), gc); + gc.gridx++; + jp.add(new JLabel("Blue"), gc); + gc.gridx++; + jp.add(new JLabel("Yellow"), gc); + gc.gridx++; + jp.add(new JLabel("Orange"), gc); + gc.gridx++; + jp.add(new JLabel("Cyan"), gc); + + gc.gridy = 1; + gc.gridx = 0; + jp.add(helper.createField("Red", ""+helper.getNbRed()), gc); + gc.gridx++; + jp.add(helper.createField("Green", ""+helper.getNbGreen()), gc); + gc.gridx++; + jp.add(helper.createField("Blue", ""+helper.getNbBlue()), gc); + gc.gridx++; + jp.add(helper.createField("Yellow", ""+helper.getNbYellow()), gc); + gc.gridx++; + jp.add(helper.createField("Orange", ""+helper.getNbOrange()), gc); + gc.gridx++; + jp.add(helper.createField("Cyan", ""+helper.getNbCyan()), gc); + + return jp; + } +} diff --git a/src/clp/edit/graphics/dial/PNDialogHelper.java b/src/clp/edit/graphics/dial/PNDialogHelper.java new file mode 100644 index 0000000..260272d --- /dev/null +++ b/src/clp/edit/graphics/dial/PNDialogHelper.java @@ -0,0 +1,329 @@ +package clp.edit.graphics.dial; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; +import java.io.Serializable; + +import javax.swing.JTextField; + +public class PNDialogHelper implements Serializable { + + private static final long serialVersionUID = -2200338022612806887L; + + private int nbRed; + private int nbGreen; + private int nbBlue; + private int nbYellow; + private int nbOrange; + private int nbCyan; + private int nbBlack; + /** + * @return the nbRed + */ + public int getNbRed() { + return nbRed; + } + /** + * increment nbRed + */ + public void incNbRed() { + this.nbRed ++; + } + /** + * @param nbRed the nbRed to set + */ + public void setNbRed(int nbRed) { + this.nbRed = nbRed; + } + /** + * @return the nbGreen + */ + public int getNbGreen() { + return nbGreen; + } + /** + * increment nbGreen + */ + public void incNbGreen() { + this.nbGreen ++; + } + /** + * @param nbGreen the nbGreen to set + */ + public void setNbGreen(int nbGreen) { + this.nbGreen = nbGreen; + } + /** + * @return the nbBlue + */ + public int getNbBlue() { + return nbBlue; + } + /** + * increment nbBlue + */ + public void incNbBlue() { + this.nbBlue ++; + } + /** + * @param nbBlue the nbBlue to set + */ + public void setNbBlue(int nbBlue) { + this.nbBlue = nbBlue; + } + /** + * @return the nbYellow + */ + public int getNbYellow() { + return nbYellow; + } + /** + * increment nbYellow + */ + public void incNbYellow() { + this.nbYellow ++; + } + /** + * @param nbYellow the nbYellow to set + */ + public void setNbYellow(int nbYellow) { + this.nbYellow = nbYellow; + } + /** + * @return the nbOrange + */ + public int getNbOrange() { + return nbOrange; + } + /** + * increment nbOrange + */ + public void incNbOrange() { + this.nbOrange ++; + } + /** + * @param nbOrange the nbOrange to set + */ + public void setNbOrange(int nbOrange) { + this.nbOrange = nbOrange; + } + /** + * @return the nbCyan + */ + public int getNbCyan() { + return nbCyan; + } + /** + * increment nbCyan + */ + public void incNbCyan() { + this.nbCyan ++; + } + /** + * @param nbCyan the nbCyan to set + */ + public void setNbCyan(int nbCyan) { + this.nbCyan = nbCyan; + } + /** + * @return the nbBlack + */ + public int getNbBlack() { + return nbBlack; + } + /** + * increment nbBlack + */ + public void incNbBlack() { + this.nbBlack ++; + } + /** + * @param nbBlack the nbBlack to set + */ + public void setNbBlack(int nbBlack) { + this.nbBlack = nbBlack; + } + public int getAll() { + return nbRed+nbGreen+nbBlue+nbYellow+nbOrange+nbCyan; + } + + + // + public JTextField createField(String lbl, String text) { + JTextField field = new JTextField(5); + field.setText(text); + field.setName(lbl); + field.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + updateNumber((JTextField)e.getSource()); + } + }); + field.addFocusListener(new FocusListener() { + @Override + public void focusLost(FocusEvent e) { + updateNumber((JTextField)e.getSource()); + } + @Override + public void focusGained(FocusEvent e) { + } + }); + return field; + } + + // + private void updateNumber(JTextField source) { + try { + int nb = Integer.parseInt(source.getText()); + switch (source.getName()) { + case "Black": + setNbBlack(nb); + break; + case "Red": + setNbRed(nb); + break; + case "Green": + setNbGreen(nb); + break; + case "Blue": + setNbBlue(nb); + break; + case "Yellow": + setNbYellow(nb); + break; + case "Orange": + setNbOrange(nb); + break; + case "Cyan": + setNbCyan(nb); + break; + + default: + break; + } + } + catch (NumberFormatException e) { + + } + } + + public void setNb(char c, int nb) { + switch (c) { + case 'R': + setNbRed(nb); + break; + case 'G': + setNbGreen(nb); + break; + case 'B': + setNbBlue(nb); + break; + case 'Y': + setNbYellow(nb); + break; + case 'O': + setNbOrange(nb); + break; + case 'C': + setNbCyan(nb); + break; + + default: + int n = Integer.parseInt(""+c); + setNbBlack(n); + break; + } + } + + @Override + public String toString() { + if (nbBlack > 0) { + return nbBlack > 1 ? ""+nbBlack : "1"; + } + String text = ""; + text += getFromColor(true, nbRed, "R"); + text += getFromColor(text.isEmpty(), nbGreen, "G"); + text += getFromColor(text.isEmpty(), nbBlue, "B"); + text += getFromColor(text.isEmpty(), nbYellow, "Y"); + text += getFromColor(text.isEmpty(), nbOrange, "O"); + text += getFromColor(text.isEmpty(), nbCyan, "C"); + return text; + } + + // + private String getFromColor(boolean b, int color, String ch) { + if (color > 0) { + if (color > 1) { + return (b ? "" : ".") + color + ch; + } + return (b ? "" : ".") + ch; + } + return ""; + } + + public String getMarks() { + if (nbBlack > 0) { + return "'N':" + nbBlack; + } + String text = ""; + text += getMarkFromColor(true, nbRed, "R"); + text += getMarkFromColor(text.isEmpty(), nbGreen, "G"); + text += getMarkFromColor(text.isEmpty(), nbBlue, "B"); + text += getMarkFromColor(text.isEmpty(), nbYellow, "Y"); + text += getMarkFromColor(text.isEmpty(), nbOrange, "O"); + text += getMarkFromColor(text.isEmpty(), nbCyan, "C"); + + return text; + } + + private String getMarkFromColor(boolean b, int color, String ch) { + if (color > 0) { + return (b ? "'" : ", '") + ch+"':"+color; + } + return ""; + } + + public int getSize() { + int size = 0; + if (nbBlack > 0) { + size++; + } + else { + if (nbRed > 0) { + size++; + } + if (nbGreen > 0) { + size++; + } + if (nbBlue > 0) { + size++; + } + if (nbYellow > 0) { + size++; + } + if (nbOrange > 0) { + size++; + } + if (nbCyan > 0) { + size++; + } + } + return size; + } + + public void resetAll() { + nbBlack = 0; + nbRed = 0; + nbGreen = 0; + nbBlue = 0; + nbYellow = 0; + nbOrange = 0; + nbCyan = 0; + } + + public Token[] getTokens() { + return Token.getTokens(this); + } +} diff --git a/src/clp/edit/graphics/dial/PNTransitionDialog.java b/src/clp/edit/graphics/dial/PNTransitionDialog.java new file mode 100644 index 0000000..aff3069 --- /dev/null +++ b/src/clp/edit/graphics/dial/PNTransitionDialog.java @@ -0,0 +1,444 @@ +package clp.edit.graphics.dial; + +import java.awt.Component; +import java.awt.Frame; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; + +import javax.swing.BorderFactory; +import javax.swing.Box; +import javax.swing.JButton; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.border.EtchedBorder; + +import clp.edit.graphics.shapes.ABindingShape; +import clp.edit.graphics.shapes.TriBinding; +import clp.edit.graphics.shapes.pn.PetriNetsShape; +import clp.edit.graphics.shapes.pn.TransitionNodeShape; + + +public class PNTransitionDialog extends TransitionDialog { + + private static final long serialVersionUID = -6433146820679639497L; + + private static final Insets insets = new Insets(3, 3, 3, 3); + + protected enum DownWeightingType { + MONO, BI, TRI; + } + + public enum TransitionPosition { + INITIAL, MIDDLE, FINAL; + } + + private boolean isNotFirstCall; + + private PNDialogHelper uphelper; + private PNDialogHelper uplefthelper; + private PNDialogHelper uprighthelper; + + private PNDialogHelper downhelper; + private PNDialogHelper downlefthelper; + private PNDialogHelper downrighthelper; + + private TransitionNodeShape transitionNodeShape; + + private DownWeightingType downtype; + + + /** + * CONSTRUCTOR + * + * @param frame + * @param pnShape + * @param transitionNodeShape + * @param tt: transition type + * @param tp: transition position + * @param height + */ + public PNTransitionDialog(Frame frame, PetriNetsShape pnShape, TransitionNodeShape transitionNodeShape, TransitionType tt, TransitionPosition tp, int height) { + super(frame, transitionNodeShape, null, height); + this.transitionNodeShape = transitionNodeShape; + pnsetup(pnShape); + } + + // + public void pnsetup(PetriNetsShape pnShape) { + if (pnShape != null) { + if (transitionNodeShape.getTrPos() != TransitionPosition.INITIAL) { + uphelper = new PNDialogHelper(); + countTokens(uphelper, pnShape.getWeightOrColor()); + } + if (transitionNodeShape.getTrPos() != TransitionPosition.FINAL) { + downhelper = new PNDialogHelper(); + countTokens(downhelper, pnShape.getWeightOrColor()); + downtype = DownWeightingType.MONO; + } + } + else { + if (transitionNodeShape.getTrPos() != TransitionPosition.INITIAL) { + ABindingShape b = transitionNodeShape.getParent(); + if (b instanceof TriBinding) { + TriBinding tri = (TriBinding) b; + if (tri.getLeft() != null) { + if (uplefthelper == null) { + uplefthelper = new PNDialogHelper(); + } + countTokens(uplefthelper, tri.getLeft().getText()); + } + else { + uplefthelper = null; + } + if (tri.getMiddle() != null) { + if (uphelper == null) { + uphelper = new PNDialogHelper(); + } + countTokens(uphelper, tri.getMiddle().getText()); + } + else { + uphelper = null; + } + if (tri.getRight() != null) { + if (uprighthelper == null) { + uprighthelper = new PNDialogHelper(); + } + countTokens(uprighthelper, tri.getRight().getText()); + } + else { + uprighthelper = null; + } + } + else { + countTokens(uphelper, transitionNodeShape.getParent().getText()); + } + } + if (transitionNodeShape.getTrPos() != TransitionPosition.FINAL) { + ABindingShape b = transitionNodeShape.getChild(); + if (b instanceof TriBinding) { + downtype = DownWeightingType.TRI; + TriBinding tri = (TriBinding) b; + if (downlefthelper == null) { + downlefthelper = new PNDialogHelper(); + } + if (downrighthelper == null) { + downrighthelper = new PNDialogHelper(); + } + if (tri.getLeft() != null) { + countTokens(downlefthelper, tri.getLeft().getText()); + } + else { + downtype = DownWeightingType.BI; + } + if (tri.getMiddle() != null) { + countTokens(downhelper, tri.getMiddle().getText()); + } + if (tri.getRight() != null) { + countTokens(downrighthelper, tri.getRight().getText()); + } + else { + downtype = DownWeightingType.BI; + } + } + else if (b != null) { + countTokens(downhelper, b.getText()); + downtype = DownWeightingType.MONO; + } + } + } + } + + @Override + public void edit(String t, String d) { + pnsetup(null); + defineOwnContent(); + super.edit(t, d); + } + + @Override + public String getTransitionText() { + if (transitionNodeShape.getTrPos() != TransitionPosition.INITIAL) { + ABindingShape b = transitionNodeShape.getParent(); + if (b instanceof TriBinding) { + TriBinding tri = (TriBinding) b; + if (tri.getLeft() != null) { + tri.getLeft().setText(uplefthelper.toString()); + } + if (tri.getMiddle() != null) { + tri.getMiddle().setText(uphelper.toString()); + } + if (tri.getRight() != null) { + tri.getRight().setText(uprighthelper.toString()); + } + } + else { + if (transitionNodeShape.getParent() != null) { + transitionNodeShape.getParent().setText(uphelper.toString()); + } + } + } + if (transitionNodeShape.getTrPos() != TransitionPosition.FINAL) { + if (transitionNodeShape.getChild() != null) { + ABindingShape b = transitionNodeShape.getChild(); + if (b instanceof TriBinding) { + ((TriBinding) b).getLeft().setText(downlefthelper.toString()); + ((TriBinding) b).getMiddle().setText(downhelper.toString()); + if (((TriBinding) b).getRight() != null) { + ((TriBinding) b).getRight().setText(downrighthelper.toString()); + } + } + else { + b.setText(downhelper.toString()); + } + } + } + return super.getTransitionText(); + } + + // + private void countTokens(PNDialogHelper helper, String text) { + if (text == null || text.isEmpty()) { + helper.setNbBlack(1); + } + else { + String[] sp = text.split("\\."); + for (int i=0; i 0) { + defaultNumber = x; + } + } + catch(NumberFormatException e) { + } + } + + @Override + public void actionPerformed(ActionEvent e) { + setVisible(false); + } + + @Override + public boolean isOk() { + return gal.isOk(); + } + + public void edit(String t, String d) { + nfield.setText(t); + updateFields(); + setVisible(true); + } + + public String getTransitionText() { + if (gal.isOk() || gal.isInitial()) { + return nfield.getText(); + } + return null; + } + + public String getDescription() { + if (gal.isOk() || gal.isInitial()) { + return area.getText(); + } + return null; + } + + + public String getDefaultWeightOrColor() { + if (isColored) { + return COLORS.substring(0, defaultNumber*2-1); + } + return ""+defaultNumber; + } +} diff --git a/src/clp/edit/graphics/dial/PlaceDialog.java b/src/clp/edit/graphics/dial/PlaceDialog.java new file mode 100644 index 0000000..4942c95 --- /dev/null +++ b/src/clp/edit/graphics/dial/PlaceDialog.java @@ -0,0 +1,199 @@ +package clp.edit.graphics.dial; + +import java.awt.Frame; +import java.util.List; + +import javax.swing.BorderFactory; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.SpringLayout; +import javax.swing.border.EtchedBorder; +import javax.swing.border.TitledBorder; + +import clp.edit.graphics.code.ClappInstruction; +import clp.edit.graphics.shapes.ActionShape; +import clp.edit.graphics.shapes.pn.PlaceNodeShape; +import clp.edit.graphics.shapes.pn.PlaceNodeShape.ColorInfo; + + +public class PlaceDialog extends ActionOrStepDialog { + + private static final long serialVersionUID = 3157746775633064158L; + + private PNDialogHelper helper; + + private boolean isColored; + + private boolean isPlaceSetup; + + /** + * CONSTRUCTOR + * + * @param parent + * @param isColored + * @param caller + * @param list + */ + public PlaceDialog(Frame parent, boolean isColored, ActionShape caller, List list) { + super(parent, caller, list); + helper = new PNDialogHelper(); + this.isColored = isColored; + defineOwnContent(); + isPlaceSetup = true; + } + + // + public void count(ColorInfo[] tokens) { + for (ColorInfo ci : tokens) { + switch (ci.getC()) { + case 'R': + helper.incNbRed(); + break; + case 'G': + helper.incNbGreen(); + break; + case 'B': + helper.incNbBlue(); + break; + case 'Y': + helper.incNbYellow(); + break; + case 'O': + helper.incNbOrange(); + break; + case 'C': + helper.incNbCyan(); + break; + + default: + helper.incNbBlack(); + break; + } + } + } + + public void recount(ColorInfo[] tokens) { + helper.resetAll(); + if (tokens != null) { + count(tokens); + } + defineOwnContent(); + } + + @Override + public void defineContent() { + if (isPlaceSetup) { + defineOwnContent(); + pack(); + } + } + + @Override + public void edit(String t, String d) { + defineOwnContent(); + super.edit(t, d); + } + + public void defineOwnContent() { + getContentPane().removeAll(); + + getContentPane().add(createDescriptionPanel()); + getContentPane().add(createWeightingPanel()); + getContentPane().add(createInstructionsPanel()); + getContentPane().add(createControlsPanel()); + + makeCompactGrid(getContentPane(), 4, 1, 6, 6, 6, 6); + } + + @Override + public JPanel createDescriptionPanel() { + JPanel p = new JPanel(new SpringLayout()); + TitledBorder border = BorderFactory.createTitledBorder( + BorderFactory.createBevelBorder(EtchedBorder.RAISED), + "Place Description"); + p.setBorder(border); + + JLabel l = new JLabel("Place name:", JLabel.TRAILING); + p.add(l); + l.setLabelFor(getNamefield()); + p.add(getNamefield()); + + l = new JLabel("Place description:", JLabel.TRAILING); + p.add(l); + l.setLabelFor(getDescriptionfield()); + p.add(getDescriptionfield()); + + makeCompactGrid(p, 2, 2, 6, 6, 6, 6); + p.setOpaque(true); + return p; + } + + // + private JPanel createWeightingPanel() { + JPanel p = new JPanel(new SpringLayout()); + TitledBorder border = BorderFactory.createTitledBorder( + BorderFactory.createBevelBorder(EtchedBorder.RAISED), + "Weighting"); + p.setBorder(border); + + if (isColored) { + p.add(new JLabel("Red")); + p.add(new JLabel("Green")); + p.add(new JLabel("Blue")); + p.add(new JLabel("Yellow")); + p.add(new JLabel("Orange")); + p.add(new JLabel("Cyan")); + + p.add(helper.createField("Red", ""+helper.getNbRed())); + p.add(helper.createField("Green", ""+helper.getNbGreen())); + p.add(helper.createField("Blue", ""+helper.getNbBlue())); + p.add(helper.createField("Yellow", ""+helper.getNbYellow())); + p.add(helper.createField("Orange", ""+helper.getNbOrange())); + p.add(helper.createField("Cyan", ""+helper.getNbCyan())); + + makeCompactGrid(p, 2, 6, 6, 6, 6, 6); + } + else { + p.add(new JLabel("Nb Tokens")); + p.add(helper.createField("Black", ""+helper.getNbBlack())); + makeCompactGrid(p, 2, 1, 6, 6, 6, 6); + } + + p.setOpaque(true); + return p; + } + + public ColorInfo[] createTokens(PlaceNodeShape placeNodeShape) { + if (!isColored) { + ColorInfo[] tokens = new ColorInfo[helper.getNbBlack()]; + create(tokens, placeNodeShape, 0, helper.getNbBlack(), 'N'); + return tokens; + } + ColorInfo[] tokens = new ColorInfo[helper.getAll()]; + int index = create(tokens, placeNodeShape, 0, helper.getNbRed(), 'R'); + index = create(tokens, placeNodeShape, index, helper.getNbGreen(), 'G'); + index = create(tokens, placeNodeShape, index, helper.getNbBlue(), 'B'); + index = create(tokens, placeNodeShape, index, helper.getNbYellow(), 'Y'); + index = create(tokens, placeNodeShape, index, helper.getNbOrange(), 'O'); + create(tokens, placeNodeShape, index, helper.getNbCyan(), 'C'); + return tokens; + } + + // + private int create(ColorInfo[] tokens, PlaceNodeShape placeNodeShape, int index, int nb, char c) { + for (int i=index; i 0) { + fillTokens(tks, 0, helper.getNbBlack(), 'N'); + } + else { + int i = 0; + i = fillTokens(tks, i, helper.getNbRed(), 'R'); + i = fillTokens(tks, i, helper.getNbGreen(), 'G'); + i = fillTokens(tks, i, helper.getNbBlue(), 'B'); + i = fillTokens(tks, i, helper.getNbYellow(), 'Y'); + i = fillTokens(tks, i, helper.getNbOrange(), 'O'); + i = fillTokens(tks, i, helper.getNbCyan(), 'C'); + } + return tks; + } + + private static int fillTokens(Token[] tks, int i, int nb, char c) { + if (nb > 0) { + Token token = new Token(); + tks[i++] = token; + token.nb = nb; + token.c = c; + } + return i; + } +} diff --git a/src/clp/edit/graphics/dial/TransitionDialog.java b/src/clp/edit/graphics/dial/TransitionDialog.java new file mode 100644 index 0000000..4b9ffb6 --- /dev/null +++ b/src/clp/edit/graphics/dial/TransitionDialog.java @@ -0,0 +1,566 @@ +package clp.edit.graphics.dial; + +import java.awt.Dimension; +import java.awt.Frame; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.GridLayout; +import java.awt.Point; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; + +import javax.swing.BorderFactory; +import javax.swing.Box; +import javax.swing.ButtonGroup; +import javax.swing.JButton; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JRadioButton; +import javax.swing.SwingUtilities; +import javax.swing.border.EtchedBorder; +import javax.swing.border.TitledBorder; + +import clp.edit.GeneralContext; +import clp.edit.dialog.ADialog; +import clp.edit.graphics.shapes.AShape; +import clp.edit.graphics.shapes.ATransitionRoot; +import clp.edit.graphics.shapes.ATransitionShape; +import clp.edit.graphics.shapes.pn.InvisibleNode; +import clp.edit.graphics.shapes.pn.PlaceNodeShape; +import clp.edit.graphics.shapes.pn.TransitionNodeShape; +import clp.run.res.Unit; +import clp.run.res.VarType; + + +public class TransitionDialog extends ADialog implements ActionListener { + + private static final long serialVersionUID = -3695542361226180194L; + + private GenericActionListener gal; + + private GridBagConstraints c; + + private JButton okButton; + + private ATransitionShape transitionNodeShape; + private ATransitionRoot transitionRootShape; + + + /** + * CONSTRUCTOR + * + * @param frame + * @param ts transitionNodeShape + * @param tr transitionRootShape + * @param height + */ + public TransitionDialog(Frame frame, ATransitionShape ts, ATransitionRoot tr, int height) { + super(frame, "Defining a Transition Item", true); + transitionNodeShape = ts; + transitionRootShape = tr; + setup(frame, height); + } + + // + private void setup(Frame frame, int height) { + if (frame != null) { + Dimension frameSize = frame.getSize(); + Point p = frame.getLocation(); + setLocation(p.x + frameSize.width / 4, p.y + frameSize.height / 4); + } + + + setLayout(new GridBagLayout()); + c = new GridBagConstraints(); + c.fill = GridBagConstraints.HORIZONTAL; + setPreferredSize(new Dimension(650, height)); + + okButton = new JButton("ok"); + gal = new GenericActionListener(this); + okButton.addActionListener(gal); + + defineContent(c, okButton); + + setDefaultCloseOperation(DISPOSE_ON_CLOSE); + pack(); + } + + // + public void defineContent(GridBagConstraints c, JButton okButton) { + getContentPane().removeAll(); + c.gridy = 0; + c.gridx = 0; + getContentPane().add(new JLabel("Transition Type"), c); + c.gridx++; + getContentPane().add(Box.createVerticalStrut(5), c); + c.gridx++; + c.gridwidth = getGridWidthAccordingToType(); + JPanel jp1 = createRadioButtonsForType(); + getContentPane().add(jp1, c); + + c.gridy++; + c.gridx = 0; + c.gridwidth = 1; + getContentPane().add(Box.createVerticalStrut(5), c); + + c.gridy++; + c.gridx = 0; + getContentPane().add(new JLabel("Crossing"), c); + c.gridx++; + getContentPane().add(Box.createVerticalStrut(5), c); + c.gridx++; + boolean isDescriptionRequested = createCrossingFromType(c); + + if (isDescriptionRequested) { + c.gridy++; + c.gridx = 0; + getContentPane().add(new JLabel("Description"), c); + c.gridx++; + getContentPane().add(Box.createVerticalStrut(5), c); + c.gridx++; + c.gridwidth = 3; + getContentPane().add(getClassicInfo().getEventDescriptionField(), c); + c.gridx += 3; + c.gridwidth = 1; + getContentPane().add(Box.createVerticalStrut(5), c); + c.gridx++; + getContentPane().add(getClassicInfo().getConditionDescriptionField(), c); + } + + c.gridy++; + c.gridx = 0; + getContentPane().add(Box.createVerticalStrut(5), c); + + c.gridy++; + c.gridx = 1; + c.gridwidth = 2; + getContentPane().add(okButton, c); + } + + // + private int getGridWidthAccordingToType() { + switch (getTrType()) { + case TAUTOLOGY: + return 1; + case CLASSICAL: + return 5; + case DELAY: + return 7; + default: + break; + } + return 0; + } + + // + protected boolean createCrossingFromType(GridBagConstraints c) { + switch (getTrType()) { + case TAUTOLOGY: + getContentPane().add(getTautology(), c); + break; + case CLASSICAL: + getContentPane().add(getClassicInfo().getArrowfield(), c); + c.gridx++; + getContentPane().add(Box.createVerticalStrut(5), c); + c.gridx++; + getContentPane().add(getClassicInfo().getEventfield(), c); + c.gridx++; + getContentPane().add(Box.createVerticalStrut(5), c); + c.gridx++; + getContentPane().add(getClassicInfo().getConditionfield(), c); + return true; + case DELAY: + getContentPane().add(new JLabel("Step N°"), c); + c.gridx++; + getContentPane().add(Box.createVerticalStrut(5), c); + c.gridx++; + getContentPane().add(getDelayInfo().getStepfield(), c); + c.gridx++; + getContentPane().add(Box.createVerticalStrut(5), c); + c.gridx++; + getContentPane().add(new JLabel("Delay"), c); + c.gridx++; + getContentPane().add(getDelayInfo().getDelayfield(), c); + c.gridx++; + getContentPane().add(getDelayInfo().getUnitfield(), c); + break; + + default: + break; + } + return false; + } + + // + protected JPanel createRadioButtonsForType() { + JPanel jp = new JPanel(); + jp.setLayout(new GridLayout()); + TitledBorder border = BorderFactory.createTitledBorder( + BorderFactory.createBevelBorder(EtchedBorder.LOWERED), + "Choose Transition Type"); + jp.setBorder(border); + + ItemListener radioListener = new ItemListener() { + @Override + public void itemStateChanged(ItemEvent e) { + JRadioButton rb = (JRadioButton) e.getSource(); + if (rb.isSelected()) { + setTrType( TransitionType.getName(rb.getText()) ); + refresh(); + } + } + }; + ButtonGroup group = new ButtonGroup(); + for (TransitionType t : TransitionType.values()) { + JRadioButton rb = new JRadioButton(t.getVal(), true); + jp.add(rb); rb.addItemListener(radioListener); + if (t == getTrType()) { + if (!rb.isSelected()) { + rb.setSelected(true); + } + } + else if (rb.isSelected()) { + rb.setSelected(false); + } + group.add(rb); + } + return jp; + } + + @Override + public void actionPerformed(ActionEvent e) { + setVisible(false); + } + + public String getTransitionText() { + switch (getTrType()) { + case TAUTOLOGY: + return getTautology().getText(); + case CLASSICAL: + return getClassicInfo().toString(); + case DELAY: + return getDelayInfo().toString(); + + default: + break; + } + return null; + } + + public void edit(String t, String d) { + switch (getTrType()) { + case TAUTOLOGY: + getTautology().setText(t); + break; + case CLASSICAL: + getClassicInfo().parse(t); + break; + case DELAY: + getDelayInfo().parse(t); + break; + + default: + break; + } + setVisible(true); + } + + public void refresh() { + SwingUtilities.invokeLater(new Runnable() { + public void run() { + defineContent(c, okButton); + getRootPane().updateUI(); + } + }); + } + + @Override + public boolean isOk() { + return gal.isOk(); + } + + /** + * @return the classicInfo + */ + public ClassicGroup getClassicInfo() { + if (transitionNodeShape != null) { + return transitionNodeShape.getClassicInfo(); + } + return transitionRootShape.getClassicInfo(); + } + + /** + * @return the delayInfo + */ + public DelayGroup getDelayInfo() { + if (transitionNodeShape != null) { + return transitionNodeShape.getDelayInfo(); + } + return transitionRootShape.getDelayInfo(); + } + + public String getActivationCondition(String name, TransitionNodeShape node) { + boolean isParentInvisibleNode = (node.getParent().getParent() instanceof InvisibleNode); + String s = null; + switch (getTrType()) { + case CLASSICAL: + if (isParentInvisibleNode) { + name = null; + } + s = fillFromClassicInfo(name, true); + break; + case DELAY: + DelayGroup dinfo = node.getDelayInfo(); + s = dinfo.getStep('P'); + boolean isCyclic = s.equals("C"); + boolean isAccepted = isCyclic || s.endsWith("0") || s.equals(name); + String step = isCyclic || name.startsWith("INIT") && s.endsWith("0") ? name : s; + String timeIdentifier = dinfo.getTimeIdentifier(); + if (isAccepted) { + s = " activated(" + step + ") SINCE " + timeIdentifier; + addDelay(step, timeIdentifier, dinfo.getDelay(), dinfo.getUnit(), isCyclic); + } + else if (!isParentInvisibleNode) { + s = " activated(" + name + ")"; + } + else { + s = ""; + } + break; + case TAUTOLOGY: + if (node != null) { + if (!isParentInvisibleNode) { + addInputVariable(node.getName(), "", null, true); + } + if (!isParentInvisibleNode) { + s = " activated(" + name + ")"; + } + } + break; + } + return s; + } + + public String getActivationCondition(String n, char prefix, AShape node) { +// clearResources(); + boolean isToken = node instanceof PlaceNodeShape ? true : false; + boolean isParentInvisibleNode = (node instanceof InvisibleNode); + String name = n != null ? n : node.getName(); + String s = null; + switch (getTrType()) { + case CLASSICAL: + if (isParentInvisibleNode) { + name = null; + } + s = fillFromClassicInfo(name, isToken); + break; + case DELAY: + s = fillFromDelayInfo(name, prefix, true); + break; + case TAUTOLOGY: + if (node != null) { + if (isToken && !isParentInvisibleNode) { + addInputVariable(node.getName(), "", null, true); + } + if (!isParentInvisibleNode) { + s = " activated(" + name + ")"; + } + } + break; + } + return s; + } + + public String getDeactivationCondition(String name, char prefix, AShape node) { + String s = null; + switch (getTrType()) { + case TAUTOLOGY: + if (prefix == 'F') { + s = " TRUE"; + } + else { + s = " activated(" + name + ")"; + } + break; + case CLASSICAL: + if (name == null) { // case of final node + s = "TRUE"; + } + else { + s = "activated(" + name + ")"; + } + break; + case DELAY: + if (name == null) { // case of final node + s = fillFromDelayInfo(node.getName(), prefix, false); + } + else { + DelayGroup dinfo = getDelayInfo(); + if (!dinfo.getStep(prefix).equals("C")) { + s = "activated(" + name + ")"; + } + } + break; + } + return s; + } + + // + private String fillFromClassicInfo(String name, boolean isToken) { + ClassicGroup cinfo = getClassicInfo(); + String s = name == null ? "" : " activated(" + name + ")"; + switch (cinfo.getArrow()) { + case ClassicGroup.upArrow: + if (!s.isEmpty()) { + s += " AND "; + } + s += "isSetUp(" + cinfo.getEvent() + ")"; + addInputVariable(cinfo.getEvent(), cinfo.getEventDescription(), null, isToken); + checkRemovingInitActivation(name); + break; + case ClassicGroup.downArrow: + if (!s.isEmpty()) { + s += " AND "; + } + s += "isSetDown(" + cinfo.getEvent() + ")"; + addInputVariable(cinfo.getEvent(), cinfo.getEventDescription(), null, isToken); + checkRemovingInitActivation(name); + break; + default: + break; + } + String cnd = adaptToClapp(cinfo.getCondition()); + addInputVariable(cnd, cinfo.getConditionDescription(), VarType.TBOOL, isToken); + if (cnd != null && !cnd.isEmpty()) { + cnd = cnd.replace("+", " OR "); + cnd = cnd.replace(".", " AND "); + if (!s.isEmpty()) { + s += " AND "; + } + s += cnd; + } + return s; + } + + // + private String adaptToClapp(String str) { + if (str != null) { + int op = getOperatorPosition(str); + if (op > 0) { // condition pattern is: + String[] sp = str.split(" "); + if (sp.length == 3) { + return sp[1] + "(" + sp[0] + ", " + sp[2] + ")"; + } + } + } + return str; + } + + // + private int getOperatorPosition(String str) { + int i = str.indexOf("<"); + if (i > 0) { + return i; + } + i = str.indexOf(">"); + if (i > 0) { + return i; + } + i = str.indexOf("="); + if (i > 0) { + return i; + } + i = str.indexOf("#"); + if (i > 0) { + return i; + } + return 0; + } + + // + private void addInputVariable(String cnd, String desc, VarType type, boolean isToken) { + if (transitionNodeShape != null) { + transitionNodeShape.addInputVariable(cnd, desc, type); + } + else { + transitionRootShape.addInputVariable(cnd, desc, type); + } + } + + // + private void checkRemovingInitActivation(String name) { + if (name != null && name.startsWith("INIT")) { + GeneralContext.getInstance().getGraphicsPanel().getShapesContainer().removeDeactivationForInit(name); + } + } + + // + private String fillFromDelayInfo(String name, char prefix, boolean isActivation) { + DelayGroup dinfo = getDelayInfo(); + String s = prefix == 'F' ? name : dinfo.getStep(prefix); + boolean isCyclic = s.equals("C"); + boolean isAccepted = isCyclic || s.endsWith("0") || name.equals(dinfo.getStep(prefix)); + if (!isAccepted) { + s = " activated(" + name + ")"; + } + else { + String step = isCyclic || name.startsWith("INIT") && s.endsWith("0") ? name : s; + String timeIdentifier = dinfo.getTimeIdentifier(); + if (isActivation || step.startsWith("INIT")) { + s = " activated(" + step + ") SINCE " + timeIdentifier; + addDelay(step, timeIdentifier, dinfo.getDelay(), dinfo.getUnit(), isCyclic); + } + } + return s; + } + + // + private void addDelay(String step, String timeIdentifier, int delay, Unit unit, boolean isCyclic) { + if (transitionNodeShape != null) { + transitionNodeShape.addDelay(step, timeIdentifier, delay, unit, isCyclic); + } + else { + transitionRootShape.addDelay(step, timeIdentifier, delay, unit, isCyclic); + } + } + + /** + * @return the okButton + */ + public JButton getOkButton() { + return okButton; + } + + /** + * @return the tautology + */ + public JLabel getTautology() { + if (transitionNodeShape != null) { + return transitionNodeShape.getTautology(); + } + return transitionRootShape.getTautology(); + } + + @Override + public String getDescription() { + return null; + } + + public TransitionType getTrType() { + if (transitionNodeShape != null) { + return transitionNodeShape.getTrType(); + } + return transitionRootShape.getTrType(); + } + + public void setTrType(TransitionType tp) { + if (transitionNodeShape != null) { + transitionNodeShape.setTrType(tp); + } + else { + transitionRootShape.setTrType(tp); + } + } +} diff --git a/src/clp/edit/graphics/dial/TransitionRootDialog.java b/src/clp/edit/graphics/dial/TransitionRootDialog.java new file mode 100644 index 0000000..d50ebc4 --- /dev/null +++ b/src/clp/edit/graphics/dial/TransitionRootDialog.java @@ -0,0 +1,22 @@ +package clp.edit.graphics.dial; + +import java.awt.Frame; + +import clp.edit.graphics.shapes.ATransitionRoot; + + +public class TransitionRootDialog extends TransitionDialog { + + private static final long serialVersionUID = 3254365094632125403L; + + + /** + * CONSTRUCTOR + * + * @param frame + * @param ts transitionNodeShape + */ + public TransitionRootDialog(Frame frame, ATransitionRoot ts) { + super(frame, null, ts, 200); + } +} diff --git a/src/clp/edit/graphics/dial/TransitionType.java b/src/clp/edit/graphics/dial/TransitionType.java new file mode 100644 index 0000000..f524630 --- /dev/null +++ b/src/clp/edit/graphics/dial/TransitionType.java @@ -0,0 +1,26 @@ +package clp.edit.graphics.dial; + +public enum TransitionType { + + TAUTOLOGY("Tautology (= 1)"), CLASSICAL("Events & Conditions"), DELAY("Temporary Delay"); + + private String value; + + private TransitionType(String s) { + value = s; + } + + static TransitionType getName(String selectedItem) { + TransitionType[] names = values(); + for (TransitionType t : names) { + if (t.value.equalsIgnoreCase(selectedItem)) { + return t; + } + } + return null; + } + + public String getVal() { + return value; + } +} diff --git a/src/clp/edit/graphics/panel/ButtonsContainer.java b/src/clp/edit/graphics/panel/ButtonsContainer.java new file mode 100644 index 0000000..ff44521 --- /dev/null +++ b/src/clp/edit/graphics/panel/ButtonsContainer.java @@ -0,0 +1,313 @@ +package clp.edit.graphics.panel; + +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.GridLayout; +import java.awt.Rectangle; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; +import java.util.ArrayList; +import java.util.Enumeration; + +import javax.swing.AbstractButton; +import javax.swing.BorderFactory; +import javax.swing.ButtonGroup; +import javax.swing.JButton; +import javax.swing.JPanel; +import javax.swing.JRadioButton; +import javax.swing.SwingUtilities; +import javax.swing.border.EtchedBorder; +import javax.swing.border.TitledBorder; + +import clp.edit.GeneralContext; +import clp.edit.graphics.btn.act.ActigramButtonsPanel; +import clp.edit.graphics.btn.gc.GrafcetButtonsPanel; +import clp.edit.graphics.btn.pn.PetriNetsButtonsPanel; +import clp.edit.graphics.code.gui.GuiHandlerDialog; +import clp.edit.graphics.code.java.bci.JavaBCIHandlerDialog; +import clp.edit.graphics.code.prt.ConsHandlerDialog; +import clp.edit.graphics.code.web.WebHandlerDialog; + +public class ButtonsContainer extends JPanel { + + private static final long serialVersionUID = 5137435211589749278L; + + public static enum ButtonType { + ACT, SFC, WPN, CPN; + } + + private JRadioButton agm; + private JRadioButton gfc; + private JRadioButton cpn; + private JRadioButton wpn; + + transient private ItemListener radioListener; + private JRadioButton selection; + + private ButtonGroup group; + + private ActigramButtonsPanel actigramButtonsPanel; + private GrafcetButtonsPanel grafcetButtonsPanel; + private PetriNetsButtonsPanel cpnButtonsPanel; + private PetriNetsButtonsPanel wpnButtonsPanel; + + private GeneralShapesContainer shapesContainer; + + private ArrayList uiList; + private ArrayList bciList; + private ArrayList webList; + private ArrayList cslList; + + transient private JButton uiButton; + transient private JButton bciButton; + transient private JButton webButton; + transient private JButton cslButton; + + /** + * CONSTRUCTOR + * + * @param shapesContainer + */ + public ButtonsContainer(GeneralShapesContainer shapesContainer) { + setLayout(new BorderLayout()); + this.shapesContainer = shapesContainer; + uiList = new ArrayList<>(); + bciList = new ArrayList<>(); + webList = new ArrayList<>(); + cslList = new ArrayList<>(); + setup(); + } + + // + private void setup() { + Rectangle rect = shapesContainer.getBounds(); + setPreferredSize(new Dimension(rect.width, 120)); + setSize(new Dimension(rect.width, 120)); + setupRadioListener(); + + add(createFlowChartButtons(), BorderLayout.WEST); + + add(createGlobalButtons(), BorderLayout.EAST); + + addButtonsFromSelected(); + createListeners(); + } + + // + private JPanel createFlowChartButtons() { + group = new ButtonGroup(); + JPanel jp = new JPanel(); + jp.setLayout(new GridLayout()); + TitledBorder border = BorderFactory.createTitledBorder( + BorderFactory.createBevelBorder(EtchedBorder.LOWERED), + "Choose Flow Chart Type"); + jp.setBorder(border); + + agm = new JRadioButton("Activity Diagram", true); + jp.add(agm); + agm.setName(ButtonType.ACT.name()); + selection = agm; + group.add(agm); + + gfc = new JRadioButton("Grafcet (SFC)"); + jp.add(gfc); + gfc.setName(ButtonType.SFC.name()); + group.add(gfc); + + wpn = new JRadioButton("Weighted Petri Nets"); + jp.add(wpn); + wpn.setName(ButtonType.WPN.name()); + group.add(wpn); + + cpn = new JRadioButton("Colored Petri Nets"); + jp.add(cpn); + cpn.setName(ButtonType.CPN.name()); + group.add(cpn); + return jp; + } + + // + private JPanel createGlobalButtons() { + JPanel jp = new JPanel(); + jp.setLayout(new FlowLayout()); + TitledBorder border = BorderFactory.createTitledBorder( + BorderFactory.createBevelBorder(EtchedBorder.RAISED), + "Global Items"); + jp.setBorder(border); + uiButton = new JButton("GUI"); + uiButton.setToolTipText("Define GUI"); + jp.add(uiButton); + bciButton = new JButton("BCI"); + bciButton.setToolTipText("Define Byte-Code Injection"); + jp.add(bciButton); + webButton = new JButton("WEB"); + webButton.setToolTipText("Define Web Sender"); + jp.add(webButton); + cslButton = new JButton("CSL"); + cslButton.setToolTipText("Define Output Console
will only be active on exported project"); + jp.add(cslButton); + return jp; + } + + // + private void createListeners() { + setupRadioListener(); + agm.addItemListener(radioListener); + gfc.addItemListener(radioListener); + wpn.addItemListener(radioListener); + cpn.addItemListener(radioListener); + if (actigramButtonsPanel != null ) { + actigramButtonsPanel.createListeners(); + } + if (grafcetButtonsPanel != null) { + grafcetButtonsPanel.createListeners(); + } + if (cpnButtonsPanel != null) { + cpnButtonsPanel.createListeners(); + } + if (wpnButtonsPanel != null) { + wpnButtonsPanel.createListeners(); + } + uiButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + GuiHandlerDialog dial = new GuiHandlerDialog(GeneralContext.getInstance().getFrame(), new ArrayList<>(uiList), shapesContainer.getGuiContext()); + if (dial.isOk()) { + uiList = (ArrayList) dial.getUiList(); + } + } + }); + bciButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + JavaBCIHandlerDialog dial = new JavaBCIHandlerDialog(GeneralContext.getInstance().getFrame(), new ArrayList<>(bciList), shapesContainer.getJavaContext()); + if (dial.isOk()) { + bciList = (ArrayList) dial.getBciList(); + } + } + }); + webButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + WebHandlerDialog dial = new WebHandlerDialog(GeneralContext.getInstance().getFrame(), new ArrayList<>(webList), shapesContainer.getWebContext()); + if (dial.isOk()) { + webList = (ArrayList) dial.getWebList(); + } + } + }); + cslButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + ConsHandlerDialog dial = new ConsHandlerDialog(GeneralContext.getInstance().getFrame(), new ArrayList<>(cslList), shapesContainer.getConsoleContext()); + if (dial.isOk()) { + cslList = (ArrayList) dial.getConsolesList(); + } + } + }); + } + + public void recoverGlobalButtons() { + JPanel jp = (JPanel) getComponent(1); + uiButton = (JButton) jp.getComponent(0); + bciButton = (JButton) jp.getComponent(1); + webButton = (JButton) jp.getComponent(2); + cslButton = (JButton) jp.getComponent(3); + createListeners(); + } + + // + private void setupRadioListener() { + radioListener = new ItemListener() { + @Override + public void itemStateChanged(ItemEvent e) { + JRadioButton rb = (JRadioButton) e.getSource(); + if (rb.isSelected()) { + selection = rb; + SwingUtilities.invokeLater(new Runnable() { + public void run() { + addButtonsFromSelected(); + revalidate(); + updateUI(); + } + }); + } + } + }; + } + + // + private void addButtonsFromSelected() { + if (getComponentCount() > 2) { + remove(2); + } + if (selection == agm) { + if (actigramButtonsPanel == null ) { + actigramButtonsPanel = new ActigramButtonsPanel(shapesContainer); + } + add(actigramButtonsPanel, BorderLayout.SOUTH); + } + else if (selection == gfc) { + if (grafcetButtonsPanel == null) { + grafcetButtonsPanel = new GrafcetButtonsPanel(shapesContainer); + } + add(grafcetButtonsPanel, BorderLayout.SOUTH); + } + else if (selection == cpn) { + if (cpnButtonsPanel == null) { + cpnButtonsPanel = new PetriNetsButtonsPanel(true); + } + add(cpnButtonsPanel, BorderLayout.SOUTH); + } + else if (selection == wpn) { + if (wpnButtonsPanel == null) { + wpnButtonsPanel = new PetriNetsButtonsPanel(false); + } + add(wpnButtonsPanel, BorderLayout.SOUTH); + } + } + + public void updateRadioButtons(ButtonType type) { + for (Enumeration btns = group.getElements(); btns.hasMoreElements();) { + AbstractButton btn = btns.nextElement(); + ButtonType btype = ButtonType.valueOf( btn.getName() ); + if (btype == type) { + selection.setSelected(false); + selection = (JRadioButton) btn; + selection.setSelected(true); + break; + } + } + } + + public ActigramButtonsPanel getActigramButtonsPanel() { + return actigramButtonsPanel; + } + + /** + * @return the grafcetButtonsPanel + */ + public GrafcetButtonsPanel getGrafcetButtonsPanel() { + return grafcetButtonsPanel; + } + + /** + * @param isColored + * @return the pnButtonsPanel + */ + public PetriNetsButtonsPanel getPNButtonsPanel(boolean isColored) { + if (isColored) { + return cpnButtonsPanel; + } + return wpnButtonsPanel; + } + + public void setButtonsEnabled(boolean b) { + agm.setEnabled(b); + gfc.setEnabled(b); + cpn.setEnabled(b); + wpn.setEnabled(b); + } +} diff --git a/src/clp/edit/graphics/panel/ConfirmationDialog.java b/src/clp/edit/graphics/panel/ConfirmationDialog.java new file mode 100644 index 0000000..c235742 --- /dev/null +++ b/src/clp/edit/graphics/panel/ConfirmationDialog.java @@ -0,0 +1,79 @@ +package clp.edit.graphics.panel; + +import java.awt.Dimension; +import java.awt.Frame; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Point; + +import javax.swing.JButton; +import javax.swing.JDialog; +import javax.swing.JLabel; + +import clp.edit.graphics.dial.GenericActionListener; + +public class ConfirmationDialog extends JDialog { + + private static final long serialVersionUID = 6487459610119222090L; + + private GridBagConstraints c; + + private JButton okButton; + private JButton cancelButton; + private GenericActionListener gal; + + /** + * CONSTRUCTOR + * + * @param parent + */ + public ConfirmationDialog(Frame parent) { + super(parent, "Confirmation Dialog", true); + setup(parent); + setVisible(true); + } + + // + private void setup(Frame parent) { + if (parent != null) { + Dimension parentSize = parent.getSize(); + Point p = parent.getLocation(); + setLocation(p.x + parentSize.width / 4, p.y + parentSize.height / 4); + } + setPreferredSize(new Dimension(600, 200)); + setLayout(new GridBagLayout()); + + c = new GridBagConstraints(); + okButton = new JButton("ok"); + gal = new GenericActionListener(this); + okButton.addActionListener(gal); + + cancelButton = new JButton("cancel"); + cancelButton.addActionListener(gal); + + fillContent(); + + setDefaultCloseOperation(DISPOSE_ON_CLOSE); + pack(); + } + + // + private void fillContent() { + c.gridy = 0; + c.gridx = 0; + c.gridwidth = 2; + getContentPane().add(new JLabel("Do you really want to delete this container?"), c); + + c.gridy = 2; + c.gridx = 0; + c.gridwidth = 1; + getContentPane().add(cancelButton, c); + + c.gridx = 1; + getContentPane().add(okButton, c); + } + + public boolean isOk() { + return gal.isOk(); + } +} diff --git a/src/clp/edit/graphics/panel/ControlInfo.java b/src/clp/edit/graphics/panel/ControlInfo.java new file mode 100644 index 0000000..c988abd --- /dev/null +++ b/src/clp/edit/graphics/panel/ControlInfo.java @@ -0,0 +1,229 @@ +package clp.edit.graphics.panel; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.Serializable; + +import javax.swing.JComponent; +import javax.swing.JToggleButton; + +import clapp.run.token.EventHandler; +import clapp.run.util.ResourceUtility; +import clp.edit.graphics.panel.cntrl.AInputButton; +import clp.edit.graphics.panel.cntrl.ConditionButton; +import clp.edit.graphics.panel.cntrl.EventButton; +import clp.edit.graphics.panel.cntrl.OutputButton; +import clp.edit.graphics.panel.cntrl.OutputPanel; +import clp.run.res.VarType; + +public class ControlInfo implements Serializable { + + private static final long serialVersionUID = 3215829060572545836L; + + private String name; + private String text; + private VarType varType; + private JComponent component; + + private String content; + + private int index; + + private String init; + + private boolean isInput; + + public ControlInfo(String n, String x, VarType t, boolean b) { + name = n; + text = x; + varType = t; + isInput = b; + setup(true); + } + + public void setup(boolean isCreate) { + if (varType == null) { + // this one is an event + createEventToggleButton(isCreate); + } + else { + switch (varType) { + case TBOOL: + if (isInput) { + createConditionButton(isCreate); + } + else { + if (isCreate) { + createOutputButton(); + } + } + break; + case TREF: + case TDATE: + case TTIME: + case TINT: + case TFLOAT: + case TLONG: + case TSTRING: + if (isCreate) { + createOutputPanel(); + } + break; + + default: + break; + } + } + } + + // + private void createEventToggleButton(boolean isCreate) { + EventButton eb; + if (isCreate) { + eb = new EventButton(name, text); + component = eb; + } + else { + eb = (EventButton) component; + } + eb.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + JToggleButton b = (JToggleButton) e.getSource(); + EventHandler em = EventHandler.getInstance(); + em.markVarEvent(name, b.isSelected()); + } + }); + eb.setEnabled(false); + } + + // + private void createConditionButton(boolean isCreate) { + ConditionButton cb; + if (isCreate) { + cb = new ConditionButton(name, text); + component = cb; + } + else { + cb = (ConditionButton) component; + } + cb.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + JToggleButton b = (JToggleButton) e.getSource(); + ResourceUtility util = ResourceUtility.getInstance(); + util.setValue(name, b.isSelected()); + } + }); + cb.setEnabled(false); + } + + // + private void createOutputButton() { + component = new OutputButton(name); + } + + // + private void createOutputPanel() { + component = new OutputPanel(name, varType); + } + + public String toString() { + String txt; + switch (varType) { + case TBOOL: + txt = " BOOL " + name; + break; + case TINT: + txt = " INT " + name; + break; + case TFLOAT: + txt = " DOUBLE " + name; + break; + case TDATE: + txt = " DATE " + name; + break; + case TREF: + txt = " REF " + name; + break; + case TSTRING: + if (index > 0) { + txt = " STRING array[" + index + "] " + name; + } + else { + txt = " STRING " + name; + } + break; + case TUI: + return " UI " + name + content; + default: + txt = ""; + break; + } + if (init != null) { + txt += " = " + init; + } + return txt + ";"; + } + + public JComponent getComponent() { + return component; + } + + public String getName() { + return name; + } + + public VarType getType() { + return varType; + } + + public int getColumn() { + if (component instanceof AInputButton) { + return ((AInputButton)component).getCol(); + } + return -1; + } + + public int getLine() { + if (component instanceof AInputButton) { + return ((AInputButton)component).getLine(); + } + return -1; + } + + public void updateOutput() { + ResourceUtility util = ResourceUtility.getInstance(); + if (!isInput && component != null) { + if (component instanceof JToggleButton) { + ((JToggleButton)component).setSelected((boolean) util.getValue(name)); + } + else { + ((OutputPanel)component).setValue(util.getValue(name)); + } + } + } + + public void setupActionListener() { + if (component instanceof ConditionButton) { + ((ConditionButton)component).addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + JToggleButton b = (JToggleButton) e.getSource(); + ResourceUtility util = ResourceUtility.getInstance(); + util.setValue(name, b.isSelected()); + } + }); + } + else if (component instanceof EventButton) { + ((EventButton)component).addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + JToggleButton b = (JToggleButton) e.getSource(); + EventHandler em = EventHandler.getInstance(); + em.markVarEvent(name, b.isSelected()); + } + }); + } + } +} diff --git a/src/clp/edit/graphics/panel/ControlsContainer.java b/src/clp/edit/graphics/panel/ControlsContainer.java new file mode 100644 index 0000000..af71de7 --- /dev/null +++ b/src/clp/edit/graphics/panel/ControlsContainer.java @@ -0,0 +1,549 @@ +package clp.edit.graphics.panel; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.GridLayout; +import java.awt.Insets; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.ArrayList; +import java.util.Hashtable; + +import javax.swing.AbstractButton; +import javax.swing.BorderFactory; +import javax.swing.JComponent; +import javax.swing.JPanel; +import javax.swing.SwingUtilities; +import javax.swing.border.EtchedBorder; +import javax.swing.border.TitledBorder; + +import clapp.run.Supervisor; +import clapp.run.sim.api.ISimulator; +import clapp.run.token.MarkHandler; +import clapp.run.util.CellChainLink; +import clapp.run.util.CellQueueHandler; +import clp.edit.graphics.dial.Token; +import clp.edit.graphics.panel.cntrl.AInputButton; +import clp.edit.graphics.panel.cntrl.DummyButton; +import clp.edit.graphics.panel.cntrl.DummyConditionButton; +import clp.edit.graphics.panel.cntrl.DummyEventButton; +import clp.edit.graphics.panel.cntrl.DummyPanel; +import clp.edit.graphics.panel.cntrl.IOutput; +import clp.edit.graphics.panel.cntrl.OutputPanel; +import clp.edit.graphics.panel.cntrl.StartButton; +import clp.edit.graphics.shapes.ActionShape; +import clp.edit.handler.CLAppSourceHandler; +import clp.edit.panel.GraphicsPanel; +import clp.run.cel.Cell; +import clp.run.cel.Weightings; +import clp.run.res.VarType; +import clp.run.res.WebVariable; +import clp.run.res.Weighting; +import clp.run.res.ui.UiVar; +import clp.run.res.weave.WeaveVar; + +public class ControlsContainer extends JPanel implements ISimulator { + + private static final long serialVersionUID = 2187222681113479252L; + + private static final Insets insets = new Insets(3, 3, 3, 3); + + private StartButton startButton; + + private Hashtable activeQueues; + private Hashtable> previouslyActiveQueues; + + private boolean isSimulationRunning; + + private CLAppSourceHandler sourceHandler; + private SimulationHelper helper; + + private GraphicsPanel graphicsPanel; + private GeneralShapesContainer genericShapesContainer; + + private JPanel inputjp; + private GridBagConstraints gc; + + private JPanel outputjp; + + private Hashtable activities; + + + /** + * CONSTRUCTOR + * + * @param graphicsPanel + * @param shapesContainer + */ + public ControlsContainer(GraphicsPanel graphicsPanel, GeneralShapesContainer shapesContainer) { + setLayout(new BorderLayout()); + TitledBorder border = BorderFactory.createTitledBorder( + BorderFactory.createBevelBorder(EtchedBorder.LOWERED), + "Control"); + setBorder(border); + + this.graphicsPanel = graphicsPanel; + this.genericShapesContainer = shapesContainer; + + initializeFields(); + + JPanel jp1 = new JPanel(); + jp1.setLayout(new BorderLayout()); + add(jp1, BorderLayout.PAGE_START); + + JPanel jp2 = new JPanel(); + jp2.setLayout(new GridLayout(2,1)); + add(jp2, BorderLayout.CENTER); + + initializeStartArea(jp1); + + initializeInputArea(jp2); + + initializeOutputArea(jp2); + } + + // + private void initializeFields() { + activeQueues = new Hashtable<>(); + previouslyActiveQueues = new Hashtable<>(); + sourceHandler = new CLAppSourceHandler(); + helper = new SimulationHelper(this, sourceHandler); + activities = new Hashtable<>(); + + setPreferredSize(new Dimension(250, 0)); + } + + // + private void initializeStartArea(JPanel jp1) { + startButton = new StartButton(); + setupStartActionListener(); + jp1.add(startButton, BorderLayout.CENTER); + } + + // + public void setupStartActionListener() { + startButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + if (genericShapesContainer.getCurrentContainer() == null) { + return; + } + if (!isSimulationRunning) { + //===================== + // GENERATE SOURCE CODE + if (!helper.isGenerated()) { + helper.setDirty(true); + } + helper.generateCode(); + if (!helper.isGenerated() && helper.isDirty()) { + System.err.println("ERROR: problem found in code generation"); + } + else { + isSimulationRunning = true; + for (ControlInfo ci : helper.getControls()) { + if (ci.getComponent() instanceof AbstractButton) { + ((AbstractButton)ci.getComponent()).setEnabled(true); + } + else if (ci.getComponent() instanceof OutputPanel) { + ((OutputPanel)ci.getComponent()).disableIt(); + } + } + //=================================== + // GET SOURCE & TRIGGER SIMULATE + graphicsPanel.getButtonsContainer().setButtonsEnabled(false); + genericShapesContainer.setEnabled(false); + genericShapesContainer.getCurrentContainer().getAutomaton().enabling(false); + sourceHandler.startSimulation(ControlsContainer.this); + //=================================== + } + } + else { + if (Supervisor.getInstance() != null) { + Supervisor.getInstance().stopAll(ControlsContainer.this, null); // will call #onFinish() + } + } + } + }); + } + + // + public void setupControlActionListeners() { + for (ControlInfo ci : helper.getControls()) { + ci.setupActionListener(); + } + } + + // + private void initializeInputArea(JPanel jp2) { + gc = new GridBagConstraints(0, 0, 1, 1, 1.0, 1.0, GridBagConstraints.BASELINE, GridBagConstraints.HORIZONTAL, insets, 0, 0); + inputjp = new JPanel(); + inputjp.setLayout(new GridBagLayout()); + TitledBorder border = BorderFactory.createTitledBorder( + BorderFactory.createBevelBorder(EtchedBorder.RAISED), + "Inputs"); + inputjp.setBorder(border); + + for (int i=0; i<40; i++) { + gc.gridx = i%5; + gc.gridy = i/5; + DummyConditionButton dummy = new DummyConditionButton(); + dummy.setCol(gc.gridx); + dummy.setLine(gc.gridy); + inputjp.add(dummy, gc); + } + jp2.add(inputjp); + } + + // + private void initializeOutputArea(JPanel jp2) { + outputjp = new JPanel(); + outputjp.setLayout(new FlowLayout()); + TitledBorder border = BorderFactory.createTitledBorder( + BorderFactory.createBevelBorder(EtchedBorder.RAISED), + "Outputs"); + outputjp.setBorder(border); + for (int i=0; i<16; i++) { + gc.gridy = i/2; + if (i%2 == 0) { + gc.gridx = 0; + DummyEventButton dummy = new DummyEventButton(); + dummy.setCol(0); + dummy.setLine(gc.gridy); + outputjp.add(dummy, gc); + } + else { + gc.gridx = 1; + gc.gridwidth = 4; + gc.gridheight = 2; + DummyConditionButton dummy = new DummyConditionButton(); + dummy.setCol(1); + dummy.setLine(gc.gridy); + outputjp.add(dummy, gc); + } + } + gc.gridwidth = 1; + gc.gridheight = 1; + jp2.add(outputjp); + } + + /** + * add variable to output area as control button (if boolean, then toggle button, otherwise it's a field) + * + * @param name + * @param varType + * @return + */ + public boolean addOutputVariable(String name, VarType varType) { + Boolean isResult = sourceHandler.addVariableToRes(name, varType); + if (isResult == null) { + helper.addToOutput(name, varType); + } + return isResult != Boolean.FALSE; + } + + /** + * just add given UI variable to clapp resources, if not already created, replace otherwise + * + * @param name + * @param uiVar + */ + public void addVariable(String name, UiVar uiVar) { + sourceHandler.addUIVariableToRes(name, uiVar); + } + + /** + * just add given WeaveVar variable to clapp resources, if not already created, replace otherwise + * + * @param name + * @param wvar + */ + public void addVariable(String name, WeaveVar wvar) { + sourceHandler.addWeaveVariableToRes(name, wvar); + } + + /** + * just add given WebVariable variable to clapp resources, if not already created, replace otherwise + * + * @param name + * @param wvar + */ + public void addVariable(String name, WebVariable wvar) { + sourceHandler.addWebVariableToRes(name, wvar); + } + + /** + * checks whether given variable name is declared in clapp resources + * + * @param name + * @return + */ + public boolean existsVariable(String name) { + return sourceHandler.existsVariableInRes(name); + } + + public String gatherSimpleVariables() { + StringBuffer sb = new StringBuffer(); + for (ControlInfo ci : helper.getControls()) { + if (ci.getType() != VarType.TUI) { + sb.append(ci.toString()); + sb.append("\r\n"); + } + } + return sb.toString(); + } + + public String gatherUiVariables() { + return gatherVariablesFromControllers(VarType.TUI); + } + + // + private String gatherVariablesFromControllers(VarType type) { + StringBuffer sb = new StringBuffer(); + for (ControlInfo ci : helper.getControls()) { + if (ci.getType() == type) { + sb.append(ci.toString()); + sb.append("\r\n"); + } + } + return sb.toString(); + } + + @Override + public void onExecution(String key, CellQueueHandler activeQueue) { + if (activeQueue == null) { + if (key != null && activeQueues.get(key) != null) { + updateControls(); + ArrayList activeCells = populateActiveCells(activeQueues.get(key)); + ArrayList previouslyActiveCells = previouslyActiveQueues.get(key); + if (hasActivityChanged(activeCells, previouslyActiveCells)) { + updateUI(key, activeCells, previouslyActiveCells); + } + } + } + else if (!activeQueues.containsKey(key)) { + // register active queue + activeQueues.put(key, activeQueue); + ArrayList previouslyActiveCells = new ArrayList<>(); + previouslyActiveQueues.put(key, previouslyActiveCells); + } + } + + // + private void updateUI(String key, ArrayList activeCells, ArrayList previouslyActiveCells) { + sourceHandler.resetBackgroundColor(key); + for (CellChainLink ccl : activeCells) { + sourceHandler.setBackgroundColor(key, ccl.getName()); + } + previouslyActiveCells.clear(); + previouslyActiveCells.addAll(activeCells); + Hashtable mc = MarkHandler.getInstance().getMarkedCells(); + for (String name : mc.keySet()) { + sourceHandler.updateCellMarks(key, name, mc.get(name)); + } + refresh(); + } + + // + private ArrayList populateActiveCells(CellQueueHandler queue) { + ArrayList activeCells = new ArrayList<>(); + CellChainLink ccl = queue.getFirstCell(); + while (ccl != null) { + if (accepted(ccl.getCell())) { + activeCells.add(ccl); + } + ccl = ccl.getNext(); + } + return activeCells; + } + + // + private boolean accepted(Cell cell) { + if (!cell.getName().startsWith("P")) { + return true; + } + Weightings weightings = cell.getWeightings(); + Weighting w = weightings.getWeighting(); + if (w != null && w.getWeight() > 0) { + return true; + } + for (Weighting aw : weightings.getWeightings()) { + if (aw.getWeight() > 0) { + return true; + } + } + return false; + } + + // + private void updateControls() { + for (ControlInfo ci : helper.getControls()) { + ci.updateOutput(); + } + } + + // + private boolean hasActivityChanged(ArrayList activeCells, ArrayList previouslyActiveCells) { + for (CellChainLink ccl : previouslyActiveCells) { + if (!activeCells.contains(ccl)) { + return true; + } + } + for (CellChainLink ccl : activeCells) { + if (!previouslyActiveCells.contains(ccl)) { + return true; + } + } + return false; + } + + @Override + public void onFinish() { + startButton.setBackground(Color.lightGray); + startButton.setForeground(Color.black); + startButton.setText("Simulate"); + startButton.setSelected(false); + for (ControlInfo ci : helper.getControls()) { + if (ci.getComponent() instanceof AbstractButton) { + ((AbstractButton)ci.getComponent()).setSelected(false); + ((AbstractButton)ci.getComponent()).setEnabled(false); + } + else if (ci.getComponent() instanceof OutputPanel) { + ((OutputPanel)ci.getComponent()).enableIt(); + } + } + isSimulationRunning = false; + sourceHandler.resetBackgroundColorForAll(); + sourceHandler.resetAllCellMarks(); + previouslyActiveQueues.clear(); + activeQueues.clear(); + graphicsPanel.getButtonsContainer().setButtonsEnabled(true); + genericShapesContainer.setEnabled(true); + genericShapesContainer.getCurrentContainer().getAutomaton().enabling(true); + refresh(); + } + + public void refresh() { + SwingUtilities.invokeLater(new Runnable() { + public void run() { + genericShapesContainer.repaint(); + } + }); + } + + // + private void drawInputArea() { + inputjp.removeAll(); + for (int i=0; i<40; i++) { + int col = i%5; + int line = i/5; + gc.gridx = col; + gc.gridy = line; + AInputButton dummy; + if (col == 0 && line < helper.getEvents().size()) { + dummy = helper.getEvents().get(line); + } + else if (col > 0 && col-1 + line*4 < helper.getConditions().size()) { + dummy = helper.getConditions().get(col-1 + line*4); + } + else { + dummy = new DummyConditionButton(); + dummy.setCol(gc.gridx); + dummy.setLine(gc.gridy); + } + inputjp.add(dummy, gc); + } + validate(); + repaint(); + } + + // + private void drawOutputArea() { + outputjp.removeAll(); + for (int i=0; i<16; i++) { + int col = i%2; + int line = i/2; + gc.gridx = col; + gc.gridy = line; + IOutput dummy; + if (col == 0) { + gc.gridwidth = 1; + gc.gridheight = 1; + if (line < helper.getOutButtons().size()) { + dummy = helper.getOutButtons().get(line); + } + else { + dummy = new DummyButton(); + dummy.setCol(col); + dummy.setLine(line); + } + } + else { + gc.gridwidth = 4; + gc.gridheight = 2; + if (line < helper.getOutPanels().size()) { + dummy = helper.getOutPanels().get(line); + } + else { + dummy = new DummyPanel(); + dummy.setCol(col); + dummy.setLine(line); + } + } + outputjp.add((JComponent) dummy, gc); + } + gc.gridwidth = 1; + gc.gridheight = 1; + validate(); + repaint(); + } + + public void addShapeAsCell(ActionShape actionShape, String name) { + String key = genericShapesContainer.getCurrentContainer().getKey(); + sourceHandler.addShapeAsCell(key, actionShape, name); + } + + public void addTokensToRes(Token[] tokens, String name) { + sourceHandler.addTokensToRes(tokens, name); + } + + @Override + public boolean getActivity(String name) { + if (activities.containsKey(name)) { + return activities.get(name); + } + return true; + } + + @Override + public void setActivity(String name, boolean b) { + activities.put(name, b); + } + + public void drawControls() { + drawInputArea(); + drawOutputArea(); + } + + public void removeRes() { + sourceHandler.removeResources(); + } + + public SimulationHelper getSimulationHelper() { + return helper; + } + + /** + * @return the sourceHandler + */ + public CLAppSourceHandler getSourceHandler() { + return sourceHandler; + } + + public void updateTreeResources() { + sourceHandler.updateTreeResources(); + } +} diff --git a/src/clp/edit/graphics/panel/GeneralShapesContainer.java b/src/clp/edit/graphics/panel/GeneralShapesContainer.java new file mode 100644 index 0000000..c6a0934 --- /dev/null +++ b/src/clp/edit/graphics/panel/GeneralShapesContainer.java @@ -0,0 +1,615 @@ +package clp.edit.graphics.panel; + +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Point; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.awt.event.MouseMotionAdapter; +import java.awt.event.MouseMotionListener; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Set; + +import javax.swing.JPanel; +import javax.swing.SwingUtilities; + +import clp.edit.GeneralContext; +import clp.edit.dialog.ADialog; +import clp.edit.graphics.btn.IAutomaton; +import clp.edit.graphics.btn.IAutomaton.ActionMode; +import clp.edit.graphics.code.gui.GuiContext; +import clp.edit.graphics.code.java.JavaContext; +import clp.edit.graphics.code.prt.CslContext; +import clp.edit.graphics.code.prt.CslContext.CslInfo; +import clp.edit.graphics.code.web.WebContext; +import clp.edit.graphics.code.web.WebContext.WebInfo; +import clp.edit.graphics.shapes.AContainer; +import clp.edit.graphics.shapes.AContainerShape; +import clp.edit.graphics.shapes.ADecisionShape; +import clp.edit.graphics.shapes.AEventShape; +import clp.edit.graphics.shapes.AShape; +import clp.edit.graphics.shapes.ATransitionShape; +import clp.edit.graphics.shapes.ActionShape; +import clp.edit.graphics.shapes.act.ActigramContainer; +import clp.edit.graphics.shapes.act.ActivityShape; +import clp.edit.graphics.shapes.gc.GrafcetContainer; +import clp.edit.graphics.shapes.gc.GrafcetShape; +import clp.edit.graphics.shapes.menu.ContainerHeaderContextMenu; +import clp.edit.graphics.shapes.pn.PetriNetsContainer; +import clp.edit.graphics.shapes.pn.PetriNetsShape; +import clp.edit.panel.GraphicsPanel; +import clp.edit.panel.TooltipPopupProvider; +import clp.run.msc.Output; + +public class GeneralShapesContainer extends JPanel implements MouseListener { + + private static final long serialVersionUID = -8882230841386866337L; + + private List containers; + private AContainer currentContainer; + + private Point firstPoint; + private Point lastPoint; + + private GraphicsPanel graphicsPanel; + private TooltipPopupProvider popupProvider; + + private boolean isEnabled; + + private int actionNoForActigram; + private int counterForActigramDecisions; + private int actionNoForGrafcet; + private int actionNoForPetriNets; + + private int delayNo; + private int trCount; + + private JavaContext jcontext; + private GuiContext gcontext; + private WebContext wcontext; + private CslContext ccontext; + + /** + * Constructor + * @param graphicsPanel + * @param popupProvider + */ + public GeneralShapesContainer(GraphicsPanel graphicsPanel, TooltipPopupProvider popupProvider) { + setLayout(new BorderLayout()); + containers = new ArrayList<>(); + this.graphicsPanel = graphicsPanel; + this.popupProvider = popupProvider; + isEnabled = true; + jcontext = new JavaContext(); + gcontext = new GuiContext(); + wcontext = new WebContext(); + ccontext = new CslContext(); + createListeners(); + } + + public void createListeners() { + for (MouseListener ml : getMouseListeners()) { + removeMouseListener(ml); + } + for (MouseMotionListener mml : getMouseMotionListeners()) { + removeMouseMotionListener(mml); + } + addMouseListener(this); + addMouseMotionListener(new MouseMotion()); + } + + public void paint(Graphics g) { + super.paint(g); + int offset = 0; + int height = 0; + for (AContainer container : containers) { + Dimension dim = container.paint(g, offset, currentContainer == container); + offset += dim.width; + if (height < dim.height) { + height = dim.height; + } + } + Dimension psize = getPreferredSize(); + if (psize.width < offset) { + psize.width = offset+10; + } + if (psize.height < height) { + psize.height = height+60; + } + setPreferredSize(psize); + revalidate(); + } + + /** + * create activity shapes container and, within it, the corresponding CLApp Actor, evtl. wrapped by + * the right scenario. + */ + public void addActivityContainer() { + currentContainer = new ActigramContainer(graphicsPanel); + containers.add(currentContainer); + ActivityShape as = new ActivityShape(400, 600, "Activity ", containers.size()); + currentContainer.setContainerShape(as); + GeneralContext.getInstance().getClappEditor().enableExport(); + } + + /** + * create grafcet shapes container and, within it, the corresponding CLApp Actor, evtl. wrapped by + * the right scenario. + */ + public void addGrafcetContainer() { + currentContainer = new GrafcetContainer(graphicsPanel); + containers.add(currentContainer); + GrafcetShape as = new GrafcetShape(400, 600, "Grafcet ", containers.size()); + currentContainer.setContainerShape(as); + GeneralContext.getInstance().getClappEditor().enableExport(); + } + + /** + * create Petri Nets shapes container and, within it, the corresponding CLApp Actor, evtl. wrapped by + * the right scenario. + */ + public void addPNContainer(String text, boolean isColored) { + currentContainer = new PetriNetsContainer(graphicsPanel, isColored); + containers.add(currentContainer); + PetriNetsShape as = new PetriNetsShape(400, 600, text, containers.size(), isColored); + currentContainer.setContainerShape(as); + GeneralContext.getInstance().getClappEditor().enableExport(); + } + + public void addShape(AShape shape) { + currentContainer.addShape(shape); + } + + @Override + public void mouseClicked(MouseEvent e) { + if (currentContainer == null || !isEnabled) { + return; + } + int px = e.getX(); + int py = e.getY(); + switch (e.getClickCount()) { + case 1: + if (SwingUtilities.isRightMouseButton(e)) { + if (isInContainerHeader(px, py)) { + ContainerHeaderContextMenu contextMenu = new ContainerHeaderContextMenu(this, currentContainer); + contextMenu.show(currentContainer.getButtonsPanel(), px+10, py); + } + // context menu (swap - delete - insert) + AShape shape = currentContainer.getContainerShape().getSelectedShape(px, py, currentContainer.getOffset()); + if (shape != null) { + currentContainer.showContextMenu(this, shape, e); + } + } + else { + // change container / add shape / select shape(s) + handleAction(px, py, e.isMetaDown() || e.isControlDown()); + } + break; + case 2: + // edit container + popupProvider.hide(); + if (isInContainerHeader(px, py)) { + editContainer(); + } + else { + // find and edit shape + checkForShapeEdition(px, py); + } + break; + default: + break; + } + } + + // + private void handleAction(int px, int py, boolean isMultiSelect) { + AContainer csel = getSelectedContainer(px, py); + if (csel != null) { // change selected container + if (csel.getType() != currentContainer.getType()) { + GeneralContext.getInstance().getGraphicsPanel().getButtonsContainer().updateRadioButtons(csel.getType()); + } + currentContainer = csel; + refreshUI(); + } + else { // still in same container + AShape sel = currentContainer.getContainerShape().getSelectedShape(px, py, currentContainer.getOffset()); + currentContainer.handleAction(sel, px, py, isMultiSelect); + } + } + + // + private void refreshUI() { + currentContainer.getAutomaton().refreshButtons(); + revalidate(); + updateUI(); + } + + // + private AContainer getSelectedContainer(int px, int py) { + for (AContainer container : containers) { + if (container != currentContainer) { + if (container.isSelected(px, py)) { + return container; + } + } + } + return null; + } + + + // + private boolean isInContainerHeader(int px, int py) { + if (currentContainer != null) { + int x = px - currentContainer.getOffset(); + AContainerShape shapesContainer = currentContainer.getContainerShape(); + int xref = shapesContainer.getPX(); + int yref = shapesContainer.getPY(); + return x > xref && x < xref+shapesContainer.getWidth() + && py > yref && py < yref+40; + } + return false; + } + + // + private void checkForShapeEdition(int px, int py) { + AShape sel = currentContainer.getContainerShape().getSelectedShape(px, py, currentContainer.getOffset()); + edit(sel); + currentContainer.setDirty(true); + } + + // + private boolean isEnabled(AShape sel) { + if (sel instanceof ADecisionShape) { + return ((ADecisionShape) sel).isComplete(); + } + if (sel instanceof clp.edit.graphics.shapes.gc.FinalNodeShape || + sel instanceof clp.edit.graphics.shapes.pn.FinalNodeShape) { + return true; + } + if (sel instanceof ATransitionShape || sel instanceof AEventShape) { + return sel.getChild() != null; + } + return true; + } + + public void edit(AShape shape) { + if (shape != null && shape.getDialog() != null && isEnabled(shape)) { + shape.upateDialog(); + ADialog dialog = (ADialog) shape.getDialog(); + dialog.edit(shape.getName(), shape.getDesc()); + if (dialog.isOk()) { + shape.setDesc(dialog.getDescription()); + if (shape instanceof ActionShape) { + ((ActionShape)shape).setupInstructions(); + } + else { + shape.setName(dialog.getTransitionText()); + shape.cacheFromTransients(); + } + currentContainer.setDirty(true); + } + } + } + + @Override + public void mousePressed(MouseEvent e) { + } + + @Override + public void mouseReleased(MouseEvent e) { + if (currentContainer != null) { + IAutomaton auto = currentContainer.getAutomaton(); + if (auto.getMode() == ActionMode.MOVE) { + auto.setMode(ActionMode.NONE); + currentContainer.unselectAll(); + refresh(); + } + firstPoint = null; + lastPoint = null; + } + } + + @Override + public void mouseEntered(MouseEvent e) { + } + + @Override + public void mouseExited(MouseEvent e) { + } + + /** + * @return the currentContainer + */ + public AContainer getCurrentContainer() { + return currentContainer; + } + + /** + * @param currentContainer the currentContainer to set + */ + public void setCurrentContainer(AContainer currentContainer) { + this.currentContainer = currentContainer; + currentContainer.getAutomaton().updateEnabling(); + } + + public void refresh() { + SwingUtilities.invokeLater( new Runnable() { + public void run() { + updateUI(); + } + } ); + } + + class MouseMotion extends MouseMotionAdapter { + + @Override + public void mouseMoved(MouseEvent e) { + if (currentContainer != null) { + AShape sel = currentContainer.getContainerShape().getSelectedShape(e.getX(), e.getY(), currentContainer.getOffset()); + if (sel != null) { + popupProvider.show(sel, e.getLocationOnScreen()); + } + else { + popupProvider.hide(); + } + } + } + + @Override + public void mouseDragged(MouseEvent e) { + if (firstPoint == null) { + firstPoint = e.getPoint(); + } + else { + lastPoint = e.getPoint(); + Point delta = new Point(lastPoint.x-firstPoint.x, lastPoint.y-firstPoint.y); + switch (currentContainer.getAutomaton().getMode()) { + case SELECT: + case TRANSITION: + if (currentContainer.getSelected() instanceof ADecisionShape) { + if (e.isShiftDown() && delta.y > 15 && (delta.x >= 0 && delta.x < 5 ||delta.x < 0 && delta.x > -5)) { + if (currentContainer.checkForBindingUpdate((int) lastPoint.getX())) { + firstPoint = null; + lastPoint = null; + refresh(); + break; + } + } + } + if (!e.isShiftDown() && (delta.x > 5 || delta.y > 5 || delta.x < -5 || delta.y < -5)) { + currentContainer.getAutomaton().setMode(ActionMode.MOVE); + } + break; + case MOVE: + if (delta.x > 5 || delta.y > 5 || delta.x < -5 || delta.y < -5) { + currentContainer.getAutomaton().performAction(ActionMode.MOVE, delta, null, false); + firstPoint = lastPoint; + refresh(); + } + break; + default: + break; + } + } + } + } + + /** + * @return the containers + */ + public List getContainers() { + return containers; + } + + /** + * @param containers the containers to set + */ + public void setContainers(List containers) { + this.containers = containers; + } + + public boolean isFirst() { + return currentContainer == containers.get(0); + } + + public boolean isLast() { + return currentContainer == containers.get(containers.size()-1); + } + + public void moveLeft() { + int index = containers.indexOf(currentContainer); + containers.remove(index); + containers.add(index-1, currentContainer); + validate(); + repaint(); + } + + public void moveRight() { + int index = containers.indexOf(currentContainer); + containers.remove(index); + containers.add(index+1, currentContainer); + validate(); + repaint(); + } + + public void editContainer() { + AContainerShape shapesContainer = currentContainer.getContainerShape(); + ADialog dialog = (ADialog) shapesContainer.getDialog(); + dialog.edit(shapesContainer.getName(), shapesContainer.getDesc()); + shapesContainer.setName(dialog.getTransitionText()); + shapesContainer.setDesc(dialog.getDescription()); + } + + /** + * remove current shapes container and, within it, the corresponding CLApp Actor, evtl. wrapped by + * the right scenario. + */ + public void removeContainer() { + if (currentContainer.getCurrent() != null) { + ConfirmationDialog dial = new ConfirmationDialog(GeneralContext.getInstance().getFrame()); + if (dial.isOk()) { + doRemove(); + } + } + else { + doRemove(); + } + } + + // + private void doRemove() { + currentContainer.getContainerShape().removeActor(); + containers.remove(currentContainer); + if (containers.isEmpty()) { + currentContainer = null; + } + else { + currentContainer = containers.get(0); + GeneralContext.getInstance().getGraphicsPanel().getButtonsContainer().updateRadioButtons(currentContainer.getType()); + } + + SwingUtilities.invokeLater(new Runnable() { + public void run() { + GeneralContext.getInstance().getGraphicsPanel().getShapesContainer().repaint(); + } + }); + } + + /** + * @param isEnabled the isEnabled to set + */ + public void setEnabled(boolean isEnabled) { + this.isEnabled = isEnabled; + } + + public void removeDeactivationForInit(String name) { + for (AContainer container : containers) { + if (container.removeDeactivationForInit(name)) { + return; + } + } + } + + /** + * @return the incremented actionNoForActigram + */ + public int getIncrementingActionNoForActigram() { + return ++actionNoForActigram; + } + + /** + * @return the actionNoForActigram + */ + public int getActionNoForActigram() { + return actionNoForActigram; + } + + /** + * @return the incremented actionNoForGrafcet + */ + public int getIncrementingActionNoForGrafcet() { + return ++actionNoForGrafcet; + } + + /** + * @return the actionNoForGrafcet + */ + public int getActionNoForGrafcet() { + return actionNoForGrafcet; + } + + /** + * @return the incremented actionNoForPetriNets + */ + public int getIncrementingActionNoForPetriNets() { + return ++actionNoForPetriNets; + } + + /** + * @return the actionNoForActigram + */ + public int getActionNoForPetriNets() { + return actionNoForPetriNets; + } + + /** + * @return the counterForActigramDecisions + */ + public synchronized int getIncrentingCounterForActigramDecisions() { + return counterForActigramDecisions++; + } + + /** + * @return the delayNo and increment it + */ + public int getIncrementingDelayNo() { + return delayNo++; + } + + public Set getUiList() { + return gcontext.getUiList(); + } + + public String getVariableTypeForUI(String varName) { + return gcontext.getVariableType(varName); + } + + public Collection getWebInfos() { + return wcontext.getWebInfos().values(); + } + + public Set getWebInfoNames() { + return wcontext.getWebList(); + } + + public boolean addCslInfo(String cslName, Output out) { + ccontext.addCslInfo(cslName, out); + return true; + } + + public Collection getCslInfos() { + return ccontext.getCslInfos().values(); + } + + public Set getCslInfoNames() { + return ccontext.getCslInfos().keySet(); + } + + /** + * @return the trCount + */ + public int getTrIncrementingCount() { + return trCount++; + } + + /** + * @return the jcontext + */ + public JavaContext getJavaContext() { + return jcontext; + } + + /** + * @return the gcontext + */ + public GuiContext getGuiContext() { + return gcontext; + } + + /** + * @return the wcontext + */ + public WebContext getWebContext() { + return wcontext; + } + + /** + * @return the ccontext + */ + public CslContext getConsoleContext() { + return ccontext; + } +} diff --git a/src/clp/edit/graphics/panel/SimulationHelper.java b/src/clp/edit/graphics/panel/SimulationHelper.java new file mode 100644 index 0000000..6102fc7 --- /dev/null +++ b/src/clp/edit/graphics/panel/SimulationHelper.java @@ -0,0 +1,354 @@ +package clp.edit.graphics.panel; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +import javax.swing.JComponent; + +import clp.edit.GeneralContext; +import clp.edit.graphics.dial.Token; +import clp.edit.graphics.panel.cntrl.AInputButton; +import clp.edit.graphics.panel.cntrl.ConditionButton; +import clp.edit.graphics.panel.cntrl.DelayButton; +import clp.edit.graphics.panel.cntrl.EventButton; +import clp.edit.graphics.panel.cntrl.OutputButton; +import clp.edit.graphics.panel.cntrl.OutputPanel; +import clp.edit.graphics.shapes.AContainer; +import clp.edit.handler.CLAppSourceHandler; +import clp.run.res.Unit; +import clp.run.res.VarType; + +public class SimulationHelper implements Serializable { + + private static final long serialVersionUID = -3745794325213012504L; + + private ArrayList controls; + private CLAppSourceHandler sourceHandler; + + private DelayButton delayButton; // used to display as tool tip text all declared delays + private ArrayList events; // list of all declared events + private ArrayList conditions; // list of all declared conditions (input variables) + private ArrayList outButtons; // list of all declared output buttons (boolean variables) + private ArrayList outPanels; // list of all declared output panels (containing other variables) + + private ControlsContainer controlsContainer; + + private boolean isDirty; + + private boolean isGenerated; + + /** + * CONSTRUCTOR + * @param cc controlsContainer + * @param sh sourceHandler + */ + public SimulationHelper(ControlsContainer cc, CLAppSourceHandler sh) { + controls = new ArrayList<>(); + sourceHandler = sh; + controlsContainer = cc; + events = new ArrayList<>(); + conditions = new ArrayList<>(); + outButtons = new ArrayList<>(); + outPanels = new ArrayList<>(); + delayButton = new DelayButton(); + isDirty = true; + } + + /** + * @return the controls + */ + public ArrayList getControls() { + return controls; + } + + /** + * @param controls the controls to set + */ + public void setControls(ArrayList controls) { + this.controls = controls; + } + + /** + * generate CLApp code for all created container shapes, if dirty + * and additionally extracts input and output variables with associated controls + * @return + */ + public boolean generateCode() { + isGenerated = false; + GeneralShapesContainer shapesContainer = GeneralContext.getInstance().getGraphicsPanel().getShapesContainer(); + List containers = shapesContainer.getContainers(); + isDirty |= isAnyContainerDirty(containers); + if (isDirty) { + cleanAll(); + for (AContainer container : containers) { + if (container.isActive()) { + //----------- GENERATE CODE FOR A CONTAINER ---------------------- + if (!container.generateCode()) { + return false; + } + } + } + resetContainersDirtyFlag(containers); + controlsContainer.drawControls(); + controlsContainer.updateTreeResources(); + isDirty = false; + } + isGenerated = true; + return true; + } + + public boolean isAnyContainerDirty(List containers) { + for (AContainer container : containers) { + if (container.isDirty()) { + return true; + } + } + return false; + } + + public void resetContainersDirtyFlag(List containers) { + for (AContainer container : containers) { + if (container.isDirty()) { + container.setDirty(false); + } + } + // as long as project isn't saved, following flag should be true + GeneralContext.getInstance().getClappEditor().setDirty(true); + } + + private void cleanAll() { + events.clear(); + conditions.clear(); + controls.clear(); + controlsContainer.removeRes(); + delayButton.getDelays().clear(); + outButtons.clear(); + outPanels.clear(); + sourceHandler.cleanMetaScenario(); + } + + /** + * set tokens of a particular cell to the resources block + * + * @param tokens + * @param name + */ + public void addTokensToRes(Token[] tokens, String name) { + sourceHandler.addTokensToRes(tokens, name); + } + + /** + * add cell event to the resources block + * + * @param cellName + */ + public void addCellEventToRes(String cellName) { + sourceHandler.addCellEventToRes(cellName); + } + + /** + * just add given variables to clapp resources, if not already created, replace otherwise + * + * @param uiName + * @param uiVar + * @return + */ + public boolean addVariables(ArrayList variables) { + for (String text : variables) { + if (text.isBlank()) { + continue; + } + String[] sp = text.split("/"); + if (sp[0].isBlank()) { + return false; + } + VarType tp = VarType.valueOf("T"+sp[1]); + Boolean isResult = sourceHandler.addVariableToRes(sp[0], tp); + if (isResult == null) { + if (sp.length > 2 && sp[2].equals("D")) { + addToOutput(sp[0], tp); + } + } + else if (isResult == Boolean.FALSE) { + System.err.printf("Variable %s already exists but is not declared as %s variable\n", sp[0], tp.getVal()); + return false; + } + } + return true; + } + + public void addToOutput(String name, VarType varType) { + ControlInfo ci = new ControlInfo(name, name, varType, false); + controls.add(ci); + JComponent comp = ci.getComponent(); + if (comp != null) { + int x; + int y; + if (varType == VarType.TBOOL) { + x = 0; + y = outButtons.size(); + OutputButton outb = (OutputButton) comp; + outButtons.add(outb); + outb.setCol(x); + outb.setLine(y); + } + else { + x = 1; + y = outPanels.size(); + OutputPanel outp = (OutputPanel) comp; + outPanels.add(outp); + outp.setCol(x); + outp.setLine(y); + } + } + } + + public void addVariableToRes(String name, VarType varType) { + sourceHandler.addVariableToRes(name, varType); + } + + public void addInputVariableToRes(String name, String description, VarType varType) { + sourceHandler.addVariableToRes(name, varType); + ControlInfo oldci = getExistingControlInfo(name); + if (oldci != null) { + return; + } + ControlInfo ci = new ControlInfo(name, description, varType, true); + AInputButton ib = (AInputButton) ci.getComponent(); + if (ib instanceof EventButton) { + addToEvents((EventButton) ib); + } + else if (ib instanceof ConditionButton) { + addToConditions((ConditionButton) ib); + } + controls.add(ci); + } + + public void addToLibs(String usedLib, boolean isJar) { + sourceHandler.addLibToRes(usedLib, isJar); + } + + // + private void addToEvents(EventButton ev) { + int x = 0; + int y = events.size(); + ev.setCol(x); + ev.setLine(y); + events.add(ev); + } + + // + private void addToConditions(ConditionButton cnd) { + int size = conditions.size(); + int x = (size % 4) + 1; + int y = size / 4; + cnd.setCol(x); + cnd.setLine(y); + conditions.add(cnd); + } + + // + private ControlInfo getExistingControlInfo(String name) { + for (ControlInfo ci : controls) { + if (ci.getName().equals(name)) { + return ci; + } + } + return null; + } + + public void addDelay(String cellName, String timeIdentifier, int delay, Unit unit, boolean cycle) { + sourceHandler.declareDelay(cellName, timeIdentifier, delay, unit, cycle); + if (delayButton.isEmpty()) { + addToEvents(delayButton); + } + delayButton.addToToolTip(timeIdentifier); + } + + /** + * @param delayButton the delayButton to set + */ + public void setDelayButton(DelayButton delayButton) { + this.delayButton = delayButton; + if(this.delayButton == null) { + this.delayButton = new DelayButton(); + } + else if (!delayButton.isEmpty()) { + addToEvents(delayButton); + } + } + + /** + * @return the events + */ + public ArrayList getEvents() { + return events; + } + + /** + * @return the conditions + */ + public ArrayList getConditions() { + return conditions; + } + + /** + * @return the outButtons + */ + public ArrayList getOutButtons() { + return outButtons; + } + + /** + * @return the delayButton + */ + public DelayButton getDelayButton() { + return delayButton; + } + + /** + * @return the outPanels + */ + public ArrayList getOutPanels() { + return outPanels; + } + + /** + * @return the isDirty + */ + public boolean isDirty() { + return isDirty; + } + public boolean isGloballyDirty() { + GeneralShapesContainer shapesContainer = GeneralContext.getInstance().getGraphicsPanel().getShapesContainer(); + List containers = shapesContainer.getContainers(); + return isDirty || isAnyContainerDirty(containers); + } + + /** + * @return the isGenerated + */ + public boolean isGenerated() { + return isGenerated; + } + + /** + * @param isDirty the isDirty to set + */ + public void setDirty(boolean isDirty) { + this.isDirty = isDirty; + } + + public boolean isControlsEmpty() { + return isControlsEmpty(events) && conditions.isEmpty(); + } + + // + private boolean isControlsEmpty(ArrayList events) { + if (events.size() == 1) { + return events.get(0) instanceof DelayButton; + } + return events.isEmpty(); + } +} diff --git a/src/clp/edit/graphics/panel/cntrl/AInputButton.java b/src/clp/edit/graphics/panel/cntrl/AInputButton.java new file mode 100644 index 0000000..f34787f --- /dev/null +++ b/src/clp/edit/graphics/panel/cntrl/AInputButton.java @@ -0,0 +1,43 @@ +package clp.edit.graphics.panel.cntrl; + +import javax.swing.JToggleButton; + +abstract public class AInputButton extends JToggleButton { + + private static final long serialVersionUID = 7993011728489662807L; + + private int line; + private int col; + + public AInputButton(String name) { + super(name); + } + + /** + * @return the line + */ + public int getLine() { + return line; + } + + /** + * @param line the line to set + */ + public void setLine(int line) { + this.line = line; + } + + /** + * @return the col + */ + public int getCol() { + return col; + } + + /** + * @param col the col to set + */ + public void setCol(int col) { + this.col = col; + } +} diff --git a/src/clp/edit/graphics/panel/cntrl/ConditionButton.java b/src/clp/edit/graphics/panel/cntrl/ConditionButton.java new file mode 100644 index 0000000..0bb2a0b --- /dev/null +++ b/src/clp/edit/graphics/panel/cntrl/ConditionButton.java @@ -0,0 +1,34 @@ +package clp.edit.graphics.panel.cntrl; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics; + +public class ConditionButton extends AInputButton { + + private static final long serialVersionUID = 1440624849424121710L; + + private Color off = new Color(0x008700); + private Color on = new Color(0x00d700); + + public ConditionButton(String name, String text) { + super(name); + setToolTipText(text); + setSize(40, 30); + setPreferredSize(new Dimension(40, 30)); + } + + @Override + public void paint(Graphics g) { + if (isSelected()) { + g.setColor(on); + } + else { + g.setColor(off); + } + g.fillRoundRect(0, 0, 40, 30, 5, 5); + + g.setColor(Color.white); + g.drawString(getText(), 5, 22); + } +} diff --git a/src/clp/edit/graphics/panel/cntrl/DelayButton.java b/src/clp/edit/graphics/panel/cntrl/DelayButton.java new file mode 100644 index 0000000..dd2016b --- /dev/null +++ b/src/clp/edit/graphics/panel/cntrl/DelayButton.java @@ -0,0 +1,48 @@ +package clp.edit.graphics.panel.cntrl; + +import java.awt.Color; +import java.awt.Graphics; +import java.util.ArrayList; + +public class DelayButton extends EventButton { + + private static final long serialVersionUID = 1050357635174606713L; + + private Color off = new Color(0x6400c3); + + private ArrayList delays; + + public DelayButton() { + super("Delay", "NO Delays"); + delays = new ArrayList<>(); + } + + @Override + public void paint(Graphics g) { + g.setColor(off); + g.fillRoundRect(0, 0, 40, 30, 5, 5); + + g.setColor(Color.white); + g.drawString(getText(), 2, 22); + } + + public void addToToolTip(String timeIdentifier) { + if (!delays.contains(timeIdentifier)) { + delays.add(timeIdentifier); + } + setToolTipText(delays.toString()); + } + + public boolean isEmpty() { + return delays.isEmpty(); + } + + public ArrayList getDelays() { + return delays; + } + + public void removeDelay(String delay) { + delays.remove(delay); + setToolTipText(delays.toString()); + } +} diff --git a/src/clp/edit/graphics/panel/cntrl/DummyButton.java b/src/clp/edit/graphics/panel/cntrl/DummyButton.java new file mode 100644 index 0000000..e424287 --- /dev/null +++ b/src/clp/edit/graphics/panel/cntrl/DummyButton.java @@ -0,0 +1,17 @@ +package clp.edit.graphics.panel.cntrl; + +import java.awt.Graphics; + +public class DummyButton extends OutputButton { + + private static final long serialVersionUID = 7600139405990274603L; + + + public DummyButton() { + super("dummy"); + } + + @Override + public void paint(Graphics g) { + } +} diff --git a/src/clp/edit/graphics/panel/cntrl/DummyConditionButton.java b/src/clp/edit/graphics/panel/cntrl/DummyConditionButton.java new file mode 100644 index 0000000..0ba6d9c --- /dev/null +++ b/src/clp/edit/graphics/panel/cntrl/DummyConditionButton.java @@ -0,0 +1,16 @@ +package clp.edit.graphics.panel.cntrl; + +import java.awt.Graphics; + +public class DummyConditionButton extends ConditionButton implements IDummy { + + private static final long serialVersionUID = -347153608952633583L; + + public DummyConditionButton() { + super("dummy", ""); + } + + @Override + public void paint(Graphics g) { + } +} diff --git a/src/clp/edit/graphics/panel/cntrl/DummyEventButton.java b/src/clp/edit/graphics/panel/cntrl/DummyEventButton.java new file mode 100644 index 0000000..05a73b1 --- /dev/null +++ b/src/clp/edit/graphics/panel/cntrl/DummyEventButton.java @@ -0,0 +1,16 @@ +package clp.edit.graphics.panel.cntrl; + +import java.awt.Graphics; + +public class DummyEventButton extends EventButton implements IDummy { + + private static final long serialVersionUID = -5252010388177347482L; + + public DummyEventButton() { + super("dummy", ""); + } + + @Override + public void paint(Graphics g) { + } +} diff --git a/src/clp/edit/graphics/panel/cntrl/DummyPanel.java b/src/clp/edit/graphics/panel/cntrl/DummyPanel.java new file mode 100644 index 0000000..e8cd4c8 --- /dev/null +++ b/src/clp/edit/graphics/panel/cntrl/DummyPanel.java @@ -0,0 +1,17 @@ +package clp.edit.graphics.panel.cntrl; + +import java.awt.Graphics; + +public class DummyPanel extends OutputPanel { + + private static final long serialVersionUID = -9174039228087166567L; + + public DummyPanel() { + super("Dummy", null); + } + + + @Override + public void paint(Graphics g) { + } +} diff --git a/src/clp/edit/graphics/panel/cntrl/EventButton.java b/src/clp/edit/graphics/panel/cntrl/EventButton.java new file mode 100644 index 0000000..1592f73 --- /dev/null +++ b/src/clp/edit/graphics/panel/cntrl/EventButton.java @@ -0,0 +1,34 @@ +package clp.edit.graphics.panel.cntrl; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics; + +public class EventButton extends AInputButton { + + private static final long serialVersionUID = -6249930675846964865L; + + private Color off = new Color(0x000087); + private Color on = new Color(0x0000d7); + + public EventButton(String name, String text) { + super(name); + setToolTipText(text); + setSize(40, 30); + setPreferredSize(new Dimension(40, 30)); + } + + @Override + public void paint(Graphics g) { + if (isSelected()) { + g.setColor(on); + } + else { + g.setColor(off); + } + g.fillRoundRect(0, 0, 40, 30, 5, 5); + + g.setColor(Color.white); + g.drawString(getText(), 5, 22); + } +} diff --git a/src/clp/edit/graphics/panel/cntrl/IDummy.java b/src/clp/edit/graphics/panel/cntrl/IDummy.java new file mode 100644 index 0000000..5182377 --- /dev/null +++ b/src/clp/edit/graphics/panel/cntrl/IDummy.java @@ -0,0 +1,5 @@ +package clp.edit.graphics.panel.cntrl; + +public interface IDummy { + +} diff --git a/src/clp/edit/graphics/panel/cntrl/IOutput.java b/src/clp/edit/graphics/panel/cntrl/IOutput.java new file mode 100644 index 0000000..3c7ac09 --- /dev/null +++ b/src/clp/edit/graphics/panel/cntrl/IOutput.java @@ -0,0 +1,10 @@ +package clp.edit.graphics.panel.cntrl; + +public interface IOutput { + + public int getLine(); + public int getCol(); + public String getText(); + public void setCol(int col); + public void setLine(int line); +} diff --git a/src/clp/edit/graphics/panel/cntrl/OutputButton.java b/src/clp/edit/graphics/panel/cntrl/OutputButton.java new file mode 100644 index 0000000..f6a0117 --- /dev/null +++ b/src/clp/edit/graphics/panel/cntrl/OutputButton.java @@ -0,0 +1,68 @@ +package clp.edit.graphics.panel.cntrl; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics; + +import javax.swing.JToggleButton; + +public class OutputButton extends JToggleButton implements IOutput { + + private static final long serialVersionUID = 3872977572020038321L; + + private Color off = new Color(0xa74800); + private Color on = new Color(0xe08700); + + private int line; + private int col; + + public OutputButton(String name) { + super(name); + setToolTipText(name); + setEnabled(false); + setSize(40, 30); + setPreferredSize(new Dimension(40, 30)); + } + + @Override + public void paint(Graphics g) { + if (isSelected()) { + g.setColor(on); + } + else { + g.setColor(off); + } + g.fillRoundRect(0, 0, 40, 30, 5, 5); + + g.setColor(Color.white); + g.drawString(getText(), 5, 22); + } + + /** + * @return the line + */ + public int getLine() { + return line; + } + + /** + * @param line the line to set + */ + public void setLine(int line) { + this.line = line; + } + + /** + * @return the col + */ + public int getCol() { + return col; + } + + /** + * @param col the col to set + */ + public void setCol(int col) { + this.col = col; + } +} diff --git a/src/clp/edit/graphics/panel/cntrl/OutputPanel.java b/src/clp/edit/graphics/panel/cntrl/OutputPanel.java new file mode 100644 index 0000000..f6eb43f --- /dev/null +++ b/src/clp/edit/graphics/panel/cntrl/OutputPanel.java @@ -0,0 +1,132 @@ +package clp.edit.graphics.panel.cntrl; + +import java.awt.Color; +import java.awt.Dimension; +import java.sql.Date; +import java.sql.Time; +import java.text.SimpleDateFormat; + +import javax.swing.BorderFactory; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JTextField; +import javax.swing.border.EtchedBorder; +import javax.swing.border.TitledBorder; + +import clp.run.res.VarType; + +public class OutputPanel extends JPanel implements IOutput { + + private static final long serialVersionUID = -7527104666141930080L; + + private Color fldcolor = new Color(0xe08700); + + private int line; + private int col; + + private JTextField valueField; + + private VarType type; + + /** + * CONSTRUCTOR + * + * @param name + * @param type + */ + public OutputPanel(String name, VarType type) { + super(); + this.type = type; + TitledBorder border = BorderFactory.createTitledBorder( + BorderFactory.createBevelBorder(EtchedBorder.LOWERED), + name+" output"); + setBorder(border); + setToolTipText(name); + setSize(160, 60); + setPreferredSize(new Dimension(160, 60)); + if (type != null) { + setup(name, type); + } + } + + // + private void setup(String name, VarType type) { + add(new JLabel(""+type.getVal().charAt(0))); + JTextField fld = new JTextField(name); + fld.setEnabled(false); + fld.setBackground(fldcolor); + add(fld); + valueField = new JTextField(5); + add(valueField); + } + + + /** + * @return the line + */ + public int getLine() { + return line; + } + + /** + * @param line the line to set + */ + public void setLine(int line) { + this.line = line; + } + + /** + * @return the col + */ + public int getCol() { + return col; + } + + /** + * @param col the col to set + */ + public void setCol(int col) { + this.col = col; + } + + public void setValue(Object value) { + if (value == null) { + return; + } + switch (type) { + case TINT: + case TFLOAT: + case TLONG: + case TSTRING: + case TREF: + valueField.setText(""+value); + break; + case TDATE: + Date d = (Date)value; + SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy"); + valueField.setText(formatter.format(d)); + break; + case TTIME: + Time t = (Time)value; + formatter = new SimpleDateFormat("HH:mm:ss"); + valueField.setText(formatter.format(t)); + break; + + default: + break; + } + } + + public void enableIt() { + valueField.setEnabled(true); + } + + public void disableIt() { + valueField.setEnabled(false); + } + + @Override + public String getText() { + return getToolTipText(); + } +} diff --git a/src/clp/edit/graphics/panel/cntrl/StartButton.java b/src/clp/edit/graphics/panel/cntrl/StartButton.java new file mode 100644 index 0000000..98276c0 --- /dev/null +++ b/src/clp/edit/graphics/panel/cntrl/StartButton.java @@ -0,0 +1,38 @@ +package clp.edit.graphics.panel.cntrl; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics; + +import javax.swing.JToggleButton;; + +public class StartButton extends JToggleButton { + + private static final long serialVersionUID = 9016965581885122262L; + + private Color off = new Color(0x870000); + private Color on = new Color(0xd70000); + + public StartButton() { + super(""); + setSize(150, 30); + setPreferredSize(new Dimension(150, 30)); + } + + @Override + public void paint(Graphics g) { + String text; + if (isSelected()) { + g.setColor(on); + text = "Simulation is Running"; + } + else { + g.setColor(off); + text = "Simulate"; + } + g.fillRoundRect(30, 0, 170, 30, 5, 5); + + g.setColor(Color.white); + g.drawString(text, 40, 22); + } +} diff --git a/src/clp/edit/graphics/shapes/ABindingShape.java b/src/clp/edit/graphics/shapes/ABindingShape.java new file mode 100644 index 0000000..3cb1219 --- /dev/null +++ b/src/clp/edit/graphics/shapes/ABindingShape.java @@ -0,0 +1,240 @@ +package clp.edit.graphics.shapes; + +import java.awt.Graphics; +import java.util.List; + +import javax.swing.JComponent; + +public abstract class ABindingShape extends JComponent { + + private static final long serialVersionUID = -2273189660395210964L; + + + abstract public void gatherChildrenShapes(List list); + abstract public void clearChildrenEntries(); + + private AShape parent; + private AShape child; + + private String text; + + private int xshift; + + private BindingType bindingType; + + private int oldxshift; + + + public ABindingShape(String t, BindingType b) { + this.bindingType = b; + this.text = t; + setupXshiftings(); + } + + // + private void setupXshiftings() { + switch (bindingType) { + case DOWN_LEFT: + xshift = -90; + break; + case DOWN_RIGHT: + xshift = +90; + break; + default: + break; + } + } + + public void paintShape(Graphics g, int offset) { + } + + public void paintShape(AShape parent, Graphics g, int offset) { + } + + public int getChildY() { + if (getChild() == null) { + return 0; + } + return getChild().getPY(); + } + + public int getParentY() { + return getParent().getPY()+getParent().getHeight(); + } + + /** + * @return the bindingType + */ + public BindingType getBindingType() { + return bindingType; + } + + /** + * @param bindingType the bindingType to set if not already set to UP + * @return * + */ + public boolean setConditionnallyBindingType(BindingType bt) { + if (bindingType != BindingType.UP_LEFT && bindingType != BindingType.UP_RIGHT) { + bindingType = bt; + return true; + } + return false; + } + + /** + * @param bindingType the bindingType to set + */ + public void setBindingType(BindingType bt) { + bindingType = bt; + } + + /** + * @return the parent + */ + public AShape getParent() { + return parent; + } + + /** + * @param parent the parent to set + */ + public void setParent(AShape parent) { + this.parent = parent; + } + + /** + * @return the child + */ + public AShape getChild() { + return child; + } + + /** + * @param child the child to set + */ + public void setChild(AShape child) { + this.child = child; + child.setParent(this); + } + + public void setOnlyChild(AShape child) { + this.child = child; + } + + /** + * @return the text + */ + public String getText() { + return text; + } + + /** + * @param text the text to set + */ + public void setText(String text) { + this.text = text; + } + + public AShape getSelectedShape(int x, int y) { + if (getChild() != null) { + return getChild().getSelectedShape(x, y); + } + return null; + } + + /** + * X position of 1st point (binding the parent) = parent's X position + * it depends on the binding type + */ + public int getX1() { + switch (bindingType) { + case DOWN_LEFT: + case UP_LEFT: + return parent.getPX() - parent.getWidth()/2; + case DOWN_RIGHT: + case UP_RIGHT: + return parent.getPX() + parent.getWidth()/2; + + default: + return parent.getPX(); + } + } + + /** + * X position of 2nd point (binding the child) = child's X position + */ + public int getX2() { + return child.getPX(); + } + + /** + * X position of middle point (middle position) + */ + public int getXmiddle() { + return xshift; + } + + /** + * @return xshift + */ + public int getXshift() { + return xshift; + } + + /** + * @param xshift the xshift to set + */ + public void setXshift(int xshift) { + this.xshift = xshift; + if (oldxshift == 0) { // save 1st non-0 value + oldxshift = xshift; + } + } + + public void updateDownBinding() { + if (bindingType == BindingType.DOWN) { + bindingType = BindingType.DOWN_MIDDLE; + } + } + + public void shiftX(int delta) { + xshift += delta; + } + + public int getPY() { + return parent.getPY(); + } + + public void setOldXShift() { + xshift = oldxshift; + } + + public boolean generateCode(AContainer container) { + if (bindingType == BindingType.UP_LEFT || bindingType == BindingType.UP_LEFT_MIDDLE || + bindingType == BindingType.UP_RIGHT || bindingType == BindingType.UP_RIGHT_MIDDLE) { + return true; + } + return getChild().generateCode(container); + } + + public boolean generateActiveCode(AContainer container) { + return getChild().generateActiveCode(container); + } + + public String getDeactivationCondition() { + return getChild().getDeactivationCondition(); + } + + public void declareResources() { + boolean isEndNode = (bindingType == BindingType.UP_LEFT || bindingType == BindingType.UP_LEFT_MIDDLE || + bindingType == BindingType.UP_RIGHT || bindingType == BindingType.UP_RIGHT_MIDDLE); + getChild().declareResources(isEndNode); + } + + public void clearResources() { + if (bindingType != BindingType.UP_LEFT && bindingType != BindingType.UP_RIGHT && + bindingType != BindingType.UP_LEFT_MIDDLE && bindingType != BindingType.UP_RIGHT_MIDDLE) { + getChild().clearResources(); + } + } +} diff --git a/src/clp/edit/graphics/shapes/AContainer.java b/src/clp/edit/graphics/shapes/AContainer.java new file mode 100644 index 0000000..365130d --- /dev/null +++ b/src/clp/edit/graphics/shapes/AContainer.java @@ -0,0 +1,991 @@ +package clp.edit.graphics.shapes; + +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Point; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseEvent; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Hashtable; +import java.util.List; + +import javax.swing.JCheckBoxMenuItem; +import javax.swing.SwingUtilities; + +import clp.edit.GeneralContext; +import clp.edit.graphics.btn.AButtonsPanel; +import clp.edit.graphics.btn.IAutomaton; +import clp.edit.graphics.btn.IAutomaton.ActionMode; +import clp.edit.graphics.panel.ButtonsContainer.ButtonType; +import clp.edit.graphics.panel.GeneralShapesContainer; +import clp.edit.graphics.shapes.act.ActivityShape; +import clp.edit.graphics.shapes.util.CellInfo; +import clp.edit.util.TreeNodeInfo; + +abstract public class AContainer implements Serializable { + + private static final long serialVersionUID = 3958439770618221531L; + + private int offset; + + private boolean isDirty; + private boolean isActive; + private Hashtable acells; // initially active cells + private Hashtable icells; // initially inactive cells + + private AShape current; + + private int leftmost; + private int rightmost; + + private RedBindingShape pushedRedShape; + private RedBindingShape redShape; + private List bindings; + + private AShape selected; + private List slist; + + private JCheckBoxMenuItem containerEnabling; + + abstract public Dimension paint(Graphics g, int width, boolean isSelected); + abstract public AContainerShape getContainerShape(); + abstract public AButtonsPanel getButtonsPanel(); + abstract public IAutomaton getAutomaton(); + abstract public void setContainerShape(AContainerShape as); + abstract public boolean isSelected(int px, int py); + abstract public ButtonType getType(); + abstract public void addShape(AShape shape); + abstract public void handleAction(AShape sel, int px, int py, boolean isMultiSelect); + abstract public ABindingShape[] getChildren(AShape s, boolean isUp); + abstract public void showContextMenu(GeneralShapesContainer genericContainer, AShape shape, MouseEvent e); + abstract public boolean isInMainBranch(ABindingShape b); + abstract public String getStringActionNo(); + + /** + * CONSTRUTOR + */ + public AContainer() { + setLeftmost(200); + setRightmost(200); + redShape = new RedBindingShape(BindingType.DOWN); + bindings = new ArrayList<>(); + slist = new ArrayList<>(); + isActive = true; + containerEnabling = new JCheckBoxMenuItem("deactivate", true); + createLisener(); + } + + /** + * add given shape to container shape (c_shape) and update relative positions + * + * @param shape + * @param bindingType + */ + public void addShape(AShape shape, BindingType bindingType) { + if (getContainerShape().getRoot() == null) { + getContainerShape().setRoot(shape); + } + else if (bindingType == null) { + int i = getContainerShape().bindToRoot((ARootShape) shape); + shape.addToX(i*100); + updateLimits(getContainerShape(), shape); + } + else { + getCurrent().setChild(shape, bindingType); + if (shape.getParent() == null) { + return; // it didn't work + } + shape.addToX(shape.getParent().getXshift()); + shape.setYoffset(getCurrent().getHeight()+30); + storeUpBindings(bindingType); + if (getCurrent() instanceof AJoinShape) { + return; + } + if (shape instanceof ActionShape || getCurrent() instanceof AForkShape) { + if (getCurrent() instanceof AForkShape) { + checkResizing(getContainerShape(), ((AForkShape)getCurrent()).getLeftmostChild()); + } + checkResizing(getContainerShape(), shape); + } + updateLimits(getContainerShape(), shape); + } + setDirty(true); + } + + /** + * bind to existing shape + * @param shape + */ + public void bindShape(AShape shape) { + if (shape instanceof ARootShape) { + getContainerShape().bindToRoot((ARootShape) shape); + checkResizing(getContainerShape(), shape.getChild().getChild()); + } + else if (getRedShape().isAttached()) { + pinUpdating(shape); + } + setDirty(true); + } + + // + private void pinUpdating(AShape shape) { + getRedShape().reverseBindingType(getCurrent(), shape); + BindingShape pin = getRedShape().pinIt(); + int delta = getCurrent().getPX() - shape.getPX(); + if (pin.getBindingType() == BindingType.UP_LEFT) { + int x = shape.getPX()-shape.getWidth()/2 - 10; + if (delta < 0) { + pin.setXshift(delta); + } + if (x < getLeftmost()) { + setLeftmost(x-10); + } + getCurrent().setChild(pin); // attach binding to left branch + getCurrent().setChild(shape, pin.getBindingType()); // attach shape to binding + getRedShape().forceRightPartDecisionShape(); + } + else { + int x = shape.getPX()+shape.getWidth()/2 + 10; + if (delta > 0) { + pin.setXshift(delta); + } + if (x > getRightmost()) { + setRightmost(x+10); + } + getCurrent().setChild(pin); // attach binding to right (or join/fork) branch + getCurrent().setChild(shape, pin.getBindingType()); // attach shape to binding + if (getCurrent() instanceof ADecisionShape) { + getRedShape().setAttachTo(null); + } + } + } + + // + private void storeUpBindings(BindingType bindingType) { + if (getCurrent() instanceof ADecisionShape) { + ADecisionShape d = (ADecisionShape) getCurrent(); + if (bindingType == BindingType.UP_LEFT) { + getBindings().add(d.getLeftup()); + d.getLeftup().setXshift(getLeftmost()); + } + if (bindingType == BindingType.UP_RIGHT) { + getBindings().add(d.getRightup()); + d.getRightup().setXshift(getRightmost()); + } + } + } + + public boolean isDeleteAllowed(AShape shape) { + if (!(shape instanceof ARootShape) && shape.getParent().getParent() instanceof ADecisionShape) { + return false; + } + for (ABindingShape b : bindings) { + if (b.getChild().equals(shape)) { + return false; + } + } + return shape.getChild() == null; + } + + public void multiselect(AShape shape) { + if (selected != null && !slist.contains(selected)) { + slist.add(selected); + } + if (shape.isSelected()) { + shape.setSelected(false); + slist.remove(shape); + } + else { + shape.setSelected(true); + slist.add(shape); + } + getContainerShape().refresh(); + } + + public void select(AShape shape) { + if (!slist.isEmpty()) { + for (AShape s : slist) { + s.setSelected(false); + } + slist.clear(); + } + if (shape != null) { + if (shape.isSelected()) { + selected = null; + shape.setSelected(false); + } + else { + boolean wasSelected = false; + if (selected != null) { + selected.setSelected(false); + wasSelected = true; + } + shape.setSelected(true); + selected = shape; + if (wasSelected && shape.getChild() == null && !(shape instanceof AFinalShape)) { + getRedShape().setReady(true); + getRedShape().setAttachTo(shape); + getRedShape().updateXYBoundaries(); + } + else { + boolean isReady = getRedShape().isReady(); + if (!isReady && shape.getChild() == null) { + getRedShape().setReady(true); + getRedShape().setAttachTo(shape); + } + else { + getRedShape().setReady(!isReady); + } + } + setCurrent(shape); + } + getContainerShape().refresh(); + } + } + + public void provideSelection(Point op, Point fp) { + slist = getContainerShape().getSelectedShapes(op.x, op.y, fp.x, fp.y, getOffset()); + for (AShape shape : slist) { + shape.setSelected(true); + } + GeneralContext.getInstance().getGraphicsPanel().refreshUI(); + } + + /** + * check if a container shape is selected + * + * @param px + * @param py + * @param c_shape + * @return + */ + public boolean isSelected(int px, int py, AShape c_shape) { + int x = px - offset; + return (x > c_shape.getPX() && x < c_shape.getPX()+c_shape.getWidth() + && py > c_shape.getPY() && py < c_shape.getPY()+c_shape.getHeight()); + } + + public void updateRedShape(ADecisionShape d2, int delta) { + if (getRedShape().getAttach() == d2) { + int x1 = getRedShape().getX1()+delta; + getRedShape().setXshift(x1+80); + } + } + + public void selectFromRedShape() { + if (getRedShape().getAttach() != null) { + select(getRedShape().getAttach()); + } + } + + public void selectAllFromShape(AShape shape) { + slist.clear(); + shape.gatherChildrenShapes(slist); + for (AShape s : slist) { + s.setSelected(true); + } + } + + public void unselectAll() { + for (AShape shape : slist) { + shape.setSelected(false); + } + slist.clear(); + if (selected != null) { + selected.setSelected(false); + selected = null; + boolean isReady = getRedShape().isReady(); + if (!isReady) { + getAutomaton().performAction(ActionMode.INIT, null, null, false); + } + } + } + + public boolean hasSelection() { + return selected != null || !slist.isEmpty(); + } + + public boolean checkForBindingUpdate(int x) { + getRedShape().setReady(false); + ADecisionShape d = ((ADecisionShape)selected); + if (d.isDecisionUp()) { + x -= getOffset(); + BindingShape b; + if (d.getPX() < x) { + b = d.getRightup(); + if (b != null) { + b.setXshift(x-b.getX2()-b.getChild().getWidth()/2-10); + return true; + } + } + else { + b = d.getLeftup(); + if (b != null) { + b.setXshift(x-b.getX2()+b.getChild().getWidth()/2+10); + return true; + } + } + } + return false; + } + + public boolean isReadyToAddShape() { + return getRedShape().isReady(); + } + + public void setReadyToAddShape() { + getRedShape().setAttachTo(null); + } + + public void moveSelection(Point delta) { + if (selected != null && !slist.contains(selected)) { + slist.add(selected); + } + if (!slist.isEmpty()) { + getRedShape().setReady(false); + List entries = getEntries(slist); + for (AShape e : entries) { + if (!(e instanceof AJoinShape)) { + e.addToX(delta.x); + } + e.addToY(delta.y); + } + List outputs = getOutputs(slist); + for (AShape o : outputs) { + if (!(o instanceof AJoinShape)) { + o.addToX(-delta.x); + } + if (!(o instanceof ARootShape)) { + o.addToY(-delta.y); + } + } + for (AShape shape : slist) { + if (shape instanceof ActionShape) { + checkResizing(getContainerShape(), shape); + } + else if (shape instanceof ADecisionShape) { + ((ADecisionShape)shape).updateDeltaX(delta.x); + } + else if (shape instanceof ATransitionShape) { + updateBindingType((ATransitionShape) shape); + } + updateLimits(getContainerShape(), shape); + } + } + } + + // + private void updateBindingType(ATransitionShape shape) { + ABindingShape c = shape.getChild(); + if (c != null) { + if (c.getBindingType() == BindingType.UP_LEFT && c.getX1() > c.getX2()) { + c.setBindingType(BindingType.UP_RIGHT); + } + else if (c.getBindingType() == BindingType.UP_RIGHT && c.getX1() < c.getX2()) { + c.setBindingType(BindingType.UP_LEFT); + } + } + } + // + private void checkResizing(AContainerShape c_shape, AShape shape) { + int xroot = c_shape.getRoot().getPX(); + int x = shape.getPX(); + int halfShape = shape.getWidth()/2; + int delta = 0; + if (x < xroot) { + delta = halfShape + 10 - x; + if (delta > 0) { + c_shape.setWidth(c_shape.getWidth() + delta); + c_shape.getRoot().addToX(delta); + if (getCurrent() instanceof ADecisionShape) { + getRedShape().updateRightPartDecisionShape(); + } + } + else { + checkForOverlap(shape, c_shape); + } + } + else { + delta = halfShape + x + 10 - c_shape.getWidth(); + if (delta > 0) { + c_shape.setWidth(c_shape.getWidth() + delta); + } + else { + checkForOverlap(shape, c_shape); + } + } + } + + // + private void checkForOverlap(AShape shape, AContainerShape c_shape) { + BindingType type = shape.getParent().getBindingType(); + switch (type) { + case DOWN: + checkForLeftOverlaps(shape, c_shape); + checkForRightOverlaps(shape, c_shape); + break; + case DOWN_MIDDLE: + if (shape.getParent().getX1() < 0) { + checkForLeftOverlaps(shape, c_shape); + } + else { + checkForRightOverlaps(shape, c_shape); + } + break; + case DOWN_LEFT: + checkForLeftOverlaps(shape, c_shape); + break; + case DOWN_RIGHT: + checkForRightOverlaps(shape, c_shape); + break; + + default: + break; + } + } + + // + private void checkForRightOverlaps(AShape shape, AContainerShape c_shape) { + if (c_shape instanceof ActivityShape) { + int refx = shape.getPX() + shape.getWidth()/2; + int refy = shape.getPY(); + AShape s = c_shape.getRoot(); + ADecisionShape dnode = findDecisionNode(shape, s, refx, refy, false); + if (dnode != null) { + int delta = shape.getWidth() + 10; + dnode.getLeft().getChild().addToX(-delta); + s.addToX(delta); + AShape rshape = getRightmostShape(dnode); + checkResizing(c_shape, rshape); + } + } +// JoinBindingShape jnode = findJoinNode(shape, c_shape.getRoot()); +// if (jnode != null) { +// int delta = shape.getWidth() + 10; +// List parents = jnode.getParents(); +// for (ABindingShape pb : parents) { +// pb.getParent().addToX(-delta); +// } +// AShape rshape = parents.get(parents.size()-1).getParent(); +// checkResizing(c_shape, rshape); +// } + } + + // + private void checkForLeftOverlaps(AShape shape, AContainerShape c_shape) { + if (c_shape instanceof ActivityShape) { + int refx = shape.getPX() - shape.getWidth()/2; + int refy = shape.getPY(); + ADecisionShape dnode = findDecisionNode(shape, c_shape.getRoot(), refx, refy, true); + if (dnode != null) { + int delta = shape.getWidth() + 10; + dnode.getRight().getChild().addToX(delta); + AShape rshape = getRightmostShape(dnode); + checkResizing(c_shape, rshape); + getRedShape().updateRightPartDecisionShape(); + } + } +// JoinBindingShape jnode = findJoinNode(shape, c_shape.getRoot()); +// if (jnode != null) { +// int delta = shape.getWidth() + 10; +// List parents = jnode.getParents(); +// for (ABindingShape pb : parents) { +// pb.getParent().addToX(delta); +// } +// AShape rshape = parents.get(parents.size()-1).getParent(); +// checkResizing(c_shape, rshape); +// } + } + + // + private AShape getRightmostShape(ADecisionShape node) { + BindingShape n = node.getRight(); + if (n == null) { + return null; + } + AShape c = n.getChild(); + if (c.getChild() == null) { + return c; + } + AShape d = c; + while (d != null && !(d instanceof ADecisionShape)) { + ABindingShape b = d.getChild(); + if (b == null) { + d = null; + } + else { + d = b.getChild(); + } + } + if (d == null) { + return c; + } + AShape ret = getRightmostShape((ADecisionShape) d); + return ret != null ? ret : c; + } + + // + private ADecisionShape findDecisionNode(AShape shape, AShape s, int refx, int refy, boolean isLeft) { + ABindingShape b = null; + ABindingShape[] bs = null; + ADecisionShape d = null; + do { + bs = getChildren(s, false); + if (bs != null) { + for (int i=0; i refy) { + break; + } + int x = s.getPX(); + if (x-s.getWidth()/2 <= refx && x+s.getWidth()/2 >= refx + && s.getPY()-s.getHeight()/2 <= refy && s.getPY()+s.getHeight()/2 >= refy) { + d = retrieveDecisionNode(s, !isLeft); + if (d != null) { + return d; + } + } + d = findDecisionNode(shape, s, refx, refy, isLeft); + if (d != null) { + return d; + } + } + } + } + } + else { + b = s.getChild(); + if (b != null) { + s = b.getChild(); + } + } + } while (b != null && s != null && s != shape); + + return null; + } + + // + private ABindingShape getAllowedBinding(ABindingShape b) { + if (b != null && isBindingTypeAllowed(b.getBindingType())) { + return b; + } + return null; + } + + // + private boolean isBindingTypeAllowed(BindingType t) { + return t == BindingType.DOWN || t == BindingType.DOWN_LEFT || + t == BindingType.DOWN_MIDDLE || t == BindingType.DOWN_RIGHT; + } + + // + private ADecisionShape retrieveDecisionNode(AShape s, boolean isSearchForLeft) { + ABindingShape b = null; + ADecisionShape d = null; + boolean isParent = false; + do { + b = s.getParent(); + if (b != null) { + s = b.getParent(); + if (s instanceof ADecisionShape) { + if (!isParent) { + if (isSearchForLeft && b.getBindingType() == BindingType.DOWN_LEFT || + !isSearchForLeft && b.getBindingType() == BindingType.DOWN_RIGHT) { + isParent = true; + } + } + else { + if (isSearchForLeft && b.getBindingType() == BindingType.DOWN_RIGHT || + !isSearchForLeft && b.getBindingType() == BindingType.DOWN_LEFT) { + d = (ADecisionShape) s; + } + } + } + } + } while (s != null && b != null && d == null); + + return d; + } + + /** + * PAINT a container shape + * + * @param g + * @param offset + * @param isSelected + * @param c_shape + * @return + */ + public Dimension paint(Graphics g, int offset, boolean isSelected, AContainerShape c_shape) { + int width = 1; + int height = 1; + c_shape.paintShape(g, offset, isSelected, containerEnabling.getState()); + int w = c_shape.getWidth(); + if (width < w) { + width = w; + } + int h = c_shape.getHeight(); + if (height < h) { + height = h; + } + this.offset = offset; + + return new Dimension(width+2, height); + } + + public void deleteAllFromShape(AShape shape) { + ABindingShape cb = shape.getChild(); + AShape cshape = cb.getChild(); + if (cb != null) { + if (cshape instanceof AJoinShape) { + AJoinShape join = (AJoinShape) cb.getChild(); + for (int i=0; i list = new ArrayList<>(); + cshape.gatherLinksToJoin(list); + if (!list.isEmpty()) { + AJoinShape join = (AJoinShape) list.get(0).getChild(); + int nblinks = join.getParents().size(); + if (nblinks == list.size()) { + deleteAllFromShape(join); + } + else { + join.deleteChildNodes(list); + } + } + } + } + ABindingShape pb = cshape.getParent(); + if (pb instanceof TriBinding) { + ((TriBinding)pb).delete(cb, cshape, true); + } + shape.setChild(null); + cb.clearChildrenEntries(); + setCurrent(shape); + getRedShape().setAttachTo(shape); + } + + public void replaceJoin(AJoinShape join) { + AShape child = join.getChild().getChild(); + join.getParents().get(0).setChild(child); + child.addToY(30); + } + /** + * @return the offset + */ + public int getOffset() { + return offset; + } + + /** + * @param offset the offset to set + */ + public void setOffset(int offset) { + this.offset = offset; + } + + /** + * @return the current + */ + public AShape getCurrent() { + return current; + } + + /** + * @param current the current to set + */ + public void setCurrent(AShape current) { + this.current = current; + } + + // + public List getEntries(List list) { + List entries = new ArrayList<>(); + for (AShape s : list) { + if (s.getParent() == null) { + entries.add(s); + } + else { + AShape p = s.getParent().getParent(); + if (!list.contains(p)) { + entries.add(s); + } + } + } + return entries; + } + + // + public List getOutputs(List list) { + List outputs = new ArrayList<>(); + for (AShape s : list) { + if (s instanceof AJoinShape) { + continue; + } + ABindingShape[] bs = getChildren(s, true); + if (bs != null) { + for (ABindingShape b : bs) { +// if (b != null && isBindingTypeAllowed(b.getBindingType()) && +// b.getChild() != null && !list.contains(b.getChild()) && isInMainBranch(b)) { +// outputs.add(b.getChild()); +// } + if (b != null && isBindingTypeAllowed(b.getBindingType()) && + b.getChild() != null && !list.contains(b.getChild())) { + outputs.add(b.getChild()); + } + if (s instanceof ARootShape) { + ARootShape sibling = ((ARootShape) s).getSibling(); + while (sibling != null) { + outputs.add(sibling); + sibling = sibling.getSibling(); + } + } + } + } + } + return outputs; + } + + // + public void updateLimits(int left, int right) { + AContainerShape c_shape = getContainerShape(); + if (leftmost > left) { + leftmost = left; + } + if (rightmost < right) { + rightmost = right; + } + if (rightmost > c_shape.getWidth()) { + c_shape.setWidth(rightmost + 20); + } + } + + // + public void updateLimits(AContainerShape c_shape, AShape shape) { + int x = shape.getPX(); + int left = x - shape.getWidth()/2; + int right = x + shape.getWidth()/2; + if (leftmost > left) { + leftmost = left; + } + if (rightmost < right) { + rightmost = right; + } + int delta; + if (leftmost < 0) { + delta = 10 - leftmost; + leftmost += delta; + rightmost += delta; + c_shape.getRoot().addToX(delta); + } + else { + delta = rightmost - c_shape.getWidth(); + } + if (rightmost > c_shape.getWidth()) { + c_shape.setWidth(c_shape.getWidth()+delta); + } + int y_location = shape.getPY(); + if (y_location > c_shape.getHeight()-30) { + c_shape.setHeight(y_location+100); + } + } + + /** + * @return the leftmost + */ + public int getLeftmost() { + return leftmost; + } + + /** + * @param leftmost the leftmost to set + */ + public void setLeftmost(int leftmost) { + this.leftmost = leftmost; + } + + /** + * @return the rightmost + */ + public int getRightmost() { + return rightmost; + } + + /** + * @param rightmost the rightmost to set + */ + public void setRightmost(int rightmost) { + this.rightmost = rightmost; + } + + /** + * @return the redShape + */ + public RedBindingShape getRedShape() { + return redShape; + } + /** + * @return the bindings + */ + public List getBindings() { + return bindings; + } + /** + * @return the selected + */ + public AShape getSelected() { + return selected; + } + public void pushRedShape() { + pushedRedShape = redShape; + redShape = new RedBindingShape(BindingType.DOWN); + } + public void popRedShape() { + redShape = pushedRedShape; + pushedRedShape = null; + } + /** + * @return the isDirty + */ + public boolean isDirty() { + return isDirty; + } + /** + * @param isDirty the isDirty to set + */ + public void setDirty(boolean isDirty) { + this.isDirty = isDirty; + } + + public boolean generateCode() { + acells = new Hashtable<>(); + icells = new Hashtable<>(); + ARootShape shape = (ARootShape) getContainerShape().getRoot(); + while (shape != null) { + shape.clearResources(); + shape = shape.getSibling(); + } + shape = (ARootShape) getContainerShape().getRoot(); + while (shape != null) { + if (!((AShape)shape).generateCode(this)) { + return false; + } + shape = shape.getSibling(); + } + if (!acells.isEmpty() || !icells.isEmpty()) { + TreeNodeInfo nodeInfo = new TreeNodeInfo( getContainerShape()); + nodeInfo.generateCode(acells, icells); + } + shape = (ARootShape) getContainerShape().getRoot(); + while (shape != null) { + shape.declareResources(false); + shape = shape.getSibling(); + } + return true; + } + + public void register(String name, CellInfo info, boolean isInitiallyActive) { + if (isInitiallyActive) { + acells.put(name, info); + } + else { + icells.put(name, info); + } + } + + public boolean isRegistered(String name) { + return acells.containsKey(name) || icells.containsKey(name); + } + + public boolean removeDeactivationForInit(String name) { + CellInfo cinfo = acells.get(name); + if (cinfo != null) { + cinfo.setDd(null); + return true; + } + return false; + } + + public boolean addDeactivationConditionFromFinal(String name, String final_name) { + CellInfo cinfo = acells.get(name); + if (cinfo == null) { + cinfo = icells.get(name); + } + if (cinfo != null && cinfo.getDd() != null) { + String cnd = cinfo.getDd(); + int i = cnd.indexOf("{"); + if (i > 0) { + cinfo.setDd(" DD { activated(" + final_name + "); }\n"); + return true; + } + } + return false; + } + + public String getKey() { + return getContainerShape().getScenarioName() + getContainerShape().getActorName(); + } + + /** + * @return the isActive + */ + public boolean isActive() { + return isActive; + } + /** + * @param isActive the isActive to set + */ + public void setActive(boolean isActive) { + this.isActive = isActive; + } + + public JCheckBoxMenuItem getCheckBox() { + return containerEnabling; + } + + public void createLisener() { + containerEnabling.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + JCheckBoxMenuItem cb = (JCheckBoxMenuItem) e.getSource(); + if (cb.getState()) { + cb.setText("deactivate"); + setDirty(true); + setActive(true); + } + else { + cb.setText("reactivate"); + setDirty(true); + setActive(false); + } + SwingUtilities.invokeLater(new Runnable() { + public void run() { + GeneralContext.getInstance().getGraphicsPanel().getShapesContainer().repaint(); + } + }); + } + }); + } + + public boolean isPetri() { + return false; + } + public boolean isColored() { + return false; + } +} diff --git a/src/clp/edit/graphics/shapes/AContainerShape.java b/src/clp/edit/graphics/shapes/AContainerShape.java new file mode 100644 index 0000000..826c31c --- /dev/null +++ b/src/clp/edit/graphics/shapes/AContainerShape.java @@ -0,0 +1,147 @@ +package clp.edit.graphics.shapes; + +import java.awt.Color; +import java.awt.Graphics; +import java.util.ArrayList; +import java.util.List; + +import clp.edit.GeneralContext; + +public abstract class AContainerShape extends AShape { + + private static final long serialVersionUID = -4641680662938568513L; + + private AShape root; + private Color background; + + /** + * CONSTRUCTOR + * + * @param width + * @param height + * @param name + */ + public AContainerShape(int width, int height, String name) { + super(width, height, name, ""); + } + + abstract public StringBuilder getSource(String mscName); + abstract public void removeActor(); + abstract public String getScenarioName(); + abstract public String getHeapNamePrefix(); + + /** + * PAINT a container shape + * + * @param g + * @param offset + * @param isSelected + * @param isActivated + */ + public void paintShape(Graphics g, int offset, boolean isSelected, boolean isActivated) { + if (isActivated) { + if (isSelected) { + g.setColor(new Color(0xFFC508)); + } + else { + g.setColor(new Color(0xF9F5D9)); + } + } + else { + if (isSelected) { + g.setColor(Color.darkGray); + } + else { + g.setColor(Color.gray); + } + } + int x = offset; + g.fillRoundRect(x, 0, getWidth(), 40, 20, 20); + g.setColor(getBackground()); + g.fillRoundRect(x, 40, getWidth(), getHeight(), 20, 20); + g.setColor(Color.black); + g.drawLine(x+5, 40, x+getWidth()-5, 40); + g.drawString(getName(), x+(getWidth()-70)/2, 25); + } + + public AShape getSelectedShape(int px, int py, int offset) { + int x = px-offset; + int y = py; + return getRoot() == null ? null : getRoot().getSelectedShape(x, y); + } + + public List getSelectedShapes(int px1, int py1, int px2, int py2, int offset) { + if (getRoot() == null) { + return null; + } + int x1 = px1-offset; + int y1 = py1; + int x2 = px2-offset; + int y2 = py2; + List list = new ArrayList<>(); + getRoot().gatherSelectedShapes(x1, y1, x2, y2, list); + return list; + } + + @Override + public AShape getSelectedShape(int x, int y) { + return null; + } + + @Override + public void gatherSelectedShapes(int x1, int y1, int x2, int y2, List list) { + } + + @Override + public void setChild(AShape shape, BindingType bindingType) { + } + + /** + * @return the root + */ + public AShape getRoot() { + return root; + } + + /** + * @param root the root to set + */ + public void setRoot(AShape root) { + this.root = root; + } + + public int bindToRoot(ARootShape event) { + return ((ARootShape)getRoot()).setSibling(event); + } + + /** + * @return the background + */ + public Color getBackground() { + return background; + } + + /** + * @param background the background to set + */ + public void setBackground(Color background) { + this.background = background; + } + + public void refresh() { + GeneralContext.getInstance().getGraphicsPanel().getShapesContainer().refresh(); + } + + @Override + public String toString() { + return getSource("").toString(); + } + + public String getActorName() { + return getName().replace(" ", "_"); + } + + public int getHighLevel() { + return 1; + } +} diff --git a/src/clp/edit/graphics/shapes/ADecisionShape.java b/src/clp/edit/graphics/shapes/ADecisionShape.java new file mode 100644 index 0000000..9c32b70 --- /dev/null +++ b/src/clp/edit/graphics/shapes/ADecisionShape.java @@ -0,0 +1,311 @@ +package clp.edit.graphics.shapes; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Hashtable; + +import clp.edit.graphics.dial.DecisionDialog; +import clp.edit.graphics.shapes.util.ResourceHelper; +import clp.edit.graphics.shapes.util.ResourceHelper.InputResourcesInfo; +import clp.run.res.VarType; + +abstract public class ADecisionShape extends AShape { + + private static final long serialVersionUID = 6410312957242049081L; + + + private Hashtable inputResources; + + private BindingShape left; + private BindingShape right; + private BindingShape leftup; + private BindingShape rightup; + + private boolean isDecisionUp; + + private DecisionInfo info; + + private int nbBranches; + + public ADecisionShape(int width, int height, String name) { + super(width, height, name, "Decision "); + nbBranches = 2; + info = new DecisionInfo(); + inputResources = new Hashtable<>(); + } + + public void resetChildren() { + left = null; + right = null; + leftup = null; + rightup = null; + } + + @Override + public ABindingShape getChild() { + if (left != null) { + if (right != null || rightup != null) { + return left; + } + } + else if (leftup != null) { + if (right != null || rightup != null) { + return leftup; + } + } + return null; + } + + public boolean isComplete() { + return nbBranches == 0; + } + + private void decrement() { + if (nbBranches > 0) { + nbBranches--; + } + } + + /** + * @return the left + */ + public BindingShape getLeft() { + return left; + } + + /** + * @param left the left to set + */ + public void setLeft(BindingShape left) { + this.left = left; + if (left != null) { + left.setText(info.getLeftPartName()); + this.left.setConditionnallyBindingType(BindingType.DOWN_LEFT); + left.setParent(this); + decrement(); + } + } + + /** + * @return the right + */ + public BindingShape getRight() { + return right; + } + + /** + * @param right the right to set + */ + public void setRight(BindingShape right) { + this.right = right; + if (right != null) { + right.setText(info.getRightPartName()); + this.right.setConditionnallyBindingType(BindingType.DOWN_RIGHT); + right.setParent(this); + decrement(); + } + } + + /** + * @return the leftup + */ + public BindingShape getLeftup() { + return leftup; + } + + /** + * @param leftup the leftup to set + */ + public void setLeftup(BindingShape leftup) { + this.leftup = leftup; + if (leftup != null) { + leftup.setText(info.getLeftPartName()); + this.leftup.setConditionnallyBindingType(BindingType.UP_LEFT); + decrement(); + } + } + + /** + * @return the rightup + */ + public BindingShape getRightup() { + return rightup; + } + + /** + * @param rightup the rightup to set + */ + public void setRightup(BindingShape rightup) { + this.rightup = rightup; + if (rightup != null) { + rightup.setText(info.getRightPartName()); + this.rightup.setConditionnallyBindingType(BindingType.UP_RIGHT); + decrement(); + } + } + + public boolean isDecisionUp() { + return isDecisionUp; + } + + public void setDecisionUp(boolean isDecisionUp) { + this.isDecisionUp = isDecisionUp; + } + + public void swapInfo() { + String n = info.getRightPartName(); + info.setRightPartName(info.getLeftPartName()); + info.setLeftPartName(n); + n = info.getRightPartDescription(); + info.setRightPartDescription(info.getLeftPartDescription()); + info.setLeftPartDescription(n); + } + + /** + * @return the info + */ + public DecisionInfo getInfo() { + return info; + } + + public void updateDeltaX(int x) { + if (getLeftup() != null) { + getLeftup().shiftX(x); + } + if (getRightup() != null) { + getRightup().shiftX(x); + } + } + + @Override + public String getActivationCondition(ABindingShape bs) { + String s; + if (bs == left) { + s = left.getText(); + ResourceHelper.getInstance().addInputVariable(s, info.getLeftPartDescription(), VarType.TBOOL, false, inputResources); + } + else if (bs == right) { + s = right.getText(); + ResourceHelper.getInstance().addInputVariable(s, info.getRightPartDescription(), VarType.TBOOL, false, inputResources); + } + else if (bs == leftup) { + s = leftup.getText(); + ResourceHelper.getInstance().addInputVariable(s, info.getLeftPartDescription(), VarType.TBOOL, false, inputResources); + } + else { + s = rightup.getText(); + ResourceHelper.getInstance().addInputVariable(s, info.getRightPartDescription(), VarType.TBOOL, false, inputResources); + } + return " " + s + " AND activated(" + getParent().getParent().getName() + ") "; + } + + @Override + public String getDeactivationCondition() { + ArrayList list = new ArrayList<>(); + if (left != null) { + fillListAndDeclareEvent(list, left.getChild()); + } + if (right != null) { + fillListAndDeclareEvent(list, right.getChild()); + } + if (leftup != null) { + fillListAndDeclareEvent(list, leftup.getChild()); + } + if (rightup != null) { + fillListAndDeclareEvent(list, rightup.getChild()); + } + String s = list.toString(); + return s.substring(1, s.length()-2).replace(",", " OR"); + } + + // + private void fillListAndDeclareEvent(ArrayList list, AShape chld) { + ResourceHelper.getInstance().addInputVariable(chld.getName(), chld.getDesc(), null, false, inputResources); + list.add(" activated(" + chld.getName() + ") "); + } + + @Override + public void declareResources(boolean isEndNode) { + ResourceHelper.getInstance().declareIn(inputResources); + if (left != null) { + left.declareResources(); + } + if (right != null) { + right.declareResources(); + } + } + + @Override + public void clearResources() { + inputResources.clear(); + if (left != null) { + left.clearResources(); + } + if (right != null) { + right.clearResources(); + } + } + + @Override + public void upateDialog() { + ((DecisionDialog)getDialog()).updateFromInfo(info); + } + + //=========================================================================== + + public class DecisionInfo implements Serializable { + private static final long serialVersionUID = 8765843389784929551L; + private String leftPartName; + private String rightPartName; + private String leftPartDescription; + private String rightPartDescription; + /** + * @return the leftPartName + */ + public String getLeftPartName() { + return leftPartName; + } + /** + * @param leftPartName the leftPartName to set + */ + public void setLeftPartName(String leftPartName) { + this.leftPartName = leftPartName; + } + /** + * @return the rightPartName + */ + public String getRightPartName() { + return rightPartName; + } + /** + * @param rightPartName the rightPartName to set + */ + public void setRightPartName(String rightPartName) { + this.rightPartName = rightPartName; + } + /** + * @return the leftPartDescription + */ + public String getLeftPartDescription() { + return leftPartDescription; + } + /** + * @param leftPartDescription the leftPartDescription to set + */ + public void setLeftPartDescription(String leftPartDescription) { + this.leftPartDescription = leftPartDescription; + } + /** + * @return the rightPartDescription + */ + public String getRightPartDescription() { + return rightPartDescription; + } + /** + * @param rightPartDescription the rightPartDescription to set + */ + public void setRightPartDescription(String rightPartDescription) { + this.rightPartDescription = rightPartDescription; + } + } +} diff --git a/src/clp/edit/graphics/shapes/AEventShape.java b/src/clp/edit/graphics/shapes/AEventShape.java new file mode 100644 index 0000000..81a9e04 --- /dev/null +++ b/src/clp/edit/graphics/shapes/AEventShape.java @@ -0,0 +1,20 @@ +package clp.edit.graphics.shapes; + +import clp.edit.graphics.dial.TransitionType; + +abstract public class AEventShape extends ATransitionRoot { + + private static final long serialVersionUID = 7332626605015319700L; + + public AEventShape(int width, int height, TransitionType tt) { + super(width, height, tt); + } + + @Override + public boolean generateCode(AContainer container) { + if (getChild() != null) { + return getChild().generateCode(container); + } + return true; + } +} diff --git a/src/clp/edit/graphics/shapes/AFinalShape.java b/src/clp/edit/graphics/shapes/AFinalShape.java new file mode 100644 index 0000000..c967ee1 --- /dev/null +++ b/src/clp/edit/graphics/shapes/AFinalShape.java @@ -0,0 +1,17 @@ +package clp.edit.graphics.shapes; + +import clp.edit.graphics.dial.TransitionType; + +abstract public class AFinalShape extends ATransitionShape { + + private static final long serialVersionUID = 1047468899173820357L; + + public AFinalShape(int width, int height, String name, TransitionType tt) { + super(width, height, name, "", tt); + } + + @Override + public boolean generateCode(AContainer container) { + return true; + } +} diff --git a/src/clp/edit/graphics/shapes/AForkShape.java b/src/clp/edit/graphics/shapes/AForkShape.java new file mode 100644 index 0000000..317cc8a --- /dev/null +++ b/src/clp/edit/graphics/shapes/AForkShape.java @@ -0,0 +1,165 @@ +package clp.edit.graphics.shapes; + +import java.util.ArrayList; +import java.util.List; + +import clp.edit.dialog.ADialog; +import clp.edit.graphics.dial.ForkDialog; +import clp.edit.graphics.dial.TransitionType; + +public abstract class AForkShape extends ATransitionShape { + + private static final long serialVersionUID = -1011308021246755546L; + + private List destinations; + private int leftmost; + private int rightmost; + transient private ForkDialog dialog; + + public AForkShape(int width, int height, String name, TransitionType tt) { + super(width, height, name, "", tt); + destinations = new ArrayList<>(); + } + + /** + * @return the destinations + */ + public List getDestinations() { + return destinations; + } + + public AShape getLeftmostChild() { + return destinations.get(0).getChild(); + } + + @Override + public ABindingShape getChild() { + if (destinations.size() > 1) { + return destinations.get(0); + } + return null; + } + + @Override + public void setChild(AShape shape, BindingType bindingType) { + ABindingShape b = new BindingShape(bindingType, ""); + b.setParent(this); + boolean isUp = false; + if (bindingType == BindingType.UP_LEFT || bindingType == BindingType.UP_RIGHT) { + isUp = true; + b.setOnlyChild(shape); + ((ActionShape)shape).addEntryPoint(b); + } + else { + b.setChild(shape); + } + destinations.add(b); + int nb = destinations.size() < 2 ? 2 : destinations.size(); + int w = 160*(nb-1); + int pos = - w/2; + ABindingShape b0 = destinations.get(0); + b0.getChild().setXoffset(pos); + leftmost = b0.getChild().getPX(); + for (int i=1; i rightmost) { + rightmost = x; + } + } + } + + @Override + public void gatherLinksToJoin(List list) { + for (ABindingShape b : destinations) { + b.getChild().gatherLinksToJoin(list); + } + } + + @Override + public ADialog getDialog() { + if (dialog == null) { + dialog = new ForkDialog(this); + } + return dialog; + } + + public void reverseBindingType(RedBindingShape redShape) { + if (getDestinations().isEmpty()) { + redShape.setConditionnallyBindingType(BindingType.UP_LEFT); + } + else { + redShape.setConditionnallyBindingType(BindingType.UP_RIGHT); + } + } + + public void delete(ABindingShape b) { + for (ABindingShape d : destinations) { + if (b == d) { + destinations.remove(b); + break; + } + } + } + + /** + * @return the rightmost + */ + public int getRightmost() { + return rightmost; + } + + /** + * @return the leftmost + */ + public int getLeftmost() { + return leftmost; + } + + @Override + public int getWidth() { + return rightmost - leftmost; + } + + @Override + public void setWidth(int width) { + this.rightmost = leftmost + width; + } + + @Override + public boolean generateCode(AContainer container) { + boolean b = true; + for (ABindingShape d : destinations) { + b &= d.generateCode(container); + if (!b) { + return false; + } + } + return b; + } + + @Override + public String getActivationCondition(ABindingShape bs) { + return " activated(" + getParent().getParent().getName() + ") "; + } + + @Override + public String getDeactivationCondition() { + AShape chld = destinations.get(0).getChild(); + addInputVariable(chld.getName(), chld.getDesc(), null); + String s = " activated(" + chld.getName() + ") "; + for (int i=1; i parents; + + private Integer leftmost; + private Integer rightmost; + + transient private JoinDialog dialog; + + public AJoinShape(int width, int height, String name, TransitionType tt) { + super(width, height, name, "", tt); + parents = new ArrayList<>(); + } + + @Override + public void setChild(AShape shape, BindingType bindingType) { + } + + @Override + public ADialog getDialog() { + if (dialog == null) { + dialog = new JoinDialog(this); + } + return dialog; + } + + /** + * @return the parents + */ + public List getParents() { + return parents; + } + + public void deleteChildNodes(ArrayList list) { + for (ABindingShape b : list) { + parents.remove(b); + } + if (parents.size() == 1) { + ABindingShape b = getParents().get(0); + AShape chld = getChild().getChild(); + chld.addToY(30); + AShape par = b.getParent(); + if (par instanceof ActionShape && chld instanceof ActionShape || + par instanceof ATransitionShape && chld instanceof ATransitionShape) { + par.setChild(null); + } + else { + b.setChild(chld); + } + } + } + + public void exchangeChild(ABindingShape b, ABindingShape parent) { + int i = parents.indexOf(b); + parents.set(i, parent); + } + + /** + * @return the leftmost + */ + public Integer getLeftmost() { + return leftmost; + } + + /** + * @param leftmost the leftmost to set + */ + public void setLeftmost(Integer leftmost) { + this.leftmost = leftmost; + } + + /** + * @return the rightmost + */ + public Integer getRightmost() { + return rightmost; + } + + /** + * @param rightmost the rightmost to set + */ + public void setRightmost(Integer rightmost) { + this.rightmost = rightmost; + } + + @Override + public int getWidth() { + if (leftmost == null || rightmost == null) { + return 0; + } + return rightmost - leftmost; + } + + @Override + public void setWidth(int width) { + ActionShape p = null; + for (ABindingShape b : parents) { + if (p == null || b.getParent().getPX() > p.getPX()) { + p = (ActionShape) b.getParent(); + } + } + p.addToX(width - rightmost + leftmost); + GeneralContext.getInstance().getGraphicsPanel().getShapesContainer().getCurrentContainer() + .updateLimits(leftmost, leftmost+width+10); + } + + @Override + public boolean generateCode(AContainer container) { + if (getChild() != null) { + return getChild().generateCode(container); + } + return true; + } + + @Override + public String getActivationCondition(ABindingShape bsr) { + if (parents.size() > 1) { + String s = " activated(" + parents.get(0).getParent().getName() + ") "; + for (int i=1; i= 0 && delta < 4 || delta < 0 && delta > -4) { + b.setConditionnallyBindingType(BindingType.DOWN); + b.setXshift(0); + } + else { + b.setConditionnallyBindingType(BindingType.DOWN_MIDDLE); + b.setOldXShift(); // restore 1st non-0 value + } + } + } + } + + public void gatherLibsDeclaration(ArrayList jars) { + } + + /** + * this shape is selected if coordinates point within it + * if not, look up for the children + * + * @param x + * @param y + * @return + */ + public AShape getSelectedShape(int x, int y) { + int ref_x = getPX(); + if (x > ref_x-getWidth()/2 && x < ref_x+getWidth()/2 + && y > getPY() && y < getPY()+getHeight()) { + + return this; + } + if (getChild() != null) { + return getChild().getSelectedShape(x, y); + } + return null; + } + + /** + * this shape is selected if in the region given by coordinates and + * the same is proposed for children + * + * @param x1 + * @param y1 + * @param x2 + * @param y2 + * @param list + */ + public void gatherSelectedShapes(int x1, int y1, int x2, int y2, List list) { + int ref_x = getPX() - getWidth()/2; + int ref_y = getPY() + getHeight(); + if (ref_x > x1 && ref_x < x2 && ref_y > y1 && ref_y < y2) { + list.add(this); + } + if (getChild() != null) { + getChild().getChild().gatherSelectedShapes(x1, y1, x2, y2, list); + } + } + + /** + * this shape is selected and the same is proposed to children if exist + * + * @param list + */ + public void gatherChildrenShapes(List list) { + list.add(this); + if (getChild() != null) { + getChild().gatherChildrenShapes(list); + } + } + + /** + * go through the children shapes and add binding of this, if child is a join + * + * @param list + */ + public void gatherLinksToJoin(List list) { + ABindingShape b = getChild(); + if (b != null) { + AShape s = b.getChild(); + if (s instanceof AJoinShape) { + list.add(b); + } + else if (!upBinding(b.getBindingType())) { + s.gatherLinksToJoin(list); + } + } + } + + // + private boolean upBinding(BindingType bindingType) { + return bindingType == BindingType.UP_LEFT || bindingType == BindingType.UP_LEFT_MIDDLE || + bindingType == BindingType.UP_RIGHT || bindingType == BindingType.UP_RIGHT_MIDDLE; + } + + /** + * @return the x + */ + public int getPX() { + if (parent != null) { + return xoffset + parent.getX1(); + } + return xoffset; + } + + /** + * @return the py + */ + public int getPY() { + if (parent != null) { + return yoffset + parent.getPY(); + } + return yoffset; + } + + public void addToX(int delta) { + xoffset += delta; + if (getParent() != null && !(delta > 0 && delta < 4 || delta < 0 && delta > -4)) { + getParent().updateDownBinding(); + } + } + + public void addToY(int delta) { + yoffset += delta; + } + + /** + * @return the width + */ + public int getWidth() { + return width; + } + + /** + * @return the height + */ + public int getHeight() { + return height; + } + + /** + * @return the isSelected + */ + public boolean isSelected() { + return isSelected; + } + + /** + * @param isSelected the isSelected to set + */ + public void setSelected(boolean isSelected) { + this.isSelected = isSelected; + } + + /** + * @param width the width to set + */ + public void setWidth(int width) { + this.width = width; + } + + /** + * @param height the height to set + */ + public void setHeight(int height) { + this.height = height; + } + + /** + * @return the parent + */ + public ABindingShape getParent() { + return parent; + } + + /** + * @param parent the parent to set + */ + public void setParent(ABindingShape parent) { + this.parent = parent; + } + + /** + * @return the child + */ + public ABindingShape getChild() { + return child; + } + + /** + * @param child the child to set + */ + public void setChild(ABindingShape child) { + this.child = child; + if (child != null) { + child.setParent(this); + } + } + + /** + * @return the xoffset + */ + public int getXoffset() { + return xoffset; + } + + /** + * @return the yoffset + */ + public int getYoffset() { + return yoffset; + } + + public void setXoffset(int delta) { + xoffset = delta; + } + + public void setYoffset(int delta) { + yoffset = delta; + } + + /** + * @return the isReferencingSelectedCondition + */ + public boolean isReferencingSelectedCondition() { + return isReferencingSelectedCondition; + } + + /** + * @param isReferencingSelectedCondition the isReferencingSelectedCondition to set + */ + public void setReferencingSelectedCondition(boolean isReferencingSelectedCondition) { + this.isReferencingSelectedCondition = isReferencingSelectedCondition; + } + + /** + * @return the name + */ + public String getName() { + return name; + } + + /** + * @param name the name to set + */ + public void setName(String name) { + this.name = name; + } + + /** + * @return the isPublished + */ + public boolean isPublished() { + return isPublished; + } + + /** + * @param isPublished the isPublished to set + */ + public void setPublished(boolean isPublished) { + this.isPublished = isPublished; + } + + /** + * @return the desc + */ + public String getDesc() { + return desc; + } + + /** + * @param desc the desc to set + */ + public void setDesc(String desc) { + if (desc != null) { + this.desc = desc; + setToolTipText("" + this.name + " (" + this.desc + ")" + this.adesc + ""); + } + } + + /** + * @param desc the desc to set + */ + public void addToDesc(String desc) { + this.adesc = "

" + desc.replaceAll("\n", "

"); + setToolTipText("" + this.name + " (" + this.desc + ")" + this.adesc + ""); + } + + public boolean generateCode(AContainer container) { + if (!container.isRegistered(name)) { + CellInfo info = new CellInfo(name); + fillContent(container, info); + container.register(name, info, false); + if (child != null) { + if (!child.generateCode(container)) { + return false; + } + } + } + return true; + } + + public void declareResources(boolean isEndNode) { + if (getChild() != null) { + getChild().declareResources(); + } + } + + public void clearResources() { + if (getChild() != null) { + getChild().clearResources(); + } + } + + // + protected void fillContent(AContainer container, CellInfo info) { + String code = getActivationDomain(container); + if (code != null) { + info.setAd(" AD { " + code + "; }\n"); + } + code = getDeactivationDomain(container); + if (code != null) { + info.setDd(" DD { " + code + "; }\n"); + } + ArrayList instList = getExecutionDomain(container); + if (instList != null && !instList.isEmpty()) { + info.setXd(instList); + } + } + + public String getActivationDomain(AContainer container) { + return null; + } + + public String getDeactivationDomain(AContainer container) { + return null; + } + + public ArrayList getExecutionDomain(AContainer container) { + return null; + } + + public boolean generateActiveCode(AContainer container) { + if (!container.isRegistered(name)) { + CellInfo info = new CellInfo(name); + fillContent(container, info); + container.register(name, info, true); + if (child != null) { + if (!child.generateCode(container)) { + return false; + } + } + } + return true; + } + + public String getActivationCondition(ABindingShape bs) { + return " activated(" + getName() + ") "; + } + + public String getDeactivationCondition() { + if (this instanceof ActionShape) { + ((ActionShape)this).addInputVariable(getName(), getDesc(), null, false); + } + return " activated(" + getName() + ") "; + } + + public void upateDialog() { + } +} diff --git a/src/clp/edit/graphics/shapes/ATransitionRoot.java b/src/clp/edit/graphics/shapes/ATransitionRoot.java new file mode 100644 index 0000000..19f1f16 --- /dev/null +++ b/src/clp/edit/graphics/shapes/ATransitionRoot.java @@ -0,0 +1,165 @@ +package clp.edit.graphics.shapes; + +import java.awt.Color; +import java.awt.Graphics; +import java.util.Hashtable; + +import javax.swing.JLabel; + +import clp.edit.GeneralContext; +import clp.edit.graphics.dial.ClassicGroup; +import clp.edit.graphics.dial.DelayGroup; +import clp.edit.graphics.dial.TransitionType; +import clp.edit.graphics.shapes.util.ResourceHelper; +import clp.edit.graphics.shapes.util.ResourceHelper.InputResourcesInfo; +import clp.run.res.Unit; +import clp.run.res.VarType; + +public abstract class ATransitionRoot extends ARootShape { + + private static final long serialVersionUID = 2081801530762140695L; + + private JLabel tautology; + private ClassicGroup classicInfo; + private DelayGroup delayInfo; + + private TransitionType trType; + + private Hashtable inputResources; + + /** + * CONSTRUCTOR + * + * @param tt: transition type + */ + public ATransitionRoot(TransitionType tt) { + super(40, 5, ""); + setup(tt); + } + + + public ATransitionRoot(int width, int height, TransitionType tt) { + super(width, height, ""); + setup(tt); + } + + // + private void setup(TransitionType tt) { + trType = tt; + int delayNo = GeneralContext.getInstance().getGraphicsPanel().getShapesContainer().getIncrementingDelayNo(); + tautology = new JLabel("= 1"); + classicInfo = new ClassicGroup(); + delayInfo = new DelayGroup(delayNo); + inputResources = new Hashtable<>(); + } + + + public void paintShape(Graphics g, int offset) { + Color c = g.getColor(); + int sx = getPX()+offset; + int sy = getPY(); + if (isSelected()) { + g.setColor(Color.lightGray); + } + g.fillRect(sx-20, sy, 40, 4); + if (getChild() == null) { + g.drawLine(sx, sy, sx, sy+20); + } + g.setColor(c); + if (getName() != null) { + g.drawString(getName(), sx+23, sy+5); + } + if (getChild() != null) { + checkDownType(); + getChild().paintShape(g, offset); + } + } + + @Override + public boolean generateCode(AContainer container) { + if (getChild() != null) { + return getChild().generateCode(container); + } + return true; + } + + @Override + public boolean generateActiveCode(AContainer container) { + if (getChild() != null) { + return getChild().generateActiveCode(container); + } + return true; + } + + + /** + * @return the trType + */ + public TransitionType getTrType() { + return trType; + } + + + /** + * @param trType the trType to set + */ + public void setTrType(TransitionType trType) { + this.trType = trType; + } + + + /** + * @return the tautology + */ + public JLabel getTautology() { + return tautology; + } + + + /** + * @return the classicInfo + */ + public ClassicGroup getClassicInfo() { + return classicInfo; + } + + + /** + * @return the delayInfo + */ + public DelayGroup getDelayInfo() { + return delayInfo; + } + + public void addInputVariable(String cnd, String desc, VarType type) { + ResourceHelper.getInstance().addInputVariable(cnd, desc, type, false, inputResources); + } + + public void addDelay(String step, String timeIdentifier, int delay, Unit unit, boolean isCyclic) { + ResourceHelper.getInstance().addDelay(step, timeIdentifier, delay, unit, isCyclic, inputResources); + } + + + /** + * @return the inputResources + */ + public Hashtable getInputResources() { + return inputResources; + } + + @Override + public void declareResources(boolean isEndNode) { + ResourceHelper.getInstance().declareIn(inputResources); + if (getChild() != null) { + getChild().declareResources(); + } + } + + @Override + public void clearResources() { + inputResources.clear(); + if (getChild() != null) { + getChild().clearResources(); + } + } +} diff --git a/src/clp/edit/graphics/shapes/ATransitionShape.java b/src/clp/edit/graphics/shapes/ATransitionShape.java new file mode 100644 index 0000000..ffe2cf8 --- /dev/null +++ b/src/clp/edit/graphics/shapes/ATransitionShape.java @@ -0,0 +1,165 @@ +package clp.edit.graphics.shapes; + +import java.awt.Color; +import java.awt.Graphics; +import java.util.Hashtable; + +import javax.swing.JLabel; + +import clp.edit.GeneralContext; +import clp.edit.graphics.dial.ClassicGroup; +import clp.edit.graphics.dial.DelayGroup; +import clp.edit.graphics.dial.TransitionType; +import clp.edit.graphics.shapes.util.ResourceHelper; +import clp.edit.graphics.shapes.util.ResourceHelper.InputResourcesInfo; +import clp.run.res.Unit; +import clp.run.res.VarType; + +public abstract class ATransitionShape extends AShape { + + private static final long serialVersionUID = -6805542307034576950L; + + private JLabel tautology; + private ClassicGroup classicInfo; + private DelayGroup delayInfo; + + private TransitionType trType; + + private Hashtable inputResources; + + /** + * CONSTRUCTOR + * + * @param tt: transition type + */ + public ATransitionShape(TransitionType tt) { + super(40, 5, "", ""); + setup(tt); + } + + + public ATransitionShape(int width, int height, String name, String string, TransitionType tt) { + super(width, height, name, string); + setup(tt); + } + + // + private void setup(TransitionType tt) { + trType = tt; + int delayNo = GeneralContext.getInstance().getGraphicsPanel().getShapesContainer().getIncrementingDelayNo(); + tautology = new JLabel("= 1"); + classicInfo = new ClassicGroup(); + delayInfo = new DelayGroup(delayNo); + inputResources = new Hashtable<>(); + } + + + public void paintShape(Graphics g, int offset) { + Color c = g.getColor(); + int sx = getPX()+offset; + int sy = getPY(); + if (isSelected()) { + g.setColor(Color.lightGray); + } + g.fillRect(sx-20, sy, 40, 4); + if (getChild() == null) { + g.drawLine(sx, sy, sx, sy+20); + } + g.setColor(c); + if (getName() != null) { + g.drawString(getName(), sx+23, sy+5); + } + if (getChild() != null) { + checkDownType(); + getChild().paintShape(g, offset); + } + } + + @Override + public boolean generateCode(AContainer container) { + if (getChild() != null) { + return getChild().generateCode(container); + } + return true; + } + + @Override + public boolean generateActiveCode(AContainer container) { + if (getChild() != null) { + return getChild().generateActiveCode(container); + } + return true; + } + + + /** + * @return the trType + */ + public TransitionType getTrType() { + return trType; + } + + + /** + * @param trType the trType to set + */ + public void setTrType(TransitionType trType) { + this.trType = trType; + } + + + /** + * @return the tautology + */ + public JLabel getTautology() { + return tautology; + } + + + /** + * @return the classicInfo + */ + public ClassicGroup getClassicInfo() { + return classicInfo; + } + + + /** + * @return the delayInfo + */ + public DelayGroup getDelayInfo() { + return delayInfo; + } + + public void addInputVariable(String cnd, String desc, VarType type) { + ResourceHelper.getInstance().addInputVariable(cnd, desc, type, false, inputResources); + } + + public void addDelay(String step, String timeIdentifier, int delay, Unit unit, boolean isCyclic) { + ResourceHelper.getInstance().addDelay(step, timeIdentifier, delay, unit, isCyclic, inputResources); + } + + + /** + * @return the inputResources + */ + public Hashtable getInputResources() { + return inputResources; + } + + @Override + public void declareResources(boolean isEndNode) { + ResourceHelper.getInstance().declareIn(inputResources); + if (getChild() != null) { + getChild().declareResources(); + } + } + + @Override + public void clearResources() { + inputResources.clear(); + if (getChild() != null) { + getChild().clearResources(); + } + } +} diff --git a/src/clp/edit/graphics/shapes/ActionShape.java b/src/clp/edit/graphics/shapes/ActionShape.java new file mode 100644 index 0000000..64edec1 --- /dev/null +++ b/src/clp/edit/graphics/shapes/ActionShape.java @@ -0,0 +1,412 @@ +package clp.edit.graphics.shapes; + +import java.awt.Color; +import java.awt.Graphics; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Hashtable; +import java.util.List; + +import clp.edit.GeneralContext; +import clp.edit.dialog.ADialog; +import clp.edit.graphics.code.ClappInstruction; +import clp.edit.graphics.dial.ActionOrStepDialog; +import clp.edit.graphics.dial.ActionOrStepDialog.IntructionType; +import clp.edit.graphics.dial.Token; +import clp.edit.graphics.panel.ControlsContainer; +import clp.edit.graphics.panel.GeneralShapesContainer; +import clp.edit.graphics.shapes.util.ResourceHelper; +import clp.edit.graphics.shapes.util.ResourceHelper.InputResourcesInfo; +import clp.edit.graphics.shapes.util.ResourceHelper.OutputResourcesInfo; +import clp.run.res.VarType; + +abstract public class ActionShape extends AShape { + + private static final long serialVersionUID = 8795899175363804863L; + + private Color bgcolor; + + abstract public ActionOrStepDialog getActionOrStepDialog(); + + private ArrayList entries; + + private List instructions; + private List libs; + + private Hashtable inputResources; + private Hashtable outputResources; + + private String uiName; + private String bciName; + private String webName; + + private String respValue; + + private int level; + + /** + * CONSTRUCTOR + * + * @param width + * @param height + * @param name + * @param prefix + * @param level + */ + public ActionShape(int width, int height, String name , String prefix, int level) { + super(width, height, name, prefix); + this.level = level; + entries = new ArrayList<>(); + ControlsContainer cc = GeneralContext.getInstance().getGraphicsPanel().getControlsContainer(); + cc.addShapeAsCell(this, getName()); + inputResources = new Hashtable<>(); + outputResources = new Hashtable<>(); + libs = new ArrayList<>(); + } + + /** + * paint instructions + * + * @param g + * @param offset + */ + public void paintInstructionsFromShape(Graphics g, int offset) { + if (instructions != null && !instructions.isEmpty()) { + int x1 = getPX() + getWidth()/2 + offset; + int x2 = x1 + 5; + int y0 = getPY(); + int y1 = y0 + getHeight()/2; + g.drawLine(x1, y1, x2, y1); + int width = instructions.size()*6 + 2; + int height = getHeight(); + Color clr = g.getColor(); + g.setColor(Color.black); + g.fillRect(x2, y0, width, height); + int x0 = x2 + 2; + height -= 4; + y0 += 2; + for (ClappInstruction inst : instructions) { + g.setColor(inst.getColor()); + g.fillRect(x0, y0, 4, height); + x0 += 6; + } + g.setColor(clr); + } + } + + @Override + public ADialog getDialog() { + return getActionOrStepDialog(); + } + + @Override + public void gatherLibsDeclaration(ArrayList jars) { + System.err.println("NOT IMPLEMENTED YET"); +// ArrayList j = dialog.getLibsDeclaration(); +// if (j != null) { +// jars.addAll( j ); +// } + } + + /** + * @return the bgcolor + */ + public Color getBgcolor() { + return bgcolor; + } + + /** + * @param bgcolor the bgcolor to set + */ + public void setBgcolor(Color bgcolor) { + this.bgcolor = bgcolor; + } + + /** + * entries are bindings from decision, fork or join nodes from below + * @param b + */ + public void addEntryPoint(ABindingShape b) { + if (!entries.contains(b)) { + entries.add(b); + } + if (!entries.contains(getParent())) { + entries.add(getParent()); + } + } + + /** + * @return the cell source + */ + public StringBuilder getSource() { + // TODO + return null; + } + + // + private StringBuilder getInstructions(Collection c) { + StringBuilder sb = new StringBuilder(); + for (String inst : c) { + sb.append(inst); + sb.append("
"); + } + return sb; + } + + @Override + public String toString() { + return getSource().toString(); + } + + /** + * @return the entries + */ + public ArrayList getEntries() { + return entries; + } + + public void setupInstructions() { + instructions = getActionOrStepDialog().getInstructions(); + if (instructions != null) { + ArrayList slist = new ArrayList<>(); + for (ClappInstruction inst : instructions) { + if (inst.getStatement() != null) { + slist.add(inst.getStatement()); + } + } + String instructions = getInstructions(slist).toString(); + addToDesc(instructions); + } + } + + /** + * @return the instructions + */ + public List getInstructions() { + return instructions; + } + + /** + * @param instruction to be added to the instructions set + */ + public void addToInstructions(ClappInstruction instruction) { + if (instructions == null) { + instructions = new ArrayList<>(); + } + instructions.add(instruction); + } + + public int getRightPart() { + if (instructions == null || instructions.isEmpty()) { + return getPX() + getWidth()/2; + } + return getPX() + getWidth()/2 + instructions.size()*6 + 6; + } + + public void setAsInitial() { +// getTreeNodeInfo().moveToActiveHeap(this.getName()); + } + + public void setAsEventRoot(ActionShape shape) { +// getTreeNodeInfo().updateActivationDomain(this.getName(), shape.getName()); + } + + @Override + public String getActivationDomain(AContainer container) { + if (entries.isEmpty()) { + return getParent().getParent().getActivationCondition(getParent()); + } + ArrayList list = new ArrayList<>(); + String s; + for (ABindingShape b : entries) { + s = b.getParent().getActivationCondition(b); + if (s != null) { + list.add(s); + } + } + if (!list.isEmpty()) { + s = list.get(0); + if (list.size() > 1) { + for (int i=1; i getExecutionDomain(AContainer container) { + if (instructions != null && !instructions.isEmpty()) { + ArrayList instList = new ArrayList<>(); + for (ClappInstruction inst : instructions) { + if (inst.getInstructionType().equals(IntructionType.ASSIGN.name())) { + instList.add("1: " + inst.getStatement()); + } + else { + instList.add(level+": " + inst.getStatement()); + } + } + return instList; + } + return null; + } + + public void addInputVariable(String cnd, String desc, VarType type, boolean isToken) { + if (cnd.charAt(0) == '!') { + cnd = cnd.substring(1); + } + ResourceHelper.getInstance().addInputVariable(cnd, desc, type, isToken, inputResources); + } + + public void setTokensForCell(Token[] tokens, String name) { + ResourceHelper.getInstance().setTokensForCell(tokens, name, inputResources); + } + + @Override + public void declareResources(boolean isEndNode) { + GeneralShapesContainer shapesContainer = GeneralContext.getInstance().getGraphicsPanel().getShapesContainer(); + ResourceHelper.getInstance().declareUI(shapesContainer.getGuiContext().getUiInfo(uiName), uiName); + ResourceHelper.getInstance().declareBCI(shapesContainer.getJavaContext().getBciInfo(bciName), bciName); + ResourceHelper.getInstance().declareWEB(shapesContainer.getWebContext().getWebInfo(webName), webName); + ResourceHelper.getInstance().declareLibs(libs); + ResourceHelper.getInstance().declareIn(inputResources); + ResourceHelper.getInstance().declareOut(outputResources); + if (!isEndNode && getChild() != null) { + getChild().declareResources(); + } + } + + public void addOutputVariable(String name, VarType vtype) { + if (name.charAt(0) == '!') { + name = name.substring(1); + } + ResourceHelper.getInstance().addOutputVariable(name, vtype, outputResources); + } + + public void addVariables(ArrayList variables) { + ResourceHelper.getInstance().addVariables(variables, inputResources, outputResources); + } + + public void addToLibs(String usedLib, boolean isjar) { + if (!contains(libs, usedLib)) { + LibInfo li = new LibInfo(usedLib, isjar); + libs.add(li); + } + } + + // + private boolean contains(List libs, String usedLib) { + for (LibInfo li : libs) { + if (usedLib.equals(li.getUsedLib())) { + return true; + } + } + return false; + } + + public static class LibInfo implements Serializable { + private static final long serialVersionUID = -5011254741874900541L; + + private String usedLib; + private boolean isJar; + + public LibInfo(String usedLib, boolean isjar) { + this.usedLib = usedLib; + this.isJar = isjar; + } + + /** + * @return the usedLib + */ + public String getUsedLib() { + return usedLib; + } + + /** + * @return the isJar + */ + public boolean isJar() { + return isJar; + } + } + + public int getInstructionSize() { + if (instructions != null && !instructions.isEmpty()) { + return instructions.size() + 1; + } + return 0; + } + + /** + * @return the uiName + */ + public String getUiName() { + return uiName; + } + + /** + * @return the bciName + */ + public String getBciName() { + return bciName; + } + + /** + * @param uiName the uiName to set + */ + public void setUiName(String uiName) { + this.uiName = uiName; + } + + /** + * @param bciName the bciName to set + */ + public void setBciName(String bciName) { + this.bciName = bciName; + } + + /** + * @return the webName + */ + public String getWebName() { + return webName; + } + + /** + * @param webName the webName to set + */ + public void setWebName(String webName) { + this.webName = webName; + } + + public void setWebRespValue(String respValue) { + this.respValue = respValue; + } + + public String getWebRespValue() { + return respValue; + } +} diff --git a/src/clp/edit/graphics/shapes/BindingShape.java b/src/clp/edit/graphics/shapes/BindingShape.java new file mode 100644 index 0000000..0e3eafd --- /dev/null +++ b/src/clp/edit/graphics/shapes/BindingShape.java @@ -0,0 +1,253 @@ +package clp.edit.graphics.shapes; + +import java.awt.Color; +import java.awt.Graphics; +import java.util.List; + +import clp.edit.graphics.shapes.gc.JoinBindingShape; +import clp.edit.graphics.shapes.gc.TransitionNodeShape; + +public class BindingShape extends ABindingShape { + + private static final long serialVersionUID = 1436254108715557862L; + + private Color color; + + public BindingShape(BindingType b, String t) { + super(t, b); + color = Color.black; + } + + @Override + public void paintShape(Graphics g, int offset) { + paintShape(getParent(), g, offset); + } + + @Override + public void paintShape(AShape parent, Graphics g, int offset) { + Color c = g.getColor(); + g.setColor(getColor()); + int py = parent.getPY()+parent.getHeight(); + int cy = getChildY(); + switch (getBindingType()) { + case DOWN: + int x = getX1() + offset; + g.drawLine(x, py, x, cy); + break; + case DOWN_MIDDLE: + int x1 = getX1() + offset; + int x2 = getX2() + offset; + int delta = x2 - x1; + if (delta > 0 && delta < 4 || delta < 0 && delta > -4) { + setConditionnallyBindingType(BindingType.DOWN); + g.drawLine(x1, py, x1, cy); + getChild().addToX(-delta); + } + else { + int middle = (cy-py)/2; + g.drawLine(x1, py, x1, py+middle); + g.drawLine(x1, py+middle, x2, py+middle); + g.drawLine(x2, py+middle, x2, cy); + } + break; + case DOWN_LEFT: + x1 = getX1() + offset; + if (getChild() instanceof JoinBindingShape) { + x2 = ((JoinBindingShape)getChild()).getRightMost() - 10 + offset; + } + else { + x2 = getX2() + offset; + } + int y = py-10; + g.drawLine(x1, y, x2, y); + g.drawLine(x2, y, x2, cy); + if (getText() != null) { + g.drawString(getText(), x2+5, y-3); + } + break; + case DOWN_RIGHT: + x1 = getX1() + offset; + if (getChild() instanceof JoinBindingShape) { + x2 = ((JoinBindingShape)getChild()).getLeftMost() + 10 + offset; + } + else { + x2 = getX2() + offset; + } + y = py-10; + g.drawLine(x1, y, x2, y); + g.drawLine(x2, y, x2, cy); + if (getText() != null) { + g.drawString(getText(), x1+5, y-3); + } + break; + case UP_LEFT: + int xi = getX1() + offset; + int yi = py - parent.getHeight()/2; + int xl; + int xf = getX2() - getChild().getWidth()/2 + offset; + int yf = cy + getChild().getHeight()/2; + if (parent instanceof TransitionNodeShape) { + xl = parent.getPX() + offset; + } + else { + xl = xf + getXmiddle() - 10; + } + g.drawLine(xi, yi, xl, yi); + g.drawLine(xl, yi, xl, yf); + g.drawLine(xl, yf, xf, yf); + g.drawLine(xf-5, yf-5, xf, yf); + g.drawLine(xf-5, yf+5, xf, yf); + if (getText() != null) { + g.drawString(getText(), xl+2, yi-3); + } + break; + case UP_LEFT_RIGHT: + if (getChild() instanceof ActionShape) { + xf = ((ActionShape)getChild()).getRightPart() + offset; + } + else { + xf = getX2() + getChild().getWidth()/2 + offset; + } + yf = cy + getChild().getHeight()/2; + xi = getX1() + offset; + yi = py - parent.getHeight()/2; + if (parent instanceof TransitionNodeShape) { + xi -= parent.getWidth()/2; + g.drawLine(xi, yi, xi, yf); + g.drawLine(xi, yf, xf, yf); + } + else { + int xr = xf + getXmiddle() + 10; + g.drawLine(xi, yi, xr, yi); + g.drawLine(xr, yi, xr, yf); + g.drawLine(xr, yf, xf, yf); + } + g.drawLine(xf+5, yf+5, xf, yf); + g.drawLine(xf+5, yf-5, xf, yf); + if (getText() != null) { + g.drawString(getText(), xf+2, yi-3); + } + break; + case UP_LEFT_MIDDLE: + x1 = getX1() + offset; + x2 = getX2() + offset; + int y1 = py; + cy = getChildY(); + int y2 = cy > y1 ? cy+15 : y1+15; + g.drawLine(x1, y1, x1, y2); + g.drawLine(x1, y2, x2, y2); + g.drawLine(x2, y2, x2, cy); + if (getText() != null) { + g.drawString(getText(), x2+5, y2-3); + } + break; + case UP_RIGHT: + if (getChild() instanceof ActionShape) { + xf = ((ActionShape)getChild()).getRightPart() + offset; + } + else { + xf = getX2() + getChild().getWidth()/2 + offset; + } + yf = cy + getChild().getHeight()/2; + xi = getX1() + offset; + yi = py - parent.getHeight()/2; + if (parent instanceof TransitionNodeShape) { + xi -= parent.getWidth()/2; + g.drawLine(xi, yi, xi, yf); + g.drawLine(xi, yf, xf, yf); + } + else { + int xr = xf + getXmiddle() + 10; + g.drawLine(xi, yi, xr, yi); + g.drawLine(xr, yi, xr, yf); + g.drawLine(xr, yf, xf, yf); + } + g.drawLine(xf+5, yf+5, xf, yf); + g.drawLine(xf+5, yf-5, xf, yf); + if (getText() != null) { + g.drawString(getText(), xi+2, yi-3); + } + break; + case UP_RIGHT_LEFT: + xi = getX1() + offset; + yi = py - parent.getHeight()/2; + xf = getX2() - getChild().getWidth()/2 + offset; + yf = cy + getChild().getHeight()/2; + if (parent instanceof TransitionNodeShape) { + xl = parent.getPX() + offset; + } + else { + xl = xf + getXmiddle() - 10; + } + g.drawLine(xi, yi, xl, yi); + g.drawLine(xl, yi, xl, yf); + g.drawLine(xl, yf, xf, yf); + g.drawLine(xf-5, yf-5, xf, yf); + g.drawLine(xf-5, yf+5, xf, yf); + if (getText() != null) { + g.drawString(getText(), xi+2, yi-3); + } + break; + default: + break; + } + g.setColor(c); + if (getChild() != null && getBindingType() != BindingType.UP_LEFT && getBindingType() != BindingType.UP_RIGHT + && getBindingType() != BindingType.UP_LEFT_RIGHT && getBindingType() != BindingType.UP_RIGHT_LEFT) { + getChild().paintShape(g, offset); + } + } + + public BindingType getDirection() { + return getBindingType(); + } + + /** + * @return the color + */ + public Color getColor() { + return color; + } + + @Override + public AShape getSelectedShape(int x, int y) { + if (getChild() != null && getBindingType() != BindingType.UP_LEFT && getBindingType() != BindingType.UP_RIGHT) { + return getChild().getSelectedShape(x, y); + } + return null; + } + + @Override + public void gatherChildrenShapes(List list) { + if (getChild() != null && isBindingTypeAllowed(getBindingType())) { + if (getChild().getChild() != null) { + getChild().gatherChildrenShapes(list); + } + else { + list.add(getChild()); + } + } + } + + // + private boolean isBindingTypeAllowed(BindingType t) { + return t == BindingType.DOWN || t == BindingType.DOWN_LEFT || + t == BindingType.DOWN_MIDDLE || t == BindingType.DOWN_RIGHT; + } + + @Override + public void clearChildrenEntries() { + clearEntries(getChild()); + } + + public void clearEntries(AShape child) { + if (child instanceof ATransitionShape) { + if (child.getChild() != null) { + clearEntries(child.getChild().getChild()); + } + } + else if (child instanceof ActionShape) { + ((ActionShape)child).getEntries().clear(); + } + } +} diff --git a/src/clp/edit/graphics/shapes/BindingType.java b/src/clp/edit/graphics/shapes/BindingType.java new file mode 100644 index 0000000..8e29051 --- /dev/null +++ b/src/clp/edit/graphics/shapes/BindingType.java @@ -0,0 +1,5 @@ +package clp.edit.graphics.shapes; + +public enum BindingType { + NONE, DOWN, DOWN_MIDDLE, UP_LEFT, UP_LEFT_MIDDLE, UP_RIGHT, UP_RIGHT_MIDDLE, DOWN_LEFT, DOWN_RIGHT, UP_LEFT_RIGHT, UP_RIGHT_LEFT +} diff --git a/src/clp/edit/graphics/shapes/ContainerHelper.java b/src/clp/edit/graphics/shapes/ContainerHelper.java new file mode 100644 index 0000000..1c2dbfa --- /dev/null +++ b/src/clp/edit/graphics/shapes/ContainerHelper.java @@ -0,0 +1,257 @@ +package clp.edit.graphics.shapes; + +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Serializable; +import java.util.ArrayList; + +import javax.swing.tree.TreeNode; + +import clp.edit.GeneralContext; +import clp.edit.graphics.panel.ControlsContainer; +import clp.edit.tree.node.ATreeNode; +import clp.edit.tree.node.ActorTreeNode; +import clp.edit.tree.node.DisplayActorTreeNode; +import clp.edit.tree.node.DisplayHeapTreeNode; +import clp.edit.tree.node.DisplayMetaScenarioTreeNode; +import clp.edit.tree.node.DisplayResourcesTreeNode; +import clp.edit.tree.node.DisplayScenarioTreeNode; +import clp.edit.tree.node.FileTreeNode; +import clp.edit.tree.node.HeapTreeNode; +import clp.edit.tree.node.MetaScenarioTreeNode; +import clp.edit.tree.node.ProjectTreeNode; +import clp.edit.tree.node.ResourcesTreeNode; +import clp.edit.tree.node.ScenarioTreeNode; +import clp.parse.CLAppParser; +import clp.parse.scn.ScnParser; +import clp.run.act.Actor; +import clp.run.cel.Heap; +import clp.run.msc.MetaScenario; +import clp.run.msc.MetaScenarioBody; +import clp.run.msc.MscTaskName; +import clp.run.msc.MscTasks; +import clp.run.res.Resources; +import clp.run.scn.Scenario; + +public class ContainerHelper implements Serializable { + + private static final long serialVersionUID = -695404666949388182L; + + public static final String resName = "FLOW_RES"; + + private ATreeNode lastNode; + + private int activity; + + /** + * CONSTRUCTOR + * + * @param count + * @param activity + */ + public ContainerHelper(int count, int activity) { + this.activity = activity; + } + + /** + * create all necessary tree nodes related to given container shape + * + * @param c_shape + * @param sname + * @param hname + */ + public void createTreeNodes(AContainerShape c_shape, String sname, String hname) { + String aname = getActorName(c_shape.getName()); + ProjectTreeNode rootNode = GeneralContext.getInstance().getRootNode(); + + MetaScenarioTreeNode mnode = getMetaScenario(rootNode); + MetaScenario msc = (MetaScenario) mnode.getAssociatedObject(); + File ref = new File(""); + + ResourcesTreeNode rnode = rootNode.findResources(resName); + if (rnode == null) { + ArrayList rlist = msc.getMetaScenarioBody().getResourcess(); + if (rlist == null) { + rlist = new ArrayList<>(); + msc.getMetaScenarioBody().setResourcess(rlist); + } + for (int i=0; i 0) { + TreeNode msc = fnode.getChildAt(0); + if (msc instanceof MetaScenarioTreeNode) { + return (MetaScenarioTreeNode) msc; + } + } + else if (fnode.isGraphics()) { + break; + } + } + MetaScenario msc = new MetaScenario(); + msc.setName("MSC"); + MetaScenarioBody mb = new MetaScenarioBody(); + MscTasks mtasks = new MscTasks(); + mtasks.addMscTaskName(MscTaskName.SCHEDULER); + mb.setMscTasks(mtasks); + msc.setMetaScenarioBody(mb); + MetaScenarioTreeNode mnode = new DisplayMetaScenarioTreeNode("MSC", msc, null, null); + fnode.add(mnode); + return mnode; + } + + // + private String getActorName(String text) { + return text.replace(" ", "_"); + } + + /** + * @return the lastNode + */ + public ATreeNode getLastNode() { + return lastNode; + } + + /** + * @param lastNode the lastNode to set + */ + public void setLastNode(ATreeNode lastNode) { + this.lastNode = lastNode; + } + + /** + * remove given actor and scenario if empty + */ + public void removeActor(String scn_Name, String act_Name) { + ProjectTreeNode rootNode = GeneralContext.getInstance().getRootNode(); + ScenarioTreeNode snode = rootNode.findScenario(scn_Name); + if (snode != null) { + String aname = getActorName(act_Name); + for (int i=0; i children; + + public MultiBinding() { + super(BindingType.DOWN_MIDDLE, null); + children = new ArrayList<>(); + } + + public void addChildren(TriBinding tri) { + addChild(tri.getLeft()); + addChild(tri.getMiddle()); + addChild(tri.getRight()); + } + + public void addChild(ABindingShape nb) { + children.add(nb); + int n = children.size(); + for (int i=1; i<=n; i++) { + AShape ch = children.get(i-1).getChild(); + ch.setXoffset((n-i)*80); + ch.setYoffset(i*80); + } + } + + @Override + public void paintShape(Graphics g, int offset) { + Color c = g.getColor(); + for (ABindingShape b : children) { + int py = b.getParentY(); + int cy = b.getChildY(); + int x1 = b.getX1() + offset; + int x2 = b.getX2() + offset; + int middle = (cy-py)/2; + g.setColor(getColor()); + g.drawLine(x1, py, x1, py+middle); + g.drawLine(x1, py+middle, x2, py+middle); + g.drawLine(x2, py+middle, x2, cy); + g.setColor(c); + b.getChild().paintShape(g, offset); + } + } + + /** + * @return the children + */ + public ArrayList getChildren() { + return children; + } + + public int getRightmost() { + return children.get(0).getX2() + 50; + } + + @Override + public void gatherChildrenShapes(List list) { + for (ABindingShape b : children) { + b.gatherChildrenShapes(list); + } + } + + @Override + public AShape getSelectedShape(int x, int y) { + for (ABindingShape b : children) { + AShape s = b.getChild().getSelectedShape(x, y); + if (s != null) { + return s; + } + } + return null; + } + + @Override + public boolean generateCode(AContainer container) { + boolean b = true; + for (int i=0; b && i shape.getPX()) { + setConditionnallyBindingType(BindingType.UP_LEFT); + } + else { + setConditionnallyBindingType(BindingType.UP_RIGHT); + } + return true; + } + return false; + } + + public boolean isAttached() { + return attach != null; + } + + /** + * @return the attach + */ + public AShape getAttach() { + return attach; + } + + /** + * @param shape the attach to set + */ + public void setAttachTo(AShape shape) { + this.attach = shape; + if (shape instanceof AFinalShape || shape instanceof FinalNodeShape) { + isReady = false; + } + } + + /** + * update X,Y boundaries + */ + public void updateXYBoundaries() { + if (attach != null && !(attach instanceof DecisionNodeShape)) { + setConditionnallyBindingType(BindingType.DOWN); + } + } + + + /** + * @param shape the {@link DecisionNodeShape} attach to set + */ + public void setAttachToDecisionShape(DecisionNodeShape shape, int x) { + this.attach = shape; + setConditionnallyBindingType(BindingType.DOWN_LEFT); + } + + /** + * @param attach to right part of {@link DecisionNodeShape} + */ + public void updateRightPartDecisionShape() { + setConditionnallyBindingType(BindingType.DOWN_RIGHT); + } + + /** + * @param attach to right part of {@link DecisionNodeShape} + */ + public void forceRightPartDecisionShape() { + setBindingType(BindingType.DOWN_RIGHT); + } + + /** + * @return the isReady + */ + public boolean isReady() { + return isReady; + } + + /** + * @param isReady the isReady to set + */ + public void setReady(boolean isReady) { + if (attach instanceof AFinalShape || attach instanceof FinalNodeShape) { + this.isReady = false; + return; + } + this.isReady = isReady; + if (attach == null) { + return; + } + if (attach instanceof ActionShape) { + setBindingType(BindingType.DOWN); + } + } + + /** + * X position of 1st point (binding the parent) = parent's X position + * it depends on the binding type + */ + public int getX1() { + if (attach instanceof AForkShape || attach instanceof AJoinShape) { + return attach.getPX(); + } + switch (getBindingType()) { + case DOWN: + case DOWN_MIDDLE: + return attach.getPX(); + case DOWN_LEFT: + case UP_LEFT: + return attach.getPX() - attach.getWidth()/2; + case DOWN_RIGHT: + case UP_RIGHT: + return attach.getPX() + attach.getWidth()/2; + + default: + break; + } + return 0; + } + + /** + * X position of 2nd point (binding the child) = child's X position + * it depends on the binding type + */ + public int getX2() { + if (attach instanceof AForkShape || attach instanceof AJoinShape) { + return attach.getPX()+30; + } + switch (getBindingType()) { + case DOWN: + case DOWN_MIDDLE: + return attach.getPX()+30; + case DOWN_LEFT: + case UP_LEFT: + return attach.getPX() - attach.getWidth()/2 - 90; + case DOWN_RIGHT: + case UP_RIGHT: + return attach.getPX() - attach.getWidth()/2 + 90; + + default: + break; + } + return 0; + } + + /** + * X position of middle point (middle position) + * it depends on the xshift from parent + */ + public int getXmiddle() { + return attach.getPX() + getXshift(); + } + + @Override + public int getChildY() { + return getParentY() + 30; + } + + @Override + public int getParentY() { + return attach == null ? 0 : attach.getPY()+attach.getHeight(); + } +} diff --git a/src/clp/edit/graphics/shapes/SelectShape.java b/src/clp/edit/graphics/shapes/SelectShape.java new file mode 100644 index 0000000..c37bcd0 --- /dev/null +++ b/src/clp/edit/graphics/shapes/SelectShape.java @@ -0,0 +1,26 @@ +package clp.edit.graphics.shapes; + +import java.awt.Color; +import java.awt.Graphics; + +public class SelectShape { + + private int x; + private int y; + private int width; + private int height; + + public SelectShape(int x, int y, int width, int height) { + this.x = x; + this.y = y; + this.width = width; + this.height = height; + } + + public void paintShape(Graphics g) { + Color c = g.getColor(); + g.setColor(Color.blue); + g.drawRect(x, y, width, height); + g.setColor(c); + } +} diff --git a/src/clp/edit/graphics/shapes/TriBinding.java b/src/clp/edit/graphics/shapes/TriBinding.java new file mode 100644 index 0000000..34bafd3 --- /dev/null +++ b/src/clp/edit/graphics/shapes/TriBinding.java @@ -0,0 +1,349 @@ +package clp.edit.graphics.shapes; + +import java.awt.Graphics; +import java.util.List; + +import clp.edit.graphics.dial.PNTransitionDialog; +import clp.edit.graphics.shapes.pn.TransitionNodeShape; + +public class TriBinding extends BindingShape { + + private static final long serialVersionUID = -3685729487706661431L; + + private ABindingShape left; + private ABindingShape middle; + private ABindingShape right; + + public TriBinding() { + super(BindingType.DOWN, null); + } + + @Override + public void paintShape(Graphics g, int offset) { + if (left != null) { + left.paintShape(getParent(), g, offset); + } + if (middle != null) { + middle.paintShape(getParent(), g, offset); + } + if (right != null) { + right.paintShape(getParent(), g, offset); + } + } + + public void addChild(BindingShape b) { + if (left == null) { + left = b; + b.setXshift(-9); + } + else if (middle == null) { + middle = b; + b.setXshift(0); + } + else if (right == null) { + right = b; + b.setXshift(+9); + } + } + + @Override + public boolean setConditionnallyBindingType(BindingType bindingType) { + super.setConditionnallyBindingType(bindingType); + if (left != null) { + left.setConditionnallyBindingType(bindingType); + } + else if (middle != null) { + middle.setConditionnallyBindingType(bindingType); + } + return false; + } + + @Override + public void setOldXShift() { + } + + @Override + public AShape getChild() { + if (left != null) { + return left.getChild(); + } + else if (middle != null) { + return middle.getChild(); + } + else if (right != null) { + return right.getChild(); + } + return null; + } + + @Override + public int getX2() { + return getChild().getPX(); + } + + @Override + public AShape getSelectedShape(int x, int y) { + if (left != null) { + AShape s = left.getChild().getSelectedShape(x, y); + if (s != null) { + return s; + } + } + if (middle != null) { + AShape s = middle.getChild().getSelectedShape(x, y); + if (s != null) { + return s; + } + } + if (right != null) { + AShape s = right.getChild().getSelectedShape(x, y); + if (s != null) { + return s; + } + } + return null; + } + + @Override + public void gatherChildrenShapes(List list) { + if (left != null) { + left.gatherChildrenShapes(list); + } + if (middle != null) { + middle.gatherChildrenShapes(list); + } + if (right != null) { + right.gatherChildrenShapes(list); + } + } + + @Override + public void setText(String text) { + super.setText(text); + if (left != null) { + left.setText(text); + } + if (middle != null) { + middle.setText(text); + } + if (right != null) { + right.setText(text); + } + } + + /** + * @return the left + */ + public ABindingShape getLeft() { + return left; + } + + /** + * @param left the left to set + */ + public void setLeft(ABindingShape left) { + this.left = left; + } + + /** + * @return the middle + */ + public ABindingShape getMiddle() { + return middle; + } + + /** + * @param middle the middle to set + */ + public void setMiddle(ABindingShape middle) { + this.middle = middle; + } + + /** + * @return the right + */ + public ABindingShape getRight() { + return right; + } + + /** + * @param right the right to set + */ + public void setRight(ABindingShape right) { + this.right = right; + } + + public void addToX(int delta, AShape shape) { + if (left != null && left.getParent() != shape) { + left.getParent().addToX(-delta); + } + if (right != null && right.getParent() != shape) { + right.getParent().addToX(0); + } + if (middle != null && middle.getParent() != shape) { + middle.getParent().addToX(delta); + } + } + + public boolean isFull() { + return left != null && right != null && middle != null; + } + + @Override + public boolean generateCode(AContainer container) { + boolean b = true; + if (left != null) { + b &= left.generateCode(container); + } + if (b && middle != null) { + b &= middle.generateCode(container); + } + if (b && right != null) { + b &= right.generateCode(container); + } + return b; + } + + @Override + public boolean generateActiveCode(AContainer container) { + boolean b = true; + if (left != null) { + b &= left.generateActiveCode(container); + } + if (b && middle != null) { + b &= middle.generateActiveCode(container); + } + if (b && right != null) { + b &= right.generateActiveCode(container); + } + return b; + } + + @Override + public String getDeactivationCondition() { + String s = null; + if (left != null) { + s = left.getDeactivationCondition(); + } + if (middle != null) { + String m = middle.getDeactivationCondition(); + if (s == null) { + s = m; + } + else { + s += " OR " + m; + } + } + if (right != null) { + String r = right.getDeactivationCondition(); + if (s == null) { + s = r; + } + else { + s += " OR " + r; + } + } + return s; + } + + public String getDeactivationCondition(TransitionNodeShape trShape, PNTransitionDialog trDialog) { + String s = null; + if (left != null) { + AShape chld = left.getChild(); + trShape.addInputVariable(chld.getName(), chld.getDesc(), null); + s = trDialog.getDeactivationCondition(chld.getName(), 'P', chld); + } + if (middle != null) { + AShape chld = middle.getChild(); + trShape.addInputVariable(chld.getName(), chld.getDesc(), null); + String m = trDialog.getDeactivationCondition(chld.getName(), 'P', chld); + if (s == null) { + s = m; + } + else { + s += " AND " + m; + } + } + if (right != null) { + AShape chld = right.getChild(); + trShape.addInputVariable(chld.getName(), chld.getDesc(), null); + String r = trDialog.getDeactivationCondition(chld.getName(), 'P', chld); + if (s == null) { + s = r; + } + else { + s += " AND " + r; + } + } + return s; + } + + @Override + public void clearChildrenEntries() { + if (left != null) { + clearEntries(left.getChild()); + } + if (middle != null) { + clearEntries(middle.getChild()); + } + if (right != null) { + clearEntries(right.getChild()); + } + } + + @Override + public void declareResources() { + if (left != null) { + left.declareResources(); + } + if (middle != null) { + middle.declareResources(); + } + if (right != null) { + right.declareResources(); + } + } + + @Override + public void clearResources() { + if (left != null) { + left.clearResources(); + } + if (middle != null) { + middle.clearResources(); + } + if (right != null) { + right.clearResources(); + } + } + + public void delete(ABindingShape cb, AShape cshape, boolean isParentChange) { + if (left == cb) { + left = null; + } + if (middle == cb) { + middle = null; + } + if (right == cb) { + right = null; + } + if (isParentChange) { + if (left == null) { + if (middle == null) { + right.setBindingType(BindingType.DOWN); + cshape.setParent(right); + } + else if (right == null) { + middle.setBindingType(BindingType.DOWN); + cshape.setParent(middle); + } + } + else if (middle == null) { + if (right == null) { + left.setBindingType(BindingType.DOWN); + cshape.setParent(left); + } + } + } + } +} diff --git a/src/clp/edit/graphics/shapes/act/ActigramContainer.java b/src/clp/edit/graphics/shapes/act/ActigramContainer.java new file mode 100644 index 0000000..d1f6786 --- /dev/null +++ b/src/clp/edit/graphics/shapes/act/ActigramContainer.java @@ -0,0 +1,347 @@ +package clp.edit.graphics.shapes.act; + +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.event.MouseEvent; +import java.util.List; + +import clp.edit.GeneralContext; +import clp.edit.graphics.btn.AButtonsPanel; +import clp.edit.graphics.btn.AControlButton; +import clp.edit.graphics.btn.IAutomaton.ActionMode; +import clp.edit.graphics.btn.act.ActigramAutomaton; +import clp.edit.graphics.panel.ButtonsContainer.ButtonType; +import clp.edit.graphics.panel.GeneralShapesContainer; +import clp.edit.graphics.shapes.ABindingShape; +import clp.edit.graphics.shapes.AContainer; +import clp.edit.graphics.shapes.AContainerShape; +import clp.edit.graphics.shapes.AInitialShape; +import clp.edit.graphics.shapes.AJoinShape; +import clp.edit.graphics.shapes.ARootShape; +import clp.edit.graphics.shapes.AShape; +import clp.edit.graphics.shapes.ActionShape; +import clp.edit.graphics.shapes.BindingShape; +import clp.edit.graphics.shapes.BindingType; +import clp.edit.graphics.shapes.RedBindingShape; +import clp.edit.graphics.shapes.menu.ActigramContextMenu; +import clp.edit.panel.GraphicsPanel; + +public class ActigramContainer extends AContainer { + + private static final long serialVersionUID = 8466214627103329382L; + + private ActivityShape activityShape; + + private ActigramAutomaton automaton; + + private GraphicsPanel graphicsPanel; + + /** + * constructor + * @param graphicsPanel + * + * @param buttonsPanel + */ + public ActigramContainer(GraphicsPanel graphicsPanel) { + super(); + this.graphicsPanel = graphicsPanel; + automaton = new ActigramAutomaton(this, graphicsPanel); + } + + @Override + public Dimension paint(Graphics g, int offset, boolean isSelected) { + Dimension dim = super.paint(g, offset, isSelected, activityShape); + RedBindingShape rs = getRedShape(); + if (rs.isAttached() && rs.isReady()) { + rs.paintShape(g, offset); + } + return dim; + } + + @Override + public ActivityShape getContainerShape() { + return activityShape; + } + + @Override + public void setContainerShape(AContainerShape as) { + activityShape = (ActivityShape) as; + } + + @Override + public boolean isSelected(int px, int py) { + return super.isSelected(px, py, activityShape); + } + + @Override + public ButtonType getType() { + return ButtonType.ACT; + } + + /** + * ADD a new shape + */ + @Override + public void addShape(AShape shape) { + boolean isUpdateAllowed = !(getCurrent() instanceof DecisionNodeShape) + && !(getCurrent() instanceof ForkBindingShape); + BindingType bindingType = (shape instanceof InitialNodeShape || shape instanceof EventNodeShape) ? + null : getRedShape().getBindingType(); + attachRedBinding(shape, isUpdateAllowed); + addShape(shape, bindingType); + if (isUpdateAllowed) { + getRedShape().updateXYBoundaries(); + if (!(shape instanceof FinalNodeShape)) { + setCurrent(shape); + } + } + setDirty(true); + } + + // + private void attachRedBinding(AShape shape, boolean isUpdateAllowed) { + if (getRedShape().isAttached()) { + pinRedShape(shape); + if (getSelected() != null) { + getSelected().setSelected(false); + } + } + if (shape instanceof InitialNodeShape || + shape instanceof EventNodeShape || + shape instanceof ActionNodeShape) { + if (isUpdateAllowed) { + getRedShape().setAttachTo(shape); + } + } + else if (shape instanceof DecisionNodeShape) { + getRedShape().setAttachToDecisionShape((DecisionNodeShape) shape, getCurrent().getPX()); + } + } + + // + private void pinRedShape(AShape shape) { + BindingShape pin = getRedShape().pinIt(); + switch (pin.getBindingType()) { + case DOWN_LEFT: + getCurrent().setChild(pin); + getRedShape().updateRightPartDecisionShape(); + break; + case DOWN_RIGHT: + super.setCurrent(getRedShape().getAttach()); + getCurrent().setChild(pin); + getRedShape().setAttachTo(shape); + break; + default: + getCurrent().setChild(pin); + break; + } + } + + /** + * @param currentButton the currentButton to set + */ + public void setCurrentButton(AControlButton currentButton) { + setCurrentButton(currentButton); + } + + @Override + public ActigramAutomaton getAutomaton() { + return automaton; + } + + public void deleteShape(AShape shape) { + if (shape instanceof ARootShape) { + ARootShape sibling = ((ARootShape)shape).getSibling(); + getContainerShape().setRoot(sibling); + if (sibling == null) { + automaton.resetButtons(); + } + } + else { + ABindingShape b = shape.getParent(); + AShape p = b.getParent(); + if (p instanceof ForkBindingShape) { + ((ForkBindingShape)p).delete(b); + } + else { + p.setChild(shape.getChild()); + } + if (shape.getChild() != null) { + AShape c = shape.getChild().getChild(); + ARootShape root = (ARootShape) getContainerShape().getRoot(); + if (root.getSibling() != null) { + int delta = shape.getHeight()+30; + shape.addToY(delta); + root.updateOtherBranches(shape, -delta); + if (c instanceof JoinBindingShape) { + c.addToY(-delta); + } + } + if (p instanceof AInitialShape) { + ((ActionShape)c).setAsInitial(); + } + else if (p instanceof ARootShape) { + ((ActionShape)c).setAsEventRoot((ActionShape) shape); + } + } + getRedShape().setReady(false); + } + } + + @Override + public void deleteAllFromShape(AShape shape) { + super.deleteAllFromShape(shape); + if (shape instanceof ActionNodeShape) { + ((ActionNodeShape)shape).getEntries().clear(); + } + } + + public void insertActionToShape(AShape shape) { + ActionNodeShape act = new ActionNodeShape(getIncrementingActionNo()); + ABindingShape cb = shape.getChild(); + AShape c = cb.getChild(); + ABindingShape nb = new BindingShape(BindingType.DOWN, null); + act.setChild(nb); + nb.setChild(c); + cb.setChild(act); + int delta = shape.getHeight()+30; + act.addToY(delta); + if (c instanceof JoinBindingShape) { + c.addToY(delta); + ((AJoinShape)c).replaceParent(cb, nb); + } + ARootShape root = (ARootShape) getContainerShape().getRoot(); + if (root.getSibling() != null) { + root.updateOtherBranches(shape, delta); + } + getRedShape().setReady(false); + } + + public void insertDecisionToShape(AShape shape) { + ABindingShape cb = shape.getChild(); + AShape c = cb.getChild(); + DecisionNodeShape dn = new DecisionNodeShape(graphicsPanel.getShapesContainer()); + ActionNodeShape act = new ActionNodeShape(getIncrementingActionNo()); + BindingShape nbl = new BindingShape(BindingType.DOWN_LEFT, null); + BindingShape nbr = new BindingShape(BindingType.DOWN_RIGHT, null); + cb.setChild(dn); + dn.setLeft(nbl); + nbl.setChild(c); + c.setXoffset(-80); + dn.setRight(nbr); + nbr.setChild(act); + act.setXoffset(+80); + int delta = shape.getHeight()+30; + dn.addToY(delta); + act.addToY(delta); + getRedShape().setReady(false); + } + + @Override + public ABindingShape[] getChildren(AShape s, boolean isUp) { + if (s instanceof DecisionNodeShape) { + DecisionNodeShape d = (DecisionNodeShape) s; + if (isUp) { + return new ABindingShape[] {d.getLeft(), d.getRight(), d.getLeftup(), d.getRightup()}; + } + return new ABindingShape[] {d.getLeft(), d.getRight()}; + } + if (s instanceof ActionNodeShape || s instanceof InitialNodeShape || + s instanceof EventNodeShape || s instanceof JoinBindingShape) { + return new ABindingShape[] {s.getChild()}; + } + if (s instanceof ForkBindingShape) { + ForkBindingShape f = (ForkBindingShape) s; + List bs = f.getDestinations(); + ABindingShape[] cs = new ABindingShape[bs.size()]; + for (int i=0; i attach it to join (evtl. create an action in between) + AShape atShape = getRedShape().getAttach(); + if (atShape instanceof ARootShape) { + ActionNodeShape act = new ActionNodeShape(getIncrementingActionNo()); + addShape(act); + setCurrent(shape); + graphicsPanel.getButtonsContainer().getActigramButtonsPanel().bindToCorrespondingShape(act); + getRedShape().setAttachTo(child.getChild()); + } + else if (atShape instanceof ActionShape) { + setCurrent(shape); + graphicsPanel.getButtonsContainer().getActigramButtonsPanel().bindToCorrespondingShape(atShape); + getRedShape().setAttachTo(child.getChild()); + } + } + else { + // create action+event above the given join shape + EventNodeShape event = shape.addEventAbove(); + setCurrent(shape); + graphicsPanel.getButtonsContainer().getActigramButtonsPanel().bindToCorrespondingShape(event); + getRedShape().setAttachTo(child.getChild()); + } + } + + // + private boolean isRedShapeAbove(JoinBindingShape shape) { + return getRedShape().isReady() && getRedShape().getAttach().getPY() < shape.getPY(); + } + + public void addFork(ForkBindingShape shape) { + setCurrent(shape); + ActionNodeShape act = new ActionNodeShape(getIncrementingActionNo()); + graphicsPanel.getButtonsContainer().getActigramButtonsPanel().placeCorrespondingShape(act); + } + + // + private int getIncrementingActionNo() { + return GeneralContext.getInstance().getGraphicsPanel().getShapesContainer().getIncrementingActionNoForActigram(); + } + + @Override + public AButtonsPanel getButtonsPanel() { + return graphicsPanel.getButtonsContainer().getActigramButtonsPanel(); + } +} diff --git a/src/clp/edit/graphics/shapes/act/ActionNodeShape.java b/src/clp/edit/graphics/shapes/act/ActionNodeShape.java new file mode 100644 index 0000000..5e9633b --- /dev/null +++ b/src/clp/edit/graphics/shapes/act/ActionNodeShape.java @@ -0,0 +1,88 @@ +package clp.edit.graphics.shapes.act; + +import java.awt.Color; +import java.awt.Graphics; + +import clp.edit.GeneralContext; +import clp.edit.graphics.dial.ActionOrStepDialog; +import clp.edit.graphics.shapes.AShape; +import clp.edit.graphics.shapes.ActionShape; +import clp.edit.graphics.shapes.BindingType; + +public class ActionNodeShape extends ActionShape { + + private static final long serialVersionUID = 543334981363673112L; + + enum Action { + PR, AS, ODATA, UI, JAVA; + } + + private Action action; + + transient private ActionOrStepDialog dialog; + + public ActionNodeShape(int index) { + super(50, 30, "A"+index, "Action ", 1); + dialog = new ActionOrStepDialog(GeneralContext.getInstance().getFrame(), this); + } + + @Override + public void paintShape(Graphics g, int offset) { + int ref_x = getPX()+offset; + Color c = g.getColor(); + if (getBgcolor() == null) { + if (isSelected()) { + g.setColor(Color.lightGray); + g.fillRoundRect(ref_x-getWidth()/2, getPY(), 50, 30, 30, 30); + } + else { + g.setColor(Color.white); + g.fillRoundRect(ref_x-getWidth()/2, getPY(), 50, 30, 30, 30); + g.setColor(Color.black); + g.drawRoundRect(ref_x-getWidth()/2, getPY(), 50, 30, 30, 30); + } + } + else { + g.setColor(getBgcolor()); + g.fillRoundRect(ref_x-getWidth()/2, getPY(), 50, 30, 30, 30); + } + if (action != null) { + g.setColor(Color.orange); + int x = ref_x-getWidth()/2+5; + if (action.name().length() < 4) { + g.fillRoundRect(x, getPY()+5, 30, 20, 20, 20); + g.setColor(Color.yellow); + g.drawString(action.name(), x+8, getPY()+20); + } + else { + g.fillRoundRect(x, getPY()+5, 35, 20, 20, 20); + g.setColor(Color.yellow); + g.drawString(action.name(), x+5, getPY()+20); + } + } + g.setColor(c); + g.drawString(getName(), ref_x-8, getPY()+20); + + paintInstructionsFromShape(g, offset); + + if (getChild() != null) { + super.checkDownType(); + getChild().paintShape(g, offset); + } + } + + @Override + public void setChild(AShape shape, BindingType bindingType) { + if (getChild() != null) { + getChild().setChild(shape); + } + } + + @Override + public ActionOrStepDialog getActionOrStepDialog() { + if (dialog == null) { + dialog = new ActionOrStepDialog(GeneralContext.getInstance().getFrame(), this, getInstructions()); + } + return dialog; + } +} diff --git a/src/clp/edit/graphics/shapes/act/ActivityShape.java b/src/clp/edit/graphics/shapes/act/ActivityShape.java new file mode 100644 index 0000000..a985d58 --- /dev/null +++ b/src/clp/edit/graphics/shapes/act/ActivityShape.java @@ -0,0 +1,104 @@ +package clp.edit.graphics.shapes.act; + +import java.awt.Graphics; + +import clp.edit.dialog.ADialog; +import clp.edit.graphics.dial.ActivityDialog; +import clp.edit.graphics.shapes.AContainerShape; +import clp.edit.graphics.shapes.AShape; +import clp.edit.graphics.shapes.ContainerHelper; +import clp.edit.util.ColorSet; + +public class ActivityShape extends AContainerShape { + + private static final long serialVersionUID = 5414309053600708426L; + + transient private ActivityDialog dialog; + + private ContainerHelper chelper; + + private String hname; + + /** + * CONSTRUCTOR + * + * @param width + * @param height + * @param text + * @param count + */ + public ActivityShape(int width, int height, String text, int count) { + super(width, height, text+count); + super.setBackground(ColorSet.activityBackground.getLight()); + hname = "G_HEAP"+count; + dialog = new ActivityDialog(text+count, this); + chelper = new ContainerHelper(count, getHighLevel()); + chelper.createTreeNodes(this, getScenarioName(), hname); + } + + public void addShape(AShape shape) { + setRoot(shape); + } + + @Override + public void paintShape(Graphics g, int offset, boolean b1, boolean b2) { + super.paintShape(g, offset, b1, b2); + if (getRoot() != null) { + getRoot().paintShape(g, offset); + } + } + + @Override + public ADialog getDialog() { + if (dialog == null) { + dialog = new ActivityDialog(getName(), this); + } + return dialog; + } + + public void setSimpleName(String name) { + super.setName(name); + } + + @Override + public StringBuilder getSource(String mscName) { + StringBuilder sb = new StringBuilder(); + sb.append("scenario " + getScenarioName() + " {\n"); + sb.append(" properties {\n"); + sb.append(" logic {\n"); + sb.append(" deactivation = MANUAL; // means cell deactivation happens manually (use of DEACTIVATOR)\n"); + sb.append(" level = 2; // the are 2 (0, 1) activity levels for a cell\n"); + sb.append(" }\n"); + sb.append(" queues {\n"); + sb.append(" qa income=Qe;\n"); + sb.append(" qi income=Qe;\n"); + sb.append(" }\n"); + sb.append(" tasks {\n"); + sb.append(" ACTIVATOR operatingOn qi passingTo qa;\n"); + sb.append(" EXECUTOR operatingOn qa;\n"); + sb.append(" DEACTIVATOR operatingOn qa passingTo qi;\n"); + sb.append(" }\n"); + sb.append(" }\n"); + sb.append("}\n\n"); + return sb; + } + + @Override + public void removeActor() { + chelper.removeActor("AD_SCN", getName()); + } + + public boolean rename(String oldName, String newName) { + return chelper.rename(oldName, newName); + } + + @Override + public String getScenarioName() { + return "AD_SCN"; + } + + @Override + public String getHeapNamePrefix() { + return hname; + } +} \ No newline at end of file diff --git a/src/clp/edit/graphics/shapes/act/DecisionNodeShape.java b/src/clp/edit/graphics/shapes/act/DecisionNodeShape.java new file mode 100644 index 0000000..7faa5a2 --- /dev/null +++ b/src/clp/edit/graphics/shapes/act/DecisionNodeShape.java @@ -0,0 +1,226 @@ +package clp.edit.graphics.shapes.act; + +import java.awt.Color; +import java.awt.Graphics; +import java.util.List; + +import clp.edit.GeneralContext; +import clp.edit.dialog.ADialog; +import clp.edit.graphics.dial.DecisionDialog; +import clp.edit.graphics.panel.GeneralShapesContainer; +import clp.edit.graphics.shapes.ABindingShape; +import clp.edit.graphics.shapes.AContainer; +import clp.edit.graphics.shapes.ADecisionShape; +import clp.edit.graphics.shapes.AShape; +import clp.edit.graphics.shapes.ActionShape; +import clp.edit.graphics.shapes.BindingShape; +import clp.edit.graphics.shapes.BindingType; + +public class DecisionNodeShape extends ADecisionShape { + + private static final long serialVersionUID = -1158045307775943118L; + + transient private DecisionDialog dialog; + + /** + * CONSTRUCTOR + * + */ + public DecisionNodeShape(GeneralShapesContainer shapesContainer) { + super(20, 20, "c"+shapesContainer.getIncrentingCounterForActigramDecisions()); + dialog = new DecisionDialog(GeneralContext.getInstance().getFrame(), getName()); + dialog.setupInfo(getInfo()); + } + + @Override + public void setChild(ABindingShape shape) { + if (shape == null) { + super.resetChildren(); + } + else { + switch (((BindingShape) shape).getBindingType()) { + case DOWN_LEFT: + setLeft((BindingShape) shape); + super.setChild(getLeft()); + break; + case DOWN_RIGHT: + setRight((BindingShape) shape); + super.setChild(getRight()); + break; + case UP_LEFT: + setLeftup((BindingShape) shape); + shape.setParent(this); + setDecisionUp(true); + break; + case UP_RIGHT: + setRightup((BindingShape) shape); + shape.setParent(this); + setDecisionUp(true); + break; + + default: + break; + } + } + } + + @Override + public void setChild(AShape shape, BindingType bindingType) { + switch (bindingType) { + case DOWN_LEFT: + getLeft().setText(getInfo().getLeftPartName()); + getLeft().setChild(shape); + break; + case DOWN_RIGHT: + getRight().setText(getInfo().getRightPartName()); + getRight().setChild(shape); + break; + case UP_LEFT: + getLeftup().setText(getInfo().getLeftPartName()); + getLeftup().setOnlyChild(shape); + ((ActionShape)shape).addEntryPoint(getLeftup()); + break; + case UP_RIGHT: + getRightup().setText(getInfo().getRightPartName()); + getRightup().setOnlyChild(shape); + ((ActionShape)shape).addEntryPoint(getRightup()); + break; + + default: + break; + } + } + + public void paintShape(Graphics g, int offset) { + Color c = g.getColor(); + int sx = getPX()+offset; + int sy = getPY(); + int[] px = {sx, sx-10, sx, sx+10}; + int[] py = {sy, sy+10, sy+20, sy+10}; + if (isSelected()) { + g.setColor(Color.lightGray); + } + g.fillPolygon(px, py, 4); + g.setColor(c); + if (getLeft() != null) { + getLeft().paintShape(g, offset); + } + if (getLeftup() != null) { + getLeftup().paintShape(g, offset); + } + if (getRight() != null) { + getRight().paintShape(g, offset); + } + if (getRightup() != null) { + getRightup().paintShape(g, offset); + } + } + + @Override + public void setName(String text) { + getCustDialog().setupInfo(getInfo()); + if (getLeft() != null) { + getLeft().setText(getInfo().getLeftPartName()); + } + else if (getLeftup() != null) { + getLeftup().setText(getInfo().getLeftPartName()); + } + if (getRight() != null) { + getRight().setText(getInfo().getRightPartName()); + } + else if (getRightup() != null) { + getRightup().setText(getInfo().getRightPartName()); + } + } + + @Override + public AShape getSelectedShape(int x, int y) { + if (x > getPX()-getWidth() && x < getPX()+getWidth()/2 + && y > getPY() && y < getPY()+getHeight()) { + + return this; + } + if (getLeft() != null) { + AShape s = getLeft().getSelectedShape(x, y); + if (s != null) { + return s; + } + } + if (getRight() != null) { + return getRight().getSelectedShape(x, y); + } + return null; + } + + @Override + public void gatherSelectedShapes(int x1, int y1, int x2, int y2, List list) { + int ref_x = getPX() - getWidth()/2; + int ref_y = getPY() + getHeight(); + if (ref_x > x1 && ref_x < x2 && ref_y > y1 && ref_y < y2) { + list.add(this); + } + if (getLeft() != null) { + getLeft().getChild().gatherSelectedShapes(x1, y1, x2, y2, list); + } + if (getRight() != null) { + getRight().getChild().gatherSelectedShapes(x1, y1, x2, y2, list); + } + } + + @Override + public void gatherChildrenShapes(List list) { + list.add(this); + if (getLeft() != null) { + getLeft().getChild().gatherChildrenShapes(list); + } + if (getRight() != null) { + getRight().getChild().gatherChildrenShapes(list); + } + } + + @Override + public void gatherLinksToJoin(List list) { + gatherOneLinkToJoin(list, getLeft()); + gatherOneLinkToJoin(list, getRight()); + } + + // + private void gatherOneLinkToJoin(List list, ABindingShape b) { + if (b != null) { + AShape s = b.getChild(); + s.gatherLinksToJoin(list); + } + } + + public void shiftLeft(int delta) { + getLeft().getChild().addToX(-delta);; + } + + public void shiftRight(int delta) { + getRight().getChild().addToX(delta);; + } + + @Override + public ADialog getDialog() { + if (dialog == null) { + dialog = new DecisionDialog(GeneralContext.getInstance().getFrame(), getName()); + } + return dialog; + } + + public DecisionDialog getCustDialog() { + return (DecisionDialog) getDialog(); + } + + @Override + public boolean generateCode(AContainer container) { + boolean b = true; + if (getLeft() != null) { + b &= getLeft().getChild().generateCode(container); + } + if (b && getRight() != null) { + return getRight().getChild().generateCode(container); + } + return b; + } +} diff --git a/src/clp/edit/graphics/shapes/act/EventNodeShape.java b/src/clp/edit/graphics/shapes/act/EventNodeShape.java new file mode 100644 index 0000000..c768439 --- /dev/null +++ b/src/clp/edit/graphics/shapes/act/EventNodeShape.java @@ -0,0 +1,175 @@ +package clp.edit.graphics.shapes.act; + +import java.awt.Color; +import java.awt.Graphics; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.Serializable; + +import javax.swing.JComboBox; +import javax.swing.JTextField; + +import clp.edit.GeneralContext; +import clp.edit.dialog.ADialog; +import clp.edit.graphics.dial.ClassicGroup; +import clp.edit.graphics.dial.EventNodeDialog; +import clp.edit.graphics.shapes.ABindingShape; +import clp.edit.graphics.shapes.AEventShape; +import clp.edit.graphics.shapes.AShape; +import clp.edit.graphics.shapes.BindingType; + +public class EventNodeShape extends AEventShape { + + private static final long serialVersionUID = 759259210396824663L; + + transient private EventNodeDialog dialog; + + private InfoGroup info; + + public EventNodeShape() { + super(20, 20, null); + info = new InfoGroup(); + dialog = new EventNodeDialog(GeneralContext.getInstance().getFrame(), info, this); + super.setName(dialog.getTransitionText()); + setXoffset(200); + } + + @Override + public void paintShape(Graphics g, int offset) { + Color c = g.getColor(); + int sx = getPX() + offset; + int sy = getPY(); + int[] px = {sx, sx-10, sx, sx+10}; + int[] py = {sy, sy+10, sy+20, sy+10}; + if (isSelected() || getChild() == null) { + g.setColor(Color.lightGray); + } + g.drawPolygon(px, py, 4); + g.setColor(c); + g.drawString(getName(), sx+15, sy+15); + if (getChild() != null) { + super.checkDownType(); + getChild().paintShape(g, offset); + } + if (getSibling() != null) { + getSibling().paintShape(g, offset); + } + } + + public void recreateListeners() { + info.createListener(); + } + + @Override + public int getPY() { + return 50 + getYoffset(); + } + + @Override + public void setChild(AShape shape, BindingType bindingType) { + getChild().setChild(shape); + } + + @Override + public AShape getSelectedShape(int x, int y) { + AShape s = super.getSelectedShape(x, y); + if (s == null && getSibling() != null) { + return getSibling().getSelectedShape(x, y); + } + return s; + } + + @Override + public ADialog getDialog() { + if (dialog == null) { + dialog = new EventNodeDialog(GeneralContext.getInstance().getFrame(), info, this); + } + return dialog; + } + + @Override + public String getActivationCondition(ABindingShape bs) { + return ((EventNodeDialog)getDialog()).getActivationCondition(); + } + + //================================================================= + + public class InfoGroup implements Serializable { + private static final long serialVersionUID = -7079142346284252966L; + transient private JComboBox arrowfield; + private char selectedItem = ClassicGroup.upArrow; + private JTextField eventfield; + private JTextField eventdescriptionfield; + InfoGroup() { + arrowfield = new JComboBox<>(new Character[] { ClassicGroup.upArrow, ClassicGroup.downArrow }); + arrowfield.setSelectedItem(selectedItem); + createListener(); + eventfield = new JTextField(5); + eventfield.setText("e"); + eventdescriptionfield = new JTextField(10); + eventdescriptionfield.setText("event variable"); + } + public void createListener() { + arrowfield.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + if (arrowfield.getSelectedIndex() == 0) { + eventfield.setText(""); + } + selectedItem = (char) arrowfield.getSelectedItem(); + } + }); + } + public void parse(String t) { + if (t != null && !t.isEmpty()) { + arrowfield.setSelectedItem(t.charAt(0)); + eventfield.setText(t.substring(1).trim()); + } + } + /** + * @return the arrowfield + */ + public JComboBox getArrowfield() { + if (arrowfield == null) { + arrowfield = new JComboBox<>(new Character[] { ClassicGroup.upArrow, ClassicGroup.downArrow }); + arrowfield.setSelectedItem(selectedItem); + } + return arrowfield; + } + /** + * @param arrowfield the arrowfield to set + */ + public void setArrowfield(JComboBox arrowfield) { + this.arrowfield = arrowfield; + } + /** + * @return the eventfield + */ + public JTextField getEventfield() { + return eventfield; + } + /** + * @param eventfield the eventfield to set + */ + public void setEventfield(JTextField eventfield) { + this.eventfield = eventfield; + } + @Override + public String toString() { + char arrow = (char) arrowfield.getSelectedItem(); + return arrow + eventfield.getText().trim(); + } + public char getArrow() { + return (char) arrowfield.getSelectedItem(); + } + public String getEvent() { + return eventfield.getText().trim(); + } + public String getEventDescription() { + return eventdescriptionfield.getText(); + } + public JTextField getEventDescriptionField() { + return eventdescriptionfield; + } + } +} diff --git a/src/clp/edit/graphics/shapes/act/FinalNodeShape.java b/src/clp/edit/graphics/shapes/act/FinalNodeShape.java new file mode 100644 index 0000000..ae0f84c --- /dev/null +++ b/src/clp/edit/graphics/shapes/act/FinalNodeShape.java @@ -0,0 +1,44 @@ +package clp.edit.graphics.shapes.act; + +import java.awt.Color; +import java.awt.Graphics; + +import clp.edit.dialog.ADialog; +import clp.edit.graphics.shapes.AFinalShape; +import clp.edit.graphics.shapes.AShape; +import clp.edit.graphics.shapes.BindingType; + +public class FinalNodeShape extends AFinalShape { + + private static final long serialVersionUID = -1310105256433370050L; + + public FinalNodeShape() { + super(26, 26, "", null); + } + + public void paintShape(Graphics g, int offset) { + Color c = g.getColor(); + if (isSelected()) { + g.setColor(Color.lightGray); + } + int x = getPX()+offset; + int y = getPY(); + g.fillOval(x-10, y, 20, 20); + g.drawOval(x-13, y-3, 26, 26); + g.setColor(c); + } + + @Override + public void setChild(AShape shape, BindingType bindingType) { + } + + @Override + public ADialog getDialog() { + return null; + } + + @Override + public String getDeactivationCondition() { + return "TRUE"; + } +} diff --git a/src/clp/edit/graphics/shapes/act/ForkBindingShape.java b/src/clp/edit/graphics/shapes/act/ForkBindingShape.java new file mode 100644 index 0000000..6f3f0de --- /dev/null +++ b/src/clp/edit/graphics/shapes/act/ForkBindingShape.java @@ -0,0 +1,118 @@ +package clp.edit.graphics.shapes.act; + +import java.awt.Color; +import java.awt.Graphics; +import java.util.List; + +import clp.edit.graphics.shapes.ABindingShape; +import clp.edit.graphics.shapes.AForkShape; +import clp.edit.graphics.shapes.AShape; +import clp.edit.graphics.shapes.BindingType; + +public class ForkBindingShape extends AForkShape { + + private static final long serialVersionUID = -5403718943662231267L; + + public ForkBindingShape() { + super(0, 0, "", null); + } + + public void paintShape(Graphics g, int offset) { + int ox = getPX()+offset; + int oy = getPY(); + if (!getDestinations().isEmpty()) { + int w = getDestinations().size() < 2 ? 160 : getWidth(); + int dx = ox - w/2 - 10; + int dy = oy-3; + Color c = g.getColor(); + if (isSelected()) { + g.setColor(Color.lightGray); + } + g.fillRect(dx, dy, w+20, 3); + g.setColor(c); + dx += 10; + int step = getDestinations().size() < 2 ? w / 2 : w / (getDestinations().size()-1); + for (ABindingShape b : getDestinations()) { + setBindingType(b, dx, offset); + drawBinding(g, b, dx, offset); + dx += step; + } + } + else { + g.fillRect(ox-30, oy, 60, 3); + } + } + + // + private void setBindingType(ABindingShape b, int dx, int offset) { + int delta = b.getChild().getPX() + offset - dx; + if (delta > 0 && delta < 4 || delta < 0 && delta > -4) { + b.setConditionnallyBindingType(BindingType.DOWN); + b.setXshift(0); + } + else { + b.setConditionnallyBindingType(BindingType.DOWN_MIDDLE); + b.setXshift(delta); + } + } + + // + private void drawBinding(Graphics g, ABindingShape b, int dx, int offset) { + int py = b.getParentY(); + int cy = b.getChildY(); + switch (b.getBindingType()) { + case DOWN: + g.drawLine(dx, py, dx, cy); + b.getChild().paintShape(g, offset); + break; + case DOWN_MIDDLE: + int x1 = dx; + int x2 = dx + b.getXshift(); + int middle = (cy-py)/2; + g.drawLine(x1, py, x1, py+middle); + g.drawLine(x1, py+middle, x2, py+middle); + g.drawLine(x2, py+middle, x2, cy); + b.getChild().paintShape(g, offset); + break; + case UP_LEFT: + break; + case UP_RIGHT: + break; + + default: + break; + } + } + + @Override + public AShape getSelectedShape(int x, int y) { + int ref_x = getPX(); + int ref_y = getPY(); + int nb = getDestinations().size() < 2 ? 2 : getDestinations().size(); + int w_2 = 80*(nb-1)+10; + if (x > ref_x-w_2 && x < ref_x+w_2 + && y > ref_y-3 && y < ref_y+3) { + + return this; + } + for (ABindingShape bs : getDestinations()) { + AShape s = bs.getSelectedShape(x, y); + if (s != null) { + return s; + } + } + return null; + } + + @Override + public void gatherChildrenShapes(List list) { + list.add(this); + for (ABindingShape bs : getDestinations()) { + bs.getChild().gatherChildrenShapes(list); + } + } + + @Override + public void setChild(ABindingShape shape) { + } +} diff --git a/src/clp/edit/graphics/shapes/act/InitialNodeShape.java b/src/clp/edit/graphics/shapes/act/InitialNodeShape.java new file mode 100644 index 0000000..5d8f7e0 --- /dev/null +++ b/src/clp/edit/graphics/shapes/act/InitialNodeShape.java @@ -0,0 +1,70 @@ +package clp.edit.graphics.shapes.act; + +import java.awt.Color; +import java.awt.Graphics; + +import clp.edit.dialog.ADialog; +import clp.edit.graphics.shapes.ABindingShape; +import clp.edit.graphics.shapes.AInitialShape; +import clp.edit.graphics.shapes.AShape; +import clp.edit.graphics.shapes.BindingType; + +public class InitialNodeShape extends AInitialShape { + + private static final long serialVersionUID = -1951022843974693067L; + + public InitialNodeShape() { + super(20, 20, "Initial node"); + setXoffset(200); + } + + public void paintShape(Graphics g, int offset) { + Color c = g.getColor(); + if (isSelected() || getChild() == null) { + g.setColor(Color.lightGray); + } + g.fillOval(getPX()+offset-10, getPY(), 20, 20); + g.setColor(c); + if (getChild() != null) { + super.checkDownType(); + getChild().paintShape(g, offset); + } + if (getSibling() != null) { + getSibling().paintShape(g, offset); + } + } + + @Override + public AShape getSelectedShape(int x, int y) { + AShape s = super.getSelectedShape(x, y); + if (s == null && getSibling() != null) { + return getSibling().getSelectedShape(x, y); + } + return s; + } + + @Override + public void setChild(AShape shape, BindingType bindingType) { + getChild().setChild(shape); + } + + @Override + public int getPX() { + return getXoffset(); + } + + @Override + public int getPY() { + return 50 + getYoffset(); + } + + @Override + public ADialog getDialog() { + return null; + } + + @Override + public String getActivationCondition(ABindingShape bs) { + return null; + } +} diff --git a/src/clp/edit/graphics/shapes/act/JoinBindingShape.java b/src/clp/edit/graphics/shapes/act/JoinBindingShape.java new file mode 100644 index 0000000..7bb7b2c --- /dev/null +++ b/src/clp/edit/graphics/shapes/act/JoinBindingShape.java @@ -0,0 +1,171 @@ +package clp.edit.graphics.shapes.act; + +import java.awt.Color; +import java.awt.Graphics; + +import clp.edit.GeneralContext; +import clp.edit.graphics.shapes.ABindingShape; +import clp.edit.graphics.shapes.AJoinShape; +import clp.edit.graphics.shapes.AShape; +import clp.edit.graphics.shapes.BindingShape; +import clp.edit.graphics.shapes.BindingType; + +public class JoinBindingShape extends AJoinShape { + + private static final long serialVersionUID = 7173833530898590776L; + + private ABindingShape lmb; // leftmost binding shape + + private BindingType btype; + + private int py; + + /** + * CONSTRUCTOR + */ + public JoinBindingShape() { + super(0, 0, "", null); + } + + public void paintShape(Graphics g, int offset) { + int ox = getPX() + offset; + int oy = getPY()-3; + Color c = g.getColor(); + if (isSelected()) { + g.setColor(Color.lightGray); + } + if (getParents().size() < 2) { + g.fillRect(ox-30, oy, 60, 3); + } + else { + int w = getRightmost() - getLeftmost(); + g.fillRect(offset+getLeftmost()-10, oy, w+20, 3); + } + g.setColor(c); + if (getChild() != null) { + getChild().paintShape(g, offset); + } + } + + // + private void defineLimits() { + Integer lmost = null; + Integer rmost = null; + for (ABindingShape b : getParents()) { + int x = b.getParent().getPX(); + if (lmost == null || x < lmost) { + lmost = x; + lmb = b; + } + if (rmost == null || x > rmost) { + rmost = x; + } + } + setLeftmost(lmost); + setRightmost(rmost); + } + + @Override + public int getPX() { + defineLimits(); + int w = 20; + if (getLeftmost() == null || getRightmost() == null) { + setLeftmost(getParent().getX1() - 10); + } + else { + w = getWidth(); + } + return getLeftmost() + w/2; + } + + @Override + public int getPY() { + if (py == 0) { + py = super.getPY(); + setYoffset(0); + } + return py + getYoffset(); + } + + @Override + public AShape getSelectedShape(int x, int y) { + int ref_x = getPX(); + int ref_y = getPY(); + if (getLeftmost() != null && getRightmost() != null) { + int w_2 = getWidth()/2 + 10; + if (x > ref_x-w_2 && x < ref_x+w_2 + && y > ref_y-3 && y < ref_y+3) { + + return this; + } + if (getChild() != null) { + return getChild().getSelectedShape(x, y); + } + } + return null; + } + + @Override + public void addToX(int delta) { + setXoffset(getXoffset()+delta); + } + + @Override + public void setChild(ABindingShape shape) { + } + + @Override + public void setChild(AShape shape, BindingType bindingType) { + if (lmb == null) { + lmb = getParent(); + getParents().add(lmb); + } + BindingShape b = new BindingShape(bindingType, ""); + if (shape.getParent() != null) { + shape.setChild(b); + b.setOnlyChild(this); + getParents().add(b); + } + else { + super.setChild(b); + b.setChild(shape); + } + } + + public BindingType getBindingType() { + return btype; + } + + public void setBindingType(BindingType t) { + btype = t; + } + + public EventNodeShape addEventAbove() { + if (lmb == null) { + lmb = getParent(); + getParents().add(lmb); + } + ActionNodeShape shape = new ActionNodeShape(GeneralContext.getInstance().getGraphicsPanel().getShapesContainer().getIncrementingActionNoForActigram()); + EventNodeShape event = new EventNodeShape(); + BindingShape be = new BindingShape(BindingType.DOWN, ""); + event.setChild(be); + be.setChild(shape); + BindingShape bs = new BindingShape(BindingType.DOWN, ""); + shape.setChild(bs); + bs.setOnlyChild(this); + defineLimits(); + int y = getPY() - 160; + int x; + if (btype == BindingType.UP_LEFT) { + x = getLeftmost() - 160; + } + else { + x = getRightmost() + 160; + } + event.setXoffset(x); + event.setYoffset(y); + shape.setYoffset(event.getHeight()+30); + getParents().add(bs); + return event; + } +} diff --git a/src/clp/edit/graphics/shapes/gc/EventNodeShape.java b/src/clp/edit/graphics/shapes/gc/EventNodeShape.java new file mode 100644 index 0000000..107a0fc --- /dev/null +++ b/src/clp/edit/graphics/shapes/gc/EventNodeShape.java @@ -0,0 +1,135 @@ +package clp.edit.graphics.shapes.gc; + +import java.awt.Color; +import java.awt.Graphics; + +import clp.edit.GeneralContext; +import clp.edit.dialog.ADialog; +import clp.edit.graphics.dial.TransitionRootDialog; +import clp.edit.graphics.dial.TransitionType; +import clp.edit.graphics.shapes.ABindingShape; +import clp.edit.graphics.shapes.AContainer; +import clp.edit.graphics.shapes.AEventShape; +import clp.edit.graphics.shapes.AShape; +import clp.edit.graphics.shapes.BindingShape; +import clp.edit.graphics.shapes.BindingType; +import clp.edit.graphics.shapes.util.CellInfo; + +public class EventNodeShape extends AEventShape { + + private static final long serialVersionUID = 8453477157312970032L; + + transient private TransitionRootDialog dialog; + + /** + * CONSTRUCTOR + * @param grafcetShape + */ + public EventNodeShape(GrafcetShape grafcetShape, TransitionType tt) { + super(20, 20, tt); + dialog = new TransitionRootDialog(GeneralContext.getInstance().getFrame(), this); + super.setName(dialog.getTransitionText()); + } + + public void paintShape(Graphics g, int offset) { + Color c = g.getColor(); + int sx = getPX()+offset; + int sy = getPY(); + if (isSelected()) { + g.setColor(Color.lightGray); + } + g.fillRect(sx-20, sy, 40, 4); + g.drawLine(sx, sy, sx, sy+20); + g.setColor(c); + if (getName() != null) { + g.drawString(getName(), sx+23, sy+5); + } + if (getChild() != null) { + super.checkDownType(); + getChild().paintShape(g, offset); + } + if (getSibling() != null) { + getSibling().paintShape(g, offset); + } + } + + @Override + public int getPY() { + return 50 + getYoffset(); + } + + @Override + public void setChild(AShape shape, BindingType bindingType) { + BindingShape b = new BindingShape(bindingType, "e"); + setChild(b); + b.setChild(shape); + } + + @Override + public ADialog getDialog() { + if (dialog == null) { + dialog = new TransitionRootDialog(GeneralContext.getInstance().getFrame(), this); + } + return dialog; + } + + public TransitionRootDialog getCustDialog() { + return (TransitionRootDialog) getDialog(); + } + + @Override + public AShape getSelectedShape(int x, int y) { + AShape s = super.getSelectedShape(x, y); + if (s == null && getSibling() != null) { + return getSibling().getSelectedShape(x, y); + } + return s; + } + + @Override + public String getActivationCondition(ABindingShape bs) { + String init_name = "INIT_"+getChild().getChild().getName(); + return getCustDialog().getActivationCondition(init_name, 'X', getChild().getChild()); + } + + @Override + public boolean generateActiveCode(AContainer container) { + if (getChild() != null) { + String name = getChild().getChild().getName(); + String init_name = "INIT_"+name; + if (!container.isRegistered(init_name)) { + CellInfo info = new CellInfo(init_name); + String code = getDeactivationCondition(name); + if (code != null) { + info.setDd(" DD { " + code + "; }\n"); + } + container.register(init_name, info, true); + } + return getChild().generateCode(container); + } + return true; + } + + // + private String getDeactivationCondition(String name) { + return getCustDialog().getDeactivationCondition(name, 'X', null); + } + + @Override + public boolean generateCode(AContainer container) { + if (getChild() != null) { + String name = getChild().getChild().getName(); + String init_name = "INIT_"+name; + if (!container.isRegistered(init_name)) { + CellInfo info = new CellInfo(init_name); + String code = getDeactivationCondition(name); + if (code != null) { + info.setDd(" DD { " + code + "; }\n"); + } + container.register(init_name, info, true); + } + return getChild().generateCode(container); + } + return true; + } +} diff --git a/src/clp/edit/graphics/shapes/gc/FinalNodeShape.java b/src/clp/edit/graphics/shapes/gc/FinalNodeShape.java new file mode 100644 index 0000000..653c4ed --- /dev/null +++ b/src/clp/edit/graphics/shapes/gc/FinalNodeShape.java @@ -0,0 +1,95 @@ +package clp.edit.graphics.shapes.gc; + +import java.awt.Color; +import java.awt.Graphics; + +import clp.edit.GeneralContext; +import clp.edit.dialog.ADialog; +import clp.edit.graphics.dial.TransitionDialog; +import clp.edit.graphics.dial.TransitionType; +import clp.edit.graphics.shapes.AContainer; +import clp.edit.graphics.shapes.AFinalShape; +import clp.edit.graphics.shapes.AShape; +import clp.edit.graphics.shapes.BindingShape; +import clp.edit.graphics.shapes.BindingType; +import clp.edit.graphics.shapes.util.CellInfo; + +public class FinalNodeShape extends AFinalShape { + + private static final long serialVersionUID = 7864381852046391226L; + + transient private TransitionDialog dialog; + + /** + * CONSTRUCTOR + * @param grafcetShape + */ + public FinalNodeShape(GrafcetShape grafcetShape, TransitionType tt) { + super(20, 20, "", tt); + dialog = new TransitionDialog(GeneralContext.getInstance().getFrame(), this, null, 200); + setName(dialog.getTransitionText()); + } + + public void paintShape(Graphics g, int offset) { + Color c = g.getColor(); + int sx = getPX()+offset; + int sy = getPY(); + if (isSelected()) { + g.setColor(Color.lightGray); + } + g.fillRect(sx-20, sy, 40, 4); + g.drawLine(sx, sy-20, sx, sy); + g.setColor(c); + if (getName() != null) { + g.drawString(getName(), sx+23, sy+5); + } + } + + @Override + public void setChild(AShape shape, BindingType bindingType) { + BindingShape b = new BindingShape(bindingType, "e"); + setChild(b); + b.setChild(shape); + } + + @Override + public ADialog getDialog() { + if (dialog == null) { + dialog = new TransitionDialog(GeneralContext.getInstance().getFrame(), this, null, 200); + } + return dialog; + } + + public TransitionDialog getCustDialog() { + return (TransitionDialog) getDialog(); + } + + @Override + public void setName(String name) { + super.setName(name); + } + + @Override + public boolean generateCode(AContainer container) { + AShape p = getParent().getParent(); + String name = p.getName(); + String final_name = "FINAL_"+name; + if (!container.isRegistered(final_name)) { + CellInfo info = new CellInfo(final_name); + String code = getCustDialog().getActivationCondition(name, 'X', getParent().getParent()); + if (code != null) { + info.setAd(" AD { " + code + "; }\n"); + } + container.register(final_name, info, false); + container.addDeactivationConditionFromFinal(name, final_name); + info.setDd(" DD { TRUE; }\n"); + } + return true; + } + + @Override + public String getDeactivationCondition() { + AShape p = getParent().getParent(); + return getCustDialog().getDeactivationCondition("FINAL_"+p.getName(), 'F', p); + } +} diff --git a/src/clp/edit/graphics/shapes/gc/ForkBindingShape.java b/src/clp/edit/graphics/shapes/gc/ForkBindingShape.java new file mode 100644 index 0000000..30086fb --- /dev/null +++ b/src/clp/edit/graphics/shapes/gc/ForkBindingShape.java @@ -0,0 +1,176 @@ +package clp.edit.graphics.shapes.gc; + +import java.awt.Color; +import java.awt.Graphics; +import java.util.List; + +import clp.edit.GeneralContext; +import clp.edit.dialog.ADialog; +import clp.edit.graphics.dial.TransitionDialog; +import clp.edit.graphics.dial.TransitionType; +import clp.edit.graphics.shapes.ABindingShape; +import clp.edit.graphics.shapes.AForkShape; +import clp.edit.graphics.shapes.AShape; +import clp.edit.graphics.shapes.BindingType; +import clp.edit.graphics.shapes.RedBindingShape; + +public class ForkBindingShape extends AForkShape { + + private static final long serialVersionUID = -3728721663025397833L; + + transient private TransitionDialog dialog; + + public ForkBindingShape(GrafcetShape grafcetShape, TransitionType tt) { + super(0, 6, "", tt); + dialog = new TransitionDialog(GeneralContext.getInstance().getFrame(), this, null, 200); + setName(dialog.getTransitionText()); + } + + public void paintShape(Graphics g, int offset) { + int ox = getPX()+offset; + int oy = getPY(); + if (!getDestinations().isEmpty()) { + int nb = getDestinations().size() < 2 ? 2 : getDestinations().size(); + int w = 160*(nb-1); + int dx = ox - w/2 - 10; + int dy = oy-3; + Color c = g.getColor(); + if (isSelected()) { + g.setColor(Color.lightGray); + } + g.fillRect(ox-20, dy-4, 40, 4); + dy += 5; + g.drawLine(dx, dy, dx+w+20, dy); + dy += 3; + g.drawLine(dx, dy, dx+w+20, dy); + g.setColor(c); + if (getName() != null) { + g.drawString(getName(), ox+23, dy-6); + } + dx += 10; + for (ABindingShape b : getDestinations()) { + setBindingType(b, dx, offset); + drawBinding(g, b, dx, offset); + dx += 160; + } + } + else { + g.fillRect(ox-30, oy, 60, 3); + } + } + + @Override + public ADialog getDialog() { + if (dialog == null) { + dialog = new TransitionDialog(GeneralContext.getInstance().getFrame(), this, null, 200); + } + return dialog; + } + + public TransitionDialog getCustDialog() { + return (TransitionDialog) getDialog(); + } + + // + private void setBindingType(ABindingShape b, int dx, int offset) { + int delta = b.getChild().getPX() + offset - dx; + if (delta > 0 && delta < 4 || delta < 0 && delta > -4) { + b.setConditionnallyBindingType(BindingType.DOWN); + b.setXshift(0); + } + else { + if (b.setConditionnallyBindingType(BindingType.DOWN_MIDDLE)) { + b.setXshift(delta); + } + } + } + + // + private void drawBinding(Graphics g, ABindingShape b, int dx, int offset) { + int py = b.getParentY(); + int cy = b.getChildY(); + switch (b.getBindingType()) { + case DOWN: + g.drawLine(dx, py, dx, cy); + b.getChild().paintShape(g, offset); + break; + case DOWN_MIDDLE: + int x1 = dx; + int x2 = dx + b.getXshift(); + int middle = (cy-py)/2; + g.drawLine(x1, py, x1, py+middle); + g.drawLine(x1, py+middle, x2, py+middle); + g.drawLine(x2, py+middle, x2, cy); + b.getChild().paintShape(g, offset); + break; + case UP_LEFT: + case UP_RIGHT: + int xf = b.getX2() + b.getChild().getWidth()/2 + offset; + int yf = cy + b.getChild().getHeight()/2; + int xi = b.getX1() + b.getXshift() + offset; + int yi = py - getParent().getHeight()/2; + int xr = xi + 30; + g.drawLine(xi, yi, xi, yi+30); + g.drawLine(xi, yi+30, xr, yi+30); + g.drawLine(xr, yi+30, xr, yf); + g.drawLine(xr, yf, xf, yf); + g.drawLine(xf+5, yf+5, xf, yf); + g.drawLine(xf+5, yf-5, xf, yf); + if (b.getText() != null) { + g.drawString(b.getText(), xi+2, yi-3); + } + break; + + default: + break; + } + } + + @Override + public AShape getSelectedShape(int x, int y) { + int ref_x = getPX(); + int ref_y = getPY(); + int nb = getDestinations().size() < 2 ? 2 : getDestinations().size(); + int w_2 = 80*(nb-1)+10; + if (x > ref_x-w_2 && x < ref_x+w_2 + && y > ref_y-10 && y < ref_y+10) { + + return this; + } + for (ABindingShape bs : getDestinations()) { + AShape s = bs.getSelectedShape(x, y); + if (s != null) { + return s; + } + } + return null; + } + + @Override + public void gatherChildrenShapes(List list) { + list.add(this); + for (ABindingShape bs : getDestinations()) { + if (bs.getBindingType() != BindingType.UP_LEFT && bs.getBindingType() != BindingType.UP_RIGHT) { + bs.getChild().gatherChildrenShapes(list); + } + } + } + + @Override + public void setChild(ABindingShape shape) { + } + + public void reverseBindingType(RedBindingShape redShape) { + if (getDestinations().isEmpty()) { + redShape.setConditionnallyBindingType(BindingType.UP_LEFT); + } + else { + redShape.setConditionnallyBindingType(BindingType.UP_RIGHT); + } + } + + @Override + public String getActivationCondition(ABindingShape bs) { + return getCustDialog().getActivationCondition(getParent().getParent().getName(), 'X', getParent().getParent()); + } +} diff --git a/src/clp/edit/graphics/shapes/gc/GrafcetContainer.java b/src/clp/edit/graphics/shapes/gc/GrafcetContainer.java new file mode 100644 index 0000000..5d21250 --- /dev/null +++ b/src/clp/edit/graphics/shapes/gc/GrafcetContainer.java @@ -0,0 +1,367 @@ +package clp.edit.graphics.shapes.gc; + +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.event.MouseEvent; +import java.util.ArrayList; +import java.util.List; + +import clp.edit.GeneralContext; +import clp.edit.graphics.btn.AButtonsPanel; +import clp.edit.graphics.btn.IAutomaton.ActionMode; +import clp.edit.graphics.btn.gc.GrafcetAutomaton; +import clp.edit.graphics.dial.TransitionDialog; +import clp.edit.graphics.panel.ButtonsContainer.ButtonType; +import clp.edit.graphics.panel.GeneralShapesContainer; +import clp.edit.graphics.shapes.ABindingShape; +import clp.edit.graphics.shapes.AContainer; +import clp.edit.graphics.shapes.AContainerShape; +import clp.edit.graphics.shapes.AEventShape; +import clp.edit.graphics.shapes.AForkShape; +import clp.edit.graphics.shapes.AJoinShape; +import clp.edit.graphics.shapes.ARootShape; +import clp.edit.graphics.shapes.AShape; +import clp.edit.graphics.shapes.ActionShape; +import clp.edit.graphics.shapes.BindingShape; +import clp.edit.graphics.shapes.BindingType; +import clp.edit.graphics.shapes.MultiBinding; +import clp.edit.graphics.shapes.RedBindingShape; +import clp.edit.graphics.shapes.TriBinding; +import clp.edit.graphics.shapes.menu.GrafcetContextMenu; +import clp.edit.panel.GraphicsPanel; + +public class GrafcetContainer extends AContainer { + + private static final long serialVersionUID = 2304688058232161487L; + + private GrafcetShape containerShape; + private GrafcetAutomaton automaton; + + private GraphicsPanel graphicsPanel; + + /** + * CONSTRUCTOR + * @param graphicsPanel + */ + public GrafcetContainer(GraphicsPanel graphicsPanel) { + super(); + this.graphicsPanel = graphicsPanel; + automaton = new GrafcetAutomaton(this, graphicsPanel.getButtonsContainer().getGrafcetButtonsPanel()); + } + + @Override + public Dimension paint(Graphics g, int offset, boolean isSelected) { + Dimension dim = super.paint(g, offset, isSelected, containerShape); + RedBindingShape rs = getRedShape(); + if (rs.isAttached() && rs.isReady()) { + rs.paintShape(g, offset); + } + return dim; + } + + @Override + public AContainerShape getContainerShape() { + return containerShape; + } + + @Override + public void setContainerShape(AContainerShape as) { + containerShape = (GrafcetShape) as; + } + + @Override + public boolean isSelected(int px, int py) { + return super.isSelected(px, py, containerShape); + } + + @Override + public ButtonType getType() { + return ButtonType.SFC; + } + + @Override + public void addShape(AShape shape) { + boolean isUpdateAllowed = !(getCurrent() instanceof ForkBindingShape); + BindingType bindingType = getRedShape().getBindingType(); + attachRedBinding(shape, isUpdateAllowed); + addShape(shape, bindingType); + if (isUpdateAllowed) { + getRedShape().updateXYBoundaries(); +// if (shape instanceof FinalNodeShape) { +// ((FinalNodeShape)shape).setDeactivationForParent(); +// } +// else { + setCurrent(shape); +// } + setDirty(true); + } + } + + @Override + public void bindShape(AShape shape) { + if (!(shape instanceof InvisibleNode) && + getRedShape().getAttach() instanceof TransitionNodeShape && shape.getChild() != null) { + automaton.bindShape(shape); + getRedShape().setAttachTo(null); + } + else { + super.bindShape(shape); + } + } + + // + private void attachRedBinding(AShape shape, boolean isUpdateAllowed) { + if (isUpdateAllowed) { + getRedShape().setAttachTo(shape); + } + } + + @Override + public GrafcetAutomaton getAutomaton() { + return automaton; + } + + public void disableRedShape() { + getRedShape().setReady(false); + getRedShape().setAttachTo(null); + GeneralContext.getInstance().getGraphicsPanel().refreshUI(); + } + + @Override + public ABindingShape[] getChildren(AShape s, boolean isUp) { + if (s instanceof ActionShape || s instanceof TransitionNodeShape || + s instanceof EventNodeShape || s instanceof JoinBindingShape) { + if (s.getChild() instanceof TriBinding) { + TriBinding t = (TriBinding)s.getChild(); + int size = t.getLeft() == null || t.getRight() == null ? 2 : 3; + ABindingShape[] cs = new ABindingShape[size]; + int i = 0; + if (t.getLeft() != null) { + cs[i++] = t.getLeft(); + } + cs[i++] = t.getMiddle(); + if (t.getRight() != null) { + cs[i] = t.getRight(); + } + return cs; + } + else if (s.getChild() instanceof MultiBinding) { + MultiBinding multi = (MultiBinding) s.getChild(); + ArrayList children = multi.getChildren(); + ABindingShape[] cs = new ABindingShape[children.size()]; + for (int i=0; i bs = f.getDestinations(); + ABindingShape[] cs = new ABindingShape[bs.size()]; + for (int i=0; i1->0) (at 0, nothing can be executed anymore)\n"); + sb.append(" }\n"); + sb.append(" queues {\n"); + sb.append(" qa income=Qe;\n"); + sb.append(" qi income=Qe;\n"); + sb.append(" }\n"); + sb.append(" tasks {\n"); + sb.append(" ACTIVATOR operatingOn qi passingTo qa;\n"); + sb.append(" EXECUTOR operatingOn qa;\n"); + sb.append(" DEACTIVATOR operatingOn qa passingTo qi;\n"); + sb.append(" EXECUTOR operatingOn qa;\n"); + sb.append(" DEACTIVATOR operatingOn qa passingTo qi;\n"); + sb.append(" }\n"); + sb.append(" }\n"); + sb.append("}\n\n"); + return sb; + } + + /** + * @return the defaultTransitionType + */ + public TransitionType getDefaultTransitionType() { + return defaultTransitionType; + } + + /** + * @param defaultTransitionType the defaultTransitionType to set + */ + public void setDefaultTransitionType(TransitionType defaultTransitionType) { + this.defaultTransitionType = defaultTransitionType; + } + + @Override + public void removeActor() { + chelper.removeActor("GC_SCN", getName()); + } + + public boolean rename(String oldName, String newName) { + return chelper.rename(oldName, newName); + } + + @Override + public String getScenarioName() { + return "GC_SCN"; + } + + @Override + public String getHeapNamePrefix() { + return hname; + } + + @Override + public int getHighLevel() { + return 2; + } +} diff --git a/src/clp/edit/graphics/shapes/gc/InitialStepNodeShape.java b/src/clp/edit/graphics/shapes/gc/InitialStepNodeShape.java new file mode 100644 index 0000000..d77ef62 --- /dev/null +++ b/src/clp/edit/graphics/shapes/gc/InitialStepNodeShape.java @@ -0,0 +1,91 @@ +package clp.edit.graphics.shapes.gc; + +import java.awt.Color; +import java.awt.Graphics; + +import clp.edit.GeneralContext; +import clp.edit.graphics.dial.ActionOrStepDialog; +import clp.edit.graphics.shapes.AContainer; +import clp.edit.graphics.shapes.AShape; +import clp.edit.graphics.shapes.ActionShape; +import clp.edit.graphics.shapes.BindingShape; +import clp.edit.graphics.shapes.BindingType; + +public class InitialStepNodeShape extends ActionShape { + + private static final long serialVersionUID = -2425875260318670114L; + + private int number; + + transient private ActionOrStepDialog dialog; + + public InitialStepNodeShape(int i) { + super(40, 26, "X"+i, "Initial Step ", 2); + number = i; + setYoffset(30); + dialog = new ActionOrStepDialog(GeneralContext.getInstance().getFrame(), this); + } + + public void paintShape(Graphics g, int offset) { + int x = getPX()+offset; + Color c = g.getColor(); + if (getBgcolor() == null) { + if (isSelected()) { + g.setColor(Color.lightGray); + } + else { + if (isPublished()) { + g.setColor(Color.pink); + g.fillRect(x-20, getPY(), 40, 26); + g.setColor(Color.white); + g.fillRect(x-15, getPY()+5, 30, 16); + } + else { + g.setColor(Color.white); + g.fillRect(x-20, getPY(), 40, 26); + } + g.setColor(Color.black); + } + } + else { + g.setColor(Color.white); + g.fillRect(x-20, getPY(), 40, 26); + g.setColor(getBgcolor()); + g.fillOval(x-5, getPY()+10, 10, 10); + } + g.drawRect(x-20, getPY(), 40, 26); + g.drawRect(x-18, getPY()+2, 36, 22); + g.setColor(c); + g.drawString(""+number, x-5, getPY()+18); + + paintInstructionsFromShape(g, offset); + + if (getChild() != null) { + super.checkDownType(); + getChild().paintShape(g, offset); + } + } + + @Override + public void setChild(AShape shape, BindingType bindingType) { + BindingShape b = new BindingShape(bindingType, ""); + setChild(b); + b.setChild(shape); + } + + @Override + public ActionOrStepDialog getActionOrStepDialog() { + if (dialog == null) { + dialog = new ActionOrStepDialog(GeneralContext.getInstance().getFrame(), this, getInstructions()); + } + return dialog; + } + + @Override + public boolean generateCode(AContainer container) { + if (getChild() != null) { + return getChild().generateActiveCode(container); + } + return true; + } +} diff --git a/src/clp/edit/graphics/shapes/gc/InvisibleNode.java b/src/clp/edit/graphics/shapes/gc/InvisibleNode.java new file mode 100644 index 0000000..53604b0 --- /dev/null +++ b/src/clp/edit/graphics/shapes/gc/InvisibleNode.java @@ -0,0 +1,66 @@ +package clp.edit.graphics.shapes.gc; + +import java.awt.Graphics; + +import clp.edit.dialog.ADialog; +import clp.edit.graphics.shapes.ABindingShape; +import clp.edit.graphics.shapes.AInitialShape; +import clp.edit.graphics.shapes.AShape; +import clp.edit.graphics.shapes.BindingShape; +import clp.edit.graphics.shapes.BindingType; + +public class InvisibleNode extends AInitialShape { + + private static final long serialVersionUID = -8465444795125064982L; + + public InvisibleNode() { + super(60, -30, ""); + setXoffset(200); + } + + public void paintShape(Graphics g, int offset) { + super.checkDownType(); + if (getChild() != null) { + getChild().paintShape(g, offset); + } + if (getSibling() != null) { + getSibling().paintShape(g, offset); + } + } + + @Override + public AShape getSelectedShape(int x, int y) { + AShape s = super.getSelectedShape(x, y); + if (s == null && getSibling() != null) { + return getSibling().getSelectedShape(x, y); + } + return s; + } + + @Override + public void setChild(AShape shape, BindingType bindingType) { + BindingShape b = new BindingShape(bindingType, null); + setChild(b); + b.setChild(shape); + } + + @Override + public int getPX() { + return getXoffset(); + } + + @Override + public int getPY() { + return 20 + getYoffset(); + } + + @Override + public ADialog getDialog() { + return null; + } + + @Override + public String getActivationCondition(ABindingShape bs) { + return null; + } +} diff --git a/src/clp/edit/graphics/shapes/gc/JoinBindingShape.java b/src/clp/edit/graphics/shapes/gc/JoinBindingShape.java new file mode 100644 index 0000000..c1428fa --- /dev/null +++ b/src/clp/edit/graphics/shapes/gc/JoinBindingShape.java @@ -0,0 +1,253 @@ +package clp.edit.graphics.shapes.gc; + +import java.awt.Color; +import java.awt.Graphics; + +import clp.edit.GeneralContext; +import clp.edit.dialog.ADialog; +import clp.edit.graphics.dial.TransitionDialog; +import clp.edit.graphics.shapes.ABindingShape; +import clp.edit.graphics.shapes.AJoinShape; +import clp.edit.graphics.shapes.AShape; +import clp.edit.graphics.shapes.BindingShape; +import clp.edit.graphics.shapes.BindingType; +import clp.edit.graphics.shapes.TriBinding; + +public class JoinBindingShape extends AJoinShape { + + private static final long serialVersionUID = 3969967774023695547L; + + private ABindingShape lmb; // leftmost binding shape + private Integer leftmost; + private Integer rightmost; + + private BindingType btype; + + transient private TransitionDialog dialog; + + private GrafcetShape grafcetShape; + + + /** + * CONSTRUCTOR + * + * @param gs grafcetShape + */ + public JoinBindingShape(GrafcetShape gs) { + super(0, 6, "", gs.getDefaultTransitionType()); + this.grafcetShape = gs; + dialog = new TransitionDialog(GeneralContext.getInstance().getFrame(), this, null, 200); + setName(dialog.getTransitionText()); + } + + public void paintShape(Graphics g, int offset) { + int sx = getPX() + offset; + int oy = getPY()-3; + Color c = g.getColor(); + if (isSelected()) { + g.setColor(Color.lightGray); + } + int ox; + if (getParents().size() < 2) { + g.fillRect(sx-30, oy, 60, 3); + } + else { + int w = rightmost - leftmost; + ox = offset+leftmost-10; + oy += 4; + g.drawLine(ox, oy, ox+w+20, oy); + oy += 3; + g.drawLine(ox, oy, ox+w+20, oy); + g.fillRect(sx-20, oy+9, 40, 4); + } + g.setColor(c); + if (getName() != null) { + g.drawString(getName(), sx+23, oy+15); + } + if (getChild() != null) { + getChild().paintShape(g, offset); + } + } + + // + private void defineLimits() { + leftmost = null; + rightmost = null; + for (ABindingShape b : getParents()) { + int x = b.getParent().getPX(); + if (b.getParent().getChild() instanceof TriBinding) { + TriBinding tri = (TriBinding) b.getParent().getChild(); + if (b == tri.getLeft()) { + x -= 20; + } + else { + x += 20; + } + } + if (leftmost == null || x < leftmost) { + leftmost = x; + lmb = b; + } + if (rightmost == null || x > rightmost) { + rightmost = x; + } + } + } + + @Override + public int getPX() { + defineLimits(); + int w = 20; + if (leftmost == null || rightmost == null) { + leftmost = getParent().getX1() - 10; + } + else { + w = rightmost - leftmost; + } + return leftmost + w/2; + } + + public int getLeftMost() { + defineLimits(); + return leftmost; + } + + public int getRightMost() { + defineLimits(); + return rightmost; + } + + @Override + public AShape getSelectedShape(int x, int y) { + int ref_x = getPX(); + int ref_y = getPY(); + if (leftmost != null && rightmost != null) { + int w_2 = (rightmost - leftmost)/2 + 10; + if (x > ref_x-w_2 && x < ref_x+w_2 + && y > ref_y-10 && y < ref_y+10) { + + return this; + } + if (getChild() != null) { + return getChild().getSelectedShape(x, y); + } + } + return null; + } + + @Override + public void addToX(int delta) { + setXoffset(getXoffset()+delta); + } + + @Override + public void setChild(ABindingShape shape) { + } + + @Override + public void setChild(AShape shape, BindingType bindingType) { + if (lmb == null) { + lmb = getParent(); + getParents().add(lmb); + } + BindingShape b = new BindingShape(bindingType, ""); + b.setOnlyChild(this); + if (shape.getParent() != null) { + BindingShape sch = (BindingShape) shape.getChild(); + if (sch == null) { + shape.setChild(b); + } + else { + b.setParent(shape); + TriBinding tri; + if (sch instanceof TriBinding) { + tri = (TriBinding) sch; + tri.addChild(b); + b.setOnlyChild(this); + } + else { + tri = new TriBinding(); + tri.addChild(sch); + sch.setBindingType(BindingType.DOWN_LEFT); + tri.addChild(b); + shape.setChild(tri); + } + b.setBindingType(BindingType.DOWN_RIGHT); + } + getParents().add(b); + } + else { + super.setChild(b); + b.setChild(shape); + } + } + + public BindingType getBindingType() { + return btype; + } + + public void setBindingType(BindingType t) { + btype = t; + } + + public EventNodeShape addEventAbove() { + if (lmb == null) { + lmb = getParent(); + getParents().add(lmb); + } + StepNodeShape shape = new StepNodeShape(GeneralContext.getInstance().getGraphicsPanel().getShapesContainer().getIncrementingActionNoForGrafcet()); + EventNodeShape event = new EventNodeShape(grafcetShape, grafcetShape.getDefaultTransitionType()); + BindingShape be = new BindingShape(BindingType.DOWN, ""); + event.setChild(be); + be.setChild(shape); + BindingShape bs = new BindingShape(BindingType.DOWN, ""); + shape.setChild(bs); + bs.setOnlyChild(this); + defineLimits(); + int y = getPY() - 100; + if (y > 20) { + y -= 20; + } + else { + addToY(20); + } + int x; + if (btype == BindingType.UP_LEFT) { + x = leftmost - 160; + } + else { + x = rightmost + 160; + } + event.setXoffset(x); + event.setYoffset(y); + shape.setYoffset(event.getHeight()+5); + getParents().add(bs); + return event; + } + + @Override + public ADialog getDialog() { + if (dialog == null) { + dialog = new TransitionDialog(GeneralContext.getInstance().getFrame(), this, null, 200); + } + return dialog; + } + + public TransitionDialog getCustDialog() { + return (TransitionDialog) getDialog(); + } + + @Override + public String getActivationCondition(ABindingShape bs) { + if (getParents().size() > 1) { + AShape p = getParents().get(0).getParent(); + String s = getCustDialog().getActivationCondition(p.getName(), 'X', p); + for (int i=1; i 0 && xdelta < 4 || xdelta < 0 && xdelta > -4) { + setBindingType(BindingType.DOWN); + } + else { + drawBindings(parent, g, px, cx, py, cy); + } + break; + case UP_LEFT: + case UP_RIGHT: + px = parent.getPX() + offset; + cx = getX2() + offset; + drawBindings(parent, g, px, cx, py, cy); + break; + default: + break; + } + g.setColor(c); + if (getChild() != null && getBindingType() != BindingType.UP_LEFT && getBindingType() != BindingType.UP_RIGHT) { + getChild().paintShape(g, offset); + } + } + + // + private void drawBindings(AShape parent, Graphics g, int px, int cx, int py, int cy) { + int xdelta = cx - px; + if (xdelta > 0 && xdelta < 4 || xdelta < 0 && xdelta > -4) { + g.drawLine(px, py, px, cy); + drawArrowDown(g, px, cy); + drawText(g, px+2, (py+cy)/2); + getChild().addToX(-xdelta); + } + else { + int littleShift = 0; + if (parent instanceof PlaceNodeShape) { + if (getChild().getParent() != this) { + littleShift = xdelta > 0 ? -9 : +9; + } + drawFromPlaceToTransition(parent, g, px, cx+littleShift, parent.getPY(), cy); + } + else { + if (parent.getChild() != this) { + littleShift = xdelta < 0 ? -9 : +9; + } + drawFromTransitionToPlace(parent, g, px+littleShift, cx, parent.getPY(), cy); + } + } + } + + // + private void drawFromPlaceToTransition(AShape parent, Graphics g, int px, int cx, int py, int cy) { + int pw = parent.getWidth(); + int ph = parent.getHeight(); + int ch = getChild().getHeight(); + int pw_2 = pw/2; + if (cy < py) { // Transition over Place + if (cx < px) { // Transition left from Place + int dx = px - pw_2 - cx; + int dy = py + ph/2 - cy - ch/2; + g.drawArc(cx, cy+ch-dy, dx*2, dy*2, 180, 90); + drawText(g, cx+4, (py+cy)/2+2); + } + else { // Transition right from Place + int dx = cx - px - pw_2; + int dy = py + ph/2 - cy - ch/2; + g.drawArc(px+pw_2-dx, cy+ch-dy, dx*2, dy*2, 0, -90); + drawText(g, cx+2, (py+cy)/2+2); + } + drawArrowUp(g, cx, cy+ch); + } + else { // Transition under Place + if (cx < px) { // Transition left from Place + int dx = px - pw_2 - cx; + int dy = cy - py - ph/2; + g.drawArc(cx, py+ph/2, dx*2, dy*2, 90, 90); + drawText(g, cx+4, (py+cy)/2+8); + } + else { // Transition right from Place + int dx = cx - px - pw_2; + int dy = cy - py - ph/2; + g.drawArc(px+pw_2-dx, py+ph/2, dx*2, dy*2, 0, 90); + drawText(g, cx-8, (py+cy)/2+8); + } + drawArrowDown(g, cx, cy); + } + } + + // + private void drawFromTransitionToPlace(AShape parent, Graphics g, int px, int cx, int py, int cy) { + int cw = getChild().getWidth(); + int ch = getChild().getHeight(); + int ph = parent.getHeight(); + int cw_2 = cw/2; + int ch_2 = ch/2; + if (cy < py) { // Place over Transition + if (cx < px) { // Place left from Transition + int ci = ((ActionShape)getChild()).getInstructionSize() * 6; + int dx = px - cx - cw_2; + int dy = py - cy - ch_2; + g.drawArc(cx+cw_2-dx+ci, cy+ch_2, dx*2-ci, dy*2, 0, 90); + drawArrowLeft(g, cx+cw_2+ci, cy+ch_2); + drawText(g, px-dx/2, (py+cy)/2); + } + else { // Place right from Transition + int dx = cx - cw_2 - px; + int dy = py - cy - ch_2; + g.drawArc(px, cy+ch_2, dx*2, dy*2, 90, 90); + drawArrowRight(g, cx-cw_2, cy+ch_2); + drawText(g, px+dx/2, (py+cy)/2); + } + } + else { // Place under Transition + if (cx < px) { // Place left from Transition + int dx = px - cx - cw_2; + int dy = cy + ch/2 - py - ph; + g.drawArc(cx+cw_2-dx, py+ph-dy, dx*2, dy*2, 0, -90); + drawArrowLeft(g, cx+cw_2, cy+ch_2); + drawText(g, px-6, (py+cy)/2); + } + else { // Place right from Transition + int dx = cx - cw_2 - px; + int dy = cy + ch_2 - py - ph; + g.drawArc(px, py+ph-dy, dx*2, dy*2, 180, 90); + drawArrowRight(g, cx-cw_2, cy+ch_2); + drawText(g, px+4, (py+cy)/2); + } + } + } + + // + private void drawText(Graphics g, int x, int y) { + String t = getText(); + if (t != null && t.length() > 0 && !"1".equals(t)) { + Font currentFont = g.getFont(); + Font newFont = currentFont.deriveFont(currentFont.getSize() * 0.7F); + g.setFont(newFont); + g.drawString(t, x, y); + g.setFont(currentFont); + } + } + + // + private void drawArrowUp(Graphics g, int x, int y) { + int[] ptx = {x-4, x, x+4}; + int[] pty = {y+7, y, y+7}; + g.fillPolygon(ptx, pty, 3); + } + + // + private void drawArrowDown(Graphics g, int x, int y) { + int[] ptx = {x-4, x, x+4}; + int[] pty = {y-7, y, y-7}; + g.fillPolygon(ptx, pty, 3); + } + + // + private void drawArrowLeft(Graphics g, int x, int y) { + int[] ptx = {x, x+7, x+7}; + int[] pty = {y, y+4, y-4}; + g.fillPolygon(ptx, pty, 3); + } + + // + private void drawArrowRight(Graphics g, int x, int y) { + int[] ptx = {x, x-7, x-7}; + int[] pty = {y, y-4, y+4}; + g.fillPolygon(ptx, pty, 3); + } + + public BindingType getDirection() { + return getBindingType(); + } + + /** + * @return the color + */ + public Color getColor() { + return color; + } + + @Override + public AShape getSelectedShape(int x, int y) { + if (getChild() != null && getBindingType() != BindingType.UP_LEFT && getBindingType() != BindingType.UP_RIGHT) { + return getChild().getSelectedShape(x, y); + } + return null; + } + + public void setChild(PlaceNodeShape place, String name) { + super.setChild(place); + } +} diff --git a/src/clp/edit/graphics/shapes/pn/PetriNetsContainer.java b/src/clp/edit/graphics/shapes/pn/PetriNetsContainer.java new file mode 100644 index 0000000..128f7ff --- /dev/null +++ b/src/clp/edit/graphics/shapes/pn/PetriNetsContainer.java @@ -0,0 +1,480 @@ +package clp.edit.graphics.shapes.pn; + +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.event.MouseEvent; + +import clp.edit.GeneralContext; +import clp.edit.graphics.btn.AButtonsPanel; +import clp.edit.graphics.btn.IAutomaton.ActionMode; +import clp.edit.graphics.btn.pn.PetriNetsAutomaton; +import clp.edit.graphics.btn.pn.PetriNetsButtonsPanel; +import clp.edit.graphics.dial.PNTransitionDialog.TransitionPosition; +import clp.edit.graphics.panel.ButtonsContainer.ButtonType; +import clp.edit.graphics.panel.GeneralShapesContainer; +import clp.edit.graphics.shapes.ABindingShape; +import clp.edit.graphics.shapes.AContainer; +import clp.edit.graphics.shapes.AContainerShape; +import clp.edit.graphics.shapes.AEventShape; +import clp.edit.graphics.shapes.ARootShape; +import clp.edit.graphics.shapes.AShape; +import clp.edit.graphics.shapes.ActionShape; +import clp.edit.graphics.shapes.BindingShape; +import clp.edit.graphics.shapes.BindingType; +import clp.edit.graphics.shapes.RedBindingShape; +import clp.edit.graphics.shapes.TriBinding; +import clp.edit.graphics.shapes.menu.PetriNetsContextMenu; +import clp.edit.panel.GraphicsPanel; + +public class PetriNetsContainer extends AContainer { + + private static final long serialVersionUID = 3292146692884839701L; + + private AContainerShape containerShape; + private PetriNetsAutomaton automaton; + + private boolean isColored; + + private PetriNetsButtonsPanel pnButtonsPanel; + + /** + * CONSTRUCTOR + * @param graphicsPanel + * + * @param isColored + */ + public PetriNetsContainer(GraphicsPanel graphicsPanel, boolean isColored) { + super(); + this.pnButtonsPanel = graphicsPanel.getButtonsContainer().getPNButtonsPanel(isColored); + this.isColored = isColored; + automaton = new PetriNetsAutomaton(this, pnButtonsPanel); + } + + @Override + public Dimension paint(Graphics g, int offset, boolean isSelected) { + Dimension dim = super.paint(g, offset, isSelected, containerShape); + RedBindingShape rs = getRedShape(); + if (rs.isAttached() && rs.isReady()) { + rs.paintShape(g, offset); + } + return dim; + } + + @Override + public AContainerShape getContainerShape() { + return containerShape; + } + + @Override + public void setContainerShape(AContainerShape as) { + containerShape = as; + } + + @Override + public boolean isSelected(int px, int py) { + return super.isSelected(px, py, containerShape); + } + + @Override + public ButtonType getType() { + return isColored ? ButtonType.CPN : ButtonType.WPN; + } + + @Override + public void addShape(AShape shape) { + BindingType bindingType = getRedShape().getBindingType(); + getRedShape().setAttachTo(shape); + addShape(shape, bindingType); + getRedShape().updateXYBoundaries(); + setCurrent(shape); + setDirty(true); + } + + @Override + public void bindShape(AShape shape) { + if (!(shape instanceof InvisibleNode)) { + String t = ((PetriNetsShape)getContainerShape()).getWeightOrColor(); + AShape sel = getRedShape().getAttach(); + if (sel == null) { + sel = getSelected(); + } + if (sel == shape) { + return; + } + if (sel instanceof TransitionNodeShape) { + TransitionNodeShape tr = (TransitionNodeShape) sel; + PNBindingShape pin; + if (tr.getPX() < shape.getPX()) { + pin = new PNBindingShape(BindingType.UP_LEFT, t); + } + else { + pin = new PNBindingShape(BindingType.UP_RIGHT, t); + } + pin.setOnlyChild(shape); + tr.setChild(pin); + getRedShape().setAttachTo(null); + ((ActionShape)shape).addEntryPoint(pin); + } + else if (sel instanceof PlaceNodeShape) { + PlaceNodeShape pl = (PlaceNodeShape) sel; + PNBindingShape pin; + TransitionNodeShape tr = (TransitionNodeShape)shape; + if (pl.getPX() < shape.getPX()) { + if (pl.getPY() > shape.getPY()) { + pin = new PNBindingShape(BindingType.UP_LEFT, t); + pin.setXshift(-9); + tr.setUpleft(pin); + } + else { + pin = new PNBindingShape(BindingType.DOWN_RIGHT, t); + pin.setParent(pl); + BindingShape cb = (BindingShape) pl.getChild(); + TriBinding tri; + if (cb instanceof TriBinding) { + tri = (TriBinding) cb; + tri.addChild(pin); + tri.addToX(-80, shape); + tri.getLeft().setXshift(0); + } + else if (cb != null) { + tri = new TriBinding(); + tri.addChild(pin); + tri.addChild(cb); + pl.setChild(tri); + tr.addToX(-80); + } + else { + pl.setChild(pin); + } + tr.setUpleft(pin); + } + } + else { + if (pl.getPY() > shape.getPY()) { + pin = new PNBindingShape(BindingType.UP_RIGHT, t); + pin.setXshift(+9); + tr.setUpright(pin); + pl.setChild(pin); + } + else { + pin = new PNBindingShape(BindingType.DOWN_LEFT, t); + BindingShape cb = (BindingShape) pl.getChild(); + TriBinding tri; + if (cb instanceof TriBinding) { + tri = (TriBinding) cb; + tri.addChild(pin); + tri.addToX(80, shape); + tri.getLeft().setXshift(0); + } + else if (cb != null) { + tri = new TriBinding(); + tri.addChild(pin); + tri.addChild(cb); + pl.setChild(tri); + tr.addToX(80); + } + else { + pl.setChild(pin); + } + tr.setUpright(pin); + } + } + pin.setOnlyChild(shape); + getRedShape().setAttachTo(null); + } + } + else { + super.bindShape(shape); + } + } + + @Override + public PetriNetsAutomaton getAutomaton() { + return automaton; + } + + public void disableRedShape() { + getRedShape().setReady(false); + GeneralContext.getInstance().getGraphicsPanel().refreshUI(); + } + + @Override + public ABindingShape[] getChildren(AShape s, boolean isUp) { + if (s instanceof PlaceNodeShape || s instanceof TransitionNodeShape) { + if (s.getChild() instanceof TriBinding) { + TriBinding t = (TriBinding)s.getChild(); + int size = t.getLeft() == null || t.getRight() == null ? 2 : 3; + ABindingShape[] cs = new ABindingShape[size]; + int i = 0; + if (t.getLeft() != null) { + cs[i++] = t.getLeft(); + } + cs[i++] = t.getMiddle(); + if (t.getRight() != null) { + cs[i] = t.getRight(); + } + return cs; + } + return new ABindingShape[] {s.getChild()}; + } + return null; + } + + @Override + public void handleAction(AShape sel, int px, int py, boolean isMultiSelect) { + if ((automaton.getMode() == ActionMode.NONE || isMultiSelect) && sel != null) { + automaton.performAction(ActionMode.SELECT, null, sel, isMultiSelect); + } + else { + automaton.performAction(null, sel); + } + } + + @Override + public void showContextMenu(GeneralShapesContainer genericContainer, AShape shape, MouseEvent e) { + PetriNetsContextMenu cmenu = new PetriNetsContextMenu(shape, genericContainer); + cmenu.show(e.getComponent(), e.getX()+10, e.getY()); + } + + public void insertPlaceToShape(AShape shape) { + PetriNetsShape pnShape = (PetriNetsShape) getContainerShape(); + PlaceNodeShape place = new PlaceNodeShape(getIncrementingActionNo(), pnShape); + TransitionNodeShape trans = new TransitionNodeShape(pnShape, pnShape.getDefaultTransitionType(), TransitionPosition.MIDDLE); + ABindingShape cb = shape.getChild(); + String t = pnShape.getWeightOrColor(); + ABindingShape nb1 = new PNBindingShape(BindingType.DOWN, t); + ABindingShape nb2 = new PNBindingShape(BindingType.DOWN, t); + shape.setChild(nb1); + if (shape instanceof PlaceNodeShape) { + trans.addToY(shape.getHeight()+30); + place.addToY(trans.getHeight()+30); + nb1.setChild(trans); + trans.setChild(nb2); + place.setChild(cb); + nb2.setChild(place); + } + else { + place.addToY(shape.getHeight()+30); + trans.addToY(place.getHeight()+30); + trans.setChild(cb); + nb2.setChild(trans); + place.setChild(nb2); + nb1.setChild(place); + } + ARootShape root = (ARootShape) getContainerShape().getRoot(); + if (root.getSibling() != null) { + int delta = shape.getHeight()+30; + root.updateOtherBranches(shape, delta); + } + getRedShape().setReady(false); + } + + public void insertAlternateTransitionToPlace(AShape shape) { + BindingShape cb = (BindingShape) shape.getChild(); + PetriNetsShape pnShape = (PetriNetsShape) getContainerShape(); + TransitionNodeShape trans = new TransitionNodeShape(pnShape, pnShape.getDefaultTransitionType(), TransitionPosition.MIDDLE); + PlaceNodeShape place = new PlaceNodeShape(getIncrementingActionNo(), pnShape); + String t = pnShape.getWeightOrColor(); + PNBindingShape nb1 = new PNBindingShape(BindingType.DOWN, t); + PNBindingShape nb2 = new PNBindingShape(BindingType.DOWN, t); + nb1.setParent(shape); + nb1.setChild(trans); + trans.addToY(shape.getHeight()+30); + trans.setChild(nb2); + place.addToY(30); + nb2.setChild(place); + TriBinding tri; + if (cb instanceof TriBinding) { + tri = (TriBinding) cb; + tri.addChild(nb1); + tri.addToX(80, shape); + tri.getLeft().setXshift(0); + } + else { + tri = new TriBinding(); + tri.addChild(cb); + tri.addChild(nb1); + shape.setChild(tri); + trans.addToX(80); + cb.getChild().addToX(-80); + } + updateLimits(containerShape, place); + updateLimits(containerShape, cb.getChild()); + getRedShape().setReady(false); + } + + public void insertPlaceUpLeftFromTransition(AShape shape) { + InvisibleNode init = new InvisibleNode(); + init.setYoffset(shape.getPY()-90); + init.setXoffset(shape.getPX()-80); + PNBindingShape b = new PNBindingShape(BindingType.NONE, null); + init.setChild(b); + PlaceNodeShape place = new PlaceNodeShape(getIncrementingActionNo(), (PetriNetsShape) getContainerShape()); + b.setChild(place); + String t = ((PetriNetsShape)getContainerShape()).getWeightOrColor(); + PNBindingShape nb = new PNBindingShape(BindingType.DOWN, t); + place.setChild(nb); + nb.setOnlyChild(shape); + nb.setXshift(-9); + ((TransitionNodeShape)shape).setUpleft(nb); + bindShape(init); + } + + public void insertPlaceUpRightFromTransition(AShape shape) { + InvisibleNode init = new InvisibleNode(); + init.setYoffset(shape.getPY()-90); + init.setXoffset(shape.getPX()+80); + PNBindingShape b = new PNBindingShape(BindingType.NONE, null); + init.setChild(b); + PlaceNodeShape place = new PlaceNodeShape(getIncrementingActionNo(), (PetriNetsShape) getContainerShape()); + b.setChild(place); + String t = ((PetriNetsShape)getContainerShape()).getWeightOrColor(); + PNBindingShape nb = new PNBindingShape(BindingType.DOWN, t); + place.setChild(nb); + nb.setOnlyChild(shape); + nb.setXshift(+9); + ((TransitionNodeShape)shape).setUpright(nb); + bindShape(init); + } + + public void insertPlaceBelowTransition(TransitionNodeShape trans) { + PlaceNodeShape place = new PlaceNodeShape(getIncrementingActionNo(), (PetriNetsShape) getContainerShape()); + ABindingShape b = trans.getChild(); + if (b instanceof PNBindingShape) { + createTwinBinding(place, trans, (PNBindingShape)b); + } + else { + createTriBinding(place, trans, (TriBinding)b); + } + } + + // + private int getIncrementingActionNo() { + return GeneralContext.getInstance().getGraphicsPanel().getShapesContainer().getIncrementingActionNoForPetriNets(); + } + + // + private void createTwinBinding(PlaceNodeShape place, TransitionNodeShape trans, PNBindingShape cb) { + TriBinding twin = new TriBinding(); + String t = ((PetriNetsShape)getContainerShape()).getWeightOrColor(); + PNBindingShape nb = new PNBindingShape(BindingType.DOWN, t); + nb.setParent(trans); + nb.setChild(place, trans.getParent().getParent().getName()); + place.addToX(80); + place.addToY(trans.getHeight()+30); + twin.addChild(cb); + twin.addChild(nb); + trans.setChild(twin); + trans.setupDialogHelpers(); + AShape c = cb.getChild(); + c.addToX(-80); + getRedShape().setReady(false); + } + + // + private void createTriBinding(PlaceNodeShape place, TransitionNodeShape trans, TriBinding twin) { + TriBinding tri = new TriBinding(); + PNBindingShape lb = (PNBindingShape) twin.getLeft(); + PNBindingShape rb = (PNBindingShape) twin.getMiddle(); + String t = ((PetriNetsShape)getContainerShape()).getWeightOrColor(); + PNBindingShape nb = new PNBindingShape(BindingType.DOWN, t); + nb.setParent(trans); + nb.setChild(place); + place.addToY(trans.getHeight()+30); + tri.addChild(lb); + tri.addChild(nb); + tri.addChild(rb); + trans.setChild(tri); + trans.setupDialogHelpers(); + getRedShape().setReady(false); + } + + public void deleteShape(AShape shape) { + if (shape instanceof AEventShape) { + ARootShape prev = (ARootShape) getContainerShape().getRoot(); + ARootShape next = prev.getSibling(); + while (next != null && next != shape) { + prev = next; + next = next.getSibling(); + } + if (next != null) { + prev.setSibling(next.getSibling()); + } + else { + automaton.refreshButtons(); + } + } + else { + AShape p = shape.getParent().getParent(); + if (p.getChild() instanceof TriBinding) { + TriBinding tri = (TriBinding)p.getChild(); + tri.delete(shape.getParent(), shape, false); + if (tri.getChild() == null) { + setCurrent(p); + getRedShape().setAttachTo(p); + return; + } + } + else if (shape.getChild() == null) { + p.setChild(null); + } + else { + AShape next = shape.getChild().getChild().getChild().getChild(); + p.setChild(next.getParent()); + ARootShape root = (ARootShape) getContainerShape().getRoot(); + if (root.getSibling() != null) { + shape.addToY(shape.getHeight()+30); + int delta = shape.getHeight()+30; + root.updateOtherBranches(shape, -delta); + } + } + } + getRedShape().setReady(false); + } + + @Override + public boolean isDeleteAllowed(AShape shape) { + if (shape instanceof AEventShape || shape.getChild() == null) { + return true; + } + if (shape.getParent().getParent().getParent() == null || + shape.getChild().getChild().getChild() == null) { + return false; + } + for (ABindingShape b : getBindings()) { + if (b.getChild().equals(shape)) { + return false; + } + } + return true; + } + + @Override + public boolean isInMainBranch(ABindingShape b) { + AShape p = b.getParent(); + while (p != null && !(p instanceof InvisibleNode)) { + p = p.getParent().getParent(); + } + return p != getContainerShape().getRoot(); + } + + @Override + public String getStringActionNo() { + return "" + GeneralContext.getInstance().getGraphicsPanel().getShapesContainer().getActionNoForPetriNets(); + } + + @Override + public AButtonsPanel getButtonsPanel() { + return pnButtonsPanel; + } + + @Override + public boolean isPetri() { + return true; + } + + @Override + public boolean isColored() { + return isColored; + } +} diff --git a/src/clp/edit/graphics/shapes/pn/PetriNetsShape.java b/src/clp/edit/graphics/shapes/pn/PetriNetsShape.java new file mode 100644 index 0000000..0d474bd --- /dev/null +++ b/src/clp/edit/graphics/shapes/pn/PetriNetsShape.java @@ -0,0 +1,138 @@ +package clp.edit.graphics.shapes.pn; + +import java.awt.Graphics; + +import clp.edit.dialog.ADialog; +import clp.edit.graphics.dial.PetriNetsDialog; +import clp.edit.graphics.dial.TransitionType; +import clp.edit.graphics.shapes.ABindingShape; +import clp.edit.graphics.shapes.AContainerShape; +import clp.edit.graphics.shapes.ContainerHelper; +import clp.edit.util.ColorSet; + +public class PetriNetsShape extends AContainerShape { + + private static final long serialVersionUID = -3146217438324352949L; + + transient private PetriNetsDialog dialog; + + private TransitionType defaultTransitionType; + + private boolean isColored; + + private ContainerHelper chelper; + + private String hname; + + /** + * CONSTRUCTOR + * + * @param width + * @param height + * @param text + * @param count + * @param isColored + */ + public PetriNetsShape(int width, int height, String text, int count, boolean isColored) { + super(width, height, text+count); + ColorSet color = isColored ? ColorSet.cpnBackground : ColorSet.wpnBackground; + hname = "G_HEAP"+count; + this.isColored = isColored; + super.setBackground(color.getLight()); + dialog = new PetriNetsDialog(text+count, this, isColored); + chelper = new ContainerHelper(count, getHighLevel()); + chelper.createTreeNodes(this, "PN_SCN", hname); + } + + @Override + public void paintShape(Graphics g, int offset, boolean b1, boolean b2) { + super.paintShape(g, offset, b1, b2); + if (getRoot() != null) { + getRoot().paintShape(g, offset); + } + } + + @Override + public void setChild(ABindingShape shape) { + } + + @Override + public ADialog getDialog() { + if (dialog == null) { + dialog = new PetriNetsDialog(getName(), this, isColored); + } + return dialog; + } + + public void setSimpleName(String name) { + super.setName(name); + } + + @Override + public StringBuilder getSource(String mscName) { + StringBuilder sb = new StringBuilder(); + sb.append("scenario " + getScenarioName() + " {\n"); + sb.append(" properties {\n"); + sb.append(" logic {\n"); + sb.append(" deactivation = MANUAL; // cell deactivation happens manually\n"); + sb.append(" level = 2; // the are 2 (0, 1) activity levels for a cell\n"); + sb.append(" }\n"); + sb.append(" queues {\n"); + sb.append(" qa income=Qe;\n"); + sb.append(" qi income=Qe;\n"); + sb.append(" }\n"); + sb.append(" tasks {\n"); + sb.append(" ACTIVATOR operatingOn qi passingTo qa;\n"); + sb.append(" EXECUTOR operatingOn qa;\n"); + sb.append(" DEACTIVATOR operatingOn qa passingTo qi;\n"); + sb.append(" }\n"); + sb.append(" }\n"); + sb.append("}\n\n"); + return sb; + } + + /** + * @return the defaultTransitionType + */ + public TransitionType getDefaultTransitionType() { + return defaultTransitionType; + } + + /** + * @param defaultTransitionType the defaultTransitionType to set + */ + public void setDefaultTransitionType(TransitionType defaultTransitionType) { + this.defaultTransitionType = defaultTransitionType; + } + + public String getWeightOrColor() { + return ((PetriNetsDialog)getDialog()).getDefaultWeightOrColor(); + } + + public boolean isColored() { + return isColored; + } + + @Override + public void removeActor() { + chelper.removeActor("PN_SCN", getName()); + } + + public boolean rename(String oldName, String newName) { + return chelper.rename(oldName, newName); + } + + @Override + public String getScenarioName() { + return "PN_SCN"; + } + + @Override + public String getHeapNamePrefix() { + return hname; + } + + @Override + public void cacheFromTransients() { + } +} diff --git a/src/clp/edit/graphics/shapes/pn/PlaceNodeShape.java b/src/clp/edit/graphics/shapes/pn/PlaceNodeShape.java new file mode 100644 index 0000000..407b03c --- /dev/null +++ b/src/clp/edit/graphics/shapes/pn/PlaceNodeShape.java @@ -0,0 +1,415 @@ +package clp.edit.graphics.shapes.pn; + +import java.awt.Color; +import java.awt.Graphics; +import java.io.Serializable; +import java.util.ArrayList; + +import clp.edit.GeneralContext; +import clp.edit.graphics.dial.ActionOrStepDialog; +import clp.edit.graphics.dial.PNTransitionDialog; +import clp.edit.graphics.dial.PlaceDialog; +import clp.edit.graphics.dial.Token; +import clp.edit.graphics.panel.ControlsContainer; +import clp.edit.graphics.shapes.ABindingShape; +import clp.edit.graphics.shapes.AContainer; +import clp.edit.graphics.shapes.AShape; +import clp.edit.graphics.shapes.ActionShape; +import clp.edit.graphics.shapes.BindingType; +import clp.edit.graphics.shapes.util.CellInfo; +import clp.edit.handler.CLAppSourceHandler; +import clp.run.cel.Weightings; +import clp.run.res.Weighting; + +public class PlaceNodeShape extends ActionShape { + + private static final long serialVersionUID = -2747985167995681728L; + + public class ColorInfo implements Serializable { + private static final long serialVersionUID = 1973489769875258389L; + private char c; // color ref + private int dx; // relative x position + private int dy; // relative y position + + public char getC() { + return c; + } + public void setC(char c) { + this.c = c; + } + public String toString() { + return ""+c; + } + } + + private int placeNumber; + + private ColorInfo[] tokens; + + private PetriNetsShape petriNetsShape; + + transient private PlaceDialog dialog; + + private ColorInfo[] initialTokens; + + /** + * CONSTRUCTOR + * + * @param index + * @param pnShape + */ + public PlaceNodeShape(int index, PetriNetsShape pnShape) { + super(40, 40, "P"+index, "Place ", 1); + placeNumber = index; + petriNetsShape = pnShape; + dialog = (PlaceDialog) super.getDialog(); + } + + @Override + public void setParent(ABindingShape parent) { + super.setParent(parent); + if (parent.getParent() instanceof InvisibleNode) { + defineTokens(); + ((PlaceDialog)getDialog()).count(tokens); + initialTokens = tokens; + } + } + + public void resetTokens(CLAppSourceHandler clAppSourceHandler) { + tokens = initialTokens; + ((PlaceDialog)getDialog()).recount(tokens); + clAppSourceHandler.addTokensToRes(((PlaceDialog)getDialog()).getTokens(), getName()); + } + + // + private void defineTokens() { + if (petriNetsShape.isColored()) { + String s = petriNetsShape.getWeightOrColor(); + String[] sp = s.split("\\."); + tokens = new ColorInfo[sp.length]; + for (int i=0; i 0) { + ControlsContainer cc = GeneralContext.getInstance().getGraphicsPanel().getControlsContainer(); + cc.addTokensToRes(tokens, getName()); + } + } + + // + private void defineRelativePositions() { + if (tokens == null) { + return; + } + ColorInfo ci; + int coloredTokenNumber = tokens.length; + switch (coloredTokenNumber) { + case 1: + ci = tokens[0]; + ci.dx = -5; + ci.dy = 16; + break; + case 2: + ci = tokens[0]; + ci.dx = -15; + ci.dy = 14; + ci = tokens[1]; + ci.dx = 8; + ci.dy = 14; + break; + case 3: + ci = tokens[0]; + ci.dx = -15; + ci.dy = 12; + ci = tokens[1]; + ci.dx = 8; + ci.dy = 12; + ci = tokens[2]; + ci.dx = -5; + ci.dy = 20; + break; + case 4: + ci = tokens[0]; + ci.dx = -16; + ci.dy = 13; + ci = tokens[1]; + ci.dx = 7; + ci.dy = 13; + ci = tokens[2]; + ci.dx = -10; + ci.dy = 25; + ci = tokens[3]; + ci.dx = 3; + ci.dy = 25; + break; + case 5: + ci = tokens[0]; + ci.dx = -16; + ci.dy = 13; + ci = tokens[1]; + ci.dx = 7; + ci.dy = 13; + ci = tokens[2]; + ci.dx = -10; + ci.dy = 25; + ci = tokens[3]; + ci.dx = 3; + ci.dy = 25; + ci = tokens[4]; + ci.dx = -5; + ci.dy = 3; + break; + case 6: + ci = tokens[0]; + ci.dx = -16; + ci.dy = 13; + ci = tokens[1]; + ci.dx = 7; + ci.dy = 13; + ci = tokens[2]; + ci.dx = -10; + ci.dy = 25; + ci = tokens[3]; + ci.dx = 3; + ci.dy = 25; + ci = tokens[4]; + ci.dx = -10; + ci.dy = 3; + ci = tokens[5]; + ci.dx = 3; + ci.dy = 3; + break; + + default: + break; + } + } + + @Override + public void paintShape(Graphics g, int offset) { + int x = getPX()+offset; + int y = getPY(); + Color c = g.getColor(); + if (getBgcolor() == null) { + if (isSelected()) { + g.setColor(Color.lightGray); + } + else { + g.setColor(tokens == null || tokens.length < 7 ? Color.white : Color.red); + g.fillOval(x-20, y, 40, 40); + g.setColor(Color.black); + } + } + else { + g.setColor(getBgcolor()); + g.fillOval(x-24, y-4, 48, 48); + g.setColor(Color.white); + g.fillOval(x-20, y, 40, 40); + g.setColor(Color.black); + } + if (tokens == null || tokens.length < 7) { + g.drawOval(x-20, y, 40, 40); + drawTokens(g, x, y); + } + else { + g.setColor(Color.red); + g.fillOval(x-20, y, 40, 40); + } + + g.setColor(c); + + paintInstructionsFromShape(g, offset); + + g.drawString(""+placeNumber, x-5, getPY()+15); + if (getChild() != null) { + super.checkDownType(); + getChild().paintShape(g, offset); + } + } + + // + private void drawTokens(Graphics g, int x, int y) { + if (tokens != null) { + Color c = g.getColor(); + for (ColorInfo ci : tokens) { + g.setColor(getColor(ci.c)); + g.fillOval(x+ci.dx, y+ci.dy, 10, 10); + + } + g.setColor(c); + } + } + + // + private Color getColor(char c) { + switch (c) { + case 'R': + return Color.red; + case 'G': + return Color.green; + case 'B': + return Color.blue; + case 'Y': + return Color.yellow; + case 'O': + return Color.orange; + case 'C': + return Color.cyan; + + default: + break; + } + return Color.black; + } + + @Override + public void setChild(AShape shape, BindingType bindingType) { + String t = petriNetsShape.getWeightOrColor(); + PNBindingShape b = new PNBindingShape(bindingType, t); + setChild(b); + b.setChild(shape); + } + + @Override + public void setupInstructions() { + super.setupInstructions(); + tokens = ((PlaceDialog)getDialog()).createTokens(this); + initialTokens = tokens; + defineRelativePositions(); + TransitionNodeShape tr = getTransitionAbowe(); + if (tr != null) { + updateCellInitialWeighting(); + } + } + + // + private TransitionNodeShape getTransitionAbowe() { + ABindingShape b = getParent(); + if (b != null) { + AShape s = b.getParent(); + if (s instanceof TransitionNodeShape) { + return (TransitionNodeShape) b.getParent(); + } + } + return null; + } + + public void setTransportationDomainFromEntry(ABindingShape b) { + setTransportationDomainForEntries(); + } + + // + public void setTransportationDomainForEntries() { + ArrayList list = getEntries(); + if (!getEntries().contains(getParent())) { + list.add(0, getParent()); + } + } + + public void setTokens(Weightings weightings) { + ArrayList list = new ArrayList<>(); + Weighting w = weightings.getWeighting(); + if (w != null) { + list.add(w); + } + list.addAll(weightings.getWeightings()); + ArrayList cis = new ArrayList<>(); + for (Weighting lw : list) { + for (int i=0; i 0); + if (getChild() != null) { + if (!getChild().generateCode(container)) { + return false; + } + } + } + return true; + } + + @Override + public void cacheFromTransients() { + } +} diff --git a/src/clp/edit/graphics/shapes/pn/TransitionNodeShape.java b/src/clp/edit/graphics/shapes/pn/TransitionNodeShape.java new file mode 100644 index 0000000..f20259f --- /dev/null +++ b/src/clp/edit/graphics/shapes/pn/TransitionNodeShape.java @@ -0,0 +1,341 @@ +package clp.edit.graphics.shapes.pn; + +import java.util.ArrayList; +import java.util.List; + +import clp.edit.GeneralContext; +import clp.edit.dialog.ADialog; +import clp.edit.graphics.dial.PNCTransitionDialog; +import clp.edit.graphics.dial.PNTransitionDialog; +import clp.edit.graphics.dial.PNTransitionDialog.TransitionPosition; +import clp.edit.graphics.dial.TransitionType; +import clp.edit.graphics.shapes.ABindingShape; +import clp.edit.graphics.shapes.AContainer; +import clp.edit.graphics.shapes.AShape; +import clp.edit.graphics.shapes.ATransitionShape; +import clp.edit.graphics.shapes.BindingType; +import clp.edit.graphics.shapes.TriBinding; +import clp.edit.graphics.shapes.util.CellInfo; +import clp.run.res.Unit; + +public class TransitionNodeShape extends ATransitionShape { + + private static final long serialVersionUID = 1743153968064818872L; + + transient private PNTransitionDialog dialog; + private PetriNetsShape petriNetsShape; + + private String trName; + private TransitionPosition trPos; + private Unit selectedUnit; + private char selectedArrow; + + + /** + * CONSTRUCTOR + * + * @param pnShape + * @param tt: transition type + * @param tp: transition position + */ + public TransitionNodeShape(PetriNetsShape pnShape, TransitionType tt, TransitionPosition tp) { + super(tt); + trName = "Tr"+GeneralContext.getInstance().getGraphicsPanel().getShapesContainer().getTrIncrementingCount(); + petriNetsShape = pnShape; + this.trPos = tp; + dialog = pnShape.isColored() ? + new PNCTransitionDialog(GeneralContext.getInstance().getFrame(), pnShape, this, tt, tp, 340) : + new PNTransitionDialog(GeneralContext.getInstance().getFrame(), pnShape, this, tt, tp, 320); + setName(dialog.getTransitionText()); + } + + @Override + public void setChild(AShape shape, BindingType bindingType) { + String t = petriNetsShape.getWeightOrColor(); + PNBindingShape b = new PNBindingShape(bindingType, t); + setChild(b); + b.setChild(shape); + } + + @Override + public ADialog getDialog() { + if (dialog == null) { + dialog = petriNetsShape.isColored() ? + new PNCTransitionDialog(GeneralContext.getInstance().getFrame(), petriNetsShape, this, getTrType(), trPos, 340) : + new PNTransitionDialog(GeneralContext.getInstance().getFrame(), petriNetsShape, this, getTrType(), trPos, 320); + dialog.reinitializeHelpers(); + dialog.pnsetup(null); + if (dialog.getDelayInfo() != null) { + dialog.getDelayInfo().setUnit(selectedUnit); + } + if (dialog.getClassicInfo() != null) { + dialog.getClassicInfo().setArrow(selectedArrow); + } + } + return dialog; + } + + public PNTransitionDialog getCustDialog() { + return (PNTransitionDialog) getDialog(); + } + + @Override + public void setName(String name) { + super.setName(name); + if (getChild() != null) { + ABindingShape b = getChild(); + if (b instanceof TriBinding) { + TriBinding t = (TriBinding)b; + List bindings = new ArrayList<>(); + if (t.getLeft() != null) { + bindings.add(t.getLeft()); + } + bindings.add(t.getMiddle()); + if (t.getRight() != null) { + bindings.add(t.getRight()); + } + bindings.remove(0); + } + } + } + + /** + * @return the upleft + */ + public ABindingShape getUpleft() { + if (getParent() instanceof TriBinding) { + return ((TriBinding)getParent()).getLeft(); + } + return null; + } + + /** + * @param upleft the upleft to set + */ + public void setUpleft(ABindingShape upleft) { + if (getParent() instanceof TriBinding) { + ((TriBinding)getParent()).setLeft(upleft); + } + else { + TriBinding tri = new TriBinding(); + tri.setMiddle(getParent()); + tri.setLeft(upleft); + tri.setParent(getParent().getParent()); + setParent(tri); + } + getCustDialog().pnsetup(null); + } + + /** + * @return the upright + */ + public ABindingShape getUpright() { + if (getParent() instanceof TriBinding) { + return ((TriBinding)getParent()).getRight(); + } + return null; + } + + /** + * @param upright the upright to set + */ + public void setUpright(ABindingShape upright) { + if (getParent() instanceof TriBinding) { + ((TriBinding)getParent()).setRight(upright); + } + else { + TriBinding tri = new TriBinding(); + tri.setMiddle(getParent()); + tri.setRight(upright); + tri.setParent(getParent().getParent()); + setParent(tri); + } + getCustDialog().pnsetup(null); + } + + @Override + public boolean generateActiveCode(AContainer container) { + if (getParent().getParent() instanceof InvisibleNode) { + if (getChild() != null) { + String name = getChild().getChild().getName(); + String init_name = "INIT_"+name; + if (!container.isRegistered(init_name)) { + CellInfo info = new CellInfo(init_name); + String code = getDeactivationCondition(name); + if (code != null) { + info.setDd(" DD { " + code + "; }\n"); + } + container.register(init_name, info, true); + } + return getChild().generateCode(container); + } + return true; + } + return super.generateActiveCode(container); + } + + // + private String getDeactivationCondition(String name) { + return getCustDialog().getDeactivationCondition(name, 'P', null); + } + + @Override + public String getActivationCondition(ABindingShape bs) { + String s = ""; + ABindingShape b = getParent(); + if (b instanceof TriBinding) { + s = gatherUpTokensFromDialog((TriBinding) b); + } + else { + AShape p = b.getParent(); + String marks = getCustDialog().getCheckMarks(); + if (marks != null) { + s = getTrName() + " { " + p.getName() + " " + marks + " } "; + p = bs.getParent().getParent().getParent(); + String c = getCustDialog().getActivationCondition(null, 'P', p); + if (c != null) { + s += "AND " + c; + } + } + else { + s = getCustDialog().getActivationCondition("INIT_"+getChild().getChild().getName(), 'P', getChild().getChild()); + } + } + b = getChild(); + String marks; + if (b instanceof TriBinding) { + marks = getSetMarks((TriBinding) b, bs); + } + else { + marks = getCustDialog().getSetMarks(); + } + if (marks != null) { + s += " > " + marks; + } + return s; + } + + // + protected String gatherUpTokensFromDialog(TriBinding tb) { + StringBuilder buffer = new StringBuilder(); + PlaceNodeShape tbp = (PlaceNodeShape) tb.getParent(); + PlaceNodeShape p; + String sl = null; + String sm = null; + String sr = null; + buffer.append(getTrName() + " { "); + if (tb.getLeft() != null) { + p = (PlaceNodeShape) tb.getLeft().getParent(); + if (p == null) { + p = tbp; + } + else { + sl = getCustDialog().getActivationCondition(null, 'P', p); + } + buffer.append(p.getName() + "[ "+getCustDialog().getUplefthelper().getMarks()+" ], "); + } + p = tbp; + sm = getCustDialog().getActivationCondition(null, 'P', p); + buffer.append(p.getName() + "[ "+getCustDialog().getUphelper().getMarks()+" ]"); + if (tb.getRight() != null) { + p = (PlaceNodeShape) tb.getRight().getParent(); + if (p == null) { + p = tbp; + } + else { + sr = getCustDialog().getActivationCondition(null, 'P', p); + } + buffer.append(", " + p.getName() + "[ "+getCustDialog().getUprighthelper().getMarks()+" ] "); + } + buffer.append(" }"); + return fillBuffer(buffer, sl, sm, sr); + } + + // + private String fillBuffer(StringBuilder buffer, String sl, String sm, String sr) { + String str = null; + if (sl != null && !sl.isEmpty()) { + str = sl; + } + if (sm != null && !sm.isEmpty()) { + if (str == null) { + str = sm; + } + else if (!sm.equals(str)) { + str += " AND " + sm; + } + } + if (sr != null && !sr.isEmpty()) { + if (str == null) { + str = sr; + } + else if (!sr.equals(str) && !str.contains(" AND "+sr)) { + str += " AND " + sr; + } + } + if (buffer.length() == 0) { + buffer.append(str); + } + else { + buffer.append(" AND " + str); + } + return buffer.toString(); + } + + // + private String getSetMarks(TriBinding tb, ABindingShape bs) { + if (tb.getLeft() == bs) { + return "[ " + getCustDialog().getDownlefthelper().getMarks() + " ]"; + } + if (tb.getMiddle() == bs) { + return "[ " + getCustDialog().getDownhelper().getMarks() + " ]"; + } + if (tb.getRight() == bs) { + return "[ " + getCustDialog().getDownrighthelper().getMarks() + " ]"; + } + return null; + } + + @Override + public String getDeactivationCondition() { + if (getChild() instanceof TriBinding) { + TriBinding tri = (TriBinding) getChild(); + return tri.getDeactivationCondition(this, getCustDialog()); + } + else if (getChild() != null) { + AShape chld = getChild().getChild(); + addInputVariable(chld.getName(), chld.getDesc(), null); + return getCustDialog().getDeactivationCondition(chld.getName(), 'P', chld); + } + AShape p = getParent().getParent(); + return getCustDialog().getDeactivationCondition("FINAL_"+p.getName(), 'F', p); + } + + /** + * @return the trName + */ + public String getTrName() { + return "/ " + trName + " /"; + } + + public void setupDialogHelpers() { + getCustDialog().pnsetup(null); + } + + /** + * @return the trPos + */ + public synchronized TransitionPosition getTrPos() { + return trPos; + } + + @Override + public void cacheFromTransients() { + if (getCustDialog().getDelayInfo() != null) { + selectedUnit = getCustDialog().getDelayInfo().getUnit(); + } + if (getCustDialog().getClassicInfo() != null) { + selectedArrow = getCustDialog().getClassicInfo().getArrow(); + } + } +} diff --git a/src/clp/edit/graphics/shapes/util/CellInfo.java b/src/clp/edit/graphics/shapes/util/CellInfo.java new file mode 100644 index 0000000..a2d3f47 --- /dev/null +++ b/src/clp/edit/graphics/shapes/util/CellInfo.java @@ -0,0 +1,67 @@ +package clp.edit.graphics.shapes.util; + +import java.io.Serializable; +import java.util.List; + +public class CellInfo implements Serializable { + + private static final long serialVersionUID = 5107953197864289156L; + + private String name; + private String ad; + private String dd; + private List xd; + + public CellInfo(String string) { + name = string; + } + + /** + * @return the name + */ + public String getName() { + return name; + } + /** + * @param name the name to set + */ + public void setName(String name) { + this.name = name; + } + /** + * @return the ad + */ + public String getAd() { + return ad; + } + /** + * @param ad the ad to set + */ + public void setAd(String ad) { + this.ad = ad; + } + /** + * @return the dd + */ + public String getDd() { + return dd; + } + /** + * @param dd the dd to set + */ + public void setDd(String dd) { + this.dd = dd; + } + /** + * @return the xd + */ + public List getXd() { + return xd; + } + /** + * @param xd the xd to set + */ + public void setXd(List xd) { + this.xd = xd; + } +} diff --git a/src/clp/edit/graphics/shapes/util/ResourceHelper.java b/src/clp/edit/graphics/shapes/util/ResourceHelper.java new file mode 100644 index 0000000..79a5fe5 --- /dev/null +++ b/src/clp/edit/graphics/shapes/util/ResourceHelper.java @@ -0,0 +1,292 @@ +package clp.edit.graphics.shapes.util; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Hashtable; +import java.util.List; + +import clp.edit.GeneralContext; +import clp.edit.graphics.code.gui.elts.GuiInfo; +import clp.edit.graphics.code.java.JavaContext.BciInfo; +import clp.edit.graphics.code.web.WebContext.WebInfo; +import clp.edit.graphics.dial.Token; +import clp.edit.graphics.panel.ControlsContainer; +import clp.edit.graphics.panel.SimulationHelper; +import clp.edit.graphics.shapes.ActionShape.LibInfo; +import clp.run.res.Unit; +import clp.run.res.VarType; + +public class ResourceHelper { + + private static final ResourceHelper instance = new ResourceHelper(); + + public static ResourceHelper getInstance() { + return instance; + } + + private ResourceHelper() {} + + /** + * extracts variables out of given condition string and add it to the list of input resources + * + * @param cnd + * @param desc + * @param type + * @param isToken + * @param inputResources + */ + public void addInputVariable(String cnd, String desc, VarType type, boolean isToken, Hashtable inputResources) { + String[] names = extractNames(cnd); + for (String n : names) { + if (!n.isBlank()) { + InputResourcesInfo ri = null; + switch (n.charAt(0)) { + case 'A': + case 'X': + case 'P': + if (!isNumerical(n.substring(1))) { + ri = new InputResourcesInfo(desc, type); + } + else { + if (isToken) { + ri = new InputResourcesInfo(new Token[0]); + } + else { + ri = new InputResourcesInfo(); + } + } + break; + case '<': + case '>': + break; + + default: + try { + Integer.parseInt(n); + } + catch (NumberFormatException e) { + ri = new InputResourcesInfo(desc, type); + } + break; + } + if (ri != null) { + inputResources.put(n, ri); + } + } + } + } + + /** + * add variables coming from a java call + * + * @param variables + * @param inputResources + * @param outputResources + * @return + */ + public void addVariables(ArrayList variables, Hashtable inputResources, Hashtable outputResources) { + for (String text : variables) { + if (text.isBlank()) { + continue; + } + String[] sp = text.split("/"); + VarType tp = VarType.valueOf("T"+sp[1]); + if (sp.length > 2 && sp[2].equals("D")) { + OutputResourcesInfo ro = new OutputResourcesInfo(tp); + outputResources.put(sp[0], ro); + } + else { + InputResourcesInfo ri = new InputResourcesInfo(tp); + inputResources.put(sp[0], ri); + } + } + } + + /** + * add output variable of given name string and add it to the list of output resources + * + * @param name + * @param varType + * @param outputResources + */ + public void addOutputVariable(String name, VarType varType, Hashtable outputResources) { + OutputResourcesInfo ro = new OutputResourcesInfo(varType); + outputResources.put(name, ro); + } + + public void setTokensForCell(Token[] tokens, String name, Hashtable inputResources) { + InputResourcesInfo ri = new InputResourcesInfo(tokens); + inputResources.put(name, ri); + } + + public void addDelay(String step, String timeIdentifier, int delay, Unit unit, boolean isCyclic, Hashtable inputResources) { + InputResourcesInfo ri = new InputResourcesInfo(timeIdentifier, delay, unit, isCyclic); + inputResources.put(step, ri); + } + + // + private boolean isNumerical(String string) { + try { + Integer.parseInt(string); + return true; + } + catch (NumberFormatException e) { + return false; + } + } + + // + private String[] extractNames(String name) { + name = name.replaceAll("AND", " "); + name = name.replaceAll("OR", " "); + name = name.replaceAll("NOT", " "); + name = replace(name, '('); + name = replace(name, ')'); + name = replace(name, ')'); + name = replace(name, '<'); + name = replace(name, '>'); + name = replace(name, ','); + name = replace(name, '='); + return name.split(" "); + } + + // + private String replace(String name, char c) { + int i = name.indexOf(c); + while (i >= 0) { + name = name.substring(0, i) + " " + name.substring(i+1); + i = name.indexOf(c); + } + return name; + } + + public void declareLibs(List libs) { + if (!libs.isEmpty()) { + SimulationHelper sh = GeneralContext.getInstance().getGraphicsPanel().getControlsContainer().getSimulationHelper(); + for (LibInfo li : libs) { + sh.addToLibs(li.getUsedLib(), li.isJar()); + } + } + } + + public void declareUI(GuiInfo ui, String name) { + if (ui != null) { + ControlsContainer cc = GeneralContext.getInstance().getGraphicsPanel().getControlsContainer(); + cc.addVariable(name, ui.getUiVar()); + cc.getSimulationHelper().addVariables(ui.getVariables()); + } + } + + public void declareBCI(BciInfo bci, String name) { + if (bci != null) { + ControlsContainer cc = GeneralContext.getInstance().getGraphicsPanel().getControlsContainer(); + cc.addVariable(name, bci.getBciVar()); + cc.getSimulationHelper().addVariables(bci.getVariables()); + } + } + + public void declareWEB(WebInfo web, String name) { + if (web != null) { + ControlsContainer cc = GeneralContext.getInstance().getGraphicsPanel().getControlsContainer(); + cc.addVariable(name, web.getWebVar()); + } + } + + public void declareIn(Hashtable inputResources) { + if (!inputResources.isEmpty()) { + SimulationHelper sh = GeneralContext.getInstance().getGraphicsPanel().getControlsContainer().getSimulationHelper(); + for (String name : inputResources.keySet()) { + InputResourcesInfo ri = inputResources.get(name); + switch(ri.itype) { + case VAR: + sh.addInputVariableToRes(name, ri.desc, ri.type); + break; + case DUMMY: + sh.addVariableToRes(name, ri.type); + break; + case EVENT: + sh.addCellEventToRes(name); + break; + case TOKEN: + sh.addTokensToRes(ri.tokens, name); + break; + case DELAY: + sh.addDelay(name, ri.timeIdentifier, ri.delay, ri.unit, ri.isCyclic); + break; + } + } + } + } + + public void declareOut(Hashtable outputResources) { + if (!outputResources.isEmpty()) { + ControlsContainer cc = GeneralContext.getInstance().getGraphicsPanel().getControlsContainer(); + for (String name : outputResources.keySet()) { + OutputResourcesInfo ro = outputResources.get(name); + if (!cc.addOutputVariable(name, ro.type)) { + System.err.printf("variable %s already declared with another type\n", name); + } + } + } + } + + + //================================================================= + + public static enum InfoType { + VAR, EVENT, TOKEN, DELAY, DUMMY; + } + + public static class InputResourcesInfo implements Serializable { + private static final long serialVersionUID = 4735529696548584294L; + + private InfoType itype; + + private String desc; + private VarType type; + private Token[] tokens; + + private String timeIdentifier; + private int delay; + private Unit unit; + private boolean isCyclic; + + public InputResourcesInfo(VarType t) { + type = t; + itype = InfoType.DUMMY; + } + + public InputResourcesInfo(String d, VarType t) { + desc = d; + type = t; + itype = InfoType.VAR; + } + + public InputResourcesInfo(Token[] t) { + tokens = t; + itype = InfoType.TOKEN; + } + + public InputResourcesInfo() { + itype = InfoType.EVENT; + } + + public InputResourcesInfo(String t, int d, Unit u, boolean b) { + itype = InfoType.DELAY; + timeIdentifier = t; + delay = d; + unit = u; + isCyclic = b; + } + } + + public static class OutputResourcesInfo implements Serializable { + private static final long serialVersionUID = -3836670690239533614L; + + private VarType type; + + public OutputResourcesInfo(VarType t) { + type = t; + } + } +}