!7 set flag WebWithRelationsMap. set flag AllPublic. concept Drawing { S globalID = aGlobalID(); S name; S calStructure; } static new CirclesAndLines cal; static Canvas canvas; static Drawing drawing; static JLabel lblGlobalID; sbool autoVis; p { autoRestart(); useDBOf(#1007609); db(); fixGlobalIDs(); substance(); swing { fixCAL(); canvas = cal.show(1000, 600); makeMenu(); addToWindowNorth(canvas, withMargin(jcenteredline( jbutton("New drawing", f newDrawing), lblGlobalID = jlabel(), jbutton("New circle", f newCircle) ))); addToWindow(canvas, withMargin(jcenteredline( jbutton("Save drawing", f saveDrawing), jbutton("Save drawing as...", f saveDrawingAs), jbutton("PUBLISH", f publish))); //addToWindow(canvas, withMargin(jcenteredlabel("Create connections by dragging between circles with right mouse button"))); addDrawingsList(); centerFrame(canvas); hideConsole(); } bot("Circles Editor."); sleepIfMain(); } svoid newCircle { final JTextField text = jtextfield(); showFormTitled("New Circle", "Text", text, r-thread { loading { S theText = getTextTrim(text); newCircle(theText); }}); } svoid newCircle(S theText) { double x = random(0.2, 0.8), y = random(0.2, 0.8); if (autoVis) cal.circle_autoVis(theText, x, y); else cal.circle(theText, x, y); canvas.update(); } static Drawing saveDrawing() { ret saveDrawing(drawing != null ? drawing.name : ""); } static Drawing saveDrawing(S name) { if (empty(name)) { final JTextField tfName = jtextfield(makeUpName()); showFormTitled("Name drawing", "Name", tfName, r { saveDrawing(or2(getTextTrim(tfName), "Untitled")); }); null; } cal.title = name; if (drawing == null) drawing = cnew(Drawing); cal.globalID = drawing.globalID; S s = cal_structure(cal); cset(drawing, calStructure := s, +name); setDrawing(drawing); ret drawing; } svoid newDrawing { setCAL(new CirclesAndLines); setDrawing(null); newCircle(); } svoid makeMenu { /*if (hasSSHPassword("root", "tinybrain.de")) addMenu(canvas, "Menu", "Upload all drawings to tinybrain.de (only for Stefan ^^)", f uploadAll);*/ addMenu(canvas, "Menu", "Upload all drawings!", f uploadAll2); } sS drawingName(Drawing d) { ret d == null ? "" : "[" + d.id + "] " + (nempty(d.name) ? quote(d.name) + " " : ""); } static L makeDrawingsTable() { new L l; for (final Drawing d : reversed(list(Drawing))) { CirclesAndLines cal = cal_unstructure(d.calStructure); l.add(litorderedmap("Drawing" := drawingName(d), "Circles + Relations" := join("|", concatLists( collect(cal.circles, 'text), collectTreeSet(cal.lines, 'text))))); } ret l; } static Drawing drawingFromTable(JTable table, int row) { ret getConcept(Drawing, parseFirstLong((S) getTableCell(table, row, 0))); } svoid addDrawingsList { final JTable table = sexyTableWithoutDrag(); O load = voidfunc(int row) { loadDrawing(drawingFromTable(table, row)) }; onDoubleClick(table, load); tablePopupMenu(table, voidfunc(JPopupMenu menu, final int row) { final Drawing d = drawingFromTable(table, row); addMenuItem(menu, "ID: " + d.globalID, r { copyTextToClipboard(d.globalID) }); }); tablePopupMenuItem(table, "Rename...", voidfunc(int row) { final Drawing d = drawingFromTable(table, row); final JTextField tf = jtextfield(d.name); showFormTitled("Rename Drawing", "Old name", jlabel(d.name), "New name", tf, r { cset(d, name := getTextTrim(tf)); setDrawing(d); }); }); tablePopupMenuItem(table, "Show structure", voidfunc(int row) { final Drawing d = drawingFromTable(table, row); showWrappedText("Structure of drawing", cal_simplifiedStructure(d.calStructure)); }); tablePopupMenuItem(table, "Copy structure to clipboard", voidfunc(int row) { final Drawing d = drawingFromTable(table, row); copyTextToClipboard(cal_simplifiedStructure(d.calStructure)); }); tablePopupMenuItem(table, "Delete", voidfunc(int row) { final Drawing d = drawingFromTable(table, row); removeConcept(d); }); addToWindowSplitRight_aggressive(canvas, tableWithSearcher(table), 0.7f); awtCalcOnConceptsChange(table, r { dataToTable(table, makeDrawingsTable()) }); } svoid fixCAL() { cal.imageForUserMadeNodes = whiteImage(10, 10); } svoid setCAL(CirclesAndLines cal) { main.cal = cal; fixCAL(); Canvas c = canvas; canvas = cal.makeCanvas(); awtReplaceComponent(c, canvas); //new CirclesRelater(canvas, cal); } svoid setDrawing(Drawing d) { drawing = d; setText(lblGlobalID, drawing != null ? "Drawing ID: " + drawing.globalID : ""); setFrameTitle(canvas, trim(drawingName(d)) + " - " + programName()); } svoid loadDrawing(Drawing d) { setDrawing(d); CirclesAndLines cal = cast unstructure(d.calStructure); //cal_setAutoVis(cal); setCAL(cal); } svoid publish { final Drawing d = saveDrawing(); if (d == null) ret; thread { loading { S fullName = "Drawing " + d.globalID + " " + renderDate(now()) + " - " + or2(d.name, "Untitled"); S url = uploadToImageServer(canvas.getImage(), fullName); infoBox("Image uploaded to server! " + url); S id = createSuperHighSnippet(structure(d), fullName, 56 /*SN_AI_DRAWING*/, null, null); infoBox("Drawing uploaded. " + fsI(id)); }} } sS makeUpName() { Circle c = first(cal.circles); ret c == null ? "" : c.text; } svoid saveDrawingAs { drawing = cnew(Drawing); saveDrawing(); } svoid uploadAll { fixGlobalIDs(); run(#1009985); } svoid uploadAll2 { runInNewThread_awt(#1010485); } answer { if "new diagram with node *" { swing { activateFrame(canvas); newDrawing(); if (nempty($1)) newCircle($1); } ret "OK"; } } svoid fixGlobalIDs { for (Drawing d) pcall { if (!d.calStructure.contains(d.globalID)) { print("Fixing global ID: " + d.globalID); CirclesAndLines cal = cal_unstructure(d.calStructure); cal.globalID = d.globalID; cset(d, calStructure := cal_structure(cal)); } } }