!7 // class AIConcept comes from #1007160 concept ImportedFrom { S snippetID; long lastTime; } static JTable table; volatile sbool grabImages = true; volatile static double imageGrabberDelay = 1; // seconds, min 1 p-substance { conceptsAndBot(); startImageGrabber(); showConceptsTable_postProcess.set(f reversedList); table = makeConceptsTable(AIConcept, func(AIConcept c) { litorderedmap("Concept ID" := c.globalID, "Name/Description" := c.name, "Comments" := c.comment, "Has Image?" := c.pngFile.has(), "Imported From" := c.importedFrom, "Exportable" := c.exportable) }); showFrame(makeTitle(), tableWithSearcher(table)); onEnter(tableSearchField(table), f newConcept); onDoubleClick(table, r { editConcept(selectedConcept()) }); addToWindow(table, jRightAlignedLine( jbutton("New Concept...", f newConcept), tableDependButton(table, "Edit", r { editConcept(selectedConcept()) }), tableDependButton(table, "Duplicate", r { newConcept(selectedConcept()) }), jbutton("Export", f doExport), jbutton("Import...", f doImport))); tablePopupMenu(table, voidfunc(JPopupMenu menu, final int row) { addMenuItem(menu, "Edit...", r { final S globalID = (S) getTableCell(table, row, 0); editConcept(findConcept(AIConcept, +globalID)); }); addMenuItem(menu, "Delete", r { final S globalID = (S) getTableCell(table, row, 0); withDBLock(r { deleteConceptsWhere(AIConcept, +globalID) }); }); }); tableEnableTextDrag(table); awtOnConceptChanges(table, 1000, r { setFrameTitle(table, makeTitle()) }); //hideConsole(); } svoid editConcept(final AIConcept c) { if (c == null) ret; final JTextField a = jTextField(c.name); final JTextField b = jTextField(c.comment); final JTextField cc = jTextField(c.globalID); final ImageChooser ic = new ImageChooser(c.pngFile.has() ? c.pngFile->getImage() : null); Runnable r = r { BufferedImage image = ic.getImage(); if (image == null && c.pngFile.has()) { //c.pngFile->delete(); c.pngFile.clear(); } else if (image != null && (!c.pngFile.has() || !imagesIdentical(c.pngFile->getImage(), image))) { //if (c.pngFile.has()) c.pngFile->delete(); c.pngFile.set(new PNGFile(image)); } cset(c, name := getTextTrim(a), comment := getTextTrim(b), globalID := getTextTrim(cc)); }; O[] params = { "Description/Name", a, "Comment (optional)", b, "Global ID", cc, "Example Image (optional)", ic, r }; //for i over params: print("#" + i + ": " + params[i]); renameSubmitButton("Save", showFormTitled("Edit concept " + c.globalID, params)); } sS searcherInput() { ret getTextTrim(tableSearchField(table)); } svoid newConcept { newConcept(null); } svoid newConcept(AIConcept c) { final JTextField a = jTextField(c == null ? searcherInput() : c.name); final JTextField b = jTextField(getString(c, "comment")); final JTextField cc = jTextField(aGlobalID()); final new ImageChooser ic; Runnable r = r { cnew(AIConcept, name := getTextTrim(a), comment := getTextTrim(b), globalID := getTextTrim(cc), pngFile := ic.createPNGFile()) }; renameSubmitButton("Create", showFormTitled("New concept", "Description/Name", a, "Comment (optional)", b, "Global ID", cc, "Example Image (optional)", ic, r)); } static AIConcept selectedConcept() { ret findConcept(AIConcept, globalID := selectedTableCell(table, 0)); } svoid doImport { ImportedFrom last = last(sortedByField("lastTime", list(ImportedFrom))); final JTextField tf = jTextField(last == null ? #1007208 : last.snippetID); showFormTitled("Import A. I. Concepts", "Snippet ID", tf, r-thread { loading { importFrom(getTextTrim(tf)); } }); } svoid importFrom(S snippetID) { snippetID = fsI(snippetID); cset(uniq(ImportedFrom, +snippetID), lastTime := now()); S text = loadSnippet(snippetID); Concepts newConcepts = new Concepts(snippetID).safeLoad(text); print(n(list(newConcepts, "AIConcept"), "concept") + " loaded from " + snippetID); Concepts myConcepts = new Concepts(#1006463).load(); print("I have " + n(list(myConcepts, "AIConcept"), "concept"); Map myIDs = indexByField(list(myConcepts, AIConcept), "globalID"); int nNew = 0; for (Concept c : list(newConcepts, "AIConcept")) { S id = getString(c, "globalID"); bool has = myIDs.containsKey(id); print("ID: " + id + " - " + (has ? "I have it" : "I don't have it")); if (!has) { AIConcept c2 = cnew(AIConcept, importedFrom := snippetID); copyConceptFields(c, c2, "globalID", "name", "comment"); myIDs.put(id, c2); ++nNew; } } infoBox("Import done. " + n(nNew, "new concepts")); } svoid doExport { thread { loading { main.run(#1007207); } } } sS makeTitle() { ret "My AI Concepts [" + countConcepts(AIConcept) + "]"; } svoid startImageGrabber { thread "Image Grabber" { repeat with sleep imageGrabberDelay { if (grabImages) { AIConcept c = findConcept(AIConcept, suggestedImage := null); if (c != null) { S query = c.name; Window box = infoBox("Visualizing: " + c.name); showAnimation(quickVisualize(query), c.name, 4); disposeWindow(box); cset(c, suggestedImage := new PNGFile(quickVisualize_imagePath(query))); } } } } }