// $Id: RulePopupMenu.java,v 1.18 2010/09/19 16:25:01 olga Exp $ package agg.gui.popupmenu; import java.awt.Point; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.List; import java.util.Vector; import javax.swing.JCheckBoxMenuItem; import javax.swing.JMenuItem; import javax.swing.JOptionPane; import javax.swing.JPopupMenu; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.TreePath; import agg.editor.impl.EdNestedApplCond; import agg.editor.impl.EdRule; import agg.editor.impl.EdRuleScheme; import agg.gui.treeview.GraGraTreeView; import agg.gui.treeview.dialog.FormulaGraphGUI; import agg.gui.treeview.dialog.RuleSignatureDialog; import agg.gui.treeview.nodedata.ApplFormulaTreeNodeData; import agg.gui.treeview.nodedata.GraGraTreeNodeData; import agg.gui.treeview.path.GrammarTreeNode; import agg.gui.AGGAppl; import agg.xt_basis.NestedApplCond; @SuppressWarnings("serial") public class RulePopupMenu extends JPopupMenu { public RulePopupMenu(GraGraTreeView tree) { super("Rule"); this.treeView = tree; this.miAC = new JMenuItem("New GAC (General Application Condition)"); this.add(miAC); this.miAC.setActionCommand("newNestedAC"); this.miAC.addActionListener(this.treeView.getActionAdapter()); this.miAC1 = new JMenuItem("Make GAC due to RHS"); this.add(miAC1); this.miAC1.setActionCommand("makeGACFromRHS"); this.miAC1.addActionListener(this.treeView.getActionAdapter()); this.miFormula = new JMenuItem("Set Formula above GACs"); this.add(miFormula); this.miFormula.setActionCommand("setFormulaAboveACs"); this.miFormula.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { setFormula(); } }); addSeparator(); this.miNAC = add(new JMenuItem( "New NAC Shift+Alt+N")); this.miNAC.setActionCommand("newNAC"); this.miNAC.addActionListener(this.treeView.getActionAdapter()); // miNAC.setMnemonic('N'); this.miNAC1 = add(new JMenuItem( "Make NAC due to RHS ")); this.miNAC1.setActionCommand("makeNACFromRHS"); this.miNAC1.addActionListener(this.treeView.getActionAdapter()); addSeparator(); this.miPAC = add(new JMenuItem("New PAC "));// Shift+Alt+A this.miPAC.setActionCommand("newPAC"); this.miPAC.addActionListener(this.treeView.getActionAdapter()); // miPAC.setMnemonic('P'); addSeparator(); this.miPostAC = add(new JMenuItem("Create Post Conditions")); this.miPostAC.setActionCommand("convertAtomicsOfRule"); this.miPostAC.addActionListener(this.treeView.getActionAdapter()); this.miPostACdel = add(new JMenuItem("Delete Post Conditions")); this.miPostACdel.setActionCommand("deleteRuleConstraints"); this.miPostACdel.addActionListener(this.treeView.getActionAdapter()); addSeparator(); this.miLayer = add(new JMenuItem( "Set Layer Shift+Alt+L")); this.miLayer.setActionCommand("setRuleLayer"); this.miLayer.addActionListener(this.treeView.getActionAdapter()); // miLayer.setMnemonic('L'); this.miPriority = add(new JMenuItem( "Set Priority Shift+Alt+P")); this.miPriority.setActionCommand("setRulePriority"); this.miPriority.addActionListener(this.treeView.getActionAdapter()); // miPriority.setMnemonic('P'); addSeparator(); this.miAttrContext = add(new JMenuItem("Attribute Context")); this.miAttrContext.setActionCommand("attrContext"); this.miAttrContext.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { ((AGGAppl)treeView.getFrame()).getGraGraEditor().loadRuleAttrContextInEditor(rule); } }); this.miSignature = add(new JMenuItem("Signature")); this.miSignature.setActionCommand("ruleSignature"); this.miSignature.setToolTipText(RuleSignatureDialog.getToolTipText()); this.miSignature.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { // RuleSignatureDialog.infoMsg(); (new RuleSignatureDialog(treeView.getFrame(), new Point(200,200), rule)).setVisible(true); } }); addSeparator(); this.miParallelApply = new JCheckBoxMenuItem("Parallel Matching"); this.miParallelApply.setActionCommand("allowParallelApply"); this.miParallelApply.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { if (((JCheckBoxMenuItem) e.getSource()).isSelected()) RulePopupMenu.this.rule.getBasisRule().setParallelMatchingEnabled(true); else RulePopupMenu.this.rule.getBasisRule().setParallelMatchingEnabled(false); } }); add(this.miParallelApply); addSeparator(); this.miMove = add(new JMenuItem("Move")); this.miMove.setActionCommand("moveRule"); this.miMove.addActionListener(this.treeView.getActionAdapter()); // miMove.setMnemonic('M'); addSeparator(); this.miCopy = add(new JMenuItem( "Copy Shift+Alt+D")); this.miCopy.setActionCommand("copyRule"); this.miCopy.addActionListener(this.treeView.getActionAdapter()); this.miInverse = add(new JMenuItem("Make Inverse Rule")); this.miInverse.setActionCommand("reverseRule"); this.miInverse.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { reverseRule(); } }); this.miMinimal = add(new JMenuItem("Make Minimal Rule")); this.miMinimal.setActionCommand("minimalRule"); this.miMinimal.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { minimalRule(); } }); this.miMakeRS = add(new JMenuItem("Make Rule Scheme")); this.miMakeRS.setActionCommand("makeRuleScheme"); // this.miMakeRS.addActionListener(this.treeView); this.miMakeRS.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { makeRuleScheme(); } }); // miConcurrent = add(new JMenuItem("Make Disjoint Concurrent Rule With Next Rule")); // miConcurrent.setActionCommand("concurrentRule"); // miConcurrent.addActionListener(treeView); addSeparator(); this.miDelete = add(new JMenuItem( "Delete Delete")); this.miDelete.setActionCommand("deleteRule"); this.miDelete.addActionListener(this.treeView.getActionAdapter()); // miDelete.setMnemonic('D'); addSeparator(); this.miDisabled = new JCheckBoxMenuItem("disabled"); this.miDisabled.setActionCommand("disableRule"); this.miDisabled.addActionListener(this.treeView.getActionAdapter()); add(this.miDisabled); addSeparator(); this.miAnimated = new JCheckBoxMenuItem("animated"); this.miAnimated.setActionCommand("animatedRule"); // this.miAnimated.addActionListener(treeView); this.miAnimated.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { RulePopupMenu.this.rule.setAnimated(((JCheckBoxMenuItem) e.getSource()).isSelected()); } }); add(this.miAnimated); addSeparator(); this.miWait = new JCheckBoxMenuItem("Wait Before Applying Rule"); this.miWait.setActionCommand("waitBeforeApplyRule"); // this.miWait.addActionListener(treeView); this.miWait.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { RulePopupMenu.this.rule.getBasisRule().setWaitBeforeApplyEnabled(((JCheckBoxMenuItem) e.getSource()).isSelected()); } }); add(this.miWait); addSeparator(); this.miComment = add(new JMenuItem("Textual Comments")); // miComment = new JMenuItem("Textual Comments"); this.miComment.setActionCommand("commentRule"); this.miComment.addActionListener(this.treeView.getActionAdapter()); // miComment.setMnemonic('T'); pack(); setBorderPainted(true); } public boolean invoked(int x, int y) { if (this.treeView == null) { return false; } if (this.treeView.getTree().getRowForLocation(x, y) != -1) { int pl = this.treeView.getTree().getPathForLocation(x, y).getPath().length; if (pl == 3) { this.path = this.treeView.getTree().getPathForLocation(x, y); this.node = (DefaultMutableTreeNode) this.path.getLastPathComponent(); this.data = (GraGraTreeNodeData) this.node.getUserObject(); this.rule = this.treeView.getRule((DefaultMutableTreeNode) this.path .getLastPathComponent()); if (this.rule != null) { GrammarTreeNode.expand(this.treeView, this.node, this.path); this.posX = x; this.posY = y; setAllEnabled(true); this.miDisabled.setSelected(!this.rule.getBasisRule().isEnabled()); this.miParallelApply.setSelected(this.rule.getBasisRule().isParallelApplyEnabled()); this.miAnimated.setEnabled(this.rule.getTypeSet().getTypeGraph() != null && !this.rule.getTypeSet().getTypeGraph().getArcs().isEmpty()); if (this.miAnimated.isEnabled()) this.miAnimated.setSelected(this.rule.isAnimated()); this.miWait.setSelected(this.rule.getBasisRule().isWaitBeforeApplyEnabled()); return true; } } } return false; } private void setAllEnabled(boolean b) { this.miDelete.setEnabled(b); this.miAC.setEnabled(b); this.miAC1.setEnabled(b); this.miFormula.setEnabled(b); this.miNAC.setEnabled(b); this.miNAC1.setEnabled(b); this.miPAC.setEnabled(b); this.miDisabled.setEnabled(b); this.miPostAC.setEnabled(b); this.miPostACdel.setEnabled(b); this.miLayer.setEnabled(b); this.miPriority.setEnabled(b); this.miCopy.setEnabled(b); this.miInverse.setEnabled(b); this.miMakeRS.setEnabled(b); // this.miConcurrent.setEnabled(b); this.miMove.setEnabled(b); this.miParallelApply.setEnabled(b); this.miAnimated.setEnabled(b); this.miWait.setEnabled(b); } void setFormula() { String ownerName = "rule : "+this.rule.getBasisRule().getName(); FormulaGraphGUI d = new FormulaGraphGUI(this.treeView.getFrame(), ownerName, " Graph editor of Formula above General Application Conditions ", " An empty graph is the case where all nodes are connected by AND.", true); d.setExportJPEG(this.treeView.getGraphicsExportJPEG()); String oldformula = this.rule.getBasisRule().getFormulaStr(); // List<String> allVars = this.rule.getBasisRule().getNameOfEnabledACs(); List<EdNestedApplCond> allNestedACs = this.rule.getEnabledACs(); List<NestedApplCond> list = makeFrom(allNestedACs); d.setVarsAsObjs(allNestedACs, oldformula); d.setLocation(this.posX+20, this.posY+20); while (true) { d.setVisible(true); if (!d.isCanceled()) { boolean formulaChanged = d.isChanged(); String f = d.getFormula(); if (!this.rule.getBasisRule().setFormula(f, list)) { JOptionPane .showMessageDialog( this.treeView.getFrame(), "The formula definition failed. Please correct.", " Formula failed ", JOptionPane.WARNING_MESSAGE); continue; } else { f = this.rule.getBasisRule().getFormulaStr(); } if (formulaChanged) { insertFormulaIntoRuleTreeNode(f, allNestedACs); this.rule.getGraGra().setChanged(true); break; } else break; } else break; } } private List<NestedApplCond> makeFrom( List<EdNestedApplCond> list) { final List<NestedApplCond> result = new Vector<NestedApplCond>(list.size(), 0); for (int i=0; i<list.size(); i++) { result.add(list.get(i).getNestedMorphism()); } return result; } void insertFormulaIntoRuleTreeNode( final String f, final List<EdNestedApplCond> allVarsObj) { if (f.length() > 0) { Object child = this.treeView.getTreeModel().getChild(this.node, 0); if (child != null) { // remove existing formula from rule subtree if (((GraGraTreeNodeData) ((DefaultMutableTreeNode) child) .getUserObject()).isApplFormula()) { this.treeView.getTreeModel().removeNodeFromParent((DefaultMutableTreeNode)child); } // add formula tree node into rule subtree if (!"true".equals(f)) { final GraGraTreeNodeData conddata = new ApplFormulaTreeNodeData(f, true, this.rule); conddata.setString(f); final DefaultMutableTreeNode condnode = new DefaultMutableTreeNode( conddata); conddata.setTreeNode(condnode); this.treeView.getTreeModel().insertNodeInto(condnode, this.node, 0); } } } } public void enableNestedApplCond(boolean b) { this.enableNestedAC = b; } void reverseRule() { if (this.path == null) { String s = "Bad selection.\n Please select a rule."; JOptionPane.showMessageDialog(null, s, "", JOptionPane.WARNING_MESSAGE); return; } final DefaultMutableTreeNode node = (DefaultMutableTreeNode) this.path.getLastPathComponent(); GraGraTreeNodeData data = (GraGraTreeNodeData) node.getUserObject(); TreePath graPath = this.path.getParentPath(); DefaultMutableTreeNode graNode = (DefaultMutableTreeNode) graPath .getLastPathComponent(); GraGraTreeNodeData graData = (GraGraTreeNodeData) graNode .getUserObject(); EdRule inverseRule = graData.getGraGra().reverseRule(data.getRule(), true); if (inverseRule != null) { treeView.putRuleIntoTree(inverseRule, (DefaultMutableTreeNode) node.getParent(), ((DefaultMutableTreeNode) node.getParent()).getIndex(node) + 1); if (!inverseRule.getBasisRule().getErrorMsg().equals("")) { String warnMsg = inverseRule.getBasisRule().getErrorMsg().replaceAll(";", "<br>"); warnMsg = warnMsg.replaceAll("\n", "<br>"); JOptionPane.showMessageDialog(treeView.getFrame(), "<html><body>" +"During reverting the following occurred:<br><br>" +"<font color=\"#FF0000\">" +warnMsg +"</font>" +"<br>The new inverse rule: " +inverseRule.getName() +"<br>is added after its original rule into the rule set.<br><br>", "Inverse Rule: "+inverseRule.getName(), JOptionPane.WARNING_MESSAGE); } else { JOptionPane.showMessageDialog(treeView.getFrame(), "<html><body>" +"Inverting was successful.<br><br>" +"The new inverse rule: " +inverseRule.getName()+"<br>" +"is added after its original rule into the rule set.<br><br>", "Inverse Rule: "+inverseRule.getName(), JOptionPane.INFORMATION_MESSAGE); } } else { JOptionPane.showMessageDialog(treeView.getFrame(), "<html><body>" +"It isn't possible to invert the rule:<br> "+data.getRule().getName()+".", "Inverse Rule", JOptionPane.ERROR_MESSAGE); } } void minimalRule() { if (this.path == null) { String s = "Bad selection.\n Please select a rule."; JOptionPane.showMessageDialog(null, s, "", JOptionPane.WARNING_MESSAGE); return; } final DefaultMutableTreeNode node = (DefaultMutableTreeNode) this.path.getLastPathComponent(); GraGraTreeNodeData data = (GraGraTreeNodeData) node.getUserObject(); TreePath graPath = this.path.getParentPath(); DefaultMutableTreeNode graNode = (DefaultMutableTreeNode) graPath .getLastPathComponent(); GraGraTreeNodeData graData = (GraGraTreeNodeData) graNode .getUserObject(); EdRule minRule = graData.getGraGra().makeMinimalRule(data.getRule(), true); if (minRule != null) { treeView.putRuleIntoTree(minRule, (DefaultMutableTreeNode) node.getParent(), ((DefaultMutableTreeNode) node.getParent()).getIndex(node) + 1); if (minRule.getBasisRule().getErrorMsg().indexOf("identical") >= 0) { String warnMsg = minRule.getBasisRule().getErrorMsg(); JOptionPane.showMessageDialog(treeView.getFrame(), "<html><body>" +warnMsg+"<br>" +"It is added after its original rule into the rule set.<br><br>", "Minimal Rule : "+minRule.getName(), JOptionPane.WARNING_MESSAGE); } else { JOptionPane.showMessageDialog(treeView.getFrame(), "<html><body>" +"The minimal rule is added after its original rule.<br><br>", "Minimal Rule : "+minRule.getName(), JOptionPane.INFORMATION_MESSAGE); } } else { JOptionPane.showMessageDialog(treeView.getFrame(), "<html><body>" +"It isn't possible to make a minimal rule from:<br> " +data.getRule().getName()+"."+"<br>", "Minimal Rule Failed", JOptionPane.ERROR_MESSAGE); } } void makeRuleScheme() { if (this.path == null) { String s = "Bad selection.\n Please select a rule."; JOptionPane.showMessageDialog(null, s, "", JOptionPane.WARNING_MESSAGE); return; } final DefaultMutableTreeNode node = (DefaultMutableTreeNode) this.path.getLastPathComponent(); GraGraTreeNodeData data = (GraGraTreeNodeData) node.getUserObject(); TreePath graPath = this.path.getParentPath(); DefaultMutableTreeNode graNode = (DefaultMutableTreeNode) graPath .getLastPathComponent(); GraGraTreeNodeData graData = (GraGraTreeNodeData) graNode .getUserObject(); EdRuleScheme rs = graData.getGraGra().createRuleScheme(data.getRule()); if (rs != null) { treeView.putRuleSchemeIntoTree(rs, (DefaultMutableTreeNode) node.getParent(), ((DefaultMutableTreeNode) node.getParent()).getIndex(node) + 1); JOptionPane.showMessageDialog(treeView.getFrame(), "<html><body>" +"The new rule scheme: " +rs.getName()+"<br>" +"is added after its original rule into the rule set.<br><br>", "Rule Scheme: "+rs.getName(), JOptionPane.INFORMATION_MESSAGE); } else { JOptionPane.showMessageDialog(treeView.getFrame(), "<html><body>" +"It isn't possible to invert the rule:<br> "+data.getRule().getName()+".", "Inverse Rule", JOptionPane.ERROR_MESSAGE); } } GraGraTreeView treeView; TreePath path; DefaultMutableTreeNode node; GraGraTreeNodeData data; EdRule rule; int posX, posY; private JMenuItem miDelete, miDisabled, miAC, miAC1, miFormula, miNAC, miNAC1, miPAC, miParallelApply, miAnimated, miPostAC, miPostACdel, miLayer, miPriority, miCopy, miInverse, miMinimal, miMakeRS, //miConcurrent, miMove, miWait, miComment, miAttrContext, miSignature; boolean enableNestedAC; }