!7 sS in = 'Input, out = 'Output; static L data; static JTable table; static JComboBox cbFunction; static L history; //static Var historyIdx; static JLabel lblHistory; concept HistoryEntry { L data; S functionApplied; } concept Code { S code; } p-subst { newCase(); db(); history = persistentList("History"); //historyIdx = persistentVar("History index", 0); cbFunction = autoComboBox(asTreeSet(listPlus(standardFunctionNames(), "undo", "sort by input", "sort by output", "finish"))); onEnter(cbFunction, f apply); JComponent controls = centerAndEast(withLabel("Function:", cbFunction), jbutton("Apply", f apply)); data = mapToListOfOrderedMap(sentenceTypeExamples(), in, out); history.add(cnew(HistoryEntry, data := cloneList(data))); table = showTable(data); addToWindow(table, withMargin(controls)); addToWindow(table, withMargin(lblHistory = jlabel())); update(); makeAndCall_warmUp("lower"); } svoid apply { q.add(r { apply_doIt(getTextTrim(cbFunction)) }); } static Q q = startQ(); svoid apply_doIt(fS fName) { loading { if (eqic("undo", fName)) { if (l(history) < 2) { infoBox("Nothing to undo"); ret; } S f = popLast(history).functionApplied; infoBox("Undoing " + f); HistoryEntry e = last(history); data = e.data; } else try { if (eqic("sort by output", fName)) data = sortedByMapElement(data, out); else if (eqic("sort by input", fName)) data = sortedByMapElement(data, in); else if (eqic("finish", fName)) makeCode(); else data = map(data, func(Map map) { litorderedmap(in, makeAndCall(fName, map.get(in)), out, map.get(out)) }); history.add(cnew(HistoryEntry, functionApplied := fName, data := cloneList(data))); } catch e { messageBox(e); ret; } table = showTable(table, data); update(); } } svoid update { S dt = "Data type: " + join("/", new TreeSet(map className(collectMapElement(data, in)))); setText(lblHistory, dt + ". History: " + (l(history) <= 1 ? "-" : join(" -> ", collect(dropFirst(history), 'functionApplied)))); } svoid makeCode { new MultiMap mm; for (Map map : data) mm.put(map.get(in), map.get(out)); L functions = reversed(notStartingWith("sort by", collectNotNull(history, 'functionApplied))); S mapCode = structureToJava(mapValues(f listToTopTen, multiMapToMap(mm))); S code = "first(mapGet(" + mapCode + ", " + renderNestedFunctionCalls(functions, "input") + "))"; cset(uniq(Code), +code); showText("Code", code); }