!7 static int perPage = 8; static L guessPrograms = ll(#1008721, #1008696, #1008704, #1008723); static SingleComponentPanel scp; static JTextArea detailTextArea; static int startIndex; static new L guessModules; static ReliableSingleThread relearnThread = new(f relearn); static new TreeSet keys; concept Sentence { S text; new SS data; S getPart(IntRange r) { ret substring(text, r); } } p-substance { unswing { db(); indexConceptField(Sentence, "text"); gatherKeys(); L sentences = toLinesFullTrim(loadSnippet(#1008606)); sentences = notStartingWith("\"", sentences); time { makeUniqueConcepts(Sentence, "text", sentences); } for (S id : guessPrograms) pcall { guessModules.add(runDependent(id)); } } JSplitPane split; showFrame(centerAndSouth( split = jvsplit( scp = new SingleComponentPanel, detailTextArea = jtypewritertextarea()), withTopMargin(20, jcenteredline( textActionButton("Mark as...", f mark), jbutton("Prev", r { makePanel(max(startIndex-perPage, 0)) }), jbutton("Next", f nextPage), jbutton("Random", r { makePanel(random(countConcepts(Sentence))/perPage*perPage) }), jbutton("All OK", r { clickButtons(findButtons(scp, "OK")); nextPage(); }), jbutton("Add sentence...", f addSentence), //jbutton("Re-learn", r { relearnThread.trigger() }) )))); addMenu(scp, "Actions", "Rename key...", f renameKey, "Load sentences from web bot...", f fromWebBot, "Load text2tag snippet...", f loadText2Tag, "Apply splittings", f applySplittings); setFrameSize(scp, 1000, 600); setSplitPaneLater(split, 0.8); // try it again centerFrame(scp); makePanel(0); } svoid makePanel(int startIndex) { main.startIndex = startIndex; makePanel(); } svoid makePanel() { JPanel panel = gridLayoutPanel_trackWidth_evenlySpacedCols(2); panel.add(jlabel("Sentence")); panel.add(jlabel("Analysis")); for (final Sentence s : takeFirst(perPage, dropFirst(startIndex, orderByFieldDesc("created", list(Sentence))))) { final JTextField tfText = jtextfield_caretLeft(s.text); tfText.setCaret(new DefaultCaret { @Override public void setSelectionVisible(boolean visible) { super.setSelectionVisible(true); } }); panel.add(tfText); final JTextField tf = jtextfield_caretLeft(dataMapToString(s.data)); onFocus(tf, r { updateDetail(tf) }); final JTextField tfGuess = jtextfield_caretLeft(dataMapToString(makeGuess(s.text))); onFocus(tfGuess, r { updateDetail(tfGuess) }); final new Var reviseBtn, okBtn; okBtn.set(jbutton("OK", r { pcall-messagebox { cset(s, data := dataMapFromString(getTextTrim(tf))); disableTextField(tf); replaceComponent(okBtn!, reviseBtn!); relearnThread.trigger(); } })); reviseBtn.set(jbutton("Revise", r { cset(s, data := new HashMap); enableTextField(tf); replaceComponent(reviseBtn!, okBtn!); })); onUpdateAndNow(tf, r { okBtn->setEnabled(nempty(getTextTrim(tf))) }); bool hasData = nempty(s.data); if (hasData) disableTextField(tf); panel.add(vstack( centerAndEast(withLabel("Saved:", tf), hasData ? reviseBtn! : okBtn!), centerAndEast(withLabel("Guess:", tfGuess), jbutton("OK", r { pcall-messagebox { s.data.putAll(dataMapFromString(getTextTrim(tfGuess))); s.change(); disableTextField(tf); replaceComponent(okBtn!, reviseBtn!); relearnThread.trigger(); } })), )); } scp.setComponent(jscroll(panel)); } svoid relearn { for (O guessModule : guessModules) pcall { callMain(guessModule); } swing { makePanel(); } } svoid nextPage { if (startIndex+perPage < countConcepts(Sentence)) makePanel(startIndex+perPage); } static S dataMapToString(SS data) { ret dataMapToString(data, ". "); } static S dataMapToString(SS data, S glue) { ret join(glue, mapMapToList(withoutNulls(data), func(S a, S b) { a + "=" + b })); } static SS dataMapFromString(S input) { new SS data; for (S s : trimAll(splitByJavaToken(input, "."))) { L tok = javaTok(s); int i = tok.indexOf("="); if (i < 0) continue; data.put(trimJoinSubList(tok, 0, i), trimJoinSubList(tok, i+1)); } ret data; } static SS makeGuess(S sentence) { new SS data; for (O guessModule : guessModules) if (hasMethodNamed(guessModule, "guess")) pcall(guessModule, "guess", sentence, data); // new way else pcall(guessModule, "callGuesser", get(guessModule, "best"), sentence, data); ret data; } svoid mark(JTextComponent c) { final IntRange r = textComponentSelection(c); fS selection = c.getSelectedText(); fS text = c.getText(); //final JTextField tf = jtextfield("verb"); final AutoComboBox cb = autoComboBox(keys); showFormTitled("Mark sentence part", "Text", selection + " (" + r.start + "/" + r.length() + ")", "Mark as", cb, func { pcall-infobox { S as = getTextTrim(cb); Sentence s = findConcept(Sentence, +text); s.data.put(as, ai_renderAction(text, r)); s.change(); gatherKeys(s); relearnThread.trigger(); null; } false; }); } svoid addSentence { final JTextField tf = jtextfield(); showFormTitled("Add sentence", "Sentence", tf, r { uniq(Sentence, text := getTextTrim(tf)); makePanel(0); }); } svoid renameKey { final AutoComboBox tf1 = autoComboBox(keys); final JTextField tf2 = jtextfield(); showFormTitled("Rename key", "Old key name", tf1, "New key name", tf2, r { S oldKey = getTextTrim(tf1); S newKey = getTextTrim(tf2); int n = 0; for (Sentence s) { S value = s.data.get(oldKey); if (value != null) { s.data.remove(oldKey); s.data.put(newKey, value); s.change(); ++n; } } infoBox(n(n, "changes") + " made"); keys.clear(); gatherKeys(); makePanel(); }); } svoid gatherKeys { keys.clear(); for (Sentence s) gatherKeys(s); } svoid gatherKeys(Sentence s) { keys.addAll(keys(s.data)); } svoid fromWebBot { final JTextField tf = jtextfield(#1008316); showFormTitled("Load sentences from web bot", "Chat Bot ID", tf, r { Collection sentences = keys(getSentencesFromWebBotLog(getTextTrim(tf))); makeUniqueConcepts(Sentence, "text", sentences); makePanel(0); }); } svoid loadText2Tag { final JTextField tf = jtextfield(#1008363); showFormTitled("Load text 2 tag snippet", "Snippet ID", tf, r { Pair p = tok_dropAsterisks_pair(parseText2Tag(#1008363)); Collection sentences = concatLists(keys(p.a), keys(p.b)); makeUniqueConcepts(Sentence, "text", sentences); for (S tag : values(p.a)) { Sentence s = uniq(Sentence, text := tag); s.data.put("isTag", "t"); s.change(); } makePanel(0); }); } svoid applySplittings { bool change = false; for (Sentence s) { IntRange firstPart = ai_parseAction(s.data.get("firstPart")); if (firstPart != null) { if (makeUniqueConcepts(Sentence, "text", ll(trim(s.getPart(firstPart)), trim(substring(s.text, firstPart.end)))) != 0) change = true; } } if (change) makePanel(0); } svoid updateDetail(JTextField tf) { pcall-short { SS data = dataMapFromString(getTextTrim(tf)); detailTextArea.setText(dataMapToString(data, "\n")); } }