!7 sS in = 'Input, out = 'Output; static L data; static JTable table; static JComboBox cbFunction; static L history; //static Var historyIdx; concept HistoryEntry { L data; S functionApplied; } p-subst { newCase(); db(); history = persistentList("History"); //historyIdx = persistentVar("History index", 0); cbFunction = autoComboBox(standardFunctionNames()); 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)); makeAndCall_warmUp("lower"); } svoid apply { thread "Apply" { loading { fS fName = getTextTrim(cbFunction); if (eqic("undo", fName)) { if (empty(history)) { infoBox("Nothing to undo..."); ret; } HistoryEntry e = popLast(history); infoBox("Undoing " + e.functionApplied); data = e.data; } 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))); } table = showTable(table, data); } } }