!7 // class AIConcept comes from #1007160 concept ImportedFrom { S snippetID; long lastTime; } static JTable table; static JCheckBox cbGrabImages; 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, withMargin(vstack( 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)), withTopMargin(jRightAlignedLine(cbGrabImages = jCheckBox("Google For Images", grabImages)))))); tablePopupMenu(table, voidfunc(JPopupMenu menu, final int row) { final S globalID = (S) getTableCell(table, row, 0); final AIConcept c = findConcept(AIConcept, +globalID); addMenuItem(menu, "Edit...", r { editConcept(c) }); addMenuItem(menu, "Delete", r { withDBLock(r { deleteConcept(c) }); }); if (c.searchedForSuggestedImage) addMenuItem(menu, "Search for image again", r { deleteConcept(c.suggestedImage); cset(c, suggestedImage := null, searchedForSuggestedImage := false) }); }); 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->getImageSafe() : null); ic.titleForUpload = c.name; PNGFile png = c.suggestedImage!; final ImageChooser ic2 = new ImageChooser(png != null ? png.getImageSafe() : null); final Var md5 = new Var(md5OfPNGFile(png)); awtOnConceptChanges(ic2, r { ic2.titleForUpload = c.name; PNGFile png = c.suggestedImage!; S newMD5 = md5OfPNGFile(png); if (png != null && neq(md5.get(), newMD5)) { md5.set(newMD5); ic2.setImage(png.getImageSafe()); } }, true); 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)", westAndEast(ic, withLeftMargin(20, northAndCenter(vstack( jbutton("Accept", r { ic.setImage(ic2.getImage()); findButton(getFrame(ic), "Save").doClick(); }), jCenteredLabel("Suggested image:")), ic2))), 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(final AIConcept c) { final JTextField a = jTextField(c == null ? searcherInput() : c.name); final JTextField b = jTextField(getString(c, "comment")); final JTextField cc = jTextField(aGlobalID()); final JLabel lbl = jCenteredLabel("Suggested image:"); final new ImageChooser ic; final new ImageChooser ic2; final new Var md5; awtCalcRegularly(ic2, 500, 0, new Runnable { S lastTyped, lastSearched; public void run { S s = getTextTrim(a); if (nempty(s) && eq(s, lastTyped) && neq(s, lastSearched)) { lastSearched = s; lbl.setIcon(imageIcon(#1007255)); try { final BufferedImage img = quickVisualize(s); if (img != null) swing { ic2.setImage(img); } } finally { lbl.setIcon(null); } } lastTyped = s; } }); 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)", westAndEast(ic, withLeftMargin(20, northAndCenter(vstack( jbutton("Accept", r { ic.setImage(ic2.getImage()) }), lbl), ic2))), 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 (isChecked(cbGrabImages)) { AIConcept c = findConcept(AIConcept, suggestedImage := null, searchedForSuggestedImage := false); if (c != null) { cset(c, searchedForSuggestedImage := true); S query = c.name; //Window box = infoBox("Visualizing: " + c.name); BufferedImage img = quickVisualize(query); //disposeWindow(box); if (img != null) { showAnimation(img, c.name, 4); cset(c, suggestedImage := new PNGFile(quickVisualize_imagePath(query))); } else infoBox("No image found"); } } } } }