!7 set flag DynModule. cmodule TestRuleEngine2 > DynSCP { S input, processedInput, dialogHistory; transient ReliableSingleThread rstCalc = dm_rstWithPostDelay(this, r calc, 500); transient int maxResults = 500; transient bool skipBadPredictions = true; transient JTree jTree; transient GazelleTree root; transient double qualityCutOff = -0.75; transient JLabel lblInfo; S switchableFields() { ret "skipBadPredictions maxResults"; } enhanceFrame { internalFrameIcon(f, gazelle_frameIcon()); } start { dm_vmBus_onMessage('gazelleRulesChanged, rstCalc); } visualize { jTree = jDynamicTree(null, func(GazelleTree tree) -> L { dm_gazelle_getChildren(tree, +qualityCutOff, dialogHistory := tlft(dialogHistory)) }, makeChildrenIsFast := true); onTreeSelectionChanged(jTree, r updateInfo); treePopupMenu(jTree, voidfunc(JPopupMenu menu, final GazelleTree e) { addMenuItem(menu, "Copy line", rThread { copyTextToClipboard(e.line) }); addMenuItem(menu, "Make rule...", rThread { S s = e.line; GazelleTree ee = e; while ((ee = ee.parent) != null) s = ee.line + "\n+ " + s; dm_gazelle_newRuleDialog_3(s, "in = dialog"); }); addMenuItem(menu, "Enter", rThread { LS history = e.history(); /*if (oddLength(history)) setField(input := popLast(history));*/ setField(dialogHistory := lines(history)); }); }); JComponent tf = dm_textField('input); onChangeAndNow(tf, rstCalc); ret jvsplit(0.25, withMargin(withTitle("Dialog History", onChange(dm_textArea('dialogHistory), rstCalc))), northCenterAndSouthWithMargins( centerAndEastWithMargin( tf, jbutton("Make rule...", rThread { dm_gazelle_newRuleDialog_2(input) })), super.visualize(), vstackWithSpacing( rightAlignedButtons( treeDependentButton(jTree, "Mark good", rMark('good)), treeDependentButton(jTree, "Mark bad", rMark('bad)), treeDependentButton(jTree, "Mark funny", rMark('funny)), jPopDownButton_noText( "Export Rule Engine", rThread exportEngine) ), lblInfo = jlabel() ))); } visualize2 { ret jscroll(jTree); } Runnable rMark(fS judgement) { ret rThread { GazelleTree e = selected(); e.judgement = judgement; jTree_fireUserObjectChanged(jTree, e); saveEntry(e); }; } GazelleTree selected() { ret (GazelleTree) jtree_selectedUserObject(jTree); } void calc { S input = this.input; root = new GazelleTree(input); jTree_setRootObject(jTree, root); jtree_collapseAndOpenRootNode(jTree); processedInput = input; } void saveEntry(GazelleTree e) { S modifiedRule = e.mr.applyMapping().asText(); dm_gazelle_saveAppliedRule( +modifiedRule, judgement := e.judgement, matchedRuleStruct := struct(e.mr)); } void updateInfo enter { S s = " "; GazelleTree e = selected(); if (e != null && e.mr != null) { RuleEngine2.Rule r = e.mr.rule; s = "Rule: " + r.globalID + " (" + newLinesToSpaces_trim(r.text) + ")"; } setText(lblInfo, s); } void exportEngine enter { showText("Rule Engine", structWordWrap(root.ctx)); } }